From: Igor Sysoev Date: Mon, 26 Sep 2016 15:41:57 +0000 (+0300) Subject: A function stored in array could not be called. X-Git-Tag: 0.1.3~7 X-Git-Url: http://www.kaiwu.me/postgresql/commit/?a=commitdiff_plain;h=a9608f085d4ed79531c5e6b720697e37622b3248;p=njs.git A function stored in array could not be called. --- diff --git a/njs/njs_vm.c b/njs/njs_vm.c index 0d4f881b..f701afc7 100644 --- a/njs/njs_vm.c +++ b/njs/njs_vm.c @@ -83,6 +83,8 @@ static nxt_noinline njs_ret_t njs_values_equal(njs_value_t *val1, static nxt_noinline njs_ret_t njs_values_compare(njs_value_t *val1, njs_value_t *val2); static njs_object_t *njs_function_new_object(njs_vm_t *vm, njs_value_t *value); +static njs_ret_t njs_vmcode_method_call(njs_vm_t *vm, njs_value_t *object, + njs_value_t *value); static njs_ret_t njs_vmcode_continuation(njs_vm_t *vm, njs_value_t *invld1, njs_value_t *invld2); static njs_native_frame_t * @@ -2231,9 +2233,8 @@ njs_ret_t njs_vmcode_method_frame(njs_vm_t *vm, njs_value_t *object, njs_value_t *name) { njs_ret_t ret; - njs_value_t this; + njs_value_t this, *value; njs_extern_t *ext; - njs_function_t *function; njs_object_prop_t *prop; njs_property_query_t pq; njs_vmcode_method_frame_t *method; @@ -2246,31 +2247,16 @@ njs_vmcode_method_frame(njs_vm_t *vm, njs_value_t *object, njs_value_t *name) prop = pq.lhq.value; if (njs_is_function(&prop->value)) { + return njs_vmcode_method_call(vm, object, &prop->value); + } - method = (njs_vmcode_method_frame_t *) vm->current; - function = prop->value.data.u.function; - - if (!function->native) { - ret = njs_function_frame(vm, function, object, NULL, - method->nargs, method->code.ctor); - - if (nxt_fast_path(ret == NXT_OK)) { - return sizeof(njs_vmcode_method_frame_t); - } - - return ret; - } - - ret = njs_function_native_frame(vm, function, object, NULL, - method->nargs, 0, - method->code.ctor); + break; - if (nxt_fast_path(ret == NXT_OK)) { - njs_retain(object); - return sizeof(njs_vmcode_method_frame_t); - } + case NJS_ARRAY_VALUE: + value = pq.lhq.value; - return ret; + if (njs_is_function(value)) { + return njs_vmcode_method_call(vm, object, value); } break; @@ -2298,11 +2284,6 @@ njs_vmcode_method_frame(njs_vm_t *vm, njs_value_t *object, njs_value_t *name) return ret; } } - - break; - - default: - break; } vm->exception = &njs_exception_type_error; @@ -2311,6 +2292,39 @@ njs_vmcode_method_frame(njs_vm_t *vm, njs_value_t *object, njs_value_t *name) } +static njs_ret_t +njs_vmcode_method_call(njs_vm_t *vm, njs_value_t *object, njs_value_t *value) +{ + njs_ret_t ret; + njs_function_t *function; + njs_vmcode_method_frame_t *method; + + method = (njs_vmcode_method_frame_t *) vm->current; + function = value->data.u.function; + + if (!function->native) { + ret = njs_function_frame(vm, function, object, NULL, method->nargs, + method->code.ctor); + + if (nxt_fast_path(ret == NXT_OK)) { + return sizeof(njs_vmcode_method_frame_t); + } + + return ret; + } + + ret = njs_function_native_frame(vm, function, object, NULL, method->nargs, + 0, method->code.ctor); + + if (nxt_fast_path(ret == NXT_OK)) { + njs_retain(object); + return sizeof(njs_vmcode_method_frame_t); + } + + return ret; +} + + njs_ret_t njs_vmcode_function_call(njs_vm_t *vm, njs_value_t *invld, njs_value_t *retval) { diff --git a/njs/test/njs_unit_test.c b/njs/test/njs_unit_test.c index 725c3f69..af0dfcb8 100644 --- a/njs/test/njs_unit_test.c +++ b/njs/test/njs_unit_test.c @@ -2092,6 +2092,9 @@ static njs_unit_test_t njs_test[] = { nxt_string("a = [1, 2]; delete a[0]; 0 in a"), nxt_string("false") }, + { nxt_string("var a = [ function(a) {return a + 1} ]; a[0](5)"), + nxt_string("6") }, + { nxt_string("var s = '', a = [5,1,2];" "a[null] = null;" "a[undefined] = 'defined';"