[njs] Added getter support for method frame calls.

Dmitry Volyntsev xeioex at nginx.com
Mon Aug 5 12:53:05 UTC 2019


details:   https://hg.nginx.org/njs/rev/04d7a5d93ae6
branches:  
changeset: 1101:04d7a5d93ae6
user:      hongzhidao <hongzhidao at gmail.com>
date:      Sun Aug 04 04:13:02 2019 -0400
description:
Added getter support for method frame calls.

diffstat:

 src/njs_vmcode.c                |  113 +++++++++------------------------------
 src/test/njs_interactive_test.c |    4 +
 src/test/njs_unit_test.c        |    5 +
 3 files changed, 36 insertions(+), 86 deletions(-)

diffs (184 lines):

diff -r 08505f72a3e4 -r 04d7a5d93ae6 src/njs_vmcode.c
--- a/src/njs_vmcode.c	Sun Aug 04 04:06:30 2019 -0400
+++ b/src/njs_vmcode.c	Sun Aug 04 04:13:02 2019 -0400
@@ -38,8 +38,6 @@ static njs_jump_off_t njs_vmcode_instanc
 static njs_jump_off_t njs_vmcode_typeof(njs_vm_t *vm, njs_value_t *value,
     njs_value_t *invld);
 
-static njs_jump_off_t njs_vmcode_method_frame(njs_vm_t *vm, njs_value_t *object,
-    njs_value_t *method, u_char *pc);
 static njs_jump_off_t njs_vmcode_return(njs_vm_t *vm, njs_value_t *invld,
     njs_value_t *retval);
 
@@ -85,6 +83,7 @@ njs_vmcode_interpreter(njs_vm_t *vm, u_c
     double                       num, exponent;
     int32_t                      i32;
     uint32_t                     u32;
+    njs_str_t                    string;
     njs_uint_t                   hint;
     njs_bool_t                   valid, lambda_call;
     njs_value_t                  *retval, *value1, *value2, *src, *s1, *s2;
@@ -103,6 +102,7 @@ njs_vmcode_interpreter(njs_vm_t *vm, u_c
     njs_vmcode_test_jump_t       *test_jump;
     njs_vmcode_equal_jump_t      *equal;
     njs_vmcode_try_return_t      *try_return;
+    njs_vmcode_method_frame_t    *method_frame;
     njs_vmcode_function_frame_t  *function_frame;
 
 next:
@@ -683,11 +683,35 @@ next:
                 break;
 
             case NJS_VMCODE_METHOD_FRAME:
-                ret = njs_vmcode_method_frame(vm, value1, value2, pc);
+                method_frame = (njs_vmcode_method_frame_t *) pc;
+
+                ret = njs_value_property(vm, value1, value2, &dst);
                 if (njs_slow_path(ret == NJS_ERROR)) {
                     goto error;
                 }
 
+                if (njs_slow_path(!njs_is_function(&dst))) {
+                    ret = njs_value_to_string(vm, value2, value2);
+                    if (njs_slow_path(ret != NJS_OK)) {
+                        return NJS_ERROR;
+                    }
+
+                    njs_string_get(value2, &string);
+                    njs_type_error(vm,
+                               "(intermediate value)[\"%V\"] is not a function",
+                               &string);
+                    goto error;
+                }
+
+                ret = njs_function_frame_create(vm, &dst, value1,
+                                                method_frame->nargs,
+                                                method_frame->ctor);
+
+                if (njs_slow_path(ret != NJS_OK)) {
+                    goto error;
+                }
+
+                ret = sizeof(njs_vmcode_method_frame_t);
                 break;
 
             case NJS_VMCODE_FUNCTION_CALL:
@@ -1723,89 +1747,6 @@ njs_function_new_object(njs_vm_t *vm, nj
 
 
 static njs_jump_off_t
-njs_vmcode_method_frame(njs_vm_t *vm, njs_value_t *object, njs_value_t *name,
-    u_char *pc)
-{
-    njs_str_t                  string;
-    njs_value_t                *value;
-    njs_jump_off_t             ret;
-    njs_object_prop_t          *prop;
-    njs_property_query_t       pq;
-    njs_vmcode_method_frame_t  *method;
-
-    value = NULL;
-    method = (njs_vmcode_method_frame_t *) pc;
-
-    njs_property_query_init(&pq, NJS_PROPERTY_QUERY_GET, 0);
-
-    ret = njs_property_query(vm, &pq, object, name);
-
-    switch (ret) {
-
-    case NJS_OK:
-        prop = pq.lhq.value;
-
-        switch (prop->type) {
-        case NJS_PROPERTY:
-        case NJS_METHOD:
-            break;
-
-        case NJS_PROPERTY_HANDLER:
-            pq.scratch = *prop;
-            prop = &pq.scratch;
-            ret = prop->value.data.u.prop_handler(vm, object, NULL,
-                                                  &prop->value);
-            if (njs_slow_path(ret != NJS_OK)) {
-                return ret;
-            }
-
-            break;
-
-        default:
-            njs_internal_error(vm, "unexpected property type \"%s\" "
-                               "while getting method",
-                               njs_prop_type_string(prop->type));
-
-            return NJS_ERROR;
-        }
-
-        value = &prop->value;
-
-        break;
-
-    case NJS_DECLINED:
-        break;
-
-    case NJS_ERROR:
-    default:
-
-        return ret;
-    }
-
-    if (value == NULL || !njs_is_function(value)) {
-        ret = njs_value_to_string(vm, name, name);
-        if (njs_slow_path(ret != NJS_OK)) {
-            return NJS_ERROR;
-        }
-
-        njs_string_get(name, &string);
-        njs_type_error(vm, "(intermediate value)[\"%V\"] is not a function",
-                       &string);
-        return NJS_ERROR;
-    }
-
-    ret = njs_function_frame_create(vm, value, object, method->nargs,
-                                    method->ctor);
-
-    if (njs_fast_path(ret == NJS_OK)) {
-        return sizeof(njs_vmcode_method_frame_t);
-    }
-
-    return ret;
-}
-
-
-static njs_jump_off_t
 njs_vmcode_return(njs_vm_t *vm, njs_value_t *invld, njs_value_t *retval)
 {
     njs_value_t         *value;
diff -r 08505f72a3e4 -r 04d7a5d93ae6 src/test/njs_interactive_test.c
--- a/src/test/njs_interactive_test.c	Sun Aug 04 04:06:30 2019 -0400
+++ b/src/test/njs_interactive_test.c	Sun Aug 04 04:13:02 2019 -0400
@@ -165,6 +165,10 @@ static njs_interactive_test_t  njs_test[
                  "    at Math.max (native)\n"
                  "    at main (native)\n") },
 
+    { njs_str("Object.prototype()" ENTER),
+      njs_str("TypeError: (intermediate value)[\"prototype\"] is not a function\n"
+                 "    at main (native)\n") },
+
     { njs_str("eval()" ENTER),
       njs_str("InternalError: Not implemented\n"
                  "    at eval (native)\n"
diff -r 08505f72a3e4 -r 04d7a5d93ae6 src/test/njs_unit_test.c
--- a/src/test/njs_unit_test.c	Sun Aug 04 04:06:30 2019 -0400
+++ b/src/test/njs_unit_test.c	Sun Aug 04 04:13:02 2019 -0400
@@ -8559,6 +8559,11 @@ static njs_unit_test_t  njs_test[] =
                  "[] instanceof Function.prototype"),
       njs_str("Error: Oops") },
 
+     { njs_str("var o = {};"
+                 "Object.defineProperty(o, 'foo', { get: function() {return () => 1} });"
+                 "o.foo()"),
+      njs_str("1") },
+
     /* global this. */
 
     { njs_str("this"),


More information about the nginx-devel mailing list