From: hongzhidao Date: Fri, 26 Apr 2019 13:30:04 +0000 (+0800) Subject: Improved njs_vm_continuation(). X-Git-Tag: 0.3.2~39 X-Git-Url: http://www.kaiwu.me/postgresql/commit/?a=commitdiff_plain;h=6fb662600f028c2207ba7925523037f92cf1807a;p=njs.git Improved njs_vm_continuation(). This closes #142 issue on Github. --- diff --git a/njs/njs_function.c b/njs/njs_function.c index a4bbdba3..c60e3249 100644 --- a/njs/njs_function.c +++ b/njs/njs_function.c @@ -294,6 +294,7 @@ njs_function_native_frame(njs_vm_t *vm, njs_function_t *function, size_t continuation_size, nxt_bool_t ctor) { size_t size; + u_char *continuation; nxt_uint_t n; njs_value_t *value, *bound; njs_native_frame_t *frame; @@ -312,7 +313,13 @@ njs_function_native_frame(njs_vm_t *vm, njs_function_t *function, frame->nargs = function->args_offset + nargs; frame->ctor = ctor; - value = (njs_value_t *) (njs_continuation(frame) + continuation_size); + continuation = (u_char *) frame + NJS_NATIVE_FRAME_SIZE; + + if (continuation_size > 0) { + frame->continuation = (njs_continuation_t *) continuation; + } + + value = (njs_value_t *) (continuation + continuation_size); frame->arguments = value; bound = function->bound; @@ -770,6 +777,10 @@ njs_function_frame_free(njs_vm_t *vm, njs_native_frame_t *frame) do { previous = frame->previous; + if (frame->continuation != NULL) { + vm->current = frame->continuation->return_address; + } + /* GC: free frame->local, etc. */ if (frame->size != 0) { diff --git a/njs/njs_function.h b/njs/njs_function.h index 1d7b388b..149e0ae4 100644 --- a/njs/njs_function.h +++ b/njs/njs_function.h @@ -66,10 +66,7 @@ typedef struct { #define njs_vm_continuation(vm) \ - (void *) njs_continuation((vm)->top_frame) - -#define njs_continuation(frame) \ - ((u_char *) frame + NJS_NATIVE_FRAME_SIZE) + (void *) ((vm)->top_frame->continuation) #define njs_continuation_size(size) \ nxt_align_size(sizeof(size), sizeof(njs_value_t)) @@ -104,6 +101,8 @@ struct njs_native_frame_s { njs_function_t *function; njs_native_frame_t *previous; + njs_continuation_t *continuation; + njs_value_t *arguments; njs_object_t *arguments_object; diff --git a/njs/test/njs_unit_test.c b/njs/test/njs_unit_test.c index 27edbbb3..ebe5dbc1 100644 --- a/njs/test/njs_unit_test.c +++ b/njs/test/njs_unit_test.c @@ -6039,6 +6039,24 @@ static njs_unit_test_t njs_test[] = { nxt_string("function f (x){ return x**2}; f(2\n)"), nxt_string("4") }, + { nxt_string("var fn = Function.prototype.call; fn.call(() => 1)"), + nxt_string("1") }, + + { nxt_string("var fn = Function.prototype.call; fn.call(fn, () => 1)"), + nxt_string("1") }, + + { nxt_string("var fn = Function.prototype.call; fn.call(fn, fn, () => 1)"), + nxt_string("1") }, + + { nxt_string("eval.call.call(Number)"), + nxt_string("0") }, + + { nxt_string("URIError.apply.apply(RegExp)"), + nxt_string("/(?:)/") }, + + { nxt_string("[0].some(function(){return Array.call.bind(isNaN)}())"), + nxt_string("false") }, + /* Recursive factorial. */ { nxt_string("function f(a) {"