CallDepthScope should track the current microtask scope
Tracking the context is not enough, as we might clear the context to avoid repeatedly reentering the same context. Also fix unittests that relied on the default microtask queue getting automatically processed instead of the one of the current context. Bug: chromium:728583 Change-Id: Ia9a51c513fc7363a518af86cc54c5bda26b5fbe8 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2859850 Reviewed-by: Toon Verwaest <verwaest@chromium.org> Commit-Queue: Jochen Eisinger <jochen@chromium.org> Cr-Commit-Position: refs/heads/master@{#74303}
This commit is contained in:
parent
d665f40fa2
commit
a5c321024c
@ -139,6 +139,7 @@ class V8_NODISCARD CallDepthScope {
|
||||
CallDepthScope(i::Isolate* isolate, Local<Context> context)
|
||||
: isolate_(isolate),
|
||||
context_(context),
|
||||
did_enter_context_(false),
|
||||
escaped_(false),
|
||||
safe_for_termination_(isolate->next_v8_call_is_safe_for_termination()),
|
||||
interrupts_scope_(isolate_, i::StackGuard::TERMINATE_EXECUTION,
|
||||
@ -152,12 +153,11 @@ class V8_NODISCARD CallDepthScope {
|
||||
if (!context.IsEmpty()) {
|
||||
i::Handle<i::Context> env = Utils::OpenHandle(*context);
|
||||
i::HandleScopeImplementer* impl = isolate->handle_scope_implementer();
|
||||
if (!isolate->context().is_null() &&
|
||||
isolate->context().native_context() == env->native_context()) {
|
||||
context_ = Local<Context>();
|
||||
} else {
|
||||
if (isolate->context().is_null() ||
|
||||
isolate->context().native_context() != env->native_context()) {
|
||||
impl->SaveContext(isolate->context());
|
||||
isolate->set_context(*env);
|
||||
did_enter_context_ = true;
|
||||
}
|
||||
}
|
||||
if (do_callback) isolate_->FireBeforeCallEnteredCallback();
|
||||
@ -165,8 +165,10 @@ class V8_NODISCARD CallDepthScope {
|
||||
~CallDepthScope() {
|
||||
i::MicrotaskQueue* microtask_queue = isolate_->default_microtask_queue();
|
||||
if (!context_.IsEmpty()) {
|
||||
i::HandleScopeImplementer* impl = isolate_->handle_scope_implementer();
|
||||
isolate_->set_context(impl->RestoreContext());
|
||||
if (did_enter_context_) {
|
||||
i::HandleScopeImplementer* impl = isolate_->handle_scope_implementer();
|
||||
isolate_->set_context(impl->RestoreContext());
|
||||
}
|
||||
|
||||
i::Handle<i::Context> env = Utils::OpenHandle(*context_);
|
||||
microtask_queue = env->native_context().microtask_queue();
|
||||
@ -213,9 +215,9 @@ class V8_NODISCARD CallDepthScope {
|
||||
|
||||
i::Isolate* const isolate_;
|
||||
Local<Context> context_;
|
||||
bool escaped_;
|
||||
bool do_callback_;
|
||||
bool safe_for_termination_;
|
||||
bool did_enter_context_ : 1;
|
||||
bool escaped_ : 1;
|
||||
bool safe_for_termination_ : 1;
|
||||
i::InterruptsScope interrupts_scope_;
|
||||
i::Address previous_stack_height_;
|
||||
|
||||
|
@ -248,6 +248,7 @@ TEST_P(MicrotaskQueueTest, VisitRoot) {
|
||||
}
|
||||
|
||||
TEST_P(MicrotaskQueueTest, PromiseHandlerContext) {
|
||||
microtask_queue()->set_microtasks_policy(MicrotasksPolicy::kExplicit);
|
||||
Local<v8::Context> v8_context2 = v8::Context::New(v8_isolate());
|
||||
Local<v8::Context> v8_context3 = v8::Context::New(v8_isolate());
|
||||
Local<v8::Context> v8_context4 = v8::Context::New(v8_isolate());
|
||||
@ -354,6 +355,7 @@ TEST_P(MicrotaskQueueTest, DetachGlobal_Enqueue) {
|
||||
}
|
||||
|
||||
TEST_P(MicrotaskQueueTest, DetachGlobal_Run) {
|
||||
microtask_queue()->set_microtasks_policy(MicrotasksPolicy::kExplicit);
|
||||
EXPECT_EQ(0, microtask_queue()->size());
|
||||
|
||||
// Enqueue microtasks to the current context.
|
||||
@ -392,6 +394,7 @@ TEST_P(MicrotaskQueueTest, DetachGlobal_Run) {
|
||||
}
|
||||
|
||||
TEST_P(MicrotaskQueueTest, DetachGlobal_PromiseResolveThenableJobTask) {
|
||||
microtask_queue()->set_microtasks_policy(MicrotasksPolicy::kExplicit);
|
||||
RunJS(
|
||||
"var resolve;"
|
||||
"var promise = new Promise(r => { resolve = r; });"
|
||||
@ -414,6 +417,7 @@ TEST_P(MicrotaskQueueTest, DetachGlobal_PromiseResolveThenableJobTask) {
|
||||
}
|
||||
|
||||
TEST_P(MicrotaskQueueTest, DetachGlobal_ResolveThenableForeignThen) {
|
||||
microtask_queue()->set_microtasks_policy(MicrotasksPolicy::kExplicit);
|
||||
Handle<JSArray> result = RunJS<JSArray>(
|
||||
"let result = [false];"
|
||||
"result");
|
||||
@ -425,6 +429,7 @@ TEST_P(MicrotaskQueueTest, DetachGlobal_ResolveThenableForeignThen) {
|
||||
// Create a context with its own microtask queue.
|
||||
std::unique_ptr<MicrotaskQueue> sub_microtask_queue =
|
||||
MicrotaskQueue::New(isolate());
|
||||
sub_microtask_queue->set_microtasks_policy(MicrotasksPolicy::kExplicit);
|
||||
Local<v8::Context> sub_context = v8::Context::New(
|
||||
v8_isolate(),
|
||||
/* extensions= */ nullptr,
|
||||
|
Loading…
Reference in New Issue
Block a user