From a40a29c934a860305af7660b002556ac1e064ebb Mon Sep 17 00:00:00 2001 From: Dmitry Volyntsev Date: Mon, 10 Apr 2023 23:06:34 -0700 Subject: [PATCH] Simplified functional stack unwinding. --- 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(-) diff --git a/src/njs_function.c b/src/njs_function.c index c2215730..35ff6aba 100644 --- a/src/njs_function.c +++ b/src/njs_function.c @@ -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, njs_value_t *retval) 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, njs_value_t *args, njs_uint_t nargs, 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 *vm, njs_value_t *args, njs_uint_t nargs, { 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 *vm, njs_value_t *args, njs_uint_t nargs, 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 --git a/src/njs_function.h b/src/njs_function.h index c6299cd0..c5d539ed 100644 --- a/src/njs_function.h +++ b/src/njs_function.h @@ -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_function_t *function, } -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 --git a/src/njs_vm.c b/src/njs_vm.c index 6e284010..b9507676 100644 --- a/src/njs_vm.c +++ b/src/njs_vm.c @@ -442,12 +442,11 @@ njs_vm_invoke(njs_vm_t *vm, njs_function_t *function, const njs_value_t *args, 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 --git a/src/njs_vm.h b/src/njs_vm.h index 4ab3fbad..cdb71173 100644 --- a/src/njs_vm.h +++ b/src/njs_vm.h @@ -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 --git a/src/njs_vmcode.c b/src/njs_vmcode.c index 68de64e4..1c3b2310 100644 --- a/src/njs_vmcode.c +++ b/src/njs_vmcode.c @@ -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, njs_value_t *constructor) 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_value_t *invld, njs_value_t *retval) } } - 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; -- 2.47.3