From b8a8d4c3e8d55a52356fa39123b79ae774a0573e Mon Sep 17 00:00:00 2001 From: Igor Sysoev Date: Sun, 14 Feb 2016 21:49:15 +0300 Subject: [PATCH] njs_param_t removal. --- nginx/ngx_http_js_module.c | 30 ++--- njs/njs_array.c | 225 +++++++++++++++-------------------- njs/njs_array.h | 3 +- njs/njs_boolean.c | 18 +-- njs/njs_boolean.h | 3 +- njs/njs_builtin.c | 4 +- njs/njs_function.c | 236 +++++++++++++++++-------------------- njs/njs_function.h | 10 +- njs/njs_number.c | 17 +-- njs/njs_number.h | 3 +- njs/njs_object.c | 24 ++-- njs/njs_object.h | 6 +- njs/njs_regexp.c | 36 +++--- njs/njs_regexp.h | 6 +- njs/njs_string.c | 157 ++++++++++++------------ njs/njs_string.h | 3 +- njs/njs_vm.c | 44 +++---- njs/njs_vm.h | 5 +- njs/njscript.h | 9 +- njs/test/njs_unit_test.c | 21 +++- 20 files changed, 409 insertions(+), 451 deletions(-) diff --git a/nginx/ngx_http_js_module.c b/nginx/ngx_http_js_module.c index b697ee22..56840578 100644 --- a/nginx/ngx_http_js_module.c +++ b/nginx/ngx_http_js_module.c @@ -76,9 +76,12 @@ static njs_ret_t ngx_http_js_ext_get_content_length(njs_vm_t *vm, njs_value_t *value, void *obj, uintptr_t data); static njs_ret_t ngx_http_js_ext_set_content_length(njs_vm_t *vm, void *obj, uintptr_t data, nxt_str_t *value); -static njs_ret_t ngx_http_js_ext_send_header(njs_vm_t *vm, njs_param_t *param); -static njs_ret_t ngx_http_js_ext_send(njs_vm_t *vm, njs_param_t *param); -static njs_ret_t ngx_http_js_ext_finish(njs_vm_t *vm, njs_param_t *param); +static njs_ret_t ngx_http_js_ext_send_header(njs_vm_t *vm, njs_value_t *args, + nxt_uint_t nargs, njs_index_t unused); +static njs_ret_t ngx_http_js_ext_send(njs_vm_t *vm, njs_value_t *args, + nxt_uint_t nargs, njs_index_t unused); +static njs_ret_t ngx_http_js_ext_finish(njs_vm_t *vm, njs_value_t *args, + nxt_uint_t nargs, njs_index_t unused); static njs_ret_t ngx_http_js_ext_get_http_version(njs_vm_t *vm, njs_value_t *value, void *obj, uintptr_t data); static njs_ret_t ngx_http_js_ext_get_remote_address(njs_vm_t *vm, @@ -787,11 +790,12 @@ ngx_http_js_ext_set_content_length(njs_vm_t *vm, void *obj, uintptr_t data, static njs_ret_t -ngx_http_js_ext_send_header(njs_vm_t *vm, njs_param_t *param) +ngx_http_js_ext_send_header(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, + njs_index_t unused) { ngx_http_request_t *r; - r = njs_value_data(njs_argument(param->args, 0)); + r = njs_value_data(njs_argument(args, 0)); if (ngx_http_send_header(r) == NGX_ERROR) { return NJS_ERROR; @@ -802,25 +806,22 @@ ngx_http_js_ext_send_header(njs_vm_t *vm, njs_param_t *param) static njs_ret_t -ngx_http_js_ext_send(njs_vm_t *vm, njs_param_t *param) +ngx_http_js_ext_send(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, + njs_index_t unused) { nxt_int_t ret; nxt_str_t s; ngx_buf_t *b; - uintptr_t nargs, next; + uintptr_t next; ngx_uint_t n; - njs_value_t *args; ngx_chain_t *out, *cl, **ll; ngx_http_request_t *r; - r = njs_value_data(njs_argument(param->args, 0)); + r = njs_value_data(njs_argument(args, 0)); out = NULL; ll = &out; - args = param->args; - nargs = param->nargs; - for (n = 1; n < nargs; n++) { next = 0; @@ -874,11 +875,12 @@ ngx_http_js_ext_send(njs_vm_t *vm, njs_param_t *param) static njs_ret_t -ngx_http_js_ext_finish(njs_vm_t *vm, njs_param_t *param) +ngx_http_js_ext_finish(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, + njs_index_t unused) { ngx_http_request_t *r; - r = njs_value_data(njs_argument(param->args, 0)); + r = njs_value_data(njs_argument(args, 0)); if (ngx_http_send_special(r, NGX_HTTP_LAST) == NGX_ERROR) { return NJS_ERROR; diff --git a/njs/njs_array.c b/njs/njs_array.c index eda8af3c..85d1bf67 100644 --- a/njs/njs_array.c +++ b/njs/njs_array.c @@ -24,7 +24,7 @@ typedef struct { - njs_continuation_t continuation; + njs_continuation_t cont; njs_value_t *values; uint32_t max; } njs_array_join_t; @@ -38,10 +38,9 @@ typedef struct { static njs_ret_t njs_array_prototype_join_continuation(njs_vm_t *vm, - njs_param_t *param); + njs_value_t *args, nxt_uint_t nargs, njs_index_t unused); static nxt_noinline njs_value_t *njs_array_copy(njs_value_t *dst, njs_value_t *src); -static nxt_int_t njs_array_iterator_args(njs_vm_t *vm, njs_param_t *param); static nxt_noinline nxt_int_t njs_array_next(njs_value_t *value, nxt_uint_t n, nxt_uint_t length); @@ -174,15 +173,16 @@ njs_array_realloc(njs_vm_t *vm, njs_array_t *array, uint32_t prepend, njs_ret_t -njs_array_constructor(njs_vm_t *vm, njs_param_t *param) +njs_array_constructor(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, + njs_index_t unused) { double num; uint32_t size; - njs_value_t *value, *args; + njs_value_t *value; njs_array_t *array; - args = ¶m->args[1]; - size = param->nargs - 1; + args = &args[1]; + size = nargs - 1; if (size == 1 && njs_is_number(&args[0])) { num = args[0].data.u.number; @@ -276,21 +276,19 @@ njs_array_prototype_length(njs_vm_t *vm, njs_value_t *array) */ static njs_ret_t -njs_array_prototype_slice(njs_vm_t *vm, njs_param_t *param) +njs_array_prototype_slice(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, + njs_index_t unused) { int32_t start, end, length; uint32_t n; - uintptr_t nargs; njs_array_t *array; - njs_value_t *args, *value; + njs_value_t *value; start = 0; length = 0; - args = param->args; if (njs_is_array(&args[0])) { length = args[0].data.u.array->length; - nargs = param->nargs; if (nargs > 1) { start = args[1].data.u.number; @@ -347,16 +345,16 @@ njs_array_prototype_slice(njs_vm_t *vm, njs_param_t *param) static njs_ret_t -njs_array_prototype_push(njs_vm_t *vm, njs_param_t *param) +njs_array_prototype_push(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, + njs_index_t unused) { - uintptr_t i, nargs; njs_ret_t ret; - njs_value_t *args; + nxt_uint_t i, n; njs_array_t *array; - if (njs_is_array(¶m->args[0])) { - array = param->args[0].data.u.array; - nargs = param->nargs - 1; + if (njs_is_array(&args[0])) { + array = args[0].data.u.array; + n = nargs - 1; if (nargs != 0) { if (nargs > array->size - array->length) { @@ -366,9 +364,6 @@ njs_array_prototype_push(njs_vm_t *vm, njs_param_t *param) } } - args = param->args; - nargs = param->nargs; - for (i = 1; i < nargs; i++) { /* GC: njs_retain(&args[i]); */ array->start[array->length++] = args[i]; @@ -383,15 +378,16 @@ njs_array_prototype_push(njs_vm_t *vm, njs_param_t *param) static njs_ret_t -njs_array_prototype_pop(njs_vm_t *vm, njs_param_t *param) +njs_array_prototype_pop(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, + njs_index_t unused) { njs_array_t *array; const njs_value_t *retval, *value; retval = &njs_value_void; - if (njs_is_array(¶m->args[0])) { - array = param->args[0].data.u.array; + if (njs_is_array(&args[0])) { + array = args[0].data.u.array; if (array->length != 0) { array->length--; @@ -410,16 +406,16 @@ njs_array_prototype_pop(njs_vm_t *vm, njs_param_t *param) static njs_ret_t -njs_array_prototype_unshift(njs_vm_t *vm, njs_param_t *param) +njs_array_prototype_unshift(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, + njs_index_t unused) { - uintptr_t n; njs_ret_t ret; - njs_value_t *args; + nxt_uint_t n; njs_array_t *array; - if (njs_is_array(¶m->args[0])) { - array = param->args[0].data.u.array; - n = param->nargs - 1; + if (njs_is_array(&args[0])) { + array = args[0].data.u.array; + n = nargs - 1; if (n != 0) { if ((intptr_t) n > (array->start - array->data)) { @@ -430,8 +426,7 @@ njs_array_prototype_unshift(njs_vm_t *vm, njs_param_t *param) } array->length += n; - args = param->args; - n = param->nargs; + n = nargs; do { n--; @@ -449,15 +444,16 @@ njs_array_prototype_unshift(njs_vm_t *vm, njs_param_t *param) static njs_ret_t -njs_array_prototype_shift(njs_vm_t *vm, njs_param_t *param) +njs_array_prototype_shift(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, + njs_index_t unused) { njs_array_t *array; const njs_value_t *retval, *value; retval = &njs_value_void; - if (njs_is_array(¶m->args[0])) { - array = param->args[0].data.u.array; + if (njs_is_array(&args[0])) { + array = args[0].data.u.array; if (array->length != 0) { array->length--; @@ -483,14 +479,12 @@ njs_array_prototype_shift(njs_vm_t *vm, njs_param_t *param) */ static njs_ret_t -njs_array_prototype_to_string(njs_vm_t *vm, njs_param_t *param) +njs_array_prototype_to_string(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, + njs_index_t retval) { - njs_value_t *this, *args; njs_object_prop_t *prop; nxt_lvlhsh_query_t lhq; - args = param->args; - if (njs_is_object(&args[0])) { lhq.key_hash = NJS_JOIN_HASH; lhq.key.len = sizeof("join") - 1; @@ -499,26 +493,18 @@ njs_array_prototype_to_string(njs_vm_t *vm, njs_param_t *param) prop = njs_object_property(vm, args[0].data.u.object, &lhq); if (nxt_fast_path(prop != NULL && njs_is_function(&prop->value))) { - - this = &args[0]; - - if (prop->value.data.u.function->native) { - param->args = &args[0]; - param->nargs++; - this = NULL; - } - - return njs_function_apply(vm, prop->value.data.u.function, this, - param); + return njs_function_apply(vm, prop->value.data.u.function, + args, nargs, retval); } } - return njs_object_prototype_to_string(vm, param); + return njs_object_prototype_to_string(vm, args, nargs, retval); } static njs_ret_t -njs_array_prototype_join(njs_vm_t *vm, njs_param_t *param) +njs_array_prototype_join(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, + njs_index_t unused) { uint32_t max; nxt_uint_t i, n; @@ -526,11 +512,11 @@ njs_array_prototype_join(njs_vm_t *vm, njs_param_t *param) njs_value_t *value, *values; njs_array_join_t *join; - if (!njs_is_array(¶m->args[0])) { + if (!njs_is_array(&args[0])) { goto empty; } - array = param->args[0].data.u.array; + array = args[0].data.u.array; if (array->length == 0) { goto empty; @@ -558,12 +544,12 @@ njs_array_prototype_join(njs_vm_t *vm, njs_param_t *param) return NXT_ERROR; } - join->continuation.function = njs_array_prototype_join_continuation; - join->continuation.args = param->args; - join->continuation.nargs = param->nargs; + join->cont.function = njs_array_prototype_join_continuation; + join->cont.args = args; + join->cont.nargs = nargs; join->values = values; join->max = max; - vm->frame->continuation = &join->continuation; + vm->frame->continuation = &join->cont; n = 0; @@ -579,7 +565,7 @@ njs_array_prototype_join(njs_vm_t *vm, njs_param_t *param) } } - return njs_array_prototype_join_continuation(vm, param); + return njs_array_prototype_join_continuation(vm, args, nargs, unused); empty: @@ -590,7 +576,8 @@ empty: static njs_ret_t -njs_array_prototype_join_continuation(njs_vm_t *vm, njs_param_t *param) +njs_array_prototype_join_continuation(njs_vm_t *vm, njs_value_t *args, + nxt_uint_t nargs, njs_index_t unused) { u_char *p; size_t size, length, mask; @@ -617,7 +604,7 @@ njs_array_prototype_join_continuation(njs_vm_t *vm, njs_param_t *param) n = 0; mask = -1; - array = param->args[0].data.u.array; + array = args[0].data.u.array; for (i = 0; i < array->length; i++) { value = &array->start[i]; @@ -645,8 +632,8 @@ njs_array_prototype_join_continuation(njs_vm_t *vm, njs_param_t *param) } } - if (param->nargs > 1) { - value = ¶m->args[1]; + if (nargs > 1) { + value = &args[1]; } else { value = (njs_value_t *) &njs_string_comma; @@ -699,17 +686,15 @@ njs_array_prototype_join_continuation(njs_vm_t *vm, njs_param_t *param) static njs_ret_t -njs_array_prototype_concat(njs_vm_t *vm, njs_param_t *param) +njs_array_prototype_concat(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, + njs_index_t unused) { size_t length; - uintptr_t nargs; nxt_uint_t i; - njs_value_t *args, *value; + njs_value_t *value; njs_array_t *array; length = 0; - args = param->args; - nargs = param->nargs; for (i = 0; i < nargs; i++) { if (njs_is_array(&args[i])) { @@ -761,21 +746,32 @@ njs_array_copy(njs_value_t *dst, njs_value_t *src) } +nxt_inline nxt_int_t +njs_array_iterator_args(njs_vm_t *vm, njs_value_t * args, nxt_uint_t nargs) +{ + if (nargs > 1 && njs_is_array(&args[0]) && njs_is_function(&args[1])) { + return NXT_OK; + } + + vm->exception = &njs_exception_type_error; + + return NXT_ERROR; +} + + static njs_ret_t -njs_array_prototype_for_each(njs_vm_t *vm, njs_param_t *param) +njs_array_prototype_for_each(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, + njs_index_t unused) { nxt_int_t n, ret; - njs_param_t p; njs_array_t *array; - njs_value_t *this, *args, arguments[3]; njs_array_next_t *next; - - args = param->args; + njs_value_t arguments[4]; if (!vm->frame->reentrant) { vm->frame->reentrant = 1; - ret = njs_array_iterator_args(vm, param); + ret = njs_array_iterator_args(vm, args, nargs); if (nxt_slow_path(ret != NXT_OK)) { return ret; } @@ -796,11 +792,12 @@ njs_array_prototype_for_each(njs_vm_t *vm, njs_param_t *param) next = njs_native_data(vm->frame); n = next->index; + arguments[0] = (nargs > 2) ? args[2] : njs_value_void; /* GC: array elt, array */ array = args[0].data.u.array; - arguments[0] = array->start[n]; - njs_number_set(&arguments[1], n); - arguments[2] = args[0]; + arguments[1] = array->start[n]; + njs_number_set(&arguments[2], n); + arguments[3] = args[0]; n = njs_array_next(array->start, ++n, next->length); next->index = n; @@ -809,30 +806,24 @@ njs_array_prototype_for_each(njs_vm_t *vm, njs_param_t *param) vm->current += sizeof(njs_vmcode_function_call_t); } - this = (param->nargs > 2) ? &args[2] : (njs_value_t *) &njs_value_void; - p.args = arguments; - p.nargs = 3; - p.retval = (njs_index_t) &next->retval; - - return njs_function_apply(vm, args[1].data.u.function, this, &p); + return njs_function_apply(vm, args[1].data.u.function, arguments, 4, + (njs_index_t) &next->retval); } static njs_ret_t -njs_array_prototype_some(njs_vm_t *vm, njs_param_t *param) +njs_array_prototype_some(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, + njs_index_t unused) { nxt_int_t n, ret; - njs_param_t p; njs_array_t *array; - njs_value_t *this, *args, arguments[3]; njs_array_next_t *next; - - args = param->args; + njs_value_t arguments[4]; if (!vm->frame->reentrant) { vm->frame->reentrant = 1; - ret = njs_array_iterator_args(vm, param); + ret = njs_array_iterator_args(vm, args, nargs); if (nxt_slow_path(ret != NXT_OK)) { return ret; } @@ -859,38 +850,33 @@ njs_array_prototype_some(njs_vm_t *vm, njs_param_t *param) return NXT_OK; } + arguments[0] = (nargs > 2) ? args[2] : njs_value_void; /* GC: array elt, array */ array = args[0].data.u.array; - arguments[0] = array->start[n]; - njs_number_set(&arguments[1], n); - arguments[2] = args[0]; + arguments[1] = array->start[n]; + njs_number_set(&arguments[2], n); + arguments[3] = args[0]; next->index = njs_array_next(array->start, ++n, next->length); - this = (param->nargs > 2) ? &args[2] : (njs_value_t *) &njs_value_void; - p.args = arguments; - p.nargs = 3; - p.retval = (njs_index_t) &next->retval; - - return njs_function_apply(vm, args[1].data.u.function, this, &p); + return njs_function_apply(vm, args[1].data.u.function, arguments, 4, + (njs_index_t) &next->retval); } static njs_ret_t -njs_array_prototype_every(njs_vm_t *vm, njs_param_t *param) +njs_array_prototype_every(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, + njs_index_t unused) { nxt_int_t n, ret; - njs_param_t p; njs_array_t *array; - njs_value_t *this, *args, arguments[3]; njs_array_next_t *next; - - args = param->args; + njs_value_t arguments[4]; if (!vm->frame->reentrant) { vm->frame->reentrant = 1; - ret = njs_array_iterator_args(vm, param); + ret = njs_array_iterator_args(vm, args, nargs); if (nxt_slow_path(ret != NXT_OK)) { return ret; } @@ -917,36 +903,17 @@ njs_array_prototype_every(njs_vm_t *vm, njs_param_t *param) return NXT_OK; } + arguments[0] = (nargs > 2) ? args[2] : njs_value_void; /* GC: array elt, array */ array = args[0].data.u.array; - arguments[0] = array->start[n]; - njs_number_set(&arguments[1], n); - arguments[2] = args[0]; + arguments[1] = array->start[n]; + njs_number_set(&arguments[2], n); + arguments[3] = args[0]; next->index = njs_array_next(array->start, ++n, next->length); - this = (param->nargs > 2) ? &args[2] : (njs_value_t *) &njs_value_void; - p.args = arguments; - p.nargs = 3; - p.retval = (njs_index_t) &next->retval; - - return njs_function_apply(vm, args[1].data.u.function, this, &p); -} - - -static nxt_int_t -njs_array_iterator_args(njs_vm_t *vm, njs_param_t *param) -{ - if (param->nargs > 1 - && njs_is_array(¶m->args[0]) - && njs_is_function(¶m->args[1])) - { - return NXT_OK; - } - - vm->exception = &njs_exception_type_error; - - return NXT_ERROR; + return njs_function_apply(vm, args[1].data.u.function, arguments, 4, + (njs_index_t) &next->retval); } diff --git a/njs/njs_array.h b/njs/njs_array.h index d6e0bd71..c6b8d0b0 100644 --- a/njs/njs_array.h +++ b/njs/njs_array.h @@ -23,7 +23,8 @@ struct njs_array_s { njs_array_t *njs_array_alloc(njs_vm_t *vm, uint32_t length, uint32_t spare); njs_ret_t njs_array_realloc(njs_vm_t *vm, njs_array_t *array, uint32_t prepend, uint32_t size); -njs_ret_t njs_array_constructor(njs_vm_t *vm, njs_param_t *param); +njs_ret_t njs_array_constructor(njs_vm_t *vm, njs_value_t *args, + nxt_uint_t nargs, njs_index_t unused); extern const njs_object_init_t njs_array_constructor_init; extern const njs_object_init_t njs_array_prototype_init; diff --git a/njs/njs_boolean.c b/njs/njs_boolean.c index 27afc65e..13ca020d 100644 --- a/njs/njs_boolean.c +++ b/njs/njs_boolean.c @@ -18,17 +18,17 @@ njs_ret_t -njs_boolean_constructor(njs_vm_t *vm, njs_param_t *param) +njs_boolean_constructor(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, + njs_index_t unused) { njs_object_t *object; const njs_value_t *value; - if (param->nargs == 1) { + if (nargs == 1) { value = &njs_value_false; } else { - value = njs_is_true(¶m->args[1]) ? &njs_value_true: - &njs_value_false; + value = njs_is_true(&args[1]) ? &njs_value_true : &njs_value_false; } if (vm->frame->ctor) { @@ -81,11 +81,12 @@ const njs_object_init_t njs_boolean_constructor_init = { static njs_ret_t -njs_boolean_prototype_value_of(njs_vm_t *vm, njs_param_t *param) +njs_boolean_prototype_value_of(njs_vm_t *vm, njs_value_t *args, + nxt_uint_t nargs, njs_index_t unused) { njs_value_t *value; - value = ¶m->args[0]; + value = &args[0]; if (value->type != NJS_BOOLEAN) { @@ -105,11 +106,12 @@ njs_boolean_prototype_value_of(njs_vm_t *vm, njs_param_t *param) static njs_ret_t -njs_boolean_prototype_to_string(njs_vm_t *vm, njs_param_t *param) +njs_boolean_prototype_to_string(njs_vm_t *vm, njs_value_t *args, + nxt_uint_t nargs, njs_index_t unused) { njs_value_t *value; - value = ¶m->args[0]; + value = &args[0]; if (value->type != NJS_BOOLEAN) { diff --git a/njs/njs_boolean.h b/njs/njs_boolean.h index 04180222..9f087537 100644 --- a/njs/njs_boolean.h +++ b/njs/njs_boolean.h @@ -8,7 +8,8 @@ #define _NJS_BOOLEAN_H_INCLUDED_ -njs_ret_t njs_boolean_constructor(njs_vm_t *vm, njs_param_t *param); +njs_ret_t njs_boolean_constructor(njs_vm_t *vm, njs_value_t *args, + nxt_uint_t nargs, njs_index_t unused); extern const njs_object_init_t njs_boolean_constructor_init; extern const njs_object_init_t njs_boolean_prototype_init; diff --git a/njs/njs_builtin.c b/njs/njs_builtin.c index a04e9a3f..37ca2c54 100644 --- a/njs/njs_builtin.c +++ b/njs/njs_builtin.c @@ -23,8 +23,8 @@ typedef struct { - njs_native_t native; - uint8_t args_types[NJS_ARGS_TYPES_MAX]; + njs_function_native_t native; + uint8_t args_types[NJS_ARGS_TYPES_MAX]; } njs_function_init_t; diff --git a/njs/njs_function.c b/njs/njs_function.c index c0e6b533..95909e31 100644 --- a/njs/njs_function.c +++ b/njs/njs_function.c @@ -20,7 +20,7 @@ typedef struct { - njs_continuation_t continuation; + njs_continuation_t cont; njs_function_t *function; } njs_function_apply_t; @@ -29,7 +29,7 @@ static nxt_int_t njs_function_apply_frame(njs_vm_t *vm, njs_function_t *function, njs_value_t *this, njs_value_t *args, nxt_uint_t nargs); static njs_ret_t njs_function_prototype_apply_continuation(njs_vm_t *vm, - njs_param_t *param); + njs_value_t *args, nxt_uint_t nargs, njs_index_t retval); njs_function_t * @@ -122,26 +122,27 @@ njs_function_frame_alloc(njs_vm_t *vm, size_t size) njs_ret_t -njs_function_constructor(njs_vm_t *vm, njs_param_t *param) +njs_function_constructor(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, + njs_index_t unused) { return NXT_ERROR; } nxt_noinline njs_ret_t -njs_function_apply(njs_vm_t *vm, njs_function_t *function, njs_value_t *this, - njs_param_t *param) +njs_function_apply(njs_vm_t *vm, njs_function_t *function, njs_value_t *args, + nxt_uint_t nargs, njs_index_t retval) { njs_ret_t ret; if (function->native) { - return function->u.native(vm, param); + return function->u.native(vm, args, nargs, retval); } - ret = njs_function_frame(vm, function, this, param->args, param->nargs, 0); + ret = njs_function_frame(vm, function, &args[0], &args[1], nargs - 1, 0); if (nxt_fast_path(ret == NXT_OK)) { - return njs_function_call(vm, param->retval, 0); + return njs_function_call(vm, retval, 0); } return ret; @@ -266,178 +267,148 @@ const njs_object_init_t njs_function_constructor_init = { static njs_ret_t -njs_function_prototype_call(njs_vm_t *vm, njs_param_t *param) +njs_function_prototype_call(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, + njs_index_t retval) { - uintptr_t nargs; - njs_ret_t ret; - njs_param_t p; - njs_value_t *this; - njs_function_t *function; - njs_vmcode_function_call_t *call; - - if (!njs_is_function(¶m->args[0])) { + njs_ret_t ret; + njs_value_t *this; + njs_function_t *function; + + if (!njs_is_function(&args[0])) { vm->exception = &njs_exception_type_error; return NXT_ERROR; } - this = ¶m->args[1]; - p.args = ¶m->args[2]; - - nargs = param->nargs - 1; - function = param->args[0].data.u.function; + nargs = nargs - 1; + function = args[0].data.u.function; if (function->native) { if (nargs == 0) { nargs++; - param->args[1] = njs_value_void; + args[1] = njs_value_void; } - p.args = ¶m->args[1]; - p.nargs = nargs; - p.retval = param->retval; + ret = njs_normalize_args(vm, &args[1], function->args_types, nargs); - ret = njs_normalize_args(vm, ¶m->args[1], function->args_types, - nargs); if (ret != NJS_OK) { return ret; } - return function->u.native(vm, &p); + if (function->local_state_size == 0) { + args = &args[1]; + + } else { + ret = njs_function_apply_frame(vm, function, &args[1], &args[2], + nargs - 1); + if (ret != NJS_OK) { + return ret; + } + + /* Skip the "call" method frame. */ + vm->frame->previous->skip = 1; + + args = vm->frame->arguments - function->args_offset; + } + + return function->u.native(vm, args, nargs, retval); } - if (nargs != 0) { - nargs--; + this = &args[1]; - } else { + if (nargs == 0) { this = (njs_value_t *) &njs_value_void; + + } else { + nargs--; } - ret = njs_function_frame(vm, function, this, p.args, nargs, 0); + ret = njs_function_frame(vm, function, this, &args[2], nargs, 0); if (nxt_slow_path(ret != NXT_OK)) { - return NXT_ERROR; + return ret; } /* Skip the "call" method frame. */ vm->frame->previous->skip = 1; - call = (njs_vmcode_function_call_t *) vm->current; - - return njs_function_call(vm, call->retval, - sizeof(njs_vmcode_function_call_t)); + return njs_function_call(vm, retval, sizeof(njs_vmcode_function_call_t)); } static njs_ret_t -njs_function_prototype_apply(njs_vm_t *vm, njs_param_t *param) +njs_function_prototype_apply(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, + njs_index_t retval) { - uintptr_t nargs; - njs_ret_t ret; - njs_param_t p; - njs_array_t *array; - njs_value_t *this, *args; - njs_function_t *function; - njs_function_apply_t *apply; - njs_vmcode_function_call_t *code; - - args = param->args; + njs_ret_t ret; + njs_array_t *array; + njs_value_t *this; + njs_function_t *function; + njs_function_apply_t *apply; if (!njs_is_function(&args[0])) { goto type_error; } function = args[0].data.u.function; + this = &args[1]; - if (function->native) { - - this = &args[1]; - nargs = param->nargs; - - if (nargs > 2) { - if (!njs_is_array(&args[2])) { - goto type_error; - } - - array = args[2].data.u.array; - args = array->start; - nargs = array->length; - - } else { - if (nargs == 1) { - this = (njs_value_t *) &njs_value_void; - } - - nargs = 0; + if (nargs > 2) { + if (!njs_is_array(&args[2])) { + goto type_error; } - p.retval = param->retval; - - ret = njs_function_apply_frame(vm, function, this, args, nargs); - - if (nxt_fast_path(ret == NXT_OK)) { - apply = nxt_mem_cache_alloc(vm->mem_cache_pool, - sizeof(njs_function_apply_t)); - if (nxt_slow_path(apply == NULL)) { - return NXT_ERROR; - } - - p.args = vm->frame->arguments - 1; - p.nargs = nargs + 1; - - /* Skip the "apply" method frame. */ - vm->frame->previous->skip = 1; - - apply->continuation.function = - njs_function_prototype_apply_continuation; - apply->continuation.args = p.args; - apply->continuation.nargs = p.nargs; - apply->function = function; - vm->frame->continuation = &apply->continuation; + array = args[2].data.u.array; + args = array->start; + nargs = array->length; - return njs_function_prototype_apply_continuation(vm, &p); + } else { + if (nargs == 1) { + this = (njs_value_t *) &njs_value_void; } - return ret; + nargs = 0; } - this = &args[1]; - - nargs = param->nargs - 1; - p.nargs = nargs; + if (function->native) { + ret = njs_function_apply_frame(vm, function, this, args, nargs); + if (nxt_slow_path(ret != NXT_OK)) { + return ret; + } - if (nargs > 1) { - if (!njs_is_array(&args[2])) { - goto type_error; + apply = nxt_mem_cache_alloc(vm->mem_cache_pool, + sizeof(njs_function_apply_t)); + if (nxt_slow_path(apply == NULL)) { + return NXT_ERROR; } - array = args[2].data.u.array; - p.args = array->start; - p.nargs = array->length; - } + args = vm->frame->arguments - function->args_offset; + nargs = nargs + 1; - if (nargs < 2) { - if (nargs != 0) { - p.nargs = 0; + /* Skip the "apply" method frame. */ + vm->frame->previous->skip = 1; - } else { - this = (njs_value_t *) &njs_value_void; - } + apply->cont.function = njs_function_prototype_apply_continuation; + apply->cont.args = args; + apply->cont.nargs = nargs; + apply->function = function; + vm->frame->continuation = &apply->cont; + + return njs_function_prototype_apply_continuation(vm, args, nargs, + retval); } - ret = njs_function_frame(vm, function, this, p.args, p.nargs, 0); + ret = njs_function_frame(vm, function, this, args, nargs, 0); if (nxt_fast_path(ret == NXT_OK)) { /* Skip the "apply" method frame. */ vm->frame->previous->skip = 1; - code = (njs_vmcode_function_call_t *) vm->current; - - return njs_function_call(vm, code->retval, + return njs_function_call(vm, retval, sizeof(njs_vmcode_function_call_t)); } - return NXT_ERROR; + return ret; type_error: @@ -467,40 +438,46 @@ njs_function_apply_frame(njs_vm_t *vm, njs_function_t *function, arguments = (njs_value_t *) ((u_char *) njs_native_data(frame) + function->local_state_size); - frame->arguments = arguments + 1; + + frame->arguments = arguments + function->args_offset; vm->scopes[NJS_SCOPE_CALLEE_ARGUMENTS] = frame->arguments; - *arguments = *this; - memcpy(arguments + 1, args, nargs * sizeof(njs_value_t)); + *arguments++ = *this; + + memcpy(arguments, args, nargs * sizeof(njs_value_t)); return NXT_OK; } static njs_ret_t -njs_function_prototype_apply_continuation(njs_vm_t *vm, njs_param_t *param) +njs_function_prototype_apply_continuation(njs_vm_t *vm, njs_value_t *args, + nxt_uint_t nargs, njs_index_t retval) { njs_ret_t ret; + njs_function_t *function; njs_function_apply_t *apply; apply = (njs_function_apply_t *) vm->frame->continuation; + function = apply->function; - ret = njs_normalize_args(vm, param->args, apply->function->args_types, - param->nargs); - if (ret != NJS_OK) { - return ret; + ret = njs_normalize_args(vm, args, function->args_types, nargs); + + if (ret == NJS_OK) { + return function->u.native(vm, args, nargs, retval); } - return apply->function->u.native(vm, param); + return ret; } static njs_ret_t -njs_function_prototype_bind(njs_vm_t *vm, njs_param_t *param) +njs_function_prototype_bind(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, + njs_index_t unused) { njs_function_t *bound; - if (!njs_is_function(¶m->args[0])) { + if (!njs_is_function(&args[0])) { vm->exception = &njs_exception_type_error; return NXT_ERROR; } @@ -512,7 +489,7 @@ njs_function_prototype_bind(njs_vm_t *vm, njs_param_t *param) nxt_lvlhsh_init(&bound->object.shared_hash); bound->object.__proto__ = &vm->prototypes[NJS_PROTOTYPE_FUNCTION]; bound->args_offset = 1; - bound->u.lambda = param->args[0].data.u.function->u.lambda; + bound->u.lambda = args[0].data.u.function->u.lambda; vm->retval.data.u.function = bound; vm->retval.type = NJS_FUNCTION; @@ -554,7 +531,8 @@ const njs_object_init_t njs_function_prototype_init = { njs_ret_t -njs_eval_function(njs_vm_t *vm, njs_param_t *param) +njs_eval_function(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, + njs_index_t unused) { return NXT_ERROR; } diff --git a/njs/njs_function.h b/njs/njs_function.h index 4ffae48f..6843668b 100644 --- a/njs/njs_function.h +++ b/njs/njs_function.h @@ -53,7 +53,7 @@ struct njs_function_lambda_s { typedef struct { - njs_native_t function; + njs_function_native_t function; njs_value_t *args; nxt_uint_t nargs; } njs_continuation_t; @@ -132,9 +132,10 @@ typedef struct { njs_function_t *njs_function_alloc(njs_vm_t *vm); njs_native_frame_t *njs_function_frame_alloc(njs_vm_t *vm, size_t size); -njs_ret_t njs_function_constructor(njs_vm_t *vm, njs_param_t *param); +njs_ret_t njs_function_constructor(njs_vm_t *vm, njs_value_t *args, + nxt_uint_t nargs, njs_index_t unused); njs_ret_t njs_function_apply(njs_vm_t *vm, njs_function_t *function, - njs_value_t *this, njs_param_t *param); + njs_value_t *args, nxt_uint_t nargs, njs_index_t retval); njs_value_t *njs_function_native_frame(njs_vm_t *vm, njs_function_t *function, njs_vmcode_t *code); njs_ret_t njs_function_frame(njs_vm_t *vm, njs_function_t *function, @@ -144,7 +145,8 @@ njs_ret_t njs_function_call(njs_vm_t *vm, njs_index_t retval, size_t advance); extern const njs_object_init_t njs_function_constructor_init; extern const njs_object_init_t njs_function_prototype_init; -njs_ret_t njs_eval_function(njs_vm_t *vm, njs_param_t *param); +njs_ret_t njs_eval_function(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, + njs_index_t unused); extern const njs_object_init_t njs_eval_function_init; diff --git a/njs/njs_number.c b/njs/njs_number.c index e926263d..b7775a77 100644 --- a/njs/njs_number.c +++ b/njs/njs_number.c @@ -213,16 +213,17 @@ njs_number_to_string(njs_vm_t *vm, njs_value_t *string, njs_ret_t -njs_number_constructor(njs_vm_t *vm, njs_param_t *param) +njs_number_constructor(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, + njs_index_t unused) { njs_object_t *object; const njs_value_t *value; - if (param->nargs == 1) { + if (nargs == 1) { value = &njs_value_zero; } else { - value = ¶m->args[1]; + value = &args[1]; } if (vm->frame->ctor) { @@ -275,11 +276,12 @@ const njs_object_init_t njs_number_constructor_init = { static njs_ret_t -njs_number_prototype_value_of(njs_vm_t *vm, njs_param_t *param) +njs_number_prototype_value_of(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, + njs_index_t unused) { njs_value_t *value; - value = ¶m->args[0]; + value = &args[0]; if (value->type != NJS_NUMBER) { @@ -299,11 +301,12 @@ njs_number_prototype_value_of(njs_vm_t *vm, njs_param_t *param) static njs_ret_t -njs_number_prototype_to_string(njs_vm_t *vm, njs_param_t *param) +njs_number_prototype_to_string(njs_vm_t *vm, njs_value_t *args, + nxt_uint_t nargs, njs_index_t unused) { njs_value_t *value; - value = ¶m->args[0]; + value = &args[0]; if (value->type != NJS_NUMBER) { diff --git a/njs/njs_number.h b/njs/njs_number.h index 26f23905..8e95fa4e 100644 --- a/njs/njs_number.h +++ b/njs/njs_number.h @@ -28,7 +28,8 @@ double njs_number_parse(const u_char **start, const u_char *end); int64_t njs_hex_number_parse(u_char *p, u_char *end); njs_ret_t njs_number_to_string(njs_vm_t *vm, njs_value_t *string, const njs_value_t *number); -njs_ret_t njs_number_constructor(njs_vm_t *vm, njs_param_t *param); +njs_ret_t njs_number_constructor(njs_vm_t *vm, njs_value_t *args, + nxt_uint_t nargs, njs_index_t unused); extern const njs_object_init_t njs_number_constructor_init; extern const njs_object_init_t njs_number_prototype_init; diff --git a/njs/njs_object.c b/njs/njs_object.c index 282fad4b..8da185ac 100644 --- a/njs/njs_object.c +++ b/njs/njs_object.c @@ -200,7 +200,8 @@ njs_object_property(njs_vm_t *vm, njs_object_t *object, nxt_lvlhsh_query_t *lhq) njs_ret_t -njs_object_constructor(njs_vm_t *vm, njs_param_t *param) +njs_object_constructor(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, + njs_index_t unused) { nxt_uint_t type; njs_value_t *value; @@ -208,7 +209,7 @@ njs_object_constructor(njs_vm_t *vm, njs_param_t *param) type = NJS_OBJECT; - if (param->nargs == 1 || njs_is_null_or_void(¶m->args[1])) { + if (nargs == 1 || njs_is_null_or_void(&args[1])) { object = njs_object_alloc(vm); if (nxt_slow_path(object == NULL)) { @@ -216,7 +217,7 @@ njs_object_constructor(njs_vm_t *vm, njs_param_t *param) } } else { - value = ¶m->args[1]; + value = &args[1]; if (njs_is_object(value)) { object = value->data.u.object; @@ -249,13 +250,12 @@ njs_object_constructor(njs_vm_t *vm, njs_param_t *param) /* TODO: properties with attributes. */ static njs_ret_t -njs_object_create(njs_vm_t *vm, njs_param_t *param) +njs_object_create(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, + njs_index_t unused) { - njs_value_t *args; njs_object_t *object; - if (param->nargs > 1) { - args = param->args; + if (nargs > 1) { if (njs_is_object(&args[1]) || njs_is_null(&args[1])) { @@ -507,9 +507,10 @@ found: static njs_ret_t -njs_object_prototype_value_of(njs_vm_t *vm, njs_param_t *param) +njs_object_prototype_value_of(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, + njs_index_t unused) { - vm->retval = param->args[0]; + vm->retval = args[0]; return NXT_OK; } @@ -535,10 +536,10 @@ static const njs_value_t njs_object_regexp_string = njs_ret_t -njs_object_prototype_to_string(njs_vm_t *vm, njs_param_t *param) +njs_object_prototype_to_string(njs_vm_t *vm, njs_value_t *args, + nxt_uint_t nargs, njs_index_t unused) { int32_t index; - njs_value_t *args; njs_object_t *prototype; static const njs_value_t *class_name[] = { @@ -563,7 +564,6 @@ njs_object_prototype_to_string(njs_vm_t *vm, njs_param_t *param) &njs_object_regexp_string, }; - args = param->args; index = args[0].type; if (njs_is_object(&args[0])) { diff --git a/njs/njs_object.h b/njs/njs_object.h index 92035c00..87bdc57f 100644 --- a/njs/njs_object.h +++ b/njs/njs_object.h @@ -50,11 +50,13 @@ njs_object_prop_t *njs_object_property(njs_vm_t *vm, njs_object_t *obj, nxt_lvlhsh_query_t *lhq); nxt_int_t njs_object_hash_create(njs_vm_t *vm, nxt_lvlhsh_t *hash, const njs_object_prop_t *prop, nxt_uint_t n); -njs_ret_t njs_object_constructor(njs_vm_t *vm, njs_param_t *param); +njs_ret_t njs_object_constructor(njs_vm_t *vm, njs_value_t *args, + nxt_uint_t nargs, njs_index_t unused); njs_object_prop_t *njs_object_prop_alloc(njs_vm_t *vm, const njs_value_t *name); njs_ret_t njs_primitive_prototype_get_proto(njs_vm_t *vm, njs_value_t *value); njs_ret_t njs_object_prototype_create(njs_vm_t *vm, njs_value_t *value); -njs_ret_t njs_object_prototype_to_string(njs_vm_t *vm, njs_param_t *param); +njs_ret_t njs_object_prototype_to_string(njs_vm_t *vm, njs_value_t *args, + nxt_uint_t nargs, njs_index_t unused); extern const njs_object_init_t njs_object_constructor_init; extern const njs_object_init_t njs_object_prototype_init; diff --git a/njs/njs_regexp.c b/njs/njs_regexp.c index e4a5d717..cfc81146 100644 --- a/njs/njs_regexp.c +++ b/njs/njs_regexp.c @@ -38,7 +38,8 @@ static njs_ret_t njs_regexp_exec_result(njs_vm_t *vm, njs_regexp_t *regexp, njs_ret_t -njs_regexp_constructor(njs_vm_t *vm, njs_param_t *param) +njs_regexp_constructor(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, + njs_index_t unused) { size_t length; njs_regexp_t *regexp; @@ -48,10 +49,10 @@ njs_regexp_constructor(njs_vm_t *vm, njs_param_t *param) flags = 0; - switch (param->nargs) { + switch (nargs) { default: - length = njs_string_prop(&string, ¶m->args[2]); + length = njs_string_prop(&string, &args[2]); flags = njs_regexp_flags(&string.start, string.start + length, 1); if (nxt_slow_path(flags < 0)) { @@ -61,7 +62,7 @@ njs_regexp_constructor(njs_vm_t *vm, njs_param_t *param) /* Fall through. */ case 2: - string.length = njs_string_prop(&string, ¶m->args[1]); + string.length = njs_string_prop(&string, &args[1]); if (string.length != 0) { break; @@ -438,13 +439,14 @@ njs_regexp_prototype_source(njs_vm_t *vm, njs_value_t *value) static njs_ret_t -njs_regexp_prototype_to_string(njs_vm_t *vm, njs_param_t *param) +njs_regexp_prototype_to_string(njs_vm_t *vm, njs_value_t *args, + nxt_uint_t nargs, njs_index_t unused) { u_char *source; size_t length, size; njs_regexp_pattern_t *pattern; - pattern = param->args[0].data.u.regexp->pattern; + pattern = args[0].data.u.regexp->pattern; source = pattern->source; size = strlen((char *) source); @@ -455,7 +457,8 @@ njs_regexp_prototype_to_string(njs_vm_t *vm, njs_param_t *param) static njs_ret_t -njs_regexp_prototype_test(njs_vm_t *vm, njs_param_t *param) +njs_regexp_prototype_test(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, + njs_index_t unused) { njs_ret_t ret; nxt_uint_t n; @@ -464,15 +467,15 @@ njs_regexp_prototype_test(njs_vm_t *vm, njs_param_t *param) njs_string_prop_t string; njs_regexp_pattern_t *pattern; - if (!njs_is_regexp(¶m->args[0])) { + if (!njs_is_regexp(&args[0])) { vm->exception = &njs_exception_type_error; return NXT_ERROR; } retval = &njs_value_false; - if (param->nargs > 1) { - value = ¶m->args[1]; + if (nargs > 1) { + value = &args[1]; } else { value = (njs_value_t *) &njs_string_void; @@ -482,7 +485,7 @@ njs_regexp_prototype_test(njs_vm_t *vm, njs_param_t *param) n = (string.length != 0 && string.length != string.size); - pattern = param->args[0].data.u.regexp->pattern; + pattern = args[0].data.u.regexp->pattern; if (pattern->code[n] != NULL) { ret = pcre_exec(pattern->code[n], pattern->extra[n], @@ -504,7 +507,8 @@ njs_regexp_prototype_test(njs_vm_t *vm, njs_param_t *param) njs_ret_t -njs_regexp_prototype_exec(njs_vm_t *vm, njs_param_t *param) +njs_regexp_prototype_exec(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, + njs_index_t unused) { int *captures, ncaptures; njs_ret_t ret; @@ -514,19 +518,19 @@ njs_regexp_prototype_exec(njs_vm_t *vm, njs_param_t *param) njs_string_prop_t string; njs_regexp_pattern_t *pattern; - if (!njs_is_regexp(¶m->args[0])) { + if (!njs_is_regexp(&args[0])) { vm->exception = &njs_exception_type_error; return NXT_ERROR; } - if (param->nargs > 1) { - value = ¶m->args[1]; + if (nargs > 1) { + value = &args[1]; } else { value = (njs_value_t *) &njs_string_void; } - regexp = param->args[0].data.u.regexp; + regexp = args[0].data.u.regexp; regexp->string = *value; (void) njs_string_prop(&string, value); diff --git a/njs/njs_regexp.h b/njs/njs_regexp.h index 86a24475..32661c5d 100644 --- a/njs/njs_regexp.h +++ b/njs/njs_regexp.h @@ -32,13 +32,15 @@ struct njs_regexp_s { }; -njs_ret_t njs_regexp_constructor(njs_vm_t *vm, njs_param_t *param); +njs_ret_t njs_regexp_constructor(njs_vm_t *vm, njs_value_t *args, + nxt_uint_t nargs, njs_index_t unused); nxt_int_t njs_regexp_literal(njs_vm_t *vm, njs_parser_t *parser, njs_value_t *value); njs_regexp_pattern_t *njs_regexp_pattern_create(njs_vm_t *vm, u_char *string, size_t length, njs_regexp_flags_t flags); njs_regexp_t *njs_regexp_alloc(njs_vm_t *vm, njs_regexp_pattern_t *pattern); -njs_ret_t njs_regexp_prototype_exec(njs_vm_t *vm, njs_param_t *param); +njs_ret_t njs_regexp_prototype_exec(njs_vm_t *vm, njs_value_t *args, + nxt_uint_t nargs, njs_index_t unused); void njs_regexp_pattern_free(njs_regexp_pattern_t *pattern); extern const njs_object_init_t njs_regexp_constructor_init; diff --git a/njs/njs_string.c b/njs/njs_string.c index 73b31e8c..9ecc7ccf 100644 --- a/njs/njs_string.c +++ b/njs/njs_string.c @@ -30,10 +30,10 @@ #include -static nxt_noinline void njs_string_slice_prop(njs_param_t *param, - njs_string_prop_t *string, njs_slice_prop_t *slice); -static nxt_noinline void njs_string_slice_params(njs_param_t *param, - njs_slice_prop_t *slice); +static nxt_noinline void njs_string_slice_prop(njs_string_prop_t *string, + njs_slice_prop_t *slice, njs_value_t *args, nxt_uint_t nargs); +static nxt_noinline void njs_string_slice_args(njs_slice_prop_t *slice, + njs_value_t *args, nxt_uint_t nargs); static nxt_noinline ssize_t njs_string_index_of(njs_vm_t *vm, njs_value_t *src, njs_value_t *search_string, size_t index); @@ -251,16 +251,17 @@ njs_string_prop(njs_string_prop_t *string, njs_value_t *value) njs_ret_t -njs_string_constructor(njs_vm_t *vm, njs_param_t *param) +njs_string_constructor(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, + njs_index_t unused) { njs_object_t *object; const njs_value_t *value; - if (param->nargs == 1) { + if (nargs == 1) { value = &njs_string_empty; } else { - value = ¶m->args[1]; + value = &args[1]; } if (vm->frame->ctor) { @@ -448,11 +449,12 @@ njs_string_cmp(const njs_value_t *v1, const njs_value_t *v2) static njs_ret_t -njs_string_prototype_value_of(njs_vm_t *vm, njs_param_t *param) +njs_string_prototype_value_of(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, + njs_index_t unused) { njs_value_t *value; - value = ¶m->args[0]; + value = &args[0]; if (value->type != NJS_STRING) { @@ -476,24 +478,19 @@ njs_string_prototype_value_of(njs_vm_t *vm, njs_param_t *param) */ static njs_ret_t -njs_string_prototype_concat(njs_vm_t *vm, njs_param_t *param) +njs_string_prototype_concat(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, + njs_index_t unused) { u_char *p, *start; size_t size, length, mask; - uintptr_t nargs; nxt_uint_t i; - njs_value_t *args; njs_string_prop_t string; - args = param->args; - if (njs_is_null_or_void(&args[0])) { vm->exception = &njs_exception_type_error; return NXT_ERROR; } - nargs = param->nargs; - for (i = 0; i < nargs; i++) { if (!njs_is_string(&args[i])) { @@ -553,14 +550,15 @@ njs_string_prototype_concat(njs_vm_t *vm, njs_param_t *param) */ static njs_ret_t -njs_string_prototype_from_utf8(njs_vm_t *vm, njs_param_t *param) +njs_string_prototype_from_utf8(njs_vm_t *vm, njs_value_t *args, + nxt_uint_t nargs, njs_index_t unused) { u_char *p; ssize_t length; njs_slice_prop_t slice; njs_string_prop_t string; - njs_string_slice_prop(param, &string, &slice); + njs_string_slice_prop(&string, &slice, args, nargs); if (string.length != 0) { /* ASCII or UTF8 string. */ @@ -604,17 +602,18 @@ njs_string_prototype_from_utf8(njs_vm_t *vm, njs_param_t *param) */ static njs_ret_t -njs_string_prototype_to_utf8(njs_vm_t *vm, njs_param_t *param) +njs_string_prototype_to_utf8(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, + njs_index_t unused) { njs_slice_prop_t slice; njs_string_prop_t string; - (void) njs_string_prop(&string, ¶m->args[0]); + (void) njs_string_prop(&string, &args[0]); string.length = 0; slice.string_length = string.size; - njs_string_slice_params(param, &slice); + njs_string_slice_args(&slice, args, nargs); return njs_string_slice(vm, &vm->retval, &string, &slice); } @@ -625,14 +624,15 @@ njs_string_prototype_to_utf8(njs_vm_t *vm, njs_param_t *param) */ static njs_ret_t -njs_string_prototype_from_bytes(njs_vm_t *vm, njs_param_t *param) +njs_string_prototype_from_bytes(njs_vm_t *vm, njs_value_t *args, + nxt_uint_t nargs, njs_index_t unused) { u_char *p, *s, *start, *end; size_t size; njs_slice_prop_t slice; njs_string_prop_t string; - njs_string_slice_prop(param, &string, &slice); + njs_string_slice_prop(&string, &slice, args, nargs); if (string.length != 0) { /* ASCII or UTF8 string. */ @@ -679,7 +679,8 @@ njs_string_prototype_from_bytes(njs_vm_t *vm, njs_param_t *param) */ static njs_ret_t -njs_string_prototype_to_bytes(njs_vm_t *vm, njs_param_t *param) +njs_string_prototype_to_bytes(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, + njs_index_t unused) { u_char *p; size_t length; @@ -688,7 +689,7 @@ njs_string_prototype_to_bytes(njs_vm_t *vm, njs_param_t *param) njs_slice_prop_t slice; njs_string_prop_t string; - njs_string_slice_prop(param, &string, &slice); + njs_string_slice_prop(&string, &slice, args, nargs); if (string.length == 0) { /* Byte string. */ @@ -739,12 +740,13 @@ njs_string_prototype_to_bytes(njs_vm_t *vm, njs_param_t *param) */ static nxt_noinline njs_ret_t -njs_string_prototype_slice(njs_vm_t *vm, njs_param_t *param) +njs_string_prototype_slice(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, + njs_index_t unused) { njs_slice_prop_t slice; njs_string_prop_t string; - njs_string_slice_prop(param, &string, &slice); + njs_string_slice_prop(&string, &slice, args, nargs); return njs_string_slice(vm, &vm->retval, &string, &slice); } @@ -756,28 +758,27 @@ njs_string_prototype_slice(njs_vm_t *vm, njs_param_t *param) */ static njs_ret_t -njs_string_prototype_substring(njs_vm_t *vm, njs_param_t *param) +njs_string_prototype_substring(njs_vm_t *vm, njs_value_t *args, + nxt_uint_t nargs, njs_index_t unused) { ssize_t start, end, length; - uintptr_t nargs; njs_slice_prop_t slice; njs_string_prop_t string; - length = njs_string_prop(&string, ¶m->args[0]); + length = njs_string_prop(&string, &args[0]); slice.string_length = length; start = 0; - nargs = param->nargs; if (nargs > 1) { - start = param->args[1].data.u.number; + start = args[1].data.u.number; if (start < 0) { start = 0; } if (nargs > 2) { - end = param->args[2].data.u.number; + end = args[2].data.u.number; if (end < 0) { end = 0; @@ -805,21 +806,20 @@ njs_string_prototype_substring(njs_vm_t *vm, njs_param_t *param) */ static njs_ret_t -njs_string_prototype_substr(njs_vm_t *vm, njs_param_t *param) +njs_string_prototype_substr(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, + njs_index_t unused) { ssize_t start, length; - uintptr_t nargs; njs_slice_prop_t slice; njs_string_prop_t string; - length = njs_string_prop(&string, ¶m->args[0]); + length = njs_string_prop(&string, &args[0]); slice.string_length = length; start = 0; - nargs = param->nargs; if (nargs > 1) { - start = param->args[1].data.u.number; + start = args[1].data.u.number; if (start < 0) { @@ -830,7 +830,7 @@ njs_string_prototype_substr(njs_vm_t *vm, njs_param_t *param) } if (nargs > 2) { - length = param->args[2].data.u.number; + length = args[2].data.u.number; } } @@ -842,19 +842,20 @@ njs_string_prototype_substr(njs_vm_t *vm, njs_param_t *param) static njs_ret_t -njs_string_prototype_char_at(njs_vm_t *vm, njs_param_t *param) +njs_string_prototype_char_at(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, + njs_index_t unused) { ssize_t start, length; njs_slice_prop_t slice; njs_string_prop_t string; - slice.string_length = njs_string_prop(&string, ¶m->args[0]); + slice.string_length = njs_string_prop(&string, &args[0]); start = 0; length = 1; - if (param->nargs > 1) { - start = param->args[1].data.u.number; + if (nargs > 1) { + start = args[1].data.u.number; if (start < 0) { length = 0; @@ -869,27 +870,26 @@ njs_string_prototype_char_at(njs_vm_t *vm, njs_param_t *param) static nxt_noinline void -njs_string_slice_prop(njs_param_t *param, njs_string_prop_t *string, - njs_slice_prop_t *slice) +njs_string_slice_prop(njs_string_prop_t *string, njs_slice_prop_t *slice, + njs_value_t *args, nxt_uint_t nargs) { - slice->string_length = njs_string_prop(string, ¶m->args[0]); + slice->string_length = njs_string_prop(string, &args[0]); - njs_string_slice_params(param, slice); + njs_string_slice_args(slice, args, nargs); } static nxt_noinline void -njs_string_slice_params(njs_param_t *param, njs_slice_prop_t *slice) +njs_string_slice_args(njs_slice_prop_t *slice, njs_value_t *args, + nxt_uint_t nargs) { ssize_t start, end, length; - uintptr_t nargs; length = slice->string_length; start = 0; - nargs = param->nargs; if (nargs > 1) { - start = param->args[1].data.u.number; + start = args[1].data.u.number; if (start < 0) { start += length; @@ -902,7 +902,7 @@ njs_string_slice_params(njs_param_t *param, njs_slice_prop_t *slice) end = length; if (nargs > 2) { - end = param->args[2].data.u.number; + end = args[2].data.u.number; if (end < 0) { end += length; @@ -994,7 +994,8 @@ njs_string_slice(njs_vm_t *vm, njs_value_t *dst, static njs_ret_t -njs_string_prototype_char_code_at(njs_vm_t *vm, njs_param_t *param) +njs_string_prototype_char_code_at(njs_vm_t *vm, njs_value_t *args, + nxt_uint_t nargs, njs_index_t unused) { double num; ssize_t index, length; @@ -1002,12 +1003,12 @@ njs_string_prototype_char_code_at(njs_vm_t *vm, njs_param_t *param) const u_char *start, *end; njs_string_prop_t string; - length = njs_string_prop(&string, ¶m->args[0]); + length = njs_string_prop(&string, &args[0]); index = 0; - if (param->nargs > 1) { - index = param->args[1].data.u.number; + if (nargs > 1) { + index = args[1].data.u.number; if (nxt_slow_path(index < 0 || index >= length)) { num = NJS_NAN; @@ -1037,15 +1038,12 @@ done: static njs_ret_t -njs_string_prototype_index_of(njs_vm_t *vm, njs_param_t *param) +njs_string_prototype_index_of(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, + njs_index_t unused) { - ssize_t start, index; - uintptr_t nargs; - njs_value_t *args; + ssize_t start, index; index = -1; - args = param->args; - nargs = param->nargs; if (nargs > 1) { start = 0; @@ -1068,15 +1066,12 @@ njs_string_prototype_index_of(njs_vm_t *vm, njs_param_t *param) static njs_ret_t -njs_string_prototype_last_index_of(njs_vm_t *vm, njs_param_t *param) +njs_string_prototype_last_index_of(njs_vm_t *vm, njs_value_t *args, + nxt_uint_t nargs, njs_index_t unused) { - ssize_t ret, index, last; - uintptr_t nargs; - njs_value_t *args; + ssize_t ret, index, last; index = -1; - args = param->args; - nargs = param->nargs; if (nargs > 1) { last = NJS_STRING_MAX_LENGTH; @@ -1221,7 +1216,8 @@ njs_string_index(njs_string_prop_t *string, uint32_t offset) static njs_ret_t -njs_string_prototype_search(njs_vm_t *vm, njs_param_t *param) +njs_string_prototype_search(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, + njs_index_t unused) { int ret; nxt_int_t index; @@ -1232,15 +1228,15 @@ njs_string_prototype_search(njs_vm_t *vm, njs_param_t *param) index = 0; - if (param->nargs > 1) { + if (nargs > 1) { - switch (param->args[1].type) { + switch (args[1].type) { case NJS_VOID: goto done; case NJS_STRING: - (void) njs_string_prop(&string, ¶m->args[1]); + (void) njs_string_prop(&string, &args[1]); if (string.size == 0) { goto done; @@ -1255,12 +1251,12 @@ njs_string_prototype_search(njs_vm_t *vm, njs_param_t *param) break; default: /* NJS_REGEXP */ - pattern = param->args[1].data.u.regexp->pattern; + pattern = args[1].data.u.regexp->pattern; } index = -1; - (void) njs_string_prop(&string, ¶m->args[0]); + (void) njs_string_prop(&string, &args[0]); n = (string.length != 0 && string.length != string.size); @@ -1292,24 +1288,23 @@ done: */ static njs_ret_t -njs_string_prototype_match(njs_vm_t *vm, njs_param_t *param) +njs_string_prototype_match(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, + njs_index_t unused) { u_char *start; int32_t size, length; njs_ret_t ret; nxt_uint_t n, utf8; - njs_value_t *args, tmp; + njs_value_t tmp; njs_array_t *array; njs_string_prop_t string; njs_regexp_pattern_t *pattern; int captures[3]; - if (param->nargs == 1) { + if (nargs == 1) { goto empty; } - args = param->args; - switch (args[1].type) { case NJS_VOID: @@ -1341,13 +1336,13 @@ njs_string_prototype_match(njs_vm_t *vm, njs_param_t *param) args[0] = args[1]; args[1] = tmp; - return njs_regexp_prototype_exec(vm, param); + return njs_regexp_prototype_exec(vm, args, nargs, unused); } } vm->retval = njs_value_null; - (void) njs_string_prop(&string, ¶m->args[0]); + (void) njs_string_prop(&string, &args[0]); utf8 = 0; n = 0; diff --git a/njs/njs_string.h b/njs/njs_string.h index 69ce39df..fb242cf2 100644 --- a/njs/njs_string.h +++ b/njs/njs_string.h @@ -88,7 +88,8 @@ njs_ret_t njs_string_validate(njs_vm_t *vm, njs_string_prop_t *string, njs_value_t *value); nxt_noinline size_t njs_string_prop(njs_string_prop_t *string, njs_value_t *value); -njs_ret_t njs_string_constructor(njs_vm_t *vm, njs_param_t *param); +njs_ret_t njs_string_constructor(njs_vm_t *vm, njs_value_t *args, + nxt_uint_t nargs, njs_index_t unused); void njs_string_offset_map_init(const u_char *start, size_t size); nxt_bool_t njs_string_eq(const njs_value_t *val1, const njs_value_t *val2); nxt_int_t njs_string_cmp(const njs_value_t *val1, const njs_value_t *val2); diff --git a/njs/njs_vm.c b/njs/njs_vm.c index 9618219a..d9ff811a 100644 --- a/njs/njs_vm.c +++ b/njs/njs_vm.c @@ -2228,12 +2228,12 @@ njs_ret_t njs_vmcode_function_call(njs_vm_t *vm, njs_value_t *invld, njs_value_t *retval) { njs_ret_t ret; + nxt_uint_t nargs; njs_value_t *args; - njs_param_t param; - njs_native_t native; njs_function_t *function; njs_native_frame_t *frame, *previous, *skip; njs_continuation_t *continuation; + njs_function_native_t native; njs_vmcode_function_call_t *call; function = vm->frame->function; @@ -2245,32 +2245,28 @@ njs_vmcode_function_call(njs_vm_t *vm, njs_value_t *invld, njs_value_t *retval) } call = (njs_vmcode_function_call_t *) vm->current; - args = vm->scopes[NJS_SCOPE_CALLEE_ARGUMENTS]; + args = vm->scopes[NJS_SCOPE_CALLEE_ARGUMENTS] - function->args_offset; continuation = vm->frame->continuation; if (continuation == NULL) { - ret = njs_normalize_args(vm, args - 1, function->args_types, - call->code.nargs); + nargs = call->code.nargs; + + ret = njs_normalize_args(vm, args, function->args_types, nargs); if (ret != NJS_OK) { return ret; } - param.args = args - 1; - param.nargs = call->code.nargs; - param.retval = (njs_index_t) retval; - native = function->u.native; } else { - param.args = continuation->args; - param.retval = (njs_index_t) retval; - param.nargs = continuation->nargs; - + args = continuation->args; + nargs = continuation->nargs; native = continuation->function; } - ret = native(vm, ¶m); + ret = native(vm, args, nargs, (njs_index_t) retval); + /* * A native method can return: * NXT_OK on method success; @@ -2914,8 +2910,8 @@ static nxt_noinline njs_ret_t njs_primitive_value(njs_vm_t *vm, njs_value_t *value, nxt_uint_t hint) { njs_ret_t ret; - njs_param_t param; njs_value_t *retval; + njs_function_t *function; njs_object_prop_t *prop; nxt_lvlhsh_query_t lhq; njs_continuation_t *continuation; @@ -2933,12 +2929,9 @@ njs_primitive_value(njs_vm_t *vm, njs_value_t *value, nxt_uint_t hint) continuation = vm->frame->continuation; if (continuation != NULL) { - param.args = continuation->args; - param.nargs = continuation->nargs; - param.retval = (njs_index_t) &vm->frame->trap_scratch; - - ret = continuation->function(vm, ¶m); - + ret = continuation->function(vm, continuation->args, + continuation->nargs, + (njs_index_t) &vm->frame->trap_scratch); if (ret != NXT_OK) { return ret; } @@ -2976,13 +2969,10 @@ njs_primitive_value(njs_vm_t *vm, njs_value_t *value, nxt_uint_t hint) continue; } - param.retval = (njs_index_t) retval; - param.args = value; - param.nargs = 0; + function = prop->value.data.u.function; - ret = njs_function_apply(vm, - prop->value.data.u.function, - value, ¶m); + ret = njs_function_apply(vm, function, value, 1, + (njs_index_t) retval); /* * njs_function_apply() can return * NXT_OK, NJS_APPLIED, NXT_ERROR, NXT_AGAIN. diff --git a/njs/njs_vm.h b/njs/njs_vm.h index 0910488a..10b6c9eb 100644 --- a/njs/njs_vm.h +++ b/njs/njs_vm.h @@ -99,7 +99,8 @@ typedef enum { typedef struct njs_parser_s njs_parser_t; typedef njs_ret_t (*njs_getter_t) (njs_vm_t *vm, njs_value_t *obj); -typedef njs_ret_t (*njs_native_t) (njs_vm_t *vm, njs_param_t *param); +typedef njs_ret_t (*njs_function_native_t) (njs_vm_t *vm, njs_value_t *args, + nxt_uint_t nargs, njs_index_t retval); typedef struct njs_string_s njs_string_t; @@ -147,7 +148,7 @@ typedef struct { union { njs_function_lambda_t *lambda; - njs_native_t native; + njs_function_native_t native; } u; njs_value_t *args; diff --git a/njs/njscript.h b/njs/njscript.h index ce6f3fff..6486a4c7 100644 --- a/njs/njscript.h +++ b/njs/njscript.h @@ -14,12 +14,6 @@ typedef struct njs_vm_s njs_vm_t; typedef union njs_value_s njs_value_t; typedef struct njs_vm_shared_s njs_vm_shared_t; -typedef struct { - njs_value_t *args; - uintptr_t nargs; - njs_index_t retval; -} njs_param_t; - /* sizeof(njs_value_t) is 16 bytes. */ #define njs_argument(args, n) \ @@ -35,7 +29,8 @@ typedef njs_ret_t (*njs_extern_find_t)(njs_vm_t *vm, void *obj, uintptr_t data, typedef njs_ret_t (*njs_extern_foreach_t)(njs_vm_t *vm, void *obj, void *next); typedef njs_ret_t (*njs_extern_next_t)(njs_vm_t *vm, njs_value_t *value, void *obj, void *next); -typedef njs_ret_t (*njs_extern_method_t)(njs_vm_t *vm, njs_param_t *param); +typedef njs_ret_t (*njs_extern_method_t)(njs_vm_t *vm, njs_value_t *args, + nxt_uint_t nargs, njs_index_t unused); typedef struct njs_external_s njs_external_t; diff --git a/njs/test/njs_unit_test.c b/njs/test/njs_unit_test.c index 288fe576..baab9466 100644 --- a/njs/test/njs_unit_test.c +++ b/njs/test/njs_unit_test.c @@ -2161,6 +2161,17 @@ static njs_unit_test_t njs_test[] = "a.forEach(function(v, i, a) { a[i+3] = a.length }); a"), nxt_string("1,2,3,3,4,5") }, + { nxt_string("var a = [1,2,3]; var s = { sum: 0 };" + "[].forEach.call(a, function(v, i, a) { this.sum += v }, s);" + "s.sum"), + nxt_string("6") }, + + { nxt_string("var a = [1,2,3]; var s = { sum: 0 };" + "[].forEach.apply(a," + "[ function(v, i, a) { this.sum += v }, s ]);" + "s.sum"), + nxt_string("6") }, + { nxt_string("var a = [];" "a.some(function(v, i, a) { return v > 1 })"), nxt_string("false") }, @@ -3888,7 +3899,8 @@ njs_unit_test_header_next_external(njs_vm_t *vm, njs_value_t *value, void *obj, static njs_ret_t -njs_unit_test_method_external(njs_vm_t *vm, njs_param_t *param) +njs_unit_test_method_external(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, + njs_index_t unused) { nxt_int_t ret; nxt_str_t s; @@ -3897,13 +3909,12 @@ njs_unit_test_method_external(njs_vm_t *vm, njs_param_t *param) next = 0; - if (param->nargs > 1) { + if (nargs > 1) { - ret = njs_value_string_copy(vm, &s, njs_argument(param->args, 1), - &next); + ret = njs_value_string_copy(vm, &s, njs_argument(args, 1), &next); if (ret == NXT_OK && s.len == 3 && memcmp(s.data, "YES", 3) == 0) { - r = njs_value_data(njs_argument(param->args, 0)); + r = njs_value_data(njs_argument(args, 0)); njs_vm_return_string(vm, r->uri.data, r->uri.len); return NXT_OK; -- 2.47.3