[njs] Introduced njs_function_native_call().

Dmitry Volyntsev xeioex at nginx.com
Thu Jan 10 13:08:39 UTC 2019


details:   https://hg.nginx.org/njs/rev/045ba10db769
branches:  
changeset: 716:045ba10db769
user:      hongzhidao <hongzhidao at gmail.com>
date:      Mon Jan 07 22:14:17 2019 +0800
description:
Introduced njs_function_native_call().

diffstat:

 njs/njs_function.c |   92 ++++++++++++++++++++++++++++++++++
 njs/njs_function.h |    4 +
 njs/njs_vm.c       |  140 ++++++----------------------------------------------
 3 files changed, 113 insertions(+), 123 deletions(-)

diffs (304 lines):

diff -r 0e7fc17f6071 -r 045ba10db769 njs/njs_function.c
--- a/njs/njs_function.c	Mon Jan 07 17:42:00 2019 +0800
+++ b/njs/njs_function.c	Mon Jan 07 22:14:17 2019 +0800
@@ -531,6 +531,98 @@ njs_function_call(njs_vm_t *vm, njs_inde
 }
 
 
+njs_ret_t
+njs_function_native_call(njs_vm_t *vm, njs_function_native_t native,
+    njs_value_t *args, nxt_uint_t nargs, njs_index_t retval)
+{
+    njs_ret_t           ret;
+    njs_value_t         *value;
+    njs_function_t      *function;
+    njs_native_frame_t  *frame;
+
+    ret = native(vm, args, nargs, retval);
+
+    /*
+     * A native method can return:
+     *   NXT_OK on method success;
+     *   NJS_APPLIED by Function.apply() and Function.call();
+     *   NXT_AGAIN to postpone nJSVM processing;
+     *   NXT_ERROR.
+     *
+     * The callee arguments must be preserved
+     * for NJS_APPLIED and NXT_AGAIN cases.
+     */
+    if (ret == NXT_OK) {
+        frame = vm->top_frame;
+
+        vm->top_frame = njs_function_previous_frame(frame);
+        njs_function_frame_free(vm, frame);
+
+        /*
+         * If a retval is in a callee arguments scope it
+         * must be in the previous callee arguments scope.
+         */
+        args = vm->top_frame->arguments;
+        function = vm->top_frame->function;
+
+        if (function != NULL) {
+            args += function->args_offset;
+        }
+
+        vm->scopes[NJS_SCOPE_CALLEE_ARGUMENTS] = args;
+
+        if (!frame->skip) {
+            value = njs_vmcode_operand(vm, retval);
+            /*
+             * GC: value external/internal++ depending
+             * on vm->retval and retval type
+             */
+            *value = vm->retval;
+        }
+
+        return NXT_OK;
+    }
+
+    return ret;
+}
+
+
+njs_native_frame_t *
+njs_function_previous_frame(njs_native_frame_t *frame)
+{
+    njs_native_frame_t  *previous;
+
+    do {
+        previous = frame->previous;
+        frame = previous;
+
+    } while (frame->skip);
+
+    return frame;
+}
+
+
+void
+njs_function_frame_free(njs_vm_t *vm, njs_native_frame_t *frame)
+{
+    njs_native_frame_t  *previous;
+
+    do {
+        previous = frame->previous;
+
+        /* GC: free frame->local, etc. */
+
+        if (frame->size != 0) {
+            vm->stack_size -= frame->size;
+            nxt_mem_cache_free(vm->mem_cache_pool, frame);
+        }
+
+        frame = previous;
+
+    } while (frame->skip);
+}
+
+
 /*
  * The "prototype" property of user defined functions is created on
  * demand in private hash of the functions by the "prototype" getter.
diff -r 0e7fc17f6071 -r 045ba10db769 njs/njs_function.h
--- a/njs/njs_function.h	Mon Jan 07 17:42:00 2019 +0800
+++ b/njs/njs_function.h	Mon Jan 07 22:14:17 2019 +0800
@@ -171,6 +171,10 @@ njs_ret_t njs_function_frame(njs_vm_t *v
     const njs_value_t *this, const njs_value_t *args, nxt_uint_t nargs,
     nxt_bool_t ctor);
 njs_ret_t njs_function_call(njs_vm_t *vm, njs_index_t retval, size_t advance);
+njs_ret_t njs_function_native_call(njs_vm_t *vm, njs_function_native_t native,
+    njs_value_t *args, nxt_uint_t nargs, njs_index_t retval);
+njs_native_frame_t *njs_function_previous_frame(njs_native_frame_t *frame);
+void njs_function_frame_free(njs_vm_t *vm, njs_native_frame_t *frame);
 
 extern const njs_object_init_t  njs_function_constructor_init;
 extern const njs_object_init_t  njs_function_prototype_init;
diff -r 0e7fc17f6071 -r 045ba10db769 njs/njs_vm.c
--- a/njs/njs_vm.c	Mon Jan 07 17:42:00 2019 +0800
+++ b/njs/njs_vm.c	Mon Jan 07 22:14:17 2019 +0800
@@ -36,10 +36,6 @@ static void njs_vm_scopes_restore(njs_vm
     njs_native_frame_t *previous);
 static njs_ret_t njs_vmcode_continuation(njs_vm_t *vm, njs_value_t *invld1,
     njs_value_t *invld2);
-static njs_native_frame_t *
-    njs_function_previous_frame(njs_native_frame_t *frame);
-static void njs_function_frame_free(njs_vm_t *vm,
-    njs_native_frame_t *frame);
 
 static void njs_vm_trap(njs_vm_t *vm, njs_trap_t trap, njs_value_t *value1,
     njs_value_t *value2);
@@ -2064,52 +2060,19 @@ njs_vmcode_function_call(njs_vm_t *vm, n
         return 0;
     }
 
-     ret = function->u.native(vm, args, nargs, (njs_index_t) retval);
-
-    /*
-     * A native method can return:
-     *   NXT_OK on method success;
-     *   NJS_APPLIED by Function.apply() and Function.call();
-     *   NXT_AGAIN to postpone nJSVM processing;
-     *   NXT_ERROR.
-     *
-     * The callee arguments must be preserved
-     * for NJS_APPLIED and NXT_AGAIN cases.
-     */
-    if (ret == NXT_OK) {
-        frame = vm->top_frame;
-
-        vm->top_frame = njs_function_previous_frame(frame);
-        njs_function_frame_free(vm, frame);
-
-        /*
-         * If a retval is in a callee arguments scope it
-         * must be in the previous callee arguments scope.
-         */
-        args = vm->top_frame->arguments;
-        function = vm->top_frame->function;
-
-        if (function != NULL) {
-            args += function->args_offset;
-        }
-
-        vm->scopes[NJS_SCOPE_CALLEE_ARGUMENTS] = args;
-
-        retval = njs_vmcode_operand(vm, retval);
-        /*
-         * GC: value external/internal++ depending
-         * on vm->retval and retval type
-         */
-        *retval = vm->retval;
-
-        ret = sizeof(njs_vmcode_function_call_t);
-
-    } else if (ret == NJS_APPLIED) {
-        /* A user-defined method has been prepared to run. */
-        ret = 0;
+    ret = njs_function_native_call(vm, function->u.native, args, nargs,
+                                   (njs_index_t) retval);
+
+    switch (ret) {
+    case NXT_OK:
+        return sizeof(njs_vmcode_function_call_t);
+
+    case NJS_APPLIED:
+        return 0;
+
+    default:
+        return ret;
     }
-
-    return ret;
 }
 
 
@@ -2467,60 +2430,27 @@ static njs_ret_t
 njs_vmcode_continuation(njs_vm_t *vm, njs_value_t *invld1, njs_value_t *invld2)
 {
     njs_ret_t           ret;
-    nxt_bool_t          skip;
-    njs_value_t         *args, *retval;
-    njs_function_t      *function;
     njs_native_frame_t  *frame;
     njs_continuation_t  *cont;
 
     cont = njs_vm_continuation(vm);
     frame = vm->top_frame;
-    args = frame->arguments;
 
     if (cont->args_types != NULL) {
-        ret = njs_normalize_args(vm, args, cont->args_types, frame->nargs);
+        ret = njs_normalize_args(vm, frame->arguments, cont->args_types,
+                                 frame->nargs);
         if (ret != NJS_OK) {
             return ret;
         }
     }
 
-    ret = cont->function(vm, args, frame->nargs, cont->retval);
+    ret = njs_function_native_call(vm, cont->function, frame->arguments,
+                                   frame->nargs, cont->retval);
 
     switch (ret) {
-
     case NXT_OK:
-
-        frame = vm->top_frame;
-        skip = frame->skip;
-
-        vm->top_frame = njs_function_previous_frame(frame);
-
-        /*
-         * If a retval is in a callee arguments scope it
-         * must be in the previous callee arguments scope.
-         */
-        args = vm->top_frame->arguments;
-        function = vm->top_frame->function;
-
-        if (function != NULL) {
-            args += function->args_offset;
-        }
-
-        vm->scopes[NJS_SCOPE_CALLEE_ARGUMENTS] = args;
-
-        if (!skip) {
-            retval = njs_vmcode_operand(vm, cont->retval);
-            /*
-             * GC: value external/internal++ depending
-             * on vm->retval and retval type
-             */
-            *retval = vm->retval;
-        }
-
         vm->current = cont->return_address;
-        (void) njs_function_frame_free(vm, frame);
-
-        return 0;
+        /* Fall through. */
 
     case NJS_APPLIED:
         return 0;
@@ -2531,42 +2461,6 @@ njs_vmcode_continuation(njs_vm_t *vm, nj
 }
 
 
-static njs_native_frame_t *
-njs_function_previous_frame(njs_native_frame_t *frame)
-{
-    njs_native_frame_t  *previous;
-
-    do {
-        previous = frame->previous;
-        frame = previous;
-
-    } while (frame->skip);
-
-    return frame;
-}
-
-
-static void
-njs_function_frame_free(njs_vm_t *vm, njs_native_frame_t *frame)
-{
-    njs_native_frame_t  *previous;
-
-    do {
-        previous = frame->previous;
-
-        /* GC: free frame->local, etc. */
-
-        if (frame->size != 0) {
-            vm->stack_size -= frame->size;
-            nxt_mem_cache_free(vm->mem_cache_pool, frame);
-        }
-
-        frame = previous;
-
-    } while (frame->skip);
-}
-
-
 njs_ret_t
 njs_vmcode_stop(njs_vm_t *vm, njs_value_t *invld, njs_value_t *retval)
 {


More information about the nginx-devel mailing list