[njs] Fixed match of native function is backtraces.

Dmitry Volyntsev xeioex at nginx.com
Wed Jan 22 12:58:10 UTC 2020


details:   https://hg.nginx.org/njs/rev/b247b1c5531f
branches:  
changeset: 1313:b247b1c5531f
user:      Dmitry Volyntsev <xeioex at nginx.com>
date:      Wed Jan 22 15:29:47 2020 +0300
description:
Fixed match of native function is backtraces.

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.

diffstat:

 src/njs_builtin.c               |  10 ++++++----
 src/njs_function.h              |   7 +++++++
 src/njs_vm.c                    |   3 +--
 src/njs_vm.h                    |   2 +-
 src/test/njs_interactive_test.c |  13 +++++++++----
 5 files changed, 24 insertions(+), 11 deletions(-)

diffs (116 lines):

diff -r 74c2de51636c -r b247b1c5531f src/njs_builtin.c
--- a/src/njs_builtin.c	Wed Jan 22 15:29:44 2020 +0300
+++ b/src/njs_builtin.c	Wed Jan 22 15:29:47 2020 +0300
@@ -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_t
     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_t
 
     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
 
 
 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
     njs_builtin_traverse_t  ctx;
 
     ctx.type = NJS_BUILTIN_TRAVERSE_MATCH;
-    ctx.native = func;
+    ctx.func = function;
 
     /* Global object. */
 
diff -r 74c2de51636c -r b247b1c5531f src/njs_function.h
--- a/src/njs_function.h	Wed Jan 22 15:29:44 2020 +0300
+++ b/src/njs_function.h	Wed Jan 22 15:29:47 2020 +0300
@@ -203,6 +203,13 @@ njs_function_apply(njs_vm_t *vm, njs_fun
 }
 
 
+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;
diff -r 74c2de51636c -r b247b1c5531f src/njs_vm.c
--- a/src/njs_vm.c	Wed Jan 22 15:29:44 2020 +0300
+++ b/src/njs_vm.c	Wed Jan 22 15:29:47 2020 +0300
@@ -991,8 +991,7 @@ njs_vm_add_backtrace_entry(njs_vm_t *vm,
             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;
         }
diff -r 74c2de51636c -r b247b1c5531f src/njs_vm.h
--- a/src/njs_vm.h	Wed Jan 22 15:29:44 2020 +0300
+++ b/src/njs_vm.h	Wed Jan 22 15:29:47 2020 +0300
@@ -302,7 +302,7 @@ njs_int_t njs_vm_backtrace_to_string(njs
 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);
 
diff -r 74c2de51636c -r b247b1c5531f src/test/njs_interactive_test.c
--- a/src/test/njs_interactive_test.c	Wed Jan 22 15:29:44 2020 +0300
+++ b/src/test/njs_interactive_test.c	Wed Jan 22 15:29:47 2020 +0300
@@ -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"


More information about the nginx-devel mailing list