[njs] Improved njs_vm_continuation().

Dmitry Volyntsev xeioex at nginx.com
Sat Apr 27 14:32:40 UTC 2019


details:   https://hg.nginx.org/njs/rev/28c972d5416d
branches:  
changeset: 934:28c972d5416d
user:      hongzhidao <hongzhidao at gmail.com>
date:      Fri Apr 26 21:30:04 2019 +0800
description:
Improved njs_vm_continuation().

This closes #142 issue on Github.

diffstat:

 njs/njs_function.c       |  13 ++++++++++++-
 njs/njs_function.h       |   7 +++----
 njs/test/njs_unit_test.c |  18 ++++++++++++++++++
 3 files changed, 33 insertions(+), 5 deletions(-)

diffs (89 lines):

diff -r b9becf29a21d -r 28c972d5416d njs/njs_function.c
--- a/njs/njs_function.c	Fri Apr 26 19:57:54 2019 +0800
+++ b/njs/njs_function.c	Fri Apr 26 21:30:04 2019 +0800
@@ -294,6 +294,7 @@ njs_function_native_frame(njs_vm_t *vm, 
     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, 
     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, nj
     do {
         previous = frame->previous;
 
+        if (frame->continuation != NULL) {
+            vm->current = frame->continuation->return_address;
+        }
+
         /* GC: free frame->local, etc. */
 
         if (frame->size != 0) {
diff -r b9becf29a21d -r 28c972d5416d njs/njs_function.h
--- a/njs/njs_function.h	Fri Apr 26 19:57:54 2019 +0800
+++ b/njs/njs_function.h	Fri Apr 26 21:30:04 2019 +0800
@@ -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 -r b9becf29a21d -r 28c972d5416d njs/test/njs_unit_test.c
--- a/njs/test/njs_unit_test.c	Fri Apr 26 19:57:54 2019 +0800
+++ b/njs/test/njs_unit_test.c	Fri Apr 26 21:30:04 2019 +0800
@@ -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) {"


More information about the nginx-devel mailing list