]> git.kaiwu.me - njs.git/commitdiff
Fixed getter/setter proto.
authorDmitry Volyntsev <xeioex@nginx.com>
Thu, 31 Oct 2019 16:53:21 +0000 (19:53 +0300)
committerDmitry Volyntsev <xeioex@nginx.com>
Thu, 31 Oct 2019 16:53:21 +0000 (19:53 +0300)
This closes #238 issue on Github.

src/njs_function.c
src/njs_object_prop.c
src/test/njs_unit_test.c

index d43bfb282d9ee7415dc30393a99a44475ac7da53..e72d8cdb1cd553bd93c2dd17a3b91eb932a1394a 100644 (file)
@@ -90,6 +90,13 @@ njs_function_value_copy(njs_vm_t *vm, njs_value_t *value)
         return NULL;
     }
 
+    if (copy->ctor) {
+        copy->object.shared_hash = vm->shared->function_instance_hash;
+
+    } else {
+        copy->object.shared_hash = vm->shared->arrow_instance_hash;
+    }
+
     value->data.u.function = copy;
 
     return copy;
index 546b902393339da3927f6cc96c3a7d7e9925d506..87bbbbd5cbd09d406f6151785c1673b6693886bc 100644 (file)
@@ -381,8 +381,6 @@ njs_prop_private_copy(njs_vm_t *vm, njs_property_query_t *pq)
     njs_object_prop_t   *prop, *shared, *name;
     njs_lvlhsh_query_t  lhq;
 
-    static const njs_value_t  name_string = njs_string("name");
-
     prop = njs_mp_align(vm->mem_pool, sizeof(njs_value_t),
                         sizeof(njs_object_prop_t));
     if (njs_slow_path(prop == NULL)) {
@@ -403,6 +401,32 @@ njs_prop_private_copy(njs_vm_t *vm, njs_property_query_t *pq)
         return NJS_ERROR;
     }
 
+    if (njs_is_accessor_descriptor(prop)) {
+        if (njs_is_function(&prop->getter)) {
+            function = njs_function_value_copy(vm, &prop->getter);
+            if (njs_slow_path(function == NULL)) {
+                return NJS_ERROR;
+            }
+
+            if (njs_is_function(&prop->setter)
+                && function->native && njs_function(&prop->setter)->native
+                && function->u.native == njs_function(&prop->setter)->u.native)
+            {
+                prop->setter = prop->getter;
+                return NJS_OK;
+            }
+        }
+
+        if (njs_is_function(&prop->setter)) {
+            function = njs_function_value_copy(vm, &prop->setter);
+            if (njs_slow_path(function == NULL)) {
+                return NJS_ERROR;
+            }
+        }
+
+        return NJS_OK;
+    }
+
     if (!njs_is_function(&prop->value)) {
         return NJS_OK;
     }
@@ -412,14 +436,7 @@ njs_prop_private_copy(njs_vm_t *vm, njs_property_query_t *pq)
         return NJS_ERROR;
     }
 
-    if (function->ctor) {
-        function->object.shared_hash = vm->shared->function_instance_hash;
-
-    } else {
-        function->object.shared_hash = vm->shared->arrow_instance_hash;
-    }
-
-    name = njs_object_prop_alloc(vm, &name_string, &prop->name, 0);
+    name = njs_object_prop_alloc(vm, &njs_string_name, &prop->name, 0);
     if (njs_slow_path(name == NULL)) {
         return NJS_ERROR;
     }
index ad5133ef0137584db364acedaca78ae9d5064215..65c3b19e8275e2ca56edbd6d8218b299607fe95a 100644 (file)
@@ -8111,6 +8111,14 @@ static njs_unit_test_t  njs_test[] =
     { njs_str("(function() {}).arguments"),
       njs_str("TypeError: \"caller\", \"callee\", \"arguments\" properties may not be accessed") },
 
+    { njs_str("var desc = Object.getOwnPropertyDescriptor(Object.getPrototypeOf(Math.min), 'caller');"
+              "desc.get === desc.set"),
+      njs_str("true") },
+
+    { njs_str("var desc = Object.getOwnPropertyDescriptor(Object.getPrototypeOf(Math.min), 'caller');"
+              "1/desc.get"),
+      njs_str("NaN") },
+
     { njs_str("var p = Object.getPrototypeOf(function() {});"
               "var d = Object.getOwnPropertyDescriptor(p, 'caller');"
               "typeof d.get == 'function' && typeof d.get == typeof d.set"