Commit 40d01184 authored by jl's avatar jl Committed by Commit bot

Do not enter contexts implicitly

Blink uses Isolate::GetEnteredContext() to implement HTML's "entry
context" concept, and thus depends on it not being changed except
explicitly (by Blink.) To support this, stop entering contexts
implicitly in all external API entry points; rather just set the
context as current. The only thing that changes the entered context
is now Context::Enter()/Context::Exit() (and Context::Scope.)

BUG=v8:6307

Review-Url: https://codereview.chromium.org/2862483003
Cr-Commit-Position: refs/heads/master@{#45064}
parent 17a0a575
......@@ -232,17 +232,20 @@ class CallDepthScope {
i::Handle<i::Context> env = Utils::OpenHandle(*context);
i::HandleScopeImplementer* impl = isolate->handle_scope_implementer();
if (isolate->context() != nullptr &&
isolate->context()->native_context() == env->native_context() &&
impl->LastEnteredContextWas(env)) {
isolate->context()->native_context() == env->native_context()) {
context_ = Local<Context>();
} else {
context_->Enter();
impl->SaveContext(isolate->context());
isolate->set_context(*env);
}
}
if (do_callback) isolate_->FireBeforeCallEnteredCallback();
}
~CallDepthScope() {
if (!context_.IsEmpty()) context_->Exit();
if (!context_.IsEmpty()) {
i::HandleScopeImplementer* impl = isolate_->handle_scope_implementer();
isolate_->set_context(impl->RestoreContext());
}
if (!escaped_) isolate_->handle_scope_implementer()->DecrementCallDepth();
if (do_callback) isolate_->FireCallCompletedCallback();
#ifdef DEBUG
......
......@@ -26601,3 +26601,69 @@ UNINITIALIZED_TEST(AllowAtomicsWait) {
}
isolate->Dispose();
}
enum ContextId { EnteredContext, CurrentContext };
void CheckContexts(v8::Isolate* isolate) {
CHECK_EQ(CurrentContext, isolate->GetCurrentContext()
->GetEmbedderData(1)
.As<v8::Integer>()
->Value());
CHECK_EQ(EnteredContext, isolate->GetEnteredContext()
->GetEmbedderData(1)
.As<v8::Integer>()
->Value());
}
void ContextCheckGetter(Local<String> name,
const v8::PropertyCallbackInfo<v8::Value>& info) {
CheckContexts(info.GetIsolate());
info.GetReturnValue().Set(true);
}
void ContextCheckSetter(Local<String> name, Local<Value>,
const v8::PropertyCallbackInfo<void>& info) {
CheckContexts(info.GetIsolate());
}
void ContextCheckToString(const v8::FunctionCallbackInfo<v8::Value>& info) {
CheckContexts(info.GetIsolate());
info.GetReturnValue().Set(v8_str("foo"));
}
TEST(CorrectEnteredContext) {
v8::HandleScope scope(CcTest::isolate());
LocalContext currentContext;
currentContext->SetEmbedderData(
1, v8::Integer::New(currentContext->GetIsolate(), CurrentContext));
LocalContext enteredContext;
enteredContext->SetEmbedderData(
1, v8::Integer::New(enteredContext->GetIsolate(), EnteredContext));
v8::Context::Scope contextScope(enteredContext.local());
v8::Local<v8::ObjectTemplate> object_template =
ObjectTemplate::New(currentContext->GetIsolate());
object_template->SetAccessor(v8_str("p"), &ContextCheckGetter,
&ContextCheckSetter);
v8::Local<v8::Object> object =
object_template->NewInstance(currentContext.local()).ToLocalChecked();
object->Get(currentContext.local(), v8_str("p")).ToLocalChecked();
object->Set(currentContext.local(), v8_str("p"), v8_int(0)).FromJust();
v8::Local<v8::Function> to_string =
v8::Function::New(currentContext.local(), ContextCheckToString)
.ToLocalChecked();
to_string->Call(currentContext.local(), object, 0, nullptr).ToLocalChecked();
object
->CreateDataProperty(currentContext.local(), v8_str("toString"),
to_string)
.FromJust();
object->ToString(currentContext.local()).ToLocalChecked();
}
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