From e73f852c6e8924f65a1443c4623841c6553a2691 Mon Sep 17 00:00:00 2001 From: Dmitry Volyntsev Date: Wed, 26 Aug 2020 14:55:47 +0000 Subject: [PATCH] Generator: simplified runtime errors generation. --- src/njs_disassembler.c | 24 ++++++++++++++-- src/njs_generator.c | 23 ++++----------- src/njs_vmcode.c | 25 +++++++--------- src/njs_vmcode.h | 12 ++++---- src/test/njs_unit_test.c | 62 ++++++++++++++++++++-------------------- test/njs_expect_test.exp | 14 +++++---- 6 files changed, 83 insertions(+), 77 deletions(-) diff --git a/src/njs_disassembler.c b/src/njs_disassembler.c index b4b1a21b..af99cafb 100644 --- a/src/njs_disassembler.c +++ b/src/njs_disassembler.c @@ -167,8 +167,10 @@ njs_disassemble(njs_vm_code_t *code) uint32_t line; njs_str_t *name; njs_uint_t n; + const char *type; njs_code_name_t *code_name; njs_vmcode_jump_t *jump; + njs_vmcode_error_t *error; njs_vmcode_1addr_t *code1; njs_vmcode_2addr_t *code2; njs_vmcode_3addr_t *code3; @@ -451,10 +453,26 @@ njs_disassemble(njs_vm_code_t *code) continue; } - if (operation == NJS_VMCODE_REFERENCE_ERROR) { - njs_printf("%5uD | %05uz REFERENCE ERROR\n", line, p - start); + if (operation == NJS_VMCODE_ERROR) { + error = (njs_vmcode_error_t *) p; - p += sizeof(njs_vmcode_reference_error_t); + switch (error->type) { + case NJS_OBJ_TYPE_REF_ERROR: + type = "REFERENCE"; + break; + + case NJS_OBJ_TYPE_TYPE_ERROR: + type = "TYPE"; + break; + + case NJS_OBJ_TYPE_ERROR: + default: + type = ""; + } + + njs_printf("%5uD | %05uz %s ERROR\n", line, p - start, type); + + p += sizeof(njs_vmcode_error_t); continue; } diff --git a/src/njs_generator.c b/src/njs_generator.c index 31192718..1730986e 100644 --- a/src/njs_generator.c +++ b/src/njs_generator.c @@ -3459,9 +3459,8 @@ static njs_int_t njs_generate_reference_error(njs_vm_t *vm, njs_generator_t *generator, njs_parser_node_t *node) { - njs_jump_off_t ret; - const njs_lexer_entry_t *lex_entry; - njs_vmcode_reference_error_t *ref_err; + njs_vmcode_error_t *ref_err; + const njs_lexer_entry_t *lex_entry; if (njs_slow_path(!node->u.reference.not_defined)) { njs_internal_error(vm, "variable is not defined but not_defined " @@ -3469,24 +3468,14 @@ njs_generate_reference_error(njs_vm_t *vm, njs_generator_t *generator, return NJS_ERROR; } - njs_generate_code(generator, njs_vmcode_reference_error_t, ref_err, - NJS_VMCODE_REFERENCE_ERROR, 0, NULL); - - ref_err->token_line = node->token_line; - - ref_err->file.length = node->scope->file.length; - - if (ref_err->file.length != 0) { - ret = njs_name_copy(vm, &ref_err->file, &node->scope->file); - if (njs_slow_path(ret != NJS_OK)) { - return NJS_ERROR; - } - } + njs_generate_code(generator, njs_vmcode_error_t, ref_err, NJS_VMCODE_ERROR, + 0, NULL); + ref_err->type = NJS_OBJ_TYPE_REF_ERROR; lex_entry = njs_lexer_entry(node->u.reference.unique_id); if (njs_slow_path(lex_entry == NULL)) { return NJS_ERROR; } - return njs_name_copy(vm, &ref_err->name, &lex_entry->name); + return njs_name_copy(vm, &ref_err->u.name, &lex_entry->name); } diff --git a/src/njs_vmcode.c b/src/njs_vmcode.c index c4e38d43..31b4239a 100644 --- a/src/njs_vmcode.c +++ b/src/njs_vmcode.c @@ -49,7 +49,7 @@ static njs_jump_off_t njs_vmcode_try_end(njs_vm_t *vm, njs_value_t *invld, njs_value_t *offset); static njs_jump_off_t njs_vmcode_finally(njs_vm_t *vm, njs_value_t *invld, njs_value_t *retval, u_char *pc); -static void njs_vmcode_reference_error(njs_vm_t *vm, u_char *pc); +static void njs_vmcode_error(njs_vm_t *vm, u_char *pc); /* * These functions are forbidden to inline to minimize JavaScript VM @@ -217,7 +217,7 @@ next: pc += sizeof(njs_vmcode_prop_get_t); if (ret == NJS_OK) { - pc += sizeof(njs_vmcode_reference_error_t); + pc += sizeof(njs_vmcode_error_t); } goto next; @@ -888,8 +888,8 @@ next: break; - case NJS_VMCODE_REFERENCE_ERROR: - njs_vmcode_reference_error(vm, pc); + case NJS_VMCODE_ERROR: + njs_vmcode_error(vm, pc); goto error; default: @@ -1859,21 +1859,16 @@ njs_vmcode_finally(njs_vm_t *vm, njs_value_t *invld, njs_value_t *retval, static void -njs_vmcode_reference_error(njs_vm_t *vm, u_char *pc) +njs_vmcode_error(njs_vm_t *vm, u_char *pc) { - njs_str_t *file; - njs_vmcode_reference_error_t *ref_err; + njs_vmcode_error_t *err; - ref_err = (njs_vmcode_reference_error_t *) pc; + err = (njs_vmcode_error_t *) pc; - file = &ref_err->file; - - if (file->length != 0 && !vm->options.quiet) { - njs_reference_error(vm, "\"%V\" is not defined in %V:%uD", - &ref_err->name, file, ref_err->token_line); + if (err->type == NJS_OBJ_TYPE_REF_ERROR) { + njs_reference_error(vm, "\"%V\" is not defined", &err->u.name); } else { - njs_reference_error(vm, "\"%V\" is not defined in %uD", &ref_err->name, - ref_err->token_line); + njs_error_fmt_new(vm, &vm->retval, err->type, "%V", &err->u.message); } } diff --git a/src/njs_vmcode.h b/src/njs_vmcode.h index 1c90112a..9f1dd206 100644 --- a/src/njs_vmcode.h +++ b/src/njs_vmcode.h @@ -61,7 +61,7 @@ typedef uint8_t njs_vmcode_operation_t; #define NJS_VMCODE_TRY_END VMCODE0(37) #define NJS_VMCODE_CATCH VMCODE0(38) #define NJS_VMCODE_FINALLY VMCODE0(39) -#define NJS_VMCODE_REFERENCE_ERROR VMCODE0(40) +#define NJS_VMCODE_ERROR VMCODE0(40) #define NJS_VMCODE_NORET 127 @@ -386,10 +386,12 @@ typedef struct { typedef struct { njs_vmcode_t code; - njs_str_t name; - njs_str_t file; - uint32_t token_line; -} njs_vmcode_reference_error_t; + njs_object_type_t type; + union { + njs_str_t name; + njs_str_t message; + } u; +} njs_vmcode_error_t; njs_int_t njs_vmcode_interpreter(njs_vm_t *vm, u_char *pc); diff --git a/src/test/njs_unit_test.c b/src/test/njs_unit_test.c index eac1e8f8..0621bfb6 100644 --- a/src/test/njs_unit_test.c +++ b/src/test/njs_unit_test.c @@ -253,10 +253,10 @@ static njs_unit_test_t njs_test[] = njs_str("SyntaxError: Unexpected token \"_\" in 1") }, { njs_str("-_1"), - njs_str("ReferenceError: \"_1\" is not defined in 1") }, + njs_str("ReferenceError: \"_1\" is not defined") }, { njs_str("_1"), - njs_str("ReferenceError: \"_1\" is not defined in 1") }, + njs_str("ReferenceError: \"_1\" is not defined") }, /* Octal Numbers. */ @@ -2645,25 +2645,25 @@ static njs_unit_test_t njs_test[] = njs_str("1") }, { njs_str("a"), - njs_str("ReferenceError: \"a\" is not defined in 1") }, + njs_str("ReferenceError: \"a\" is not defined") }, { njs_str("\na"), - njs_str("ReferenceError: \"a\" is not defined in 2") }, + njs_str("ReferenceError: \"a\" is not defined") }, { njs_str("\n\na"), - njs_str("ReferenceError: \"a\" is not defined in 3") }, + njs_str("ReferenceError: \"a\" is not defined") }, { njs_str("a + a"), - njs_str("ReferenceError: \"a\" is not defined in 1") }, + njs_str("ReferenceError: \"a\" is not defined") }, { njs_str("a = b + 1"), - njs_str("ReferenceError: \"a\" is not defined in 1") }, + njs_str("ReferenceError: \"a\" is not defined") }, { njs_str("a = a + 1"), - njs_str("ReferenceError: \"a\" is not defined in 1") }, + njs_str("ReferenceError: \"a\" is not defined") }, { njs_str("a += 1"), - njs_str("ReferenceError: \"a\" is not defined in 1") }, + njs_str("ReferenceError: \"a\" is not defined") }, { njs_str("a += 1; var a = 2"), njs_str("undefined") }, @@ -3418,10 +3418,10 @@ static njs_unit_test_t njs_test[] = njs_str("undefined") }, { njs_str("typeof a; a"), - njs_str("ReferenceError: \"a\" is not defined in 1") }, + njs_str("ReferenceError: \"a\" is not defined") }, { njs_str("typeof a; a = 1"), - njs_str("ReferenceError: \"a\" is not defined in 1") }, + njs_str("ReferenceError: \"a\" is not defined") }, /**/ @@ -3446,7 +3446,7 @@ static njs_unit_test_t njs_test[] = njs_str("1 undefined") }, { njs_str("a = 1"), - njs_str("ReferenceError: \"a\" is not defined in 1") }, + njs_str("ReferenceError: \"a\" is not defined") }, { njs_str("var a; a = 1; a"), njs_str("1") }, @@ -3610,7 +3610,7 @@ static njs_unit_test_t njs_test[] = njs_str("{a:1,b:undefined}") }, { njs_str("var a = 1, b = 2; ({a,b,c})"), - njs_str("ReferenceError: \"c\" is not defined in 1") }, + njs_str("ReferenceError: \"c\" is not defined") }, { njs_str("var a = 1, b = 2; njs.dump({a,b,c:3})"), njs_str("{a:1,b:2,c:3}") }, @@ -9123,7 +9123,7 @@ static njs_unit_test_t njs_test[] = njs_str("undefined") }, { njs_str("function f() { var a = f2(); } f();"), - njs_str("ReferenceError: \"f2\" is not defined in 1") }, + njs_str("ReferenceError: \"f2\" is not defined") }, { njs_str("typeof Buffer !== 'undefined' ? Buffer : function Buffer(){}"), njs_str("[object Function]") }, @@ -9132,19 +9132,19 @@ static njs_unit_test_t njs_test[] = njs_str("123") }, { njs_str("1 == 1 ? func() : '123'"), - njs_str("ReferenceError: \"func\" is not defined in 1") }, + njs_str("ReferenceError: \"func\" is not defined") }, { njs_str("function f(){ if (1 == 1) { 1 == 2 ? some_var : '123' } }; f()"), njs_str("undefined") }, { njs_str("function f(){ if (1 == 1) { 1 == 1 ? some_var : '123' } }; f()"), - njs_str("ReferenceError: \"some_var\" is not defined in 1") }, + njs_str("ReferenceError: \"some_var\" is not defined") }, { njs_str("function f(){ if (1 == 1) { 1 == 2 ? some_func() : '123' } }; f()"), njs_str("undefined") }, { njs_str("function f(){ if (1 == 1) { 1 == 1 ? some_func() : '123' } }; f()"), - njs_str("ReferenceError: \"some_func\" is not defined in 1") }, + njs_str("ReferenceError: \"some_func\" is not defined") }, { njs_str("(function(){ function f() {return f}; return f()})()"), njs_str("[object Function]") }, @@ -9269,7 +9269,7 @@ static njs_unit_test_t njs_test[] = njs_str("20") }, { njs_str("var f = function b(a) { a *= 2; return a }; b(10)"), - njs_str("ReferenceError: \"b\" is not defined in 1") }, + njs_str("ReferenceError: \"b\" is not defined") }, { njs_str("var f; f = function(a) { a *= 2; return a }; f(10)"), njs_str("20") }, @@ -9342,7 +9342,7 @@ static njs_unit_test_t njs_test[] = { njs_str("var a = +function f(a) { return a + 1 }(2);" "var b = f(5); a"), - njs_str("ReferenceError: \"f\" is not defined in 1") }, + njs_str("ReferenceError: \"f\" is not defined") }, { njs_str("var o = { f: function(a) { return a * 2 } }; o.f(5)"), njs_str("10") }, @@ -11448,7 +11448,7 @@ static njs_unit_test_t njs_test[] = njs_str("1") }, { njs_str("delete this.Array; Array"), - njs_str("ReferenceError: \"Array\" is not defined in 1") }, + njs_str("ReferenceError: \"Array\" is not defined") }, { njs_str("Array.__proto__ === Function.prototype"), njs_str("true") }, @@ -14641,7 +14641,7 @@ static njs_unit_test_t njs_test[] = njs_str("InternalError: Not implemented") }, { njs_str("delete this.eval; eval"), - njs_str("ReferenceError: \"eval\" is not defined in 1") }, + njs_str("ReferenceError: \"eval\" is not defined") }, { njs_str("var d = Object.getOwnPropertyDescriptor(this, 'eval');" "d.writable && !d.enumerable && d.configurable"), @@ -15882,7 +15882,7 @@ static njs_unit_test_t njs_test[] = njs_str("1") }, { njs_str("delete this.JSON; JSON"), - njs_str("ReferenceError: \"JSON\" is not defined in 1") }, + njs_str("ReferenceError: \"JSON\" is not defined") }, /* Top-level constructors. */ @@ -17585,10 +17585,10 @@ static njs_unit_test_t njs_test[] = njs_str("SyntaxError: Unexpected token \"}\" in 1") }, { njs_str("{{}a = b++}"), - njs_str("ReferenceError: \"a\" is not defined in 1") }, + njs_str("ReferenceError: \"a\" is not defined") }, { njs_str("{{}a = b--}"), - njs_str("ReferenceError: \"a\" is not defined in 1") }, + njs_str("ReferenceError: \"a\" is not defined") }, { njs_str("{{}a =}"), njs_str("SyntaxError: Unexpected token \"}\" in 1") }, @@ -17672,7 +17672,7 @@ static njs_unit_test_t njs_test[] = njs_str("SyntaxError: Unexpected end of input in 1") }, { njs_str("`${{a: 1, b}}`"), - njs_str("ReferenceError: \"b\" is not defined in 1") }, + njs_str("ReferenceError: \"b\" is not defined") }, { njs_str("`${{a: 1, b:}}`"), njs_str("SyntaxError: Unexpected token \"}\" in 1") }, @@ -18528,7 +18528,7 @@ static njs_unit_test_t njs_shared_test[] = njs_str("false") }, { njs_str("isFin()"), - njs_str("ReferenceError: \"isFin\" is not defined in 1") }, + njs_str("ReferenceError: \"isFin\" is not defined") }, { njs_str("isNaN(function(){})"), njs_str("true") }, @@ -19022,11 +19022,11 @@ static njs_unit_test_t njs_shell_test[] = " at main (:3)\n") }, { njs_str("1\n+a" ENTER), - njs_str("ReferenceError: \"a\" is not defined in 2\n" + njs_str("ReferenceError: \"a\" is not defined\n" " at main (:2)\n") }, { njs_str("\n`\n${Object}\n${a}`" ENTER), - njs_str("ReferenceError: \"a\" is not defined in 4\n" + njs_str("ReferenceError: \"a\" is not defined\n" " at main (:4)\n") }, { njs_str("function log(v) {}\nlog({}\n.a\n.a)" ENTER), @@ -19034,15 +19034,15 @@ static njs_unit_test_t njs_shell_test[] = " at main (:4)\n") }, { njs_str("\nfor (var i = 0;\n i < a;\n i++) { }\n" ENTER), - njs_str("ReferenceError: \"a\" is not defined in 3\n" + njs_str("ReferenceError: \"a\" is not defined\n" " at main (:3)\n") }, { njs_str("\nfor (var i = 0;\n i < 5;\n a) {\n }" ENTER), - njs_str("ReferenceError: \"a\" is not defined in 4\n" + njs_str("ReferenceError: \"a\" is not defined\n" " at main (:4)\n") }, { njs_str("Math\n.min(1,\na)" ENTER), - njs_str("ReferenceError: \"a\" is not defined in 3\n" + njs_str("ReferenceError: \"a\" is not defined\n" " at Math.min (native)\n" " at main (:3)\n") }, }; diff --git a/test/njs_expect_test.exp b/test/njs_expect_test.exp index 4bb95e0b..e891dcfe 100644 --- a/test/njs_expect_test.exp +++ b/test/njs_expect_test.exp @@ -747,12 +747,12 @@ njs_test { njs_run {"-c" "setTimeout(() => {console.log('A'.repeat(1024))}, 0); ref"} \ "^Thrown: -ReferenceError: \"ref\" is not defined in string:1 +ReferenceError: \"ref\" is not defined at main \\\(string:1\\\)\n$" njs_run {"-c" "setTimeout(() => {ref}, 0); setTimeout(() => {console.log('A'.repeat(1024))}, 0)"} \ "^Thrown: -ReferenceError: \"ref\" is not defined in string:1 +ReferenceError: \"ref\" is not defined at anonymous \\\(string:1\\\) at main \\\(string:1\\\)\n$" @@ -816,6 +816,8 @@ njs_run {"test/script_args.js" "A" "B"} "AB" njs_test { {"1+1\r\n" " 1 | 00000 ADD*\r\n*2"} + {"__unknown\r\n" + " 1 | 00000 GLOBAL GET*\r\n*REFERENCE ERROR*"} {"for (var n in [1]) {try {break} finally{}}\r\n" " 1 | 00000 ARRAY*\r\n*TRY BREAK*PROP NEXT*-*\r\n\r\nundefined"} {"(function() {try {return} finally{}})()\r\n" @@ -831,9 +833,9 @@ njs_test { # # For example: # {"import ref from 'ref_exception.js'\r\n" -# "ReferenceError: \"undeclared\" is not defined in ref_exception.js:1"} +# "ReferenceError: \"undeclared\" is not defined"} # {"ref\r\n" -# "ReferenceError: \"ref\" is not defined in shell:1\r\n"} +# "ReferenceError: \"ref\" is not defined\r\n"} njs_test { {"import lib1 from 'lib1.js'; import lib2 from 'lib1.js'\r\n" @@ -851,11 +853,11 @@ njs_test { {"import m from 'export_non_default.js'\r\n" "Non-default export is not supported in export_non_default.js:3\r\n"} {"import ref from 'ref_exception.js'\r\n" - "ReferenceError: \"undeclared\" is not defined in ref_exception.js:1"} + "ReferenceError: \"undeclared\" is not defined"} {"var ref\r\n" "undefined\r\n"} {"import ref from 'ref_exception.js'\r\n" - "ReferenceError: \"undeclared\" is not defined in ref_exception.js:1"} + "ReferenceError: \"undeclared\" is not defined"} {"import m from 'declaration_exception.js'\r\n" "SyntaxError: \"f\" has already been declared in declaration_exception.js:6"} {"import m from 'loading_exception.js'\r\n" -- 2.47.3