Assertion failure for bound function with custom prototype and Reflect.construct
authorutatane.tea@gmail.com <utatane.tea@gmail.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 2 May 2016 08:09:21 +0000 (08:09 +0000)
committerutatane.tea@gmail.com <utatane.tea@gmail.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 2 May 2016 08:09:21 +0000 (08:09 +0000)
https://bugs.webkit.org/show_bug.cgi?id=157081

Reviewed by Saam Barati.

We ensured `newTarget != exec->callee()`. However, it does not mean `newTarget.get("prototype") != exec->callee()->get("prototype")`.
When the given `prototype` is the same to `baseStructure->sotredPrototype()`, it is unnecessary to create a new structure from this
baseStructure.

* bytecode/InternalFunctionAllocationProfile.h:
(JSC::InternalFunctionAllocationProfile::createAllocationStructureFromBase):
* tests/stress/custom-prototype-may-be-same-to-original-one.js: Added.
(shouldBe):
(boundFunction):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@200319 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/bytecode/InternalFunctionAllocationProfile.h
Source/JavaScriptCore/tests/stress/custom-prototype-may-be-same-to-original-one.js [new file with mode: 0644]

index 19e5a6a..f795375 100644 (file)
@@ -1,3 +1,20 @@
+2016-05-02  Yusuke Suzuki  <utatane.tea@gmail.com>
+
+        Assertion failure for bound function with custom prototype and Reflect.construct
+        https://bugs.webkit.org/show_bug.cgi?id=157081
+
+        Reviewed by Saam Barati.
+
+        We ensured `newTarget != exec->callee()`. However, it does not mean `newTarget.get("prototype") != exec->callee()->get("prototype")`.
+        When the given `prototype` is the same to `baseStructure->sotredPrototype()`, it is unnecessary to create a new structure from this
+        baseStructure.
+
+        * bytecode/InternalFunctionAllocationProfile.h:
+        (JSC::InternalFunctionAllocationProfile::createAllocationStructureFromBase):
+        * tests/stress/custom-prototype-may-be-same-to-original-one.js: Added.
+        (shouldBe):
+        (boundFunction):
+
 2016-04-30  Konstantin Tokarev  <annulen@yandex.ru>
 
         Guard ObjC-specific code in Heap.cpp with USE(FOUNDATION)
index 1926e93..56675b4 100644 (file)
@@ -47,10 +47,13 @@ private:
 
 inline Structure* InternalFunctionAllocationProfile::createAllocationStructureFromBase(VM& vm, JSCell* owner, JSObject* prototype, Structure* baseStructure)
 {
-    ASSERT(prototype != baseStructure->storedPrototype());
     ASSERT(!m_structure || m_structure.get()->classInfo() != baseStructure->classInfo());
 
-    Structure* structure = vm.prototypeMap.emptyStructureForPrototypeFromBaseStructure(prototype, baseStructure);
+    Structure* structure;
+    if (prototype == baseStructure->storedPrototype())
+        structure = baseStructure;
+    else
+        structure = vm.prototypeMap.emptyStructureForPrototypeFromBaseStructure(prototype, baseStructure);
 
     // Ensure that if another thread sees the structure, it will see it properly created.
     WTF::storeStoreFence();
diff --git a/Source/JavaScriptCore/tests/stress/custom-prototype-may-be-same-to-original-one.js b/Source/JavaScriptCore/tests/stress/custom-prototype-may-be-same-to-original-one.js
new file mode 100644 (file)
index 0000000..2d0d465
--- /dev/null
@@ -0,0 +1,11 @@
+function shouldBe(actual, expected) {
+    if (actual !== expected)
+        throw new Error(`bad value: ${String(actual)}`);
+}
+
+var boundFunction = function(){}.bind();
+Object.defineProperty(boundFunction, "prototype", {
+    value: Array.prototype
+});
+var result = Reflect.construct(Array, [], boundFunction);
+shouldBe(result.__proto__, Array.prototype);