]> git.kaiwu.me - njs.git/commitdiff
Native methods called by iterators should run via continuation
authorIgor Sysoev <igor@sysoev.ru>
Mon, 5 Dec 2016 14:35:33 +0000 (17:35 +0300)
committerIgor Sysoev <igor@sysoev.ru>
Mon, 5 Dec 2016 14:35:33 +0000 (17:35 +0300)
to normilize arguments.

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

index eaab0a7bfb755ae8590b5f8b433a7a1e8c5db7e9..d63efbfa27f0e1159a2e6773d5a130d38de48f26 100644 (file)
@@ -252,21 +252,12 @@ nxt_noinline njs_ret_t
 njs_function_apply(njs_vm_t *vm, njs_function_t *function, njs_value_t *args,
     nxt_uint_t nargs, njs_index_t retval)
 {
-    size_t              reserve;
     njs_ret_t           ret;
     njs_continuation_t  *cont;
 
     if (function->native) {
-
-        if (function->continuation_size == 0 && function->bound == NULL) {
-            return function->u.native(vm, args, nargs, retval);
-        }
-
-        reserve = nxt_align_size(sizeof(njs_continuation_t),
-                                 sizeof(njs_value_t)),
-
         ret = njs_function_native_frame(vm, function, &args[0], &args[1],
-                                        nargs - 1, reserve, 0);
+                                        nargs - 1, NJS_CONTINUATION_SIZE, 0);
         if (ret != NJS_OK) {
             return ret;
         }
@@ -274,6 +265,7 @@ njs_function_apply(njs_vm_t *vm, njs_function_t *function, njs_value_t *args,
         cont = njs_continuation(vm->frame);
 
         cont->function = function->u.native;
+        cont->args_types = function->args_types;
         cont->retval = retval;
 
         cont->return_address = vm->current;
index 1f79bbd79267b5f850118a0f1eea142694b4cb48..f64b044a4d9bfd9136768967b47fd7921a78aae8 100644 (file)
@@ -50,6 +50,7 @@ struct njs_function_lambda_s {
 
 typedef struct {
     njs_function_native_t          function;
+    uint8_t                        *args_types;
     u_char                         *return_address;
     njs_index_t                    retval;
 } njs_continuation_t;
index 8be5ecf49752558dc51183ab2f2e76e0c02a51ae..9f92abbcb16e963676365a65b9f7b8b6a68fc9ab 100644 (file)
@@ -2358,6 +2358,7 @@ njs_vmcode_function_call(njs_vm_t *vm, njs_value_t *invld, njs_value_t *retval)
         cont = njs_continuation(vm->frame);
 
         cont->function = function->u.native;
+        cont->args_types = function->args_types;
         cont->retval = (njs_index_t) retval;
 
         cont->return_address = vm->current + sizeof(njs_vmcode_function_call_t);
@@ -2609,6 +2610,13 @@ njs_vmcode_continuation(njs_vm_t *vm, njs_value_t *invld1, njs_value_t *invld2)
     cont = njs_continuation(frame);
     args = frame->arguments - frame->function->args_offset;
 
+    if (cont->args_types != NULL) {
+        ret = njs_normalize_args(vm, args, cont->args_types, frame->nargs);
+        if (ret != NJS_OK) {
+            return ret;
+        }
+    }
+
     ret = cont->function(vm, args, frame->nargs, cont->retval);
 
     switch (ret) {
index 83fad66d24094572fe778ba9dae6b5f33840cdc7..a21507544da2382a7ffbca25d2a1325180a141c9 100644 (file)
@@ -5461,6 +5461,9 @@ static njs_unit_test_t  njs_test[] =
     { nxt_string("var d = new Date(); d.__proto__ === Date.prototype"),
       nxt_string("true") },
 
+    { nxt_string("[0].map(new Date().getDate)"),
+      nxt_string("TypeError") },
+
     { nxt_string("new Date(eval)"),
       nxt_string("Invalid Date") },