[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: Georg Neis <neis@chromium.org> Cr-Commit-Position: refs/heads/master@{#75886}
This commit is contained in:
parent
66b4c39d95
commit
6a5568b48e
@ -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";
|
||||
|
Loading…
Reference in New Issue
Block a user