[njs] Simplified functional stack unwinding.

Dmitry Volyntsev xeioex at nginx.com
Wed Apr 12 01:42:39 UTC 2023


details:   https://hg.nginx.org/njs/rev/29ddc56f7aa5
branches:  
changeset: 2085:29ddc56f7aa5
user:      Dmitry Volyntsev <xeioex at nginx.com>
date:      Mon Apr 10 23:06:34 2023 -0700
description:
Simplified functional stack unwinding.

diffstat:

 src/njs_function.c |  73 +++++++++++++----------------------------------------
 src/njs_function.h |  18 -------------
 src/njs_vm.c       |   5 +--
 src/njs_vm.h       |   3 +-
 src/njs_vmcode.c   |   9 ++----
 5 files changed, 24 insertions(+), 84 deletions(-)

diffs (235 lines):

diff -r 46c0af7318b8 -r 29ddc56f7aa5 src/njs_function.c
--- a/src/njs_function.c	Mon Apr 10 23:06:29 2023 -0700
+++ b/src/njs_function.c	Mon Apr 10 23:06:34 2023 -0700
@@ -620,7 +620,7 @@ njs_function_native_call(njs_vm_t *vm)
 {
     njs_int_t              ret;
     njs_function_t         *function;
-    njs_native_frame_t     *native, *previous;
+    njs_native_frame_t     *native;
     njs_function_native_t  call;
 
     native = vm->top_frame;
@@ -656,17 +656,9 @@ njs_function_native_call(njs_vm_t *vm)
         return ret;
     }
 
-    if (ret == NJS_DECLINED) {
-        return NJS_OK;
-    }
-
-    previous = njs_function_previous_frame(native);
+    njs_vm_scopes_restore(vm, native);
 
-    njs_vm_scopes_restore(vm, native, previous);
-
-    if (!native->skip) {
-        *native->retval = vm->retval;
-    }
+    *native->retval = vm->retval;
 
     njs_function_frame_free(vm, native);
 
