c13981cd22
This addresses two TODOs in Ignition where the Construct and the ConstructWithSpread bytecodes didn't collect JSBoundFunction new.target feedback. This is fairly trivial to add now with the existing machinery and the TurboFan side of this was already fixed before, so we can leverage the new feedback. Bug: v8:5267, v8:7109 Change-Id: Iae257836716c14f05f5d301326cbe8b2acaeb38b Reviewed-on: https://chromium-review.googlesource.com/793048 Reviewed-by: Mythri Alle <mythria@chromium.org> Commit-Queue: Benedikt Meurer <bmeurer@chromium.org> Cr-Commit-Position: refs/heads/master@{#49712}
287 lines
5.7 KiB
JavaScript
287 lines
5.7 KiB
JavaScript
// Copyright 2017 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() {
|
|
"use strict";
|
|
function bar() { return this; }
|
|
|
|
function foo(x) {
|
|
return bar.bind(x);
|
|
}
|
|
|
|
assertEquals(0, foo(0)());
|
|
assertEquals(1, foo(1)());
|
|
%OptimizeFunctionOnNextCall(foo);
|
|
assertEquals("", foo("")());
|
|
})();
|
|
|
|
(function() {
|
|
"use strict";
|
|
function bar(x) { return x; }
|
|
|
|
function foo(x) {
|
|
return bar.bind(undefined, x);
|
|
}
|
|
|
|
assertEquals(0, foo(0)());
|
|
assertEquals(1, foo(1)());
|
|
%OptimizeFunctionOnNextCall(foo);
|
|
assertEquals("", foo("")());
|
|
})();
|
|
|
|
(function() {
|
|
function bar(x) { return x; }
|
|
|
|
function foo(x) {
|
|
return bar.bind(undefined, x);
|
|
}
|
|
|
|
assertEquals(0, foo(0)());
|
|
assertEquals(1, foo(1)());
|
|
%OptimizeFunctionOnNextCall(foo);
|
|
assertEquals("", foo("")());
|
|
})();
|
|
|
|
(function() {
|
|
"use strict";
|
|
function bar(x, y) { return x + y; }
|
|
|
|
function foo(x, y) {
|
|
return bar.bind(undefined, x, y);
|
|
}
|
|
|
|
assertEquals(0, foo(0, 0)());
|
|
assertEquals(2, foo(1, 1)());
|
|
%OptimizeFunctionOnNextCall(foo);
|
|
assertEquals("ab", foo("a", "b")());
|
|
assertEquals(0, foo(0, 1).length);
|
|
assertEquals("bound bar", foo(1, 2).name)
|
|
})();
|
|
|
|
(function() {
|
|
function bar(x, y) { return x + y; }
|
|
|
|
function foo(x, y) {
|
|
return bar.bind(undefined, x, y);
|
|
}
|
|
|
|
assertEquals(0, foo(0, 0)());
|
|
assertEquals(2, foo(1, 1)());
|
|
%OptimizeFunctionOnNextCall(foo);
|
|
assertEquals("ab", foo("a", "b")());
|
|
assertEquals(0, foo(0, 1).length);
|
|
assertEquals("bound bar", foo(1, 2).name)
|
|
})();
|
|
|
|
(function() {
|
|
function bar(f) { return f(1); }
|
|
|
|
function foo(g) { return bar(g.bind(null, 2)); }
|
|
|
|
assertEquals(3, foo((x, y) => x + y));
|
|
assertEquals(1, foo((x, y) => x - y));
|
|
%OptimizeFunctionOnNextCall(foo);
|
|
assertEquals(3, foo((x, y) => x + y));
|
|
assertEquals(1, foo((x, y) => x - y));
|
|
})();
|
|
|
|
(function() {
|
|
function add(x, y) { return x + y; }
|
|
|
|
function foo(a) { return a.map(add.bind(null, 1)); }
|
|
|
|
assertEquals([1, 2, 3], foo([0, 1, 2]));
|
|
assertEquals([2, 3, 4], foo([1, 2, 3]));
|
|
%OptimizeFunctionOnNextCall(foo);
|
|
assertEquals([1, 2, 3], foo([0, 1, 2]));
|
|
assertEquals([2, 3, 4], foo([1, 2, 3]));
|
|
})();
|
|
|
|
(function() {
|
|
const add = (x, y) => x + y;
|
|
const inc = add.bind(null, 1);
|
|
|
|
function foo(inc) { return inc(1); }
|
|
|
|
assertEquals(2, foo(inc));
|
|
assertEquals(2, foo(inc));
|
|
%OptimizeFunctionOnNextCall(foo);
|
|
assertEquals(2, foo(inc));
|
|
})();
|
|
|
|
(function() {
|
|
const A = class A {};
|
|
const B = A.bind();
|
|
|
|
function foo() { return new B; }
|
|
|
|
assertInstanceof(foo(), A);
|
|
assertInstanceof(foo(), B);
|
|
%OptimizeFunctionOnNextCall(foo);
|
|
assertInstanceof(foo(), A);
|
|
assertInstanceof(foo(), B);
|
|
})();
|
|
|
|
(function() {
|
|
const A = class A {
|
|
constructor(x, y, z) {
|
|
this.x = x;
|
|
this.y = y;
|
|
this.z = z;
|
|
}
|
|
};
|
|
const B = A.bind(null, 1, 2);
|
|
|
|
function foo(z) { return new B(z); }
|
|
|
|
assertEquals(1, foo(3).x);
|
|
assertEquals(2, foo(3).y);
|
|
assertEquals(3, foo(3).z);
|
|
%OptimizeFunctionOnNextCall(foo);
|
|
assertEquals(1, foo(3).x);
|
|
assertEquals(2, foo(3).y);
|
|
assertEquals(3, foo(3).z);
|
|
})();
|
|
|
|
(function() {
|
|
const A = class A {};
|
|
|
|
function foo() {
|
|
const B = A.bind();
|
|
return new B;
|
|
}
|
|
|
|
assertInstanceof(foo(), A);
|
|
assertInstanceof(foo(), A);
|
|
%OptimizeFunctionOnNextCall(foo);
|
|
assertInstanceof(foo(), A);
|
|
})();
|
|
|
|
(function() {
|
|
const A = class A {
|
|
constructor(x, y, z) {
|
|
this.x = x;
|
|
this.y = y;
|
|
this.z = z;
|
|
}
|
|
};
|
|
|
|
function foo(z) {
|
|
const B = A.bind(null, 1, 2);
|
|
return new B(z);
|
|
}
|
|
|
|
assertEquals(1, foo(3).x);
|
|
assertEquals(2, foo(3).y);
|
|
assertEquals(3, foo(3).z);
|
|
%OptimizeFunctionOnNextCall(foo);
|
|
assertEquals(1, foo(3).x);
|
|
assertEquals(2, foo(3).y);
|
|
assertEquals(3, foo(3).z);
|
|
})();
|
|
|
|
(function() {
|
|
const A = class A {};
|
|
const B = A.bind();
|
|
|
|
function foo(B) {
|
|
return new B;
|
|
}
|
|
|
|
assertInstanceof(foo(B), A);
|
|
assertInstanceof(foo(B), A);
|
|
%OptimizeFunctionOnNextCall(foo);
|
|
assertInstanceof(foo(B), A);
|
|
})();
|
|
|
|
(function() {
|
|
const A = class A {
|
|
constructor(x, y, z) {
|
|
this.x = x;
|
|
this.y = y;
|
|
this.z = z;
|
|
}
|
|
};
|
|
const B = A.bind(null, 1, 2);
|
|
|
|
function foo(B, z) {
|
|
return new B(z);
|
|
}
|
|
|
|
assertEquals(1, foo(B, 3).x);
|
|
assertEquals(2, foo(B, 3).y);
|
|
assertEquals(3, foo(B, 3).z);
|
|
%OptimizeFunctionOnNextCall(foo);
|
|
assertEquals(1, foo(B, 3).x);
|
|
assertEquals(2, foo(B, 3).y);
|
|
assertEquals(3, foo(B, 3).z);
|
|
})();
|
|
|
|
(function() {
|
|
const A = class A {
|
|
constructor(value) {
|
|
this.value = value;
|
|
}
|
|
};
|
|
const C = class C extends A {
|
|
constructor() { super(1); }
|
|
};
|
|
const B = C.__proto__ = A.bind(null, 1);
|
|
|
|
assertInstanceof(new C(), A);
|
|
assertInstanceof(new C(), B);
|
|
assertInstanceof(new C(), C);
|
|
assertEquals(1, new C().value);
|
|
%OptimizeFunctionOnNextCall(C);
|
|
assertInstanceof(new C(), A);
|
|
assertInstanceof(new C(), B);
|
|
assertInstanceof(new C(), C);
|
|
assertEquals(1, new C().value);
|
|
})();
|
|
|
|
(function() {
|
|
const A = class A {};
|
|
const B = A.bind();
|
|
|
|
function bar(B, ...args) {
|
|
return new B(...args);
|
|
}
|
|
function foo(B) {
|
|
return bar(B)
|
|
}
|
|
|
|
assertInstanceof(foo(B), A);
|
|
assertInstanceof(foo(B), A);
|
|
%OptimizeFunctionOnNextCall(foo);
|
|
assertInstanceof(foo(B), A);
|
|
})();
|
|
|
|
(function() {
|
|
const A = class A {
|
|
constructor(x, y, z) {
|
|
this.x = x;
|
|
this.y = y;
|
|
this.z = z;
|
|
}
|
|
};
|
|
const B = A.bind(null, 1, 2);
|
|
|
|
function bar(B, ...args) {
|
|
return new B(...args);
|
|
}
|
|
function foo(B, z) {
|
|
return bar(B, z);
|
|
}
|
|
|
|
assertEquals(1, foo(B, 3).x);
|
|
assertEquals(2, foo(B, 3).y);
|
|
assertEquals(3, foo(B, 3).z);
|
|
%OptimizeFunctionOnNextCall(foo);
|
|
assertEquals(1, foo(B, 3).x);
|
|
assertEquals(2, foo(B, 3).y);
|
|
assertEquals(3, foo(B, 3).z);
|
|
})();
|