changeset 2011:68b28e924908

Extended njs_vm_function_alloc().
author Dmitry Volyntsev <xeioex@nginx.com>
date Wed, 07 Dec 2022 18:11:56 -0800
parents f2ab76784741
children 61357fb10f4a
files external/njs_webcrypto_module.c nginx/ngx_http_js_module.c nginx/ngx_js_fetch.c src/njs.h src/njs_function.c src/test/njs_externals_test.c src/test/njs_unit_test.c
diffstat 7 files changed, 60 insertions(+), 8 deletions(-) [+]
line wrap: on
line diff
--- 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 @@
         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;
     }
--- 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 @@
     }
 
     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;
         }
--- 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 @@
         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 @@
         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;
     }
--- 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 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);
 
--- 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 @@
 
 
 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 @@
     }
 
     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;
 }
--- 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 @@
         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 @@
 }
 
 
+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_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_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));
--- 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 @@
     { 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 @@
 #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") },