v8/test/mjsunit/compiler/reflect-apply.js
bmeurer 767ce78871 [turbofan] Introduce new JSCallWithArrayLike operator.
Add a new JSCallWithArrayLike operator that is backed by the
CallWithArrayLike builtin, and use that operator for both
Function.prototype.apply and Reflect.apply inlining. Also unify
the handling of JSCallWithArrayLike and JSCallWithSpread in
the JSCallReducer to reduce the copy&paste overhead.

Drive-by-fix: Add a lot of test coverage for Reflect.apply and
Function.prototype.apply in optimized code, especially for some
corner cases, which was missing so far.

BUG=v8:4587,v8:5269
R=petermarshall@chromium.org

Review-Url: https://codereview.chromium.org/2950773002
Cr-Commit-Position: refs/heads/master@{#46041}
2017-06-20 12:36:43 +00:00

115 lines
2.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
// Test Reflect.apply with wrong number of arguments.
(function() {
"use strict";
function bar() { return this; }
function foo() { return Reflect.apply(bar); }
assertThrows(foo);
assertThrows(foo);
%OptimizeFunctionOnNextCall(foo);
assertThrows(foo);
})();
(function() {
"use strict";
function bar() { return this; }
function foo() { return Reflect.apply(bar, this); }
assertThrows(foo);
assertThrows(foo);
%OptimizeFunctionOnNextCall(foo);
assertThrows(foo);
})();
(function() {
"use strict";
function bar() { return this; }
function foo() { return Reflect.apply(bar, this, arguments, this); }
assertEquals(42, foo.call(42));
assertEquals(42, foo.call(42));
%OptimizeFunctionOnNextCall(foo);
assertEquals(42, foo.call(42));
})();
// Test Reflect.apply within try/catch.
(function() {
"use strict";
function foo(bar) {
try {
return Reflect.apply(bar, bar, arguments);
} catch (e) {
return 1;
}
}
assertEquals(1, foo());
assertEquals(1, foo());
%OptimizeFunctionOnNextCall(foo);
assertEquals(1, foo());
})();
(function() {
"use strict";
function foo(bar) {
try {
return Reflect.apply(bar, bar, bar);
} catch (e) {
return 1;
}
}
assertEquals(1, foo());
assertEquals(1, foo());
%OptimizeFunctionOnNextCall(foo);
assertEquals(1, foo());
})();
// Test proper order of callable check and array-like iteration
// in Reflect.apply.
(function() {
var dummy_length_counter = 0;
var dummy = { get length() { ++dummy_length_counter; return 0; } };
function foo() {
return Reflect.apply(undefined, this, dummy);
}
assertThrows(foo, TypeError);
assertThrows(foo, TypeError);
%OptimizeFunctionOnNextCall(foo);
assertThrows(foo, TypeError);
assertEquals(0, dummy_length_counter);
})();
(function() {
var dummy_length_counter = 0;
var dummy = { get length() { ++dummy_length_counter; return 0; } };
function foo() {
return Reflect.apply(null, this, dummy);
}
assertThrows(foo, TypeError);
assertThrows(foo, TypeError);
%OptimizeFunctionOnNextCall(foo);
assertThrows(foo, TypeError);
assertEquals(0, dummy_length_counter);
})();
(function() {
var dummy_length_counter = 0;
var dummy = { get length() { ++dummy_length_counter; return 0; } };
function foo() {
return Reflect.apply(null, this, dummy);
}
assertThrows(foo, TypeError);
assertThrows(foo, TypeError);
%OptimizeFunctionOnNextCall(foo);
assertThrows(foo, TypeError);
assertEquals(0, dummy_length_counter);
})();