blob: 2a36dfe25a55f673a21bf9a8991a78f8bef32e66 [file] [log] [blame]
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "bindings/core/v8/ScriptState.h"
#include "bindings/core/v8/V8Binding.h"
#include "core/dom/ExecutionContext.h"
#include "core/frame/LocalDOMWindow.h"
#include "core/frame/LocalFrame.h"
namespace blink {
PassRefPtr<ScriptState> ScriptState::create(v8::Local<v8::Context> context,
PassRefPtr<DOMWrapperWorld> world) {
RefPtr<ScriptState> scriptState =
adoptRef(new ScriptState(context, std::move(world)));
// This ref() is for keeping this ScriptState alive as long as the v8::Context is alive.
// This is deref()ed in the weak callback of the v8::Context.
scriptState->ref();
return scriptState;
}
static void derefCallback(const v8::WeakCallbackInfo<ScriptState>& data) {
data.GetParameter()->deref();
}
static void weakCallback(const v8::WeakCallbackInfo<ScriptState>& data) {
data.GetParameter()->clearContext();
data.SetSecondPassCallback(derefCallback);
}
ScriptState::ScriptState(v8::Local<v8::Context> context,
PassRefPtr<DOMWrapperWorld> world)
: m_isolate(context->GetIsolate()),
m_context(m_isolate, context),
m_world(world),
m_perContextData(V8PerContextData::create(context))
#if ENABLE(ASSERT)
,
m_globalObjectDetached(false)
#endif
{
ASSERT(m_world);
m_context.setWeak(this, &weakCallback);
context->SetAlignedPointerInEmbedderData(v8ContextPerContextDataIndex, this);
}
ScriptState::~ScriptState() {
ASSERT(!m_perContextData);
ASSERT(m_context.isEmpty());
}
void ScriptState::detachGlobalObject() {
ASSERT(!m_context.isEmpty());
context()->DetachGlobal();
#if ENABLE(ASSERT)
m_globalObjectDetached = true;
#endif
}
void ScriptState::disposePerContextData() {
m_perContextData = nullptr;
}
ScriptValue ScriptState::getFromExtrasExports(const char* name) {
v8::HandleScope handleScope(m_isolate);
v8::Local<v8::Value> v8Value;
if (!context()
->GetExtrasBindingObject()
->Get(context(), v8AtomicString(isolate(), name))
.ToLocal(&v8Value))
return ScriptValue();
return ScriptValue(this, v8Value);
}
ExecutionContext* ScriptState::getExecutionContext() const {
v8::HandleScope scope(m_isolate);
return toExecutionContext(context());
}
void ScriptState::setExecutionContext(ExecutionContext*) {
ASSERT_NOT_REACHED();
}
LocalDOMWindow* ScriptState::domWindow() const {
v8::HandleScope scope(m_isolate);
return toLocalDOMWindow(toDOMWindow(context()));
}
ScriptState* ScriptState::forMainWorld(LocalFrame* frame) {
return ScriptState::forWorld(frame, DOMWrapperWorld::mainWorld());
}
ScriptState* ScriptState::forWorld(LocalFrame* frame, DOMWrapperWorld& world) {
ASSERT(frame);
v8::HandleScope handleScope(toIsolate(frame));
v8::Local<v8::Context> context = toV8Context(frame, world);
if (context.IsEmpty())
return nullptr;
ScriptState* scriptState = ScriptState::from(context);
ASSERT(scriptState->contextIsValid());
return scriptState;
}
} // namespace blink