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) \