[njs] A function stored in array could not be called.
Igor Sysoev
igor at sysoev.ru
Mon Sep 26 15:42:56 UTC 2016
details: http://hg.nginx.org/njs/rev/cfa17c3e25da
branches:
changeset: 184:cfa17c3e25da
user: Igor Sysoev <igor at sysoev.ru>
date: Mon Sep 26 18:41:57 2016 +0300
description:
A function stored in array could not be called.
diffstat:
njs/njs_vm.c | 116 ++++++++++++++++++++++++++--------------------
njs/test/njs_unit_test.c | 3 +
2 files changed, 68 insertions(+), 51 deletions(-)
diffs (167 lines):
diff -r fec0d8dfa38c -r cfa17c3e25da njs/njs_vm.c
--- a/njs/njs_vm.c Mon Sep 26 14:01:45 2016 +0300
+++ b/njs/njs_vm.c Mon Sep 26 18:41:57 2016 +0300
@@ -83,6 +83,8 @@ static nxt_noinline njs_ret_t njs_values
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,13 +2247,35 @@ njs_vmcode_method_frame(njs_vm_t *vm, nj
prop = pq.lhq.value;
if (njs_is_function(&prop->value)) {
-
+ return njs_vmcode_method_call(vm, object, &prop->value);
+ }
+
+ break;
+
+ case NJS_ARRAY_VALUE:
+ value = pq.lhq.value;
+
+ if (njs_is_function(value)) {
+ return njs_vmcode_method_call(vm, object, value);
+ }
+
+ break;
+
+ case NJS_EXTERNAL_VALUE:
+ ext = object->data.u.external;
+
+ ret = nxt_lvlhsh_find(&ext->hash, &pq.lhq);
+
+ if (ret == NXT_OK) {
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);
+ ext = pq.lhq.value;
+
+ if (ext->type == NJS_EXTERN_METHOD) {
+ this.data.u.data = vm->external[ext->object];
+
+ ret = njs_function_native_frame(vm, ext->function, &this, NULL,
+ method->nargs, 0,
+ method->code.ctor);
if (nxt_fast_path(ret == NXT_OK)) {
return sizeof(njs_vmcode_method_frame_t);
@@ -2260,54 +2283,45 @@ njs_vmcode_method_frame(njs_vm_t *vm, nj
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;
}
-
- break;
-
- case NJS_EXTERNAL_VALUE:
- ext = object->data.u.external;
-
- ret = nxt_lvlhsh_find(&ext->hash, &pq.lhq);
-
- if (ret == NXT_OK) {
- method = (njs_vmcode_method_frame_t *) vm->current;
- ext = pq.lhq.value;
-
- if (ext->type == NJS_EXTERN_METHOD) {
- this.data.u.data = vm->external[ext->object];
-
- ret = njs_function_native_frame(vm, ext->function, &this, NULL,
- method->nargs, 0,
- method->code.ctor);
-
- if (nxt_fast_path(ret == NXT_OK)) {
- return sizeof(njs_vmcode_method_frame_t);
- }
-
- return ret;
- }
+ }
+
+ vm->exception = &njs_exception_type_error;
+
+ return NXT_ERROR;
+}
+
+
+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);
}
- break;
-
- default:
- break;
+ return ret;
}
- vm->exception = &njs_exception_type_error;
-
- return NXT_ERROR;
+ 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;
}
diff -r fec0d8dfa38c -r cfa17c3e25da njs/test/njs_unit_test.c
--- a/njs/test/njs_unit_test.c Mon Sep 26 14:01:45 2016 +0300
+++ b/njs/test/njs_unit_test.c Mon Sep 26 18:41:57 2016 +0300
@@ -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';"
More information about the nginx-devel
mailing list