@@ -700,20 +692,10 @@ njs_function_frame_invoke(njs_vm_t *vm, 
 void
 njs_function_frame_free(njs_vm_t *vm, njs_native_frame_t *native)
 {
-    njs_native_frame_t  *previous;
-
-    do {
-        previous = native->previous;
-
-        /* GC: free frame->local, etc. */
-
-        if (native->size != 0) {
-            vm->spare_stack_size += native->size;
-            njs_mp_free(vm->mem_pool, native);
-        }
-
-        native = previous;
-    } while (native->skip);
+    if (native->size != 0) {
+        vm->spare_stack_size += native->size;
+        njs_mp_free(vm->mem_pool, native);
+    }
 }
 
 
@@ -1236,10 +1218,9 @@ static njs_int_t
 njs_function_prototype_call(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     njs_index_t unused)
 {
-    njs_int_t           ret;
-    njs_function_t      *function;
-    const njs_value_t   *this;
-    njs_native_frame_t  *frame;
+    njs_int_t          ret;
+    njs_value_t        retval;
+    const njs_value_t  *this;
 
     if (!njs_is_function(&args[0])) {
         njs_type_error(vm, "\"this\" argument is not a function");
@@ -1255,24 +1236,15 @@ njs_function_prototype_call(njs_vm_t *vm
         nargs = 0;
     }
 
-    frame = vm->top_frame;
-
-    /* Skip the "call" method frame. */
-    frame->skip = 1;
-
-    function = njs_function(&args[0]);
-
-    ret = njs_function_frame(vm, function, this, &args[2], nargs, 0);
+    ret = njs_function_call(vm, njs_function(&args[0]), this, &args[2], nargs,
+                            &retval);
     if (njs_slow_path(ret != NJS_OK)) {
         return ret;
     }
 
-    ret = njs_function_frame_invoke(vm, frame->retval);
-    if (njs_slow_path(ret != NJS_OK)) {
-        return ret;
-    }
+    njs_value_assign(&vm->retval, &retval);
 
-    return NJS_DECLINED;
+    return NJS_OK;
 }
 
 
@@ -1282,8 +1254,7 @@ njs_function_prototype_apply(njs_vm_t *v
 {
     int64_t         i, length;
     njs_int_t       ret;
-    njs_frame_t     *frame;
-    njs_value_t     *this, *arr_like;
+    njs_value_t     retval, *this, *arr_like;
     njs_array_t     *arr;
     njs_function_t  *func;
 
@@ -1332,22 +1303,14 @@ njs_function_prototype_apply(njs_vm_t *v
 
 activate:
 
-    /* Skip the "apply" method frame. */
-    vm->top_frame->skip = 1;
-
-    frame = (njs_frame_t *) vm->top_frame;
-
-    ret = njs_function_frame(vm, func, this, args, length, 0);
+    ret = njs_function_call(vm, func, this, args, length, &retval);
     if (njs_slow_path(ret != NJS_OK)) {
         return ret;
     }
 
-    ret = njs_function_frame_invoke(vm, frame->native.retval);
-    if (njs_slow_path(ret != NJS_OK)) {
-        return ret;
-    }
+    njs_value_assign(&vm->retval, &retval);
 
-    return NJS_DECLINED;
+    return NJS_OK;
 }
 
 
diff -r 46c0af7318b8 -r 29ddc56f7aa5 src/njs_function.h
--- a/src/njs_function.h	Mon Apr 10 23:06:29 2023 -0700
+++ b/src/njs_function.h	Mon Apr 10 23:06:34 2023 -0700
@@ -65,9 +65,6 @@ struct njs_native_frame_s {
     uint8_t                        native;            /* 1 bit  */
     /* Function is called as constructor with "new" keyword. */
     uint8_t                        ctor;              /* 1 bit  */
-
-    /* Skip the Function.call() and Function.apply() methods frames. */
-    uint8_t                        skip;              /* 1 bit  */
 };
 
 
@@ -161,21 +158,6 @@ njs_function_frame(njs_vm_t *vm, njs_fun
 }
 
 
-njs_inline 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;
-}
-
-
 njs_inline njs_int_t
 njs_function_call(njs_vm_t *vm, njs_function_t *function,
     const njs_value_t *this, const njs_value_t *args,
diff -r 46c0af7318b8 -r 29ddc56f7aa5 src/njs_vm.c
--- a/src/njs_vm.c	Mon Apr 10 23:06:29 2023 -0700
+++ b/src/njs_vm.c	Mon Apr 10 23:06:34 2023 -0700
@@ -442,12 +442,11 @@ njs_vm_invoke(njs_vm_t *vm, njs_function
 
 
 void
-njs_vm_scopes_restore(njs_vm_t *vm, njs_native_frame_t *native,
-    njs_native_frame_t *previous)
+njs_vm_scopes_restore(njs_vm_t *vm, njs_native_frame_t *native)
 {
     njs_frame_t  *frame;
 
-    vm->top_frame = previous;
+    vm->top_frame = native->previous;
 
     if (native->function->native) {
         return;
diff -r 46c0af7318b8 -r 29ddc56f7aa5 src/njs_vm.h
--- a/src/njs_vm.h	Mon Apr 10 23:06:29 2023 -0700
+++ b/src/njs_vm.h	Mon Apr 10 23:06:34 2023 -0700
@@ -239,8 +239,7 @@ struct njs_vm_shared_s {
 };
 
 
-void njs_vm_scopes_restore(njs_vm_t *vm, njs_native_frame_t *frame,
-    njs_native_frame_t *previous);
+void njs_vm_scopes_restore(njs_vm_t *vm, njs_native_frame_t *frame);
 
 njs_int_t njs_builtin_objects_create(njs_vm_t *vm);
 njs_int_t njs_builtin_objects_clone(njs_vm_t *vm, njs_value_t *global);
diff -r 46c0af7318b8 -r 29ddc56f7aa5 src/njs_vmcode.c
--- a/src/njs_vmcode.c	Mon Apr 10 23:06:29 2023 -0700
+++ b/src/njs_vmcode.c	Mon Apr 10 23:06:34 2023 -0700
@@ -1853,7 +1853,7 @@ error:
 
         lambda_call = (native == &vm->active_frame->native);
 
-        njs_vm_scopes_restore(vm, native, previous);
+        njs_vm_scopes_restore(vm, native);
 
         if (native->size != 0) {
             vm->spare_stack_size += native->size;
@@ -2674,8 +2674,7 @@ njs_function_new_object(njs_vm_t *vm, nj
 static njs_jump_off_t
 njs_vmcode_return(njs_vm_t *vm, njs_value_t *invld, njs_value_t *retval)
 {
-    njs_frame_t         *frame;
-    njs_native_frame_t  *previous;
+    njs_frame_t  *frame;
 
     frame = (njs_frame_t *) vm->top_frame;
 
@@ -2688,9 +2687,7 @@ njs_vmcode_return(njs_vm_t *vm, njs_valu
         }
     }
 
-    previous = njs_function_previous_frame(&frame->native);
-
-    njs_vm_scopes_restore(vm, &frame->native, previous);
+    njs_vm_scopes_restore(vm, &frame->native);
 
     *frame->native.retval = *retval;
 


More information about the nginx-devel mailing list