]> git.kaiwu.me - njs.git/commitdiff
Native methods called with Function.prototype.call() and
authorIgor Sysoev <igor@sysoev.ru>
Mon, 5 Dec 2016 14:45:02 +0000 (17:45 +0300)
committerIgor Sysoev <igor@sysoev.ru>
Mon, 5 Dec 2016 14:45:02 +0000 (17:45 +0300)
Functon.prototype.apply() should run via continuation to
normilize arguments.

njs/njs_function.c

index d63efbfa27f0e1159a2e6773d5a130d38de48f26..489a097dc01032736b39256b719313f11f588506 100644 (file)
@@ -484,18 +484,29 @@ static njs_ret_t
 njs_function_activate(njs_vm_t *vm, njs_function_t *function, njs_value_t *this,
     njs_value_t *args, nxt_uint_t nargs, njs_index_t retval)
 {
-    njs_ret_t  ret;
+    njs_ret_t           ret;
+    njs_continuation_t  *cont;
 
     if (function->native) {
-        ret = njs_function_native_frame(vm, function, this, args,
-                                        nargs, 0, 0);
+        ret = njs_function_native_frame(vm, function, this, args, nargs,
+                                        NJS_CONTINUATION_SIZE, 0);
         if (nxt_slow_path(ret != NXT_OK)) {
             return ret;
         }
 
-        /* Skip the "apply" method frame. */
+        /* Skip the "call/apply" method frame. */
         vm->frame->previous->skip = 1;
 
+        cont = njs_continuation(vm->frame);
+
+        cont->function = function->u.native;
+        cont->args_types = function->args_types;
+        cont->retval = retval;
+
+        cont->return_address = vm->current
+                               + sizeof(njs_vmcode_function_call_t);;
+        vm->current = (u_char *) njs_continuation_nexus;
+
         return NJS_APPLIED;
     }
 
@@ -505,7 +516,7 @@ njs_function_activate(njs_vm_t *vm, njs_function_t *function, njs_value_t *this,
         return ret;
     }
 
-    /* Skip the "apply" method frame. */
+    /* Skip the "call/apply" method frame. */
     vm->frame->previous->skip = 1;
 
     return njs_function_call(vm, retval, sizeof(njs_vmcode_function_call_t));