Commit 6703dacd authored by Benedikt Meurer's avatar Benedikt Meurer Committed by Commit Bot

[builtins] Don't mess with entered context for MicrotaskCallbacks.

Blink get's highly confused when we change the "entered or
microtask context" for MicrotaskCallbacks.

Bug: chromium:808911, v8:7253
Change-Id: Iee1e872b81a7cddd7138d22d10fa12aa71935dbf
Cq-Include-Trybots: master.tryserver.chromium.linux:linux_chromium_rel_ng
Reviewed-on: https://chromium-review.googlesource.com/903769Reviewed-by: 's avatarBenedikt Meurer <bmeurer@chromium.org>
Reviewed-by: 's avatarYang Guo <yangguo@chromium.org>
Commit-Queue: Benedikt Meurer <bmeurer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#51115}
parent d17b4bfb
......@@ -909,6 +909,8 @@ TF_BUILTIN(RunMicrotasks, InternalBuiltinsAssembler) {
CodeFactory::Call(isolate(), ConvertReceiverMode::kNullOrUndefined),
microtask_context, callable, UndefinedConstant());
GotoIfException(result, &if_exception, &var_exception);
LeaveMicrotaskContext();
SetCurrentContext(current_context);
Goto(&loop_next);
}
......@@ -919,10 +921,6 @@ TF_BUILTIN(RunMicrotasks, InternalBuiltinsAssembler) {
Node* const microtask_data =
LoadObjectField(microtask, CallbackTask::kDataOffset);
// We don't have a context for callback tasks, so we just execute
// them in the current native context.
EnterMicrotaskContext(current_context);
// If this turns out to become a bottleneck because of the calls
// to C++ via CEntryStub, we can choose to speed them up using a
// similar mechanism that we use for the CallApiFunction stub,
......@@ -933,10 +931,8 @@ TF_BUILTIN(RunMicrotasks, InternalBuiltinsAssembler) {
// But from our current measurements it doesn't seem to be a
// serious performance problem, even if the microtask is full
// of CallHandlerTasks (which is not a realistic use case anyways).
Node* const result =
CallRuntime(Runtime::kRunMicrotaskCallback, current_context,
microtask_callback, microtask_data);
GotoIfException(result, &if_exception, &var_exception);
Goto(&loop_next);
}
......@@ -963,6 +959,8 @@ TF_BUILTIN(RunMicrotasks, InternalBuiltinsAssembler) {
CallBuiltin(Builtins::kPromiseResolveThenableJob, microtask_context,
promise_to_resolve, thenable, then);
GotoIfException(result, &if_exception, &var_exception);
LeaveMicrotaskContext();
SetCurrentContext(current_context);
Goto(&loop_next);
}
......@@ -997,6 +995,8 @@ TF_BUILTIN(RunMicrotasks, InternalBuiltinsAssembler) {
RunPromiseHook(Runtime::kPromiseHookAfter, microtask_context,
promise_or_capability);
LeaveMicrotaskContext();
SetCurrentContext(current_context);
Goto(&loop_next);
}
......@@ -1031,6 +1031,8 @@ TF_BUILTIN(RunMicrotasks, InternalBuiltinsAssembler) {
RunPromiseHook(Runtime::kPromiseHookAfter, microtask_context,
promise_or_capability);
LeaveMicrotaskContext();
SetCurrentContext(current_context);
Goto(&loop_next);
}
......@@ -1042,12 +1044,12 @@ TF_BUILTIN(RunMicrotasks, InternalBuiltinsAssembler) {
// Report unhandled exceptions from microtasks.
CallRuntime(Runtime::kReportMessage, current_context,
var_exception.value());
LeaveMicrotaskContext();
SetCurrentContext(current_context);
Goto(&loop_next);
}
BIND(&loop_next);
LeaveMicrotaskContext();
SetCurrentContext(current_context);
Branch(IntPtrLessThan(index, num_tasks), &loop, &init_queue_loop);
}
}
......
......@@ -21648,6 +21648,42 @@ TEST(RunMicrotasksWithoutEnteringContext) {
isolate->SetMicrotasksPolicy(v8::MicrotasksPolicy::kAuto);
}
static void Regress808911_MicrotaskCallback(void* data) {
// So here we expect "current context" to be context1 and
// "entered or microtask context" to be context2.
v8::Isolate* isolate = static_cast<v8::Isolate*>(data);
CHECK(isolate->GetCurrentContext() != isolate->GetEnteredContext());
CHECK(isolate->GetCurrentContext() !=
isolate->GetEnteredOrMicrotaskContext());
}
static void Regress808911_CurrentContextWrapper(
const v8::FunctionCallbackInfo<Value>& info) {
// So here we expect "current context" to be context1 and
// "entered or microtask context" to be context2.
v8::Isolate* isolate = info.GetIsolate();
CHECK(isolate->GetCurrentContext() != isolate->GetEnteredContext());
CHECK(isolate->GetCurrentContext() !=
isolate->GetEnteredOrMicrotaskContext());
isolate->EnqueueMicrotask(Regress808911_MicrotaskCallback, isolate);
isolate->RunMicrotasks();
}
THREADED_TEST(Regress808911) {
v8::Isolate* isolate = CcTest::isolate();
HandleScope handle_scope(isolate);
Local<Context> context1 = Context::New(isolate);
Local<Function> function;
{
Context::Scope context_scope(context1);
function = Function::New(context1, Regress808911_CurrentContextWrapper)
.ToLocalChecked();
}
Local<Context> context2 = Context::New(isolate);
Context::Scope context_scope(context2);
function->CallAsFunction(context2, v8::Undefined(isolate), 0, nullptr)
.ToLocalChecked();
}
TEST(ScopedMicrotasks) {
LocalContext env;
......
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