Commit 6a5568b4 authored by Paolo Severini's avatar Paolo Severini Committed by V8 LUCI CQ

[compiler] Wrong receiver in API calls with --turbo-optimize-apply

Enabling --turbo-optimize-apply breaks tests because we are
passing the wrong receiver;
in JSCallReducer::ReduceCallOrConstructWithArrayLikeOrSpread
we create a Call node with the wrong ConvertReceiverMode, we
pass kNullOrUndefined while it should be kAny. This may break
calls to API or in general calls to functions that use the
receiver.

Bug: chromium:1231108, v8:9974
Change-Id: Ib35a1bf8746ad254b6d63274f3ae11b12aa83de8
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3043690
Commit-Queue: Paolo Severini <paolosev@microsoft.com>
Reviewed-by: 's avatarGeorg Neis <neis@chromium.org>
Cr-Commit-Position: refs/heads/master@{#75886}
parent 66b4c39d
......@@ -4301,10 +4301,10 @@ Reduction JSCallReducer::ReduceCallOrConstructWithArrayLikeOrSpread(
}
NodeProperties::ChangeOp(
node, javascript()->Call(
JSCallNode::ArityForArgc(new_argument_count), frequency,
feedback_source, ConvertReceiverMode::kNullOrUndefined,
speculation_mode, CallFeedbackRelation::kUnrelated));
node,
javascript()->Call(JSCallNode::ArityForArgc(new_argument_count),
frequency, feedback_source, ConvertReceiverMode::kAny,
speculation_mode, CallFeedbackRelation::kUnrelated));
NodeProperties::ReplaceEffectInput(node, effect);
return Changed(node).FollowedBy(ReduceJSCall(node));
}
......
......@@ -126,6 +126,57 @@ TEST(ReduceJSCreateBoundFunction) {
IrOpcode::kPhi);
}
static void SumF(const v8::FunctionCallbackInfo<v8::Value>& args) {
ApiTestFuzzer::Fuzz();
v8::Local<v8::Context> context = args.GetIsolate()->GetCurrentContext();
int this_x = args.This()
->Get(context, v8_str("x"))
.ToLocalChecked()
->Int32Value(context)
.FromJust();
args.GetReturnValue().Set(v8_num(
args[0]->Int32Value(args.GetIsolate()->GetCurrentContext()).FromJust() +
args[1]->Int32Value(args.GetIsolate()->GetCurrentContext()).FromJust() +
this_x));
}
TEST(ReduceCAPICallWithArrayLike) {
LocalContext env;
v8::Isolate* isolate = env->GetIsolate();
v8::HandleScope scope(isolate);
FLAG_allow_natives_syntax = true;
FLAG_turbo_optimize_apply = true;
Local<v8::FunctionTemplate> sum = v8::FunctionTemplate::New(isolate, SumF);
CHECK(env->Global()
->Set(env.local(), v8_str("sum"),
sum->GetFunction(env.local()).ToLocalChecked())
.FromJust());
Local<v8::FunctionTemplate> fun = v8::FunctionTemplate::New(isolate);
v8::Local<v8::String> class_name = v8_str("the_class_name");
fun->SetClassName(class_name);
Local<ObjectTemplate> templ1 = ObjectTemplate::New(isolate, fun);
templ1->Set(isolate, "x", v8_num(42));
templ1->Set(isolate, "foo", sum);
Local<v8::Object> instance1 =
templ1->NewInstance(env.local()).ToLocalChecked();
CHECK(env->Global()->Set(env.local(), v8_str("p"), instance1).FromJust());
std::string js_code =
"function bar(a, b) { return sum.apply(p, [a, b]); }"
"%PrepareFunctionForOptimization(bar);"
"bar(20, 22);"
"%OptimizeFunctionOnNextCall(bar);"
"bar(20, 22);";
v8::Local<v8::Value> result_value = CompileRun(js_code.c_str());
CHECK(result_value->IsNumber());
int32_t result =
ConvertJSValue<int32_t>::Get(result_value, env.local()).ToChecked();
CHECK_EQ(result, 84);
}
} // namespace compiler
} // namespace internal
} // namespace v8
......@@ -37,6 +37,24 @@
assertFalse(sum_js_got_interpreted);
})();
// Test using receiver
(function () {
function bar() {
return this.gaga;
}
function foo(receiver) {
return bar.apply(receiver, [""]);
}
%PrepareFunctionForOptimization(bar);
%PrepareFunctionForOptimization(foo);
var receiver = { gaga: 42 };
assertEquals(42, foo(receiver));
%OptimizeFunctionOnNextCall(foo);
assertEquals(42, foo(receiver));
assertOptimized(foo);
})();
// Test with holey array.
(function () {
"use strict";
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment