generateConditionsForInstanceOf needs to see if the object has a poly proto structure...
authorsbarati@apple.com <sbarati@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 7 Jun 2018 00:01:31 +0000 (00:01 +0000)
committersbarati@apple.com <sbarati@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 7 Jun 2018 00:01:31 +0000 (00:01 +0000)
https://bugs.webkit.org/show_bug.cgi?id=186363

Rubber-stamped by Filip Pizlo.

JSTests:

* stress/instance-of-on-poly-proto-opc-should-not-crash.js: Added.

Source/JavaScriptCore:

The code was assuming that the object it was creating an OPC for always
had a non-poly-proto structure. However, this assumption was wrong. For
example, an object in the prototype chain could be poly proto. That type
of object graph would cause a crash in this code. This patch makes it so
that we fail to generate an ObjectPropertyConditionSet if we see a poly proto
object as we traverse the prototype chain.

* bytecode/ObjectPropertyConditionSet.cpp:
(JSC::generateConditionsForInstanceOf):

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

JSTests/ChangeLog
JSTests/stress/instance-of-on-poly-proto-opc-should-not-crash.js [new file with mode: 0644]
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/bytecode/ObjectPropertyConditionSet.cpp

index 57c7bdc..3842c6c 100644 (file)
@@ -1,3 +1,12 @@
+2018-06-06  Saam Barati  <sbarati@apple.com>
+
+        generateConditionsForInstanceOf needs to see if the object has a poly proto structure before assuming it has a constant prototype
+        https://bugs.webkit.org/show_bug.cgi?id=186363
+
+        Rubber-stamped by Filip Pizlo.
+
+        * stress/instance-of-on-poly-proto-opc-should-not-crash.js: Added.
+
 2018-06-05  David Fenton  <david_fenton@apple.com>
 
         Temporarily Skip JSC stress test failures that are consistently occurring.
diff --git a/JSTests/stress/instance-of-on-poly-proto-opc-should-not-crash.js b/JSTests/stress/instance-of-on-poly-proto-opc-should-not-crash.js
new file mode 100644 (file)
index 0000000..8d3d1bc
--- /dev/null
@@ -0,0 +1,28 @@
+function makePolyProtoObject() {
+    function foo() {
+        class C {
+            constructor() {
+                this._field = 42;
+                this.hello = 33;
+            }
+        };
+        return new C;
+    }
+    for (let i = 0; i < 15; ++i)
+        foo();
+    return foo();
+}
+
+function foo(o, c) {
+    return o instanceof c;
+}
+noInline(foo);
+
+class C { }
+
+let o = makePolyProtoObject();
+o.__proto__= new C;
+let x = {__proto__: o};
+for (let i = 0; i < 1000; ++i) {
+    foo(x, C);
+}
index 6614868..750d278 100644 (file)
@@ -1,3 +1,20 @@
+2018-06-06  Saam Barati  <sbarati@apple.com>
+
+        generateConditionsForInstanceOf needs to see if the object has a poly proto structure before assuming it has a constant prototype
+        https://bugs.webkit.org/show_bug.cgi?id=186363
+
+        Rubber-stamped by Filip Pizlo.
+
+        The code was assuming that the object it was creating an OPC for always
+        had a non-poly-proto structure. However, this assumption was wrong. For
+        example, an object in the prototype chain could be poly proto. That type 
+        of object graph would cause a crash in this code. This patch makes it so
+        that we fail to generate an ObjectPropertyConditionSet if we see a poly proto
+        object as we traverse the prototype chain.
+
+        * bytecode/ObjectPropertyConditionSet.cpp:
+        (JSC::generateConditionsForInstanceOf):
+
 2018-06-05  Brent Fulgham  <bfulgham@apple.com>
 
         Adjust compile and runtime flags to match shippable state of features
index 1d9475c..49389c1 100644 (file)
@@ -409,9 +409,13 @@ ObjectPropertyConditionSet generateConditionsForInstanceOf(
                 didHit = true;
                 return true;
             }
+
+            Structure* structure = object->structure(vm);
+            if (structure->hasPolyProto())
+                return false;
             conditions.append(
                 ObjectPropertyCondition::hasPrototype(
-                    vm, owner, object, object->structure(vm)->storedPrototypeObject()));
+                    vm, owner, object, structure->storedPrototypeObject()));
             return true;
         });
     if (result.isValid()) {