]> git.kaiwu.me - njs.git/commitdiff
Fixed function "prototype" property handler while setting.
authorDmitry Volyntsev <xeioex@nginx.com>
Tue, 18 Aug 2020 16:53:46 +0000 (16:53 +0000)
committerDmitry Volyntsev <xeioex@nginx.com>
Tue, 18 Aug 2020 16:53:46 +0000 (16:53 +0000)
njs_function_prototype_create() works as a getter and setter.  As a
getter the function is expected to create "prototype" property on the
first access, it also sets F.prototype.constructor property to ensure
F.prototype.constructor === F.

Setting of "constructor" property is not needed in setter context, as
it may overwrite existing "constructor" property in setval.

This closes #333 issue on Github.

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

index 5bd8fe922dbeb4ba85e230b8dbf2098a5331a536..796624e6a49a7f44524e116ba5ebe51efe9a6a55 100644 (file)
@@ -776,7 +776,7 @@ njs_function_frame_free(njs_vm_t *vm, njs_native_frame_t *native)
 
 
 static njs_value_t *
-njs_function_property_prototype_create(njs_vm_t *vm, njs_lvlhsh_t *hash,
+njs_function_property_prototype_set(njs_vm_t *vm, njs_lvlhsh_t *hash,
     njs_value_t *prototype)
 {
     njs_int_t           ret;
@@ -845,13 +845,14 @@ njs_function_prototype_create(njs_vm_t *vm, njs_object_prop_t *prop,
         return NJS_ERROR;
     }
 
-    proto = njs_function_property_prototype_create(vm, &function->object.hash,
-                                                   setval);
+    proto = njs_function_property_prototype_set(vm, njs_object_hash(value),
+                                                setval);
     if (njs_slow_path(proto == NULL)) {
         return NJS_ERROR;
     }
 
-    if (njs_is_object(proto)) {
+    if (setval == &proto_value && njs_is_object(proto)) {
+        /* Only in getter context. */
         cons = njs_property_constructor_create(vm, njs_object_hash(proto),
                                                value);
         if (njs_slow_path(cons == NULL)) {
index a020d16a38b5a0b6354b7721af0439ef4e5a18dd..d8dcddd4f28d902bbcdf1f9f6c22d86984199390 100644 (file)
@@ -9393,6 +9393,16 @@ static njs_unit_test_t  njs_test[] =
               "x.t == 1 && y.t == 2"),
       njs_str("true") },
 
+    { njs_str("function A(){}; A.tag = 'A'; var a = new A();"
+              "(function B(){}).prototype = A.prototype;"
+              "a.constructor.tag"),
+      njs_str("A") },
+
+    { njs_str("function A(){}; A.tag = 'A'; var a = new A();"
+              "(function B(){}).prototype = a.constructor.prototype;"
+              "a.constructor.tag"),
+      njs_str("A") },
+
     { njs_str("var x = {}, y = function() {}, z; y.prototype = x; z = new y();"
               "(z instanceof y) && (z.__proto__ == y.prototype) && (x.isPrototypeOf(z))"),
       njs_str("true") },