changeset 184:cfa17c3e25da

A function stored in array could not be called.
author Igor Sysoev <igor@sysoev.ru>
date Mon, 26 Sep 2016 18:41:57 +0300
parents fec0d8dfa38c
children 322359ec0913
files njs/njs_vm.c njs/test/njs_unit_test.c
diffstat 2 files changed, 49 insertions(+), 32 deletions(-) [+]
line wrap: on
line diff
--- 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_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_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 @@
         prop = pq.lhq.value;
 
         if (njs_is_function(&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);
-
-            if (nxt_fast_path(ret == NXT_OK)) {
-                njs_retain(object);
-                return sizeof(njs_vmcode_method_frame_t);
-            }
-
-            return ret;
+            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;
@@ -2298,11 +2284,6 @@
                 return ret;
             }
         }
-
-        break;
-
-    default:
-        break;
     }
 
     vm->exception = &njs_exception_type_error;
@@ -2311,6 +2292,39 @@
 }
 
 
+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)
 {
--- 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 @@
     { 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';"