]> git.kaiwu.me - njs.git/commitdiff
Fixed special getters for objects created using Object.create().
authorDmitry Volyntsev <xeioex@nginx.com>
Thu, 25 Apr 2019 12:19:37 +0000 (15:19 +0300)
committerDmitry Volyntsev <xeioex@nginx.com>
Thu, 25 Apr 2019 12:19:37 +0000 (15:19 +0300)
This closes #124 issue on Github.

njs/njs_array.c
njs/njs_function.c
njs/njs_object.c
njs/njs_string.c
njs/test/njs_unit_test.c

index f421f6e13721d08ad1cdf96d13adb20d69bcf728..934f6256cc1688b7a841365fbf1d5590d2862e4d 100644 (file)
@@ -420,8 +420,19 @@ njs_array_length(njs_vm_t *vm, njs_value_t *value, njs_value_t *setval,
     njs_ret_t    ret;
     njs_value_t  *val;
     njs_array_t  *array;
+    njs_object_t *proto;
 
-    array = value->data.u.array;
+    proto = value->data.u.object;
+
+    do {
+        if (nxt_fast_path(proto->type == NJS_ARRAY)) {
+            break;
+        }
+
+        proto = proto->__proto__;
+    } while (proto != NULL);
+
+    array = (njs_array_t *) proto;
 
     if (setval != NULL) {
         if (!njs_is_number(setval)) {
index cb3f4018a452e7f8b5aa39bccb33892b9f17e39b..6d36f9ff19b695a77ebaafaf25ceb85d615e49c6 100644 (file)
@@ -894,10 +894,21 @@ njs_function_instance_length(njs_vm_t *vm, njs_value_t *value,
     njs_value_t *setval, njs_value_t *retval)
 {
     nxt_uint_t             n;
+    njs_object_t           *proto;
     njs_function_t         *function;
     njs_function_lambda_t  *lambda;
 
-    function = value->data.u.function;
+    proto = value->data.u.object;
+
+    do {
+        if (nxt_fast_path(proto->type == NJS_FUNCTION)) {
+            break;
+        }
+
+        proto = proto->__proto__;
+    } while (proto != NULL);
+
+    function = (njs_function_t *) proto;
 
     if (function->native) {
         for (n = function->args_offset; n < NJS_ARGS_TYPES_MAX; n++) {
index 8526dda3a5e1b8d9af6174b8fd4ab84ff8dbad69..3018d71feab6f423d8f62caa93b89506cc5ccfdb 100644 (file)
@@ -283,7 +283,6 @@ njs_object_property(njs_vm_t *vm, const njs_object_t *object,
  *   NXT_ERROR            exception has been thrown.
  *
  *   TODO:
- *     Object.create([1,2]).length
  *     Object.defineProperty([1,2], '1', {configurable:false})
  */
 
index 1a483c251b120b963d74e1905595379d4cc93b3f..982399daebdc0a322d8d9507805b5a8d5429b857 100644 (file)
@@ -626,8 +626,10 @@ static njs_ret_t
 njs_string_instance_length(njs_vm_t *vm, njs_value_t *value,
     njs_value_t *setval, njs_value_t *retval)
 {
-    size_t     size;
-    uintptr_t  length;
+    size_t              size;
+    uintptr_t           length;
+    njs_object_t        *proto;
+    njs_object_value_t  *ov;
 
     /*
      * This getter can be called for string primitive, String object,
@@ -635,8 +637,21 @@ njs_string_instance_length(njs_vm_t *vm, njs_value_t *value,
      */
     length = 0;
 
-    if (value->type == NJS_OBJECT_STRING) {
-        value = &value->data.u.object_value->value;
+    if (nxt_slow_path(njs_is_object(value))) {
+        proto = value->data.u.object;
+
+        do {
+            if (nxt_fast_path(proto->type == NJS_OBJECT_STRING)) {
+                break;
+            }
+
+            proto = proto->__proto__;
+        } while (proto != NULL);
+
+        if (proto != NULL) {
+            ov = (njs_object_value_t *) proto;
+            value = &ov->value;
+        }
     }
 
     if (njs_is_string(value)) {
index 7bd183dd50105391fbf8b96079a47f45c2a939d0..6f4c90a46c47cdf3dd68d3195635a90851c90bc3 100644 (file)
@@ -9110,6 +9110,18 @@ static njs_unit_test_t  njs_test[] =
                  "1..isPrototypeOf(p)"),
       nxt_string("false") },
 
+    { nxt_string("Object.create(new String('asdf')).length"),
+      nxt_string("4") },
+
+    { nxt_string("Object.create(Object('123')).length"),
+      nxt_string("3") },
+
+    { nxt_string("Object.create([1,2]).length"),
+      nxt_string("2") },
+
+    { nxt_string("Object.create(function(a,b,c){}).length"),
+      nxt_string("3") },
+
     { nxt_string("Object.getOwnPropertyDescriptor({a:1}, 'a').value"),
       nxt_string("1") },