]> git.kaiwu.me - njs.git/commitdiff
Improved njs_vm_continuation().
authorhongzhidao <hongzhidao@gmail.com>
Fri, 26 Apr 2019 13:30:04 +0000 (21:30 +0800)
committerhongzhidao <hongzhidao@gmail.com>
Fri, 26 Apr 2019 13:30:04 +0000 (21:30 +0800)
This closes #142 issue on Github.

njs/njs_function.c
njs/njs_function.h
njs/test/njs_unit_test.c

index a4bbdba3fe6fc9248ec35e7030f0738b9bda9179..c60e32492005a6f1bf5f4249d8f5c64e528e1736 100644 (file)
@@ -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) {
index 1d7b388bf3fc7bfec2e93d973f12c94f28d71633..149e0ae47b279005e817fd93eea1b694dbf76aed 100644 (file)
@@ -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;
 
index 27edbbb32e263ae588e742b492d1e94f56ca9887..ebe5dbc130f35acacff375618be7492bb3f4fed8 100644 (file)
@@ -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) {"