]> git.kaiwu.me - njs.git/commitdiff
Fixed [[SetPrototypeOf]].
authorDmitry Volyntsev <xeioex@nginx.com>
Wed, 14 Aug 2019 17:22:26 +0000 (20:22 +0300)
committerDmitry Volyntsev <xeioex@nginx.com>
Wed, 14 Aug 2019 17:22:26 +0000 (20:22 +0300)
src/njs_object.c
src/test/njs_unit_test.c

index 7994f485652bdefc3a9654d0a9a0eb632becd5f3..9c734115cd5e4615b14396e70064d02f3657ba9e 100644 (file)
@@ -1846,27 +1846,30 @@ const njs_object_init_t  njs_object_constructor_init = {
 /*
  * ES6, 9.1.2: [[SetPrototypeOf]].
  */
-static njs_bool_t
+static njs_int_t
 njs_object_set_prototype_of(njs_vm_t *vm, njs_object_t *object,
     const njs_value_t *value)
 {
     const njs_object_t *proto;
 
-    proto = njs_is_object(value) ? njs_object(value)->__proto__
-                                 : NULL;
+    proto = njs_object(value);
 
     if (njs_slow_path(object->__proto__ == proto)) {
-        return 1;
+        return NJS_OK;
+    }
+
+    if (!object->extensible) {
+        return NJS_DECLINED;
     }
 
     if (njs_slow_path(proto == NULL)) {
         object->__proto__ = NULL;
-        return 1;
+        return NJS_OK;
     }
 
     do {
         if (proto == object) {
-            return 0;
+            return NJS_ERROR;
         }
 
         proto = proto->__proto__;
@@ -1875,7 +1878,7 @@ njs_object_set_prototype_of(njs_vm_t *vm, njs_object_t *object,
 
     object->__proto__ = njs_object(value);
 
-    return 1;
+    return NJS_OK;
 }
 
 
@@ -1883,7 +1886,7 @@ njs_int_t
 njs_object_prototype_proto(njs_vm_t *vm, njs_value_t *value,
     njs_value_t *setval, njs_value_t *retval)
 {
-    njs_bool_t    ret;
+    njs_int_t     ret;
     njs_object_t  *proto, *object;
 
     if (!njs_is_object(value)) {
@@ -1896,7 +1899,7 @@ njs_object_prototype_proto(njs_vm_t *vm, njs_value_t *value,
     if (setval != NULL) {
         if (njs_is_object(setval) || njs_is_null(setval)) {
             ret = njs_object_set_prototype_of(vm, object, setval);
-            if (njs_slow_path(!ret)) {
+            if (njs_slow_path(ret == NJS_ERROR)) {
                 njs_type_error(vm, "Cyclic __proto__ value");
                 return NJS_ERROR;
             }
index 7ac78b6b82aa4f19428539bed1de7e1220965e5b..6fb8a59f65c0f0b8015c8b04d3e3e1b62fdf02a6 100644 (file)
@@ -8782,9 +8782,31 @@ static njs_unit_test_t  njs_test[] =
     { njs_str("({__proto__:null, a:1}).a"),
       njs_str("1") },
 
+    { njs_str("Object.getPrototypeOf({__proto__:null})"),
+      njs_str("null") },
+
+    { njs_str("Object.getPrototypeOf({__proto__:1}) === Object.prototype"),
+      njs_str("true") },
+
+    { njs_str("Object.getPrototypeOf({__proto__:Array.prototype}) === Array.prototype"),
+      njs_str("true") },
+
     { njs_str("({__proto__: []}) instanceof Array"),
       njs_str("true") },
 
+    { njs_str("({__proto__: Array.prototype}) instanceof Array"),
+      njs_str("true") },
+
+    { njs_str("var o = {};"
+              "o.__proto__ = Array.prototype;"
+              "Object.getPrototypeOf(o) === Array.prototype"),
+      njs_str("true") },
+
+    { njs_str("var o = Object.preventExtensions({});"
+              "o.__proto__ = Array.prototype;"
+              "Object.getPrototypeOf(o) === Object.prototype"),
+      njs_str("true") },
+
     { njs_str("({}).__proto__.constructor === Object"),
       njs_str("true") },