[njs] Extended njs_vm_function_alloc().

Dmitry Volyntsev xeioex at nginx.com
Thu Dec 8 02:13:56 UTC 2022


details:   https://hg.nginx.org/njs/rev/68b28e924908
branches:  
changeset: 2011:68b28e924908
user:      Dmitry Volyntsev <xeioex at nginx.com>
date:      Wed Dec 07 18:11:56 2022 -0800
description:
Extended njs_vm_function_alloc().

diffstat:

 external/njs_webcrypto_module.c |   2 +-
 nginx/ngx_http_js_module.c      |   3 +-
 nginx/ngx_js_fetch.c            |   4 +-
 src/njs.h                       |   2 +-
 src/njs_function.c              |   8 ++++++-
 src/test/njs_externals_test.c   |  44 ++++++++++++++++++++++++++++++++++++++++-
 src/test/njs_unit_test.c        |   5 +++-
 7 files changed, 60 insertions(+), 8 deletions(-)

diffs (184 lines):

diff -r f2ab76784741 -r 68b28e924908 external/njs_webcrypto_module.c
--- a/external/njs_webcrypto_module.c	Wed Dec 07 18:11:55 2022 -0800
+++ b/external/njs_webcrypto_module.c	Wed Dec 07 18:11:56 2022 -0800
@@ -2779,7 +2779,7 @@ njs_webcrypto_result(njs_vm_t *vm, njs_v
         goto error;
     }
 
-    callback = njs_vm_function_alloc(vm, njs_promise_trampoline);
+    callback = njs_vm_function_alloc(vm, njs_promise_trampoline, 0, 0);
     if (callback == NULL) {
         goto error;
     }
diff -r f2ab76784741 -r 68b28e924908 nginx/ngx_http_js_module.c
--- a/nginx/ngx_http_js_module.c	Wed Dec 07 18:11:55 2022 -0800
+++ b/nginx/ngx_http_js_module.c	Wed Dec 07 18:11:56 2022 -0800
@@ -3191,7 +3191,8 @@ ngx_http_js_ext_subrequest(njs_vm_t *vm,
     }
 
     if (!detached && callback == NULL) {
-        callback = njs_vm_function_alloc(vm, ngx_http_js_promise_trampoline);
+        callback = njs_vm_function_alloc(vm, ngx_http_js_promise_trampoline, 0,
+                                         0);
         if (callback == NULL) {
             goto memory_error;
         }
diff -r f2ab76784741 -r 68b28e924908 nginx/ngx_js_fetch.c
--- a/nginx/ngx_js_fetch.c	Wed Dec 07 18:11:55 2022 -0800
+++ b/nginx/ngx_js_fetch.c	Wed Dec 07 18:11:56 2022 -0800
@@ -636,7 +636,7 @@ ngx_js_http_alloc(njs_vm_t *vm, ngx_pool
         goto failed;
     }
 
-    callback = njs_vm_function_alloc(vm, ngx_js_http_promise_trampoline);
+    callback = njs_vm_function_alloc(vm, ngx_js_http_promise_trampoline, 0, 0);
     if (callback == NULL) {
         goto failed;
     }
@@ -804,7 +804,7 @@ ngx_js_fetch_promissified_result(njs_vm_
         goto error;
     }
 
-    callback = njs_vm_function_alloc(vm, ngx_js_http_promise_trampoline);
+    callback = njs_vm_function_alloc(vm, ngx_js_http_promise_trampoline, 0, 0);
     if (callback == NULL) {
         goto error;
     }
diff -r f2ab76784741 -r 68b28e924908 src/njs.h
--- a/src/njs.h	Wed Dec 07 18:11:55 2022 -0800
+++ b/src/njs.h	Wed Dec 07 18:11:56 2022 -0800
@@ -384,7 +384,7 @@ NJS_EXPORT njs_int_t njs_external_proper
 NJS_EXPORT uintptr_t njs_vm_meta(njs_vm_t *vm, njs_uint_t index);
 
 NJS_EXPORT njs_function_t *njs_vm_function_alloc(njs_vm_t *vm,
-    njs_function_native_t native);
+    njs_function_native_t native, njs_bool_t shared, njs_bool_t ctor);
 
 NJS_EXPORT void njs_disassembler(njs_vm_t *vm);
 
diff -r f2ab76784741 -r 68b28e924908 src/njs_function.c
--- a/src/njs_function.c	Wed Dec 07 18:11:55 2022 -0800
+++ b/src/njs_function.c	Wed Dec 07 18:11:56 2022 -0800
@@ -65,7 +65,8 @@ fail:
 
 
 njs_function_t *
-njs_vm_function_alloc(njs_vm_t *vm, njs_function_native_t native)
+njs_vm_function_alloc(njs_vm_t *vm, njs_function_native_t native,
+    njs_bool_t shared, njs_bool_t ctor)
 {
     njs_function_t  *function;
 
@@ -76,7 +77,12 @@ njs_vm_function_alloc(njs_vm_t *vm, njs_
     }
 
     function->native = 1;
+    function->ctor = ctor;
+    function->object.shared = shared;
     function->u.native = native;
+    function->object.shared_hash = vm->shared->function_instance_hash;
+    function->object.__proto__ = &vm->prototypes[NJS_OBJ_TYPE_FUNCTION].object;
+    function->object.type = NJS_FUNCTION;
 
     return function;
 }
diff -r f2ab76784741 -r 68b28e924908 src/test/njs_externals_test.c
--- a/src/test/njs_externals_test.c	Wed Dec 07 18:11:55 2022 -0800
+++ b/src/test/njs_externals_test.c	Wed Dec 07 18:11:56 2022 -0800
@@ -417,7 +417,8 @@ njs_unit_test_r_subrequest(njs_vm_t *vm,
         return NJS_ERROR;
     }
 
-    callback = njs_vm_function_alloc(vm, njs_unit_test_promise_trampoline);
+    callback = njs_vm_function_alloc(vm, njs_unit_test_promise_trampoline, 0,
+                                     0);
     if (callback == NULL) {
         return NJS_ERROR;
     }
@@ -524,6 +525,29 @@ njs_unit_test_r_bind(njs_vm_t *vm, njs_v
 }
 
 
+static njs_int_t
+njs_unit_test_constructor(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
+    njs_index_t unused)
+{
+    njs_unit_test_req_t  *sr;
+
+    sr = njs_mp_zalloc(vm->mem_pool, sizeof(njs_unit_test_req_t));
+    if (sr == NULL) {
+        njs_memory_error(vm);
+        return NJS_ERROR;
+    }
+
+    if (njs_vm_value_to_bytes(vm, &sr->uri, njs_arg(args, nargs, 1))
+        != NJS_OK)
+    {
+        return NJS_ERROR;
+    }
+
+    return njs_vm_external_create(vm, &vm->retval, njs_external_r_proto_id,
+                                  sr, 0);
+}
+
+
 static njs_external_t  njs_unit_test_r_c[] = {
 
     {
@@ -831,9 +855,13 @@ njs_externals_init_internal(njs_vm_t *vm
 {
     njs_int_t             ret;
     njs_uint_t            i, j;
+    njs_function_t        *f;
+    njs_opaque_value_t    value;
     njs_unit_test_req_t   *requests;
     njs_unit_test_prop_t  *prop;
 
+    static const njs_str_t  external_ctor = njs_str("ExternalConstructor");
+
     if (shared) {
         njs_external_r_proto_id = njs_vm_external_prototype(vm,
                                          njs_unit_test_r_external,
@@ -842,6 +870,20 @@ njs_externals_init_internal(njs_vm_t *vm
             njs_printf("njs_vm_external_prototype() failed\n");
             return NJS_ERROR;
         }
+
+        f = njs_vm_function_alloc(vm, njs_unit_test_constructor, 1, 1);
+        if (f == NULL) {
+            njs_printf("njs_vm_function_alloc() failed\n");
+            return NJS_ERROR;
+        }
+
+        njs_value_function_set(njs_value_arg(&value), f);
+
+        ret = njs_vm_bind(vm, &external_ctor, njs_value_arg(&value), 1);
+        if (njs_slow_path(ret != NJS_OK)) {
+            njs_printf("njs_vm_bind() failed\n");
+            return NJS_ERROR;
+        }
     }
 
     requests = njs_mp_zalloc(vm->mem_pool, n * sizeof(njs_unit_test_req_t));
diff -r f2ab76784741 -r 68b28e924908 src/test/njs_unit_test.c
--- a/src/test/njs_unit_test.c	Wed Dec 07 18:11:55 2022 -0800
+++ b/src/test/njs_unit_test.c	Wed Dec 07 18:11:56 2022 -0800
@@ -21652,6 +21652,9 @@ static njs_unit_test_t  njs_externals_te
     { njs_str("var sr = $r.create('XXX'); sr.vars.p = 'a'; sr.vars.p"),
       njs_str("a") },
 
+    { njs_str("var r = new ExternalConstructor('XXX'); r.uri"),
+      njs_str("XXX") },
+
     { njs_str("var p; for (p in $r.method);"),
       njs_str("undefined") },
 
@@ -21734,7 +21737,7 @@ static njs_unit_test_t  njs_externals_te
 #endif
 
     { njs_str("Object.keys(this).sort()"),
-      njs_str(N262 "$r,$r2,$r3,$shared," NCRYPTO "global,njs,process") },
+      njs_str(N262 "$r,$r2,$r3,$shared,ExternalConstructor," NCRYPTO "global,njs,process") },
 
     { njs_str("Object.getOwnPropertySymbols($r2)[0] == Symbol.toStringTag"),
       njs_str("true") },



More information about the nginx-devel mailing list