From: Igor Sysoev Date: Mon, 5 Dec 2016 14:35:33 +0000 (+0300) Subject: Native methods called by iterators should run via continuation X-Git-Tag: 0.1.6~10 X-Git-Url: http://git.kaiwu.me/%7B@url%7D?a=commitdiff_plain;h=fe2c81b3436f22bdd777d4cfa2293eb8a14f5297;p=njs.git Native methods called by iterators should run via continuation to normilize arguments. --- diff --git a/njs/njs_function.c b/njs/njs_function.c index eaab0a7b..d63efbfa 100644 --- a/njs/njs_function.c +++ b/njs/njs_function.c @@ -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; diff --git a/njs/njs_function.h b/njs/njs_function.h index 1f79bbd7..f64b044a 100644 --- a/njs/njs_function.h +++ b/njs/njs_function.h @@ -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; diff --git a/njs/njs_vm.c b/njs/njs_vm.c index 8be5ecf4..9f92abbc 100644 --- a/njs/njs_vm.c +++ b/njs/njs_vm.c @@ -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) { diff --git a/njs/test/njs_unit_test.c b/njs/test/njs_unit_test.c index 83fad66d..a2150754 100644 --- a/njs/test/njs_unit_test.c +++ b/njs/test/njs_unit_test.c @@ -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") },