Title: [231871] trunk
Revision
231871
Author
[email protected]
Date
2018-05-16 14:02:49 -0700 (Wed, 16 May 2018)

Log Message

DFG models InstanceOf incorrectly
https://bugs.webkit.org/show_bug.cgi?id=185694

Reviewed by Keith Miller.
JSTests:


* stress/instanceof-proxy-check-structure.js: Added.
(Foo):
(Bar):
(doBadThings):
(getPrototypeOf):
(foo):
(i.new.Bar):
(new.Bar):
* stress/instanceof-proxy-loop.js: Added.
(Foo):
(Bar):
(doBadThings):
(getPrototypeOf):
(foo):
* stress/instanceof-proxy.js: Added.
(Foo):
(Bar):
(doBadThings):
(getPrototypeOf):
(foo):

Source/_javascript_Core:

        
Proxies mean that InstanceOf can have effects. Exceptions mean that it's illegal to DCE it or
hoist it.

* dfg/DFGAbstractInterpreterInlines.h:
(JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
* dfg/DFGClobberize.h:
(JSC::DFG::clobberize):
* dfg/DFGHeapLocation.cpp:
(WTF::printInternal):
* dfg/DFGHeapLocation.h:
* dfg/DFGNodeType.h:

Modified Paths

Added Paths

Diff

Modified: trunk/JSTests/ChangeLog (231870 => 231871)


--- trunk/JSTests/ChangeLog	2018-05-16 20:55:12 UTC (rev 231870)
+++ trunk/JSTests/ChangeLog	2018-05-16 21:02:49 UTC (rev 231871)
@@ -1,3 +1,31 @@
+2018-05-16  Filip Pizlo  <[email protected]>
+
+        DFG models InstanceOf incorrectly
+        https://bugs.webkit.org/show_bug.cgi?id=185694
+
+        Reviewed by Keith Miller.
+
+        * stress/instanceof-proxy-check-structure.js: Added.
+        (Foo):
+        (Bar):
+        (doBadThings):
+        (getPrototypeOf):
+        (foo):
+        (i.new.Bar):
+        (new.Bar):
+        * stress/instanceof-proxy-loop.js: Added.
+        (Foo):
+        (Bar):
+        (doBadThings):
+        (getPrototypeOf):
+        (foo):
+        * stress/instanceof-proxy.js: Added.
+        (Foo):
+        (Bar):
+        (doBadThings):
+        (getPrototypeOf):
+        (foo):
+
 2018-05-16  Caio Lima  <[email protected]>
 
         [ESNext][BigInt] Implement support for "/" operation

Added: trunk/JSTests/stress/instanceof-proxy-check-structure.js (0 => 231871)


--- trunk/JSTests/stress/instanceof-proxy-check-structure.js	                        (rev 0)
+++ trunk/JSTests/stress/instanceof-proxy-check-structure.js	2018-05-16 21:02:49 UTC (rev 231871)
@@ -0,0 +1,59 @@
+class Foo { }
+
+function Bar() { }
+
+var numberOfGetPrototypeOfCalls = 0;
+
+var doBadThings = function() { };
+
+Bar.prototype = new Proxy(
+    {},
+    {
+        getPrototypeOf()
+        {
+            numberOfGetPrototypeOfCalls++;
+            doBadThings();
+            return Foo.prototype;
+        }
+    });
+
+// Break some watchpoints.
+var o = {f:42};
+o.g = 43;
+
+function foo(o, p, q)
+{
+    var result = o.f;
+    var _ = p instanceof Foo;
+    q.f = 11;
+    return result + o.f;
+}
+
+noInline(foo);
+
+for (var i = 0; i < 10000; ++i) {
+    var result = foo({f:42}, new Bar(), {f:0});
+    if (result != 84)
+        throw "Error: bad result in loop: " + result;
+}
+
+if (numberOfGetPrototypeOfCalls != 10000)
+    throw "Error: did not call getPrototypeOf() the right number of times";
+
+var globalO = {f:42};
+var didCallGetter = false;
+doBadThings = function() {
+    delete globalO.f;
+    globalO.__defineGetter__("f", function() {
+        didCallGetter = true;
+        return 43;
+    });
+};
+
+var result = foo(globalO, new Bar(), {f:0});
+if (result != 85)
+    throw "Error: bad result at end: " + result;
+if (!didCallGetter)
+    throw "Error: did not call getter";
+if (numberOfGetPrototypeOfCalls != 10001)
+    throw "Error: did not call getPrototypeOf() the right number of times at end";

Added: trunk/JSTests/stress/instanceof-proxy-loop.js (0 => 231871)


--- trunk/JSTests/stress/instanceof-proxy-loop.js	                        (rev 0)
+++ trunk/JSTests/stress/instanceof-proxy-loop.js	2018-05-16 21:02:49 UTC (rev 231871)
@@ -0,0 +1,59 @@
+class Foo { }
+
+function Bar() { }
+
+var numberOfGetPrototypeOfCalls = 0;
+
+var doBadThings = function() { };
+
+Bar.prototype = new Proxy(
+    {},
+    {
+        getPrototypeOf()
+        {
+            numberOfGetPrototypeOfCalls++;
+            doBadThings();
+            return Foo.prototype;
+        }
+    });
+
+// Break some watchpoints.
+var o = {f:42};
+o.g = 43;
+
+function foo(o, p)
+{
+    var result = o.f;
+    for (var i = 0; i < 5; ++i)
+        var _ = p instanceof Foo;
+    return result + o.f;
+}
+
+noInline(foo);
+
+for (var i = 0; i < 10000; ++i) {
+    var result = foo({f:42}, new Bar());
+    if (result != 84)
+        throw "Error: bad result in loop: " + result;
+}
+
+if (numberOfGetPrototypeOfCalls != 10000 * 5)
+    throw "Error: did not call getPrototypeOf() the right number of times";
+
+var globalO = {f:42};
+var didCallGetter = false;
+doBadThings = function() {
+    delete globalO.f;
+    globalO.__defineGetter__("f", function() {
+        didCallGetter = true;
+        return 43;
+    });
+};
+
+var result = foo(globalO, new Bar());
+if (result != 85)
+    throw "Error: bad result at end: " + result;
+if (!didCallGetter)
+    throw "Error: did not call getter";
+if (numberOfGetPrototypeOfCalls != 10001 * 5)
+    throw "Error: did not call getPrototypeOf() the right number of times at end";

Added: trunk/JSTests/stress/instanceof-proxy.js (0 => 231871)


--- trunk/JSTests/stress/instanceof-proxy.js	                        (rev 0)
+++ trunk/JSTests/stress/instanceof-proxy.js	2018-05-16 21:02:49 UTC (rev 231871)
@@ -0,0 +1,47 @@
+class Foo { }
+
+function Bar() { }
+
+var numberOfGetPrototypeOfCalls = 0;
+
+var doBadThings = function() { };
+
+Bar.prototype = new Proxy(
+    {},
+    {
+        getPrototypeOf()
+        {
+            numberOfGetPrototypeOfCalls++;
+            doBadThings();
+            return Foo.prototype;
+        }
+    });
+
+var o = {f:42};
+
+function foo(o, p)
+{
+    var result = o.f;
+    var _ = p instanceof Foo;
+    return result + o.f;
+}
+
+noInline(foo);
+
+for (var i = 0; i < 10000; ++i) {
+    var result = foo({f:42}, new Bar());
+    if (result != 84)
+        throw "Error: bad result in loop: " + result;
+}
+
+var globalO = {f:42};
+var didCallGetter = false;
+doBadThings = function() {
+    globalO.f = 43;
+};
+
+var result = foo(globalO, new Bar());
+if (result != 85)
+    throw "Error: bad result at end: " + result;
+if (numberOfGetPrototypeOfCalls != 10001)
+    throw "Error: did not call getPrototypeOf() the right number of times at end";

Modified: trunk/Source/_javascript_Core/ChangeLog (231870 => 231871)


--- trunk/Source/_javascript_Core/ChangeLog	2018-05-16 20:55:12 UTC (rev 231870)
+++ trunk/Source/_javascript_Core/ChangeLog	2018-05-16 21:02:49 UTC (rev 231871)
@@ -1,3 +1,22 @@
+2018-05-16  Filip Pizlo  <[email protected]>
+
+        DFG models InstanceOf incorrectly
+        https://bugs.webkit.org/show_bug.cgi?id=185694
+
+        Reviewed by Keith Miller.
+        
+        Proxies mean that InstanceOf can have effects. Exceptions mean that it's illegal to DCE it or
+        hoist it.
+
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+        * dfg/DFGClobberize.h:
+        (JSC::DFG::clobberize):
+        * dfg/DFGHeapLocation.cpp:
+        (WTF::printInternal):
+        * dfg/DFGHeapLocation.h:
+        * dfg/DFGNodeType.h:
+
 2018-05-16  Andy VanWagoner  <[email protected]>
 
         Add support for Intl NumberFormat formatToParts

Modified: trunk/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h (231870 => 231871)


--- trunk/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h	2018-05-16 20:55:12 UTC (rev 231870)
+++ trunk/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h	2018-05-16 21:02:49 UTC (rev 231871)
@@ -3363,7 +3363,7 @@
         break;
             
     case InstanceOf:
-        // Sadly, we don't propagate the fact that we've done InstanceOf
+        clobberWorld();
         setNonCellTypeForNode(node, SpecBoolean);
         break;
 

Modified: trunk/Source/_javascript_Core/dfg/DFGClobberize.h (231870 => 231871)


--- trunk/Source/_javascript_Core/dfg/DFGClobberize.h	2018-05-16 20:55:12 UTC (rev 231870)
+++ trunk/Source/_javascript_Core/dfg/DFGClobberize.h	2018-05-16 21:02:49 UTC (rev 231871)
@@ -636,6 +636,7 @@
     case ToNumber:
     case NumberToStringWithRadix:
     case CreateThis:
+    case InstanceOf:
         read(World);
         write(Heap);
         return;
@@ -1042,11 +1043,6 @@
         def(HeapLocation(OverridesHasInstanceLoc, JSCell_typeInfoFlags, node->child1()), LazyNode(node));
         return;
 
-    case InstanceOf:
-        read(JSCell_structureID);
-        def(HeapLocation(InstanceOfLoc, JSCell_structureID, node->child1(), node->child2()), LazyNode(node));
-        return;
-
     case PutStructure:
         read(JSObject_butterfly);
         write(JSCell_structureID);

Modified: trunk/Source/_javascript_Core/dfg/DFGHeapLocation.cpp (231870 => 231871)


--- trunk/Source/_javascript_Core/dfg/DFGHeapLocation.cpp	2018-05-16 20:55:12 UTC (rev 231870)
+++ trunk/Source/_javascript_Core/dfg/DFGHeapLocation.cpp	2018-05-16 21:02:49 UTC (rev 231871)
@@ -144,10 +144,6 @@
         out.print("IndexedPropertyStorageLoc");
         return;
         
-    case InstanceOfLoc:
-        out.print("InstanceOfLoc");
-        return;
-        
     case NamedPropertyLoc:
         out.print("NamedPropertyLoc");
         return;

Modified: trunk/Source/_javascript_Core/dfg/DFGHeapLocation.h (231870 => 231871)


--- trunk/Source/_javascript_Core/dfg/DFGHeapLocation.h	2018-05-16 20:55:12 UTC (rev 231870)
+++ trunk/Source/_javascript_Core/dfg/DFGHeapLocation.h	2018-05-16 21:02:49 UTC (rev 231871)
@@ -52,7 +52,6 @@
     IndexedPropertyInt52Loc,
     IndexedPropertyJSLoc,
     IndexedPropertyStorageLoc,
-    InstanceOfLoc,
     InvalidationPointLoc,
     IsFunctionLoc,
     IsObjectOrNullLoc,

Modified: trunk/Source/_javascript_Core/dfg/DFGNodeType.h (231870 => 231871)


--- trunk/Source/_javascript_Core/dfg/DFGNodeType.h	2018-05-16 20:55:12 UTC (rev 231870)
+++ trunk/Source/_javascript_Core/dfg/DFGNodeType.h	2018-05-16 21:02:49 UTC (rev 231871)
@@ -344,7 +344,7 @@
     \
     /* Nodes for misc operations. */\
     macro(OverridesHasInstance, NodeMustGenerate | NodeResultBoolean) \
-    macro(InstanceOf, NodeResultBoolean) \
+    macro(InstanceOf, NodeMustGenerate | NodeResultBoolean) \
     macro(InstanceOfCustom, NodeMustGenerate | NodeResultBoolean) \
     \
     macro(IsCellWithType, NodeResultBoolean) \
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to