[maglev] Fix Function.prototype.apply with spread

Bug: v8:7700, chromium:1405445
Change-Id: I5faeb7e5229f55fdbd5cf11d79fc44d285b4bea9
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4151200
Commit-Queue: Patrick Thier <pthier@chromium.org>
Reviewed-by: Victor Gomes <victorgomes@chromium.org>
Cr-Commit-Position: refs/heads/main@{#85185}
This commit is contained in:
pthier 2023-01-10 15:08:43 +01:00 committed by V8 LUCI CQ
parent 5134d16904
commit 40f3d61836
2 changed files with 21 additions and 4 deletions

View File

@ -154,7 +154,7 @@ class CallArguments {
ConvertReceiverMode receiver_mode() const { return receiver_mode_; }
void Truncate(size_t new_args_count) {
DCHECK_LE(new_args_count, count());
if (new_args_count >= count()) return;
size_t args_to_pop = count() - new_args_count;
for (size_t i = 0; i < args_to_pop; i++) {
args_.pop_back();
@ -3363,8 +3363,9 @@ ValueNode* MaglevGraphBuilder::ReduceFunctionPrototypeApplyCallWithReceiver(
// No need for spread.
CallArguments empty_args(ConvertReceiverMode::kNullOrUndefined);
call = ReduceCall(receiver, empty_args, feedback_source, speculation_mode);
} else if (args.count() == 1 || IsNullValue(args[1]) ||
IsUndefinedValue(args[1])) {
} else if ((args.count() == 1 || IsNullValue(args[1]) ||
IsUndefinedValue(args[1])) &&
args.mode() == CallArguments::kDefault) {
// No need for spread. We have only the new receiver.
CallArguments new_args(ConvertReceiverMode::kAny, {GetTaggedValue(args[0])},
args.mode());
@ -3372,7 +3373,7 @@ ValueNode* MaglevGraphBuilder::ReduceFunctionPrototypeApplyCallWithReceiver(
} else {
// FunctionPrototypeApply only consider two arguments: the new receiver and
// an array-like arguments_list. All others shall be ignored.
if (IsConstantNode(args[1]->opcode())) {
if (args.count() > 1 && IsConstantNode(args[1]->opcode())) {
DCHECK(!IsNullValue(args[1]) && !IsUndefinedValue(args[1]));
// The arguments_list is not null, nor undefined, we can do a call with
// array like.

View File

@ -0,0 +1,16 @@
// Copyright 2023 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 --maglev
function foo() {}
function bar(...args) {
foo.apply(...args);
}
%PrepareFunctionForOptimization(bar);
assertThrows('bar(2,3,4)');
assertThrows('bar(2,3,4)');
%OptimizeMaglevOnNextCall(bar);
assertThrows('bar(2,3,4)');