]> git.kaiwu.me - njs.git/commitdiff
Fixed match of native function is backtraces.
authorDmitry Volyntsev <xeioex@nginx.com>
Wed, 22 Jan 2020 12:29:47 +0000 (15:29 +0300)
committerDmitry Volyntsev <xeioex@nginx.com>
Wed, 22 Jan 2020 12:29:47 +0000 (15:29 +0300)
Since 6df48738a043 native methods are not uniquely identifiable
by a function pointer as several method may share common
C function and differ only in magic argument.

src/njs_builtin.c
src/njs_function.h
src/njs_vm.c
src/njs_vm.h
src/test/njs_interactive_test.c

index 5206aed5e55d3b0102c98d0b6e4c28b2999f72f4..e047bdab5d4b8e0cf169dbd5cb9a6ebb1458399b 100644 (file)
@@ -15,7 +15,7 @@ typedef struct {
        NJS_BUILTIN_TRAVERSE_MATCH,
     }                          type;
 
-    njs_function_native_t      native;
+    njs_function_t             *func;
 
     njs_lvlhsh_t               keys;
     njs_str_t                  match;
@@ -391,6 +391,7 @@ njs_builtin_traverse(njs_vm_t *vm, njs_traverse_t *traverse, void *data)
     u_char                  *p, *start, *end;
     njs_int_t               ret, n;
     njs_str_t               name;
+    njs_function_t          *func;
     njs_object_prop_t       *prop;
     njs_lvlhsh_query_t      lhq;
     njs_builtin_traverse_t  *ctx;
@@ -401,10 +402,11 @@ njs_builtin_traverse(njs_vm_t *vm, njs_traverse_t *traverse, void *data)
 
     if (ctx->type == NJS_BUILTIN_TRAVERSE_MATCH) {
         prop = traverse->prop;
+        func = ctx->func;
 
         if (!(njs_is_function(&prop->value)
               && njs_function(&prop->value)->native
-              && njs_function(&prop->value)->u.native == ctx->native))
+              && njs_native_function_same(njs_function(&prop->value), func)))
         {
             return NJS_OK;
         }
@@ -739,7 +741,7 @@ njs_object_completions(njs_vm_t *vm, njs_object_t *object)
 
 
 njs_int_t
-njs_builtin_match_native_function(njs_vm_t *vm, njs_function_native_t func,
+njs_builtin_match_native_function(njs_vm_t *vm, njs_function_t *function,
     njs_str_t *name)
 {
     njs_int_t               ret;
@@ -750,7 +752,7 @@ njs_builtin_match_native_function(njs_vm_t *vm, njs_function_native_t func,
     njs_builtin_traverse_t  ctx;
 
     ctx.type = NJS_BUILTIN_TRAVERSE_MATCH;
-    ctx.native = func;
+    ctx.func = function;
 
     /* Global object. */
 
index d736508b4a788b6b29b48bbe40a596002591fcaa..cd3aca32da2dcb5bd26a874745449c59ac200758 100644 (file)
@@ -203,6 +203,13 @@ njs_function_apply(njs_vm_t *vm, njs_function_t *function,
 }
 
 
+njs_inline njs_bool_t
+njs_native_function_same(const njs_function_t *f1, const njs_function_t *f2)
+{
+    return f1->u.native == f2->u.native && f1->magic == f2->magic;
+}
+
+
 extern const njs_object_type_init_t  njs_function_type_init;
 extern const njs_object_init_t  njs_function_instance_init;
 extern const njs_object_init_t  njs_arrow_instance_init;
index ffcd39b60ec5774cba570837152ee7f244a7a227..5ae059d15a5118d392e8302b2e16575bfccc0596 100644 (file)
@@ -991,8 +991,7 @@ njs_vm_add_backtrace_entry(njs_vm_t *vm, njs_arr_t *stack,
             function = function->u.bound_target;
         }
 
-        ret = njs_builtin_match_native_function(vm, function->u.native,
-                                                &be->name);
+        ret = njs_builtin_match_native_function(vm, function, &be->name);
         if (ret == NJS_OK) {
             return NJS_OK;
         }
index 623a2176baba3f3da3b6831186fdf17c21766635..dfa11921e41fe031eaf651385b4a78d38775577d 100644 (file)
@@ -302,7 +302,7 @@ njs_int_t njs_vm_backtrace_to_string(njs_vm_t *vm, njs_arr_t *stack,
 njs_int_t njs_builtin_objects_create(njs_vm_t *vm);
 njs_int_t njs_builtin_objects_clone(njs_vm_t *vm, njs_value_t *global);
 njs_int_t njs_builtin_match_native_function(njs_vm_t *vm,
-    njs_function_native_t func, njs_str_t *name);
+    njs_function_t *function, njs_str_t *name);
 
 njs_arr_t *njs_vm_completions(njs_vm_t *vm, njs_str_t *expression);
 
index 39fd28541c779f127e6bdc0f2f21ee2ac634a2a0..685165c587e02249a066e5a4c6210ce87c01174e 100644 (file)
@@ -232,10 +232,15 @@ static njs_interactive_test_t  njs_test[] =
                  "    at f (:1)\n"
                  "    at main (native)\n") },
 
-    { njs_str("var fs = require('fs'); fs.readFile()" ENTER),
-      njs_str("TypeError: \"path\" must be a string\n"
-                 "    at fs.readFile (native)\n"
-                 "    at main (native)\n") },
+    { njs_str("var fs = require('fs');"
+              "['readFile',"
+              " 'readFileSync',"
+              " 'writeFile',"
+              " 'writeFileSync',"
+              " 'appendFile',"
+              " 'appendFileSync']"
+              ".every(v=>{ try {fs[v]();} catch (e) { return e.stack.search(`fs.${v} `) >= 0}})" ENTER),
+      njs_str("true") },
 
     { njs_str("parseInt({ toString: function() { return [1] } })" ENTER),
       njs_str("TypeError: Cannot convert object to primitive value\n"