241c024c10
This is the TurboFan counterpart of http://crrev.com/2504263004, but it is a bit more involved, since in TurboFan we always inline the appropriate call to the @@hasInstance handler, and by that we can optimize a lot more patterns of instanceof than Crankshaft, and even yield fast instanceof for custom @@hasInstance handlers (which we can now properly inline as well). Also we now properly optimize Function.prototype[@@hasInstance], even if the right hand side of an instanceof doesn't have the Function.prototype as its direct prototype. For the baseline case, we still rely on the global protector cell, but we can address that in a follow-up as well, and make it more robust in general. TEST=mjsunit/compiler/instanceof BUG=v8:5640 R=yangguo@chromium.org Review-Url: https://codereview.chromium.org/2511223003 Cr-Commit-Position: refs/heads/master@{#41092}
134 lines
2.5 KiB
JavaScript
134 lines
2.5 KiB
JavaScript
// Copyright 2016 the V8 project authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
// Flags: --allow-natives-syntax
|
|
|
|
function A() {}
|
|
var a = new A();
|
|
|
|
var B = {
|
|
[Symbol.hasInstance](o) {
|
|
return false;
|
|
}
|
|
};
|
|
%ToFastProperties(B.__proto__);
|
|
|
|
var C = Object.create({
|
|
[Symbol.hasInstance](o) {
|
|
return true;
|
|
}
|
|
});
|
|
%ToFastProperties(C.__proto__);
|
|
|
|
var D = Object.create({
|
|
[Symbol.hasInstance](o) {
|
|
return o === a;
|
|
}
|
|
});
|
|
%ToFastProperties(D.__proto__);
|
|
|
|
var E = Object.create({
|
|
[Symbol.hasInstance](o) {
|
|
if (o === a) throw o;
|
|
return true;
|
|
}
|
|
});
|
|
%ToFastProperties(E.__proto__);
|
|
|
|
function F() {}
|
|
F.__proto__ = null;
|
|
|
|
(function() {
|
|
function foo(o) { return o instanceof A; }
|
|
|
|
assertTrue(foo(a));
|
|
assertTrue(foo(a));
|
|
assertTrue(foo(new A()));
|
|
%OptimizeFunctionOnNextCall(foo);
|
|
assertTrue(foo(a));
|
|
assertTrue(foo(new A()));
|
|
})();
|
|
|
|
(function() {
|
|
function foo(o) {
|
|
try {
|
|
return o instanceof A;
|
|
} catch (e) {
|
|
return e;
|
|
}
|
|
}
|
|
|
|
assertTrue(foo(a));
|
|
assertTrue(foo(a));
|
|
assertTrue(foo(new A()));
|
|
assertEquals(1, foo(new Proxy({}, {getPrototypeOf() { throw 1; }})));
|
|
%OptimizeFunctionOnNextCall(foo);
|
|
assertTrue(foo(a));
|
|
assertTrue(foo(new A()));
|
|
assertEquals(1, foo(new Proxy({}, {getPrototypeOf() { throw 1; }})));
|
|
})();
|
|
|
|
(function() {
|
|
function foo(o) { return o instanceof B; }
|
|
|
|
assertFalse(foo(a));
|
|
assertFalse(foo(a));
|
|
assertFalse(foo(new A()));
|
|
%OptimizeFunctionOnNextCall(foo);
|
|
assertFalse(foo(a));
|
|
assertFalse(foo(new A()));
|
|
})();
|
|
|
|
(function() {
|
|
function foo(o) { return o instanceof C; }
|
|
|
|
assertTrue(foo(a));
|
|
assertTrue(foo(a));
|
|
assertTrue(foo(new A()));
|
|
%OptimizeFunctionOnNextCall(foo);
|
|
assertTrue(foo(a));
|
|
assertTrue(foo(new A()));
|
|
})();
|
|
|
|
(function() {
|
|
function foo(o) { return o instanceof D; }
|
|
|
|
assertTrue(foo(a));
|
|
assertTrue(foo(a));
|
|
assertFalse(foo(new A()));
|
|
%OptimizeFunctionOnNextCall(foo);
|
|
assertTrue(foo(a));
|
|
assertFalse(foo(new A()));
|
|
})();
|
|
|
|
(function() {
|
|
function foo(o) {
|
|
try {
|
|
return o instanceof E;
|
|
} catch (e) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
assertFalse(foo(a));
|
|
assertTrue(foo(new A()));
|
|
%OptimizeFunctionOnNextCall(foo);
|
|
assertFalse(foo(a));
|
|
assertTrue(foo(new A()));
|
|
})();
|
|
|
|
(function() {
|
|
function foo(o) {
|
|
return o instanceof F;
|
|
}
|
|
|
|
assertFalse(foo(a));
|
|
assertFalse(foo(new A()));
|
|
assertTrue(foo(new F()));
|
|
%OptimizeFunctionOnNextCall(foo);
|
|
assertFalse(foo(a));
|
|
assertFalse(foo(new A()));
|
|
assertTrue(foo(new F()));
|
|
})();
|