[njs] Refactored function object creation.

Dmitry Volyntsev xeioex at nginx.com
Mon Apr 1 16:12:22 UTC 2019


details:   https://hg.nginx.org/njs/rev/b38fe378d900
branches:  
changeset: 862:b38fe378d900
user:      Dmitry Volyntsev <xeioex at nginx.com>
date:      Mon Apr 01 19:11:39 2019 +0300
description:
Refactored function object creation.

diffstat:

 njs/njs_function.c |  62 ++++++++++++++++++++++++++++++++++-------------------
 njs/njs_function.h |   3 +-
 njs/njs_parser.c   |  21 ++++++++++++++---
 njs/njs_vm.c       |  29 +-----------------------
 4 files changed, 61 insertions(+), 54 deletions(-)

diffs (172 lines):

diff -r 1bce636aed3d -r b38fe378d900 njs/njs_function.c
--- a/njs/njs_function.c	Sun Mar 31 22:59:04 2019 +0800
+++ b/njs/njs_function.c	Mon Apr 01 19:11:39 2019 +0300
@@ -14,35 +14,53 @@ static njs_ret_t njs_normalize_args(njs_
 
 
 njs_function_t *
-njs_function_alloc(njs_vm_t *vm)
+njs_function_alloc(njs_vm_t *vm, njs_function_lambda_t *lambda,
+    njs_closure_t *closures[], nxt_bool_t shared)
 {
+    size_t          size;
+    nxt_uint_t      n, nesting;
     njs_function_t  *function;
 
-    function = nxt_mp_zalloc(vm->mem_pool, sizeof(njs_function_t));
+    nesting = lambda->nesting;
+    size = sizeof(njs_function_t) + nesting * sizeof(njs_closure_t *);
+
+    function = nxt_mp_zalloc(vm->mem_pool, size);
+    if (nxt_slow_path(function == NULL)) {
+        goto fail;
+    }
+
 
-    if (nxt_fast_path(function != NULL)) {
-        /*
-         * nxt_mp_zalloc() does also:
-         *   nxt_lvlhsh_init(&function->object.hash);
-         *   function->object.__proto__ = NULL;
-         */
+    /*
+     * nxt_mp_zalloc() does also:
+     *   nxt_lvlhsh_init(&function->object.hash);
+     *   function->object.__proto__ = NULL;
+     */
+
+    function->ctor = 1;
+    function->args_offset = 1;
+    function->u.lambda = lambda;
 
-        function->object.shared_hash = vm->shared->function_prototype_hash;
-        function->object.type = NJS_FUNCTION;
-        function->object.shared = 1;
-        function->object.extensible = 1;
-        function->args_offset = 1;
-        function->ctor = 1;
+    function->object.shared_hash = vm->shared->function_prototype_hash;
+    function->object.__proto__ = &vm->prototypes[NJS_PROTOTYPE_FUNCTION].object;
+    function->object.type = NJS_FUNCTION;
+    function->object.shared = shared;
+    function->object.extensible = 1;
+
+    if (nesting != 0 && closures != NULL) {
+        function->closure = 1;
+
+        n = 0;
 
-        function->u.lambda = nxt_mp_zalloc(vm->mem_pool,
-                                           sizeof(njs_function_lambda_t));
-        if (nxt_slow_path(function->u.lambda == NULL)) {
-            njs_memory_error(vm);
-            return NULL;
-        }
+        do {
+            /* GC: retain closure. */
+            function->closures[n] = closures[n];
+            n++;
+        } while (n < nesting);
+    }
 
-        return function;
-    }
+    return function;
+
+fail:
 
     njs_memory_error(vm);
 
diff -r 1bce636aed3d -r b38fe378d900 njs/njs_function.h
--- a/njs/njs_function.h	Sun Mar 31 22:59:04 2019 +0800
+++ b/njs/njs_function.h	Mon Apr 01 19:11:39 2019 +0300
@@ -147,7 +147,8 @@ struct njs_frame_s {
 };
 
 
-njs_function_t *njs_function_alloc(njs_vm_t *vm);
+njs_function_t *njs_function_alloc(njs_vm_t *vm, njs_function_lambda_t *lambda,
+    njs_closure_t *closures[], nxt_bool_t shared);
 njs_function_t *njs_function_value_copy(njs_vm_t *vm, njs_value_t *value);
 njs_ret_t njs_function_arguments_object_init(njs_vm_t *vm,
     njs_native_frame_t *frame);
diff -r 1bce636aed3d -r b38fe378d900 njs/njs_parser.c
--- a/njs/njs_parser.c	Sun Mar 31 22:59:04 2019 +0800
+++ b/njs/njs_parser.c	Mon Apr 01 19:11:39 2019 +0300
@@ -552,10 +552,23 @@ static njs_function_t *
 njs_parser_function_alloc(njs_vm_t *vm, njs_parser_t *parser,
     njs_variable_t *var)
 {
-    njs_value_t     *value;
-    njs_function_t  *function;
-
-    function = njs_function_alloc(vm);
+    njs_value_t            *value;
+    njs_function_t         *function;
+    njs_function_lambda_t  *lambda;
+
+    lambda = nxt_mp_zalloc(vm->mem_pool, sizeof(njs_function_lambda_t));
+    if (nxt_slow_path(lambda == NULL)) {
+        njs_memory_error(vm);
+        return NULL;
+    }
+
+    /* TODO:
+     *  njs_function_t is used to pass lambda to
+     *  njs_generate_function_declaration() and is not actually needed.
+     *  real njs_function_t is created by njs_vmcode_function() in runtime.
+     */
+
+    function = njs_function_alloc(vm, lambda, NULL, 1);
     if (nxt_slow_path(function == NULL)) {
         return NULL;
     }
diff -r 1bce636aed3d -r b38fe378d900 njs/njs_vm.c
--- a/njs/njs_vm.c	Sun Mar 31 22:59:04 2019 +0800
+++ b/njs/njs_vm.c	Mon Apr 01 19:11:39 2019 +0300
@@ -371,43 +371,18 @@ njs_vmcode_array(njs_vm_t *vm, njs_value
 njs_ret_t
 njs_vmcode_function(njs_vm_t *vm, njs_value_t *invld1, njs_value_t *invld2)
 {
-    size_t                 size;
-    nxt_uint_t             n, nesting;
     njs_function_t         *function;
     njs_function_lambda_t  *lambda;
     njs_vmcode_function_t  *code;
 
     code = (njs_vmcode_function_t *) vm->current;
     lambda = code->lambda;
-    nesting = lambda->nesting;
-
-    size = sizeof(njs_function_t) + nesting * sizeof(njs_closure_t *);
-
-    function = nxt_mp_zalloc(vm->mem_pool, size);
+
+    function = njs_function_alloc(vm, lambda, vm->active_frame->closures, 0);
     if (nxt_slow_path(function == NULL)) {
-        njs_memory_error(vm);
         return NXT_ERROR;
     }
 
-    function->u.lambda = lambda;
-    function->object.shared_hash = vm->shared->function_prototype_hash;
-    function->object.__proto__ = &vm->prototypes[NJS_PROTOTYPE_FUNCTION].object;
-    function->object.extensible = 1;
-    function->args_offset = 1;
-    function->ctor = 1;
-
-    if (nesting != 0) {
-        function->closure = 1;
-
-        n = 0;
-
-        do {
-            /* GC: retain closure. */
-            function->closures[n] = vm->active_frame->closures[n];
-            n++;
-        } while (n < nesting);
-    }
-
     vm->retval.data.u.function = function;
     vm->retval.type = NJS_FUNCTION;
     vm->retval.data.truth = 1;


More information about the nginx-devel mailing list