]> git.kaiwu.me - njs.git/commitdiff
Extended njs_vm_function_alloc().
authorDmitry Volyntsev <xeioex@nginx.com>
Thu, 8 Dec 2022 02:11:56 +0000 (18:11 -0800)
committerDmitry Volyntsev <xeioex@nginx.com>
Thu, 8 Dec 2022 02:11:56 +0000 (18:11 -0800)
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

index 38a00d7a2616fc802cc8b02dc4e33e4a88340d32..84bf5363cdc06481644e331b02bc4ec295c0c6c3 100644 (file)
@@ -2779,7 +2779,7 @@ njs_webcrypto_result(njs_vm_t *vm, njs_value_t *result, njs_int_t rc)
         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;
     }
index ac38415f608eb47c7d6ef3254062dacba961f4c5..8f3ca9e65e9f69d3cbf5a777844b964de944212a 100644 (file)
@@ -3191,7 +3191,8 @@ ngx_http_js_ext_subrequest(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     }
 
     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;
         }
index afa9a50028471d2a86f16bc6cf9f48b4a0044d49..4fbe140ab9125921469e54704d09e495f11813d6 100644 (file)
@@ -636,7 +636,7 @@ ngx_js_http_alloc(njs_vm_t *vm, ngx_pool_t *pool, ngx_log_t *log)
         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_t *vm, njs_value_t *result,
         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;
     }
index 420a9d4cff6c78f501329ef37408fcf44166c4d9..09500d6800b71d7f585d7b321f8a4938bbbb9d20 100644 (file)
--- a/src/njs.h
+++ b/src/njs.h
@@ -384,7 +384,7 @@ NJS_EXPORT njs_int_t njs_external_property(njs_vm_t *vm,
 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);
 
index 7487e6cf845baebf7d83eca4b63d22aabf27c2c8..c22157301c1f02cf25590de60ce8175981275ac8 100644 (file)
@@ -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_t native)
     }
 
     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;
 }
index 5856c2345451075cc0d5b1444dd1d92d7186e51a..ddf20f40ea3d4635031b0be4fa6639967e65b8f1 100644 (file)
@@ -417,7 +417,8 @@ njs_unit_test_r_subrequest(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         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_value_t *args, njs_uint_t nargs,
 }
 
 
+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_unit_test_req_init_t *init,
 {
     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_unit_test_req_init_t *init,
             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));
index 7b59c07ac9e0d1e749a3a9ebb4a89d25f1faa243..0888d59130dcf4359fcd380f03d1f9539394b001 100644 (file)
@@ -21652,6 +21652,9 @@ static njs_unit_test_t  njs_externals_test[] =
     { 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_test[] =
 #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") },