1// Copyright 2014 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "config.h"
6#include "bindings/v8/ScriptState.h"
7
8#include "bindings/v8/V8Binding.h"
9#include "core/dom/ExecutionContext.h"
10#include "core/frame/LocalFrame.h"
11
12namespace WebCore {
13
14PassRefPtr<ScriptState> ScriptState::create(v8::Handle<v8::Context> context, PassRefPtr<DOMWrapperWorld> world)
15{
16    RefPtr<ScriptState> scriptState = adoptRef(new ScriptState(context, world));
17    // This ref() is for keeping this ScriptState alive as long as the v8::Context is alive.
18    // This is deref()ed in the weak callback of the v8::Context.
19    scriptState->ref();
20    return scriptState;
21}
22
23static void weakCallback(const v8::WeakCallbackData<v8::Context, ScriptState>& data)
24{
25    data.GetValue()->SetAlignedPointerInEmbedderData(v8ContextPerContextDataIndex, 0);
26    data.GetParameter()->clearContext();
27    data.GetParameter()->deref();
28}
29
30ScriptState::ScriptState(v8::Handle<v8::Context> context, PassRefPtr<DOMWrapperWorld> world)
31    : m_isolate(context->GetIsolate())
32    , m_context(m_isolate, context)
33    , m_world(world)
34    , m_perContextData(V8PerContextData::create(context))
35{
36    ASSERT(m_world);
37    m_context.setWeak(this, &weakCallback);
38    context->SetAlignedPointerInEmbedderData(v8ContextPerContextDataIndex, this);
39}
40
41ScriptState::~ScriptState()
42{
43    ASSERT(!m_perContextData);
44    ASSERT(m_context.isEmpty());
45}
46
47bool ScriptState::evalEnabled() const
48{
49    v8::HandleScope handleScope(m_isolate);
50    return context()->IsCodeGenerationFromStringsAllowed();
51}
52
53void ScriptState::setEvalEnabled(bool enabled)
54{
55    v8::HandleScope handleScope(m_isolate);
56    return context()->AllowCodeGenerationFromStrings(enabled);
57}
58
59ScriptValue ScriptState::getFromGlobalObject(const char* name)
60{
61    v8::HandleScope handleScope(m_isolate);
62    v8::Local<v8::Value> v8Value = context()->Global()->Get(v8AtomicString(isolate(), name));
63    return ScriptValue(this, v8Value);
64}
65
66ExecutionContext* ScriptState::executionContext() const
67{
68    v8::HandleScope scope(m_isolate);
69    return toExecutionContext(context());
70}
71
72void ScriptState::setExecutionContext(ExecutionContext*)
73{
74    ASSERT_NOT_REACHED();
75}
76
77LocalDOMWindow* ScriptState::domWindow() const
78{
79    v8::HandleScope scope(m_isolate);
80    return toDOMWindow(context());
81}
82
83ScriptState* ScriptState::forMainWorld(LocalFrame* frame)
84{
85    v8::Isolate* isolate = toIsolate(frame);
86    v8::HandleScope handleScope(isolate);
87    return ScriptState::from(toV8Context(frame, DOMWrapperWorld::mainWorld()));
88}
89
90PassRefPtr<ScriptStateForTesting> ScriptStateForTesting::create(v8::Handle<v8::Context> context, PassRefPtr<DOMWrapperWorld> world)
91{
92    RefPtr<ScriptStateForTesting> scriptState = adoptRef(new ScriptStateForTesting(context, world));
93    // This ref() is for keeping this ScriptState alive as long as the v8::Context is alive.
94    // This is deref()ed in the weak callback of the v8::Context.
95    scriptState->ref();
96    return scriptState;
97}
98
99ScriptStateForTesting::ScriptStateForTesting(v8::Handle<v8::Context> context, PassRefPtr<DOMWrapperWorld> world)
100    : ScriptState(context, world)
101{
102}
103
104ExecutionContext* ScriptStateForTesting::executionContext() const
105{
106    return m_executionContext;
107}
108
109void ScriptStateForTesting::setExecutionContext(ExecutionContext* executionContext)
110{
111    m_executionContext = executionContext;
112}
113
114}
115