[njs] Generator: simplified runtime errors generation.

Dmitry Volyntsev xeioex at nginx.com
Wed Aug 26 14:59:06 UTC 2020


details:   https://hg.nginx.org/njs/rev/a2d12799c9f7
branches:  
changeset: 1503:a2d12799c9f7
user:      Dmitry Volyntsev <xeioex at nginx.com>
date:      Wed Aug 26 14:55:47 2020 +0000
description:
Generator: simplified runtime errors generation.

diffstat:

 src/njs_disassembler.c   |  24 ++++++++++++++++--
 src/njs_generator.c      |  25 +++++-------------
 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, 84 insertions(+), 78 deletions(-)

diffs (452 lines):

diff -r 781c6b5e81cc -r a2d12799c9f7 src/njs_disassembler.c
--- a/src/njs_disassembler.c	Wed Aug 26 14:55:28 2020 +0000
+++ b/src/njs_disassembler.c	Wed Aug 26 14:55:47 2020 +0000
@@ -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;
+
+            switch (error->type) {
+            case NJS_OBJ_TYPE_REF_ERROR:
+                type = "REFERENCE";
+                break;
 
-            p += sizeof(njs_vmcode_reference_error_t);
+            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 -r 781c6b5e81cc -r a2d12799c9f7 src/njs_generator.c
--- a/src/njs_generator.c	Wed Aug 26 14:55:28 2020 +0000
+++ b/src/njs_generator.c	Wed Aug 26 14:55:47 2020 +0000
@@ -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 *v
         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 -r 781c6b5e81cc -r a2d12799c9f7 src/njs_vmcode.c
--- a/src/njs_vmcode.c	Wed Aug 26 14:55:28 2020 +0000
+++ b/src/njs_vmcode.c	Wed Aug 26 14:55:47 2020 +0000
@@ -49,7 +49,7 @@ static njs_jump_off_t njs_vmcode_try_end
     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_val
 
 
 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;
-
-    file = &ref_err->file;
+    err = (njs_vmcode_error_t *) pc;
 
-    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 -r 781c6b5e81cc -r a2d12799c9f7 src/njs_vmcode.h
--- a/src/njs_vmcode.h	Wed Aug 26 14:55:28 2020 +0000
+++ b/src/njs_vmcode.h	Wed Aug 26 14:55:47 2020 +0000
@@ -61,7 +61,7 @@ typedef uint8_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 -r 781c6b5e81cc -r a2d12799c9f7 src/test/njs_unit_test.c
--- a/src/test/njs_unit_test.c	Wed Aug 26 14:55:28 2020 +0000
+++ b/src/test/njs_unit_test.c	Wed Aug 26 14:55:47 2020 +0000
@@ -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 -r 781c6b5e81cc -r a2d12799c9f7 test/njs_expect_test.exp
--- a/test/njs_expect_test.exp	Wed Aug 26 14:55:28 2020 +0000
+++ b/test/njs_expect_test.exp	Wed Aug 26 14:55:47 2020 +0000
@@ -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"} 
 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"


More information about the nginx-devel mailing list