Modified: trunk/JSTests/ChangeLog (233426 => 233427)
--- trunk/JSTests/ChangeLog 2018-07-02 17:51:21 UTC (rev 233426)
+++ trunk/JSTests/ChangeLog 2018-07-02 18:04:54 UTC (rev 233427)
@@ -1,3 +1,15 @@
+2018-07-02 Keith Miller <[email protected]>
+
+ InstanceOf IC should do generic if the prototype is not an object.
+ https://bugs.webkit.org/show_bug.cgi?id=187250
+
+ Reviewed by Mark Lam.
+
+ * stress/instanceof-non-object-prototype.js: Added.
+ (let):
+ (test):
+ (i.catch):
+
2018-06-30 Mark Lam <[email protected]>
Builtins and host functions should get their own structures.
Modified: trunk/Source/_javascript_Core/ChangeLog (233426 => 233427)
--- trunk/Source/_javascript_Core/ChangeLog 2018-07-02 17:51:21 UTC (rev 233426)
+++ trunk/Source/_javascript_Core/ChangeLog 2018-07-02 18:04:54 UTC (rev 233427)
@@ -1,3 +1,17 @@
+2018-07-02 Keith Miller <[email protected]>
+
+ InstanceOf IC should do generic if the prototype is not an object.
+ https://bugs.webkit.org/show_bug.cgi?id=187250
+
+ Reviewed by Mark Lam.
+
+ The old code was wrong for two reasons. First, the AccessCase expected that
+ the prototype value would be non-null. Second, we would end up returning
+ false instead of throwing an exception.
+
+ * jit/Repatch.cpp:
+ (JSC::tryCacheInstanceOf):
+
2018-07-01 Mark Lam <[email protected]>
Builtins and host functions should get their own structures.
Modified: trunk/Source/_javascript_Core/jit/Repatch.cpp (233426 => 233427)
--- trunk/Source/_javascript_Core/jit/Repatch.cpp 2018-07-02 17:51:21 UTC (rev 233426)
+++ trunk/Source/_javascript_Core/jit/Repatch.cpp 2018-07-02 18:04:54 UTC (rev 233427)
@@ -736,28 +736,27 @@
GCSafeConcurrentJSLocker locker(codeBlock->m_lock, vm.heap);
JSCell* value = valueValue.asCell();
- JSObject* prototype = jsDynamicCast<JSObject*>(vm, prototypeValue);
-
Structure* structure = value->structure(vm);
-
std::unique_ptr<AccessCase> newCase;
-
- if (!jsDynamicCast<JSObject*>(vm, value)) {
- newCase = InstanceOfAccessCase::create(
- vm, codeBlock, AccessCase::InstanceOfMiss, structure, ObjectPropertyConditionSet(),
- prototype);
- } else if (prototype && structure->prototypeQueriesAreCacheable()) {
- // FIXME: Teach this to do poly proto.
- // https://bugs.webkit.org/show_bug.cgi?id=185663
-
- ObjectPropertyConditionSet conditionSet = generateConditionsForInstanceOf(
- vm, codeBlock, exec, structure, prototype, wasFound);
-
- if (conditionSet.isValid()) {
+ JSObject* prototype = jsDynamicCast<JSObject*>(vm, prototypeValue);
+ if (prototype) {
+ if (!jsDynamicCast<JSObject*>(vm, value)) {
newCase = InstanceOfAccessCase::create(
- vm, codeBlock,
- wasFound ? AccessCase::InstanceOfHit : AccessCase::InstanceOfMiss,
- structure, conditionSet, prototype);
+ vm, codeBlock, AccessCase::InstanceOfMiss, structure, ObjectPropertyConditionSet(),
+ prototype);
+ } else if (structure->prototypeQueriesAreCacheable()) {
+ // FIXME: Teach this to do poly proto.
+ // https://bugs.webkit.org/show_bug.cgi?id=185663
+
+ ObjectPropertyConditionSet conditionSet = generateConditionsForInstanceOf(
+ vm, codeBlock, exec, structure, prototype, wasFound);
+
+ if (conditionSet.isValid()) {
+ newCase = InstanceOfAccessCase::create(
+ vm, codeBlock,
+ wasFound ? AccessCase::InstanceOfHit : AccessCase::InstanceOfMiss,
+ structure, conditionSet, prototype);
+ }
}
}
Added: trunk/jstests/stress/instanceof-non-object-prototype.js (0 => 233427)
--- trunk/jstests/stress/instanceof-non-object-prototype.js (rev 0)
+++ trunk/jstests/stress/instanceof-non-object-prototype.js 2018-07-02 18:04:54 UTC (rev 233427)
@@ -0,0 +1,21 @@
+let base = "sting";
+let constructor = function() { };
+constructor.prototype = 42;
+
+function test(a, b) {
+ return a instanceof b;
+}
+noInline(test);
+
+for (let i = 0; i < 10000; i++) {
+ let exception;
+ try {
+ var result = test(base, constructor);
+ } catch (e) {
+ exception = e;
+ }
+ if (exception)
+ throw new Error("Threw an exception: " + exception);
+ if (result !== false)
+ throw new Error("instanceof returned: " + result);
+}