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/core/v8/ScriptState.h" 7 8 #include "bindings/core/v8/V8Binding.h" 9 #include "core/dom/ExecutionContext.h" 10 #include "core/frame/LocalFrame.h" 11 12 namespace blink { 13 14 PassRefPtr<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 23 static 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 30 ScriptState::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 , m_globalObjectDetached(false) 36 { 37 ASSERT(m_world); 38 m_context.setWeak(this, &weakCallback); 39 context->SetAlignedPointerInEmbedderData(v8ContextPerContextDataIndex, this); 40 } 41 42 ScriptState::~ScriptState() 43 { 44 ASSERT(!m_perContextData); 45 ASSERT(m_context.isEmpty()); 46 } 47 48 void ScriptState::detachGlobalObject() 49 { 50 ASSERT(!m_context.isEmpty()); 51 context()->DetachGlobal(); 52 m_globalObjectDetached = true; 53 } 54 55 bool ScriptState::evalEnabled() const 56 { 57 v8::HandleScope handleScope(m_isolate); 58 return context()->IsCodeGenerationFromStringsAllowed(); 59 } 60 61 void ScriptState::setEvalEnabled(bool enabled) 62 { 63 v8::HandleScope handleScope(m_isolate); 64 return context()->AllowCodeGenerationFromStrings(enabled); 65 } 66 67 ScriptValue ScriptState::getFromGlobalObject(const char* name) 68 { 69 v8::HandleScope handleScope(m_isolate); 70 v8::Local<v8::Value> v8Value = context()->Global()->Get(v8AtomicString(isolate(), name)); 71 return ScriptValue(this, v8Value); 72 } 73 74 ExecutionContext* ScriptState::executionContext() const 75 { 76 v8::HandleScope scope(m_isolate); 77 return toExecutionContext(context()); 78 } 79 80 void ScriptState::setExecutionContext(ExecutionContext*) 81 { 82 ASSERT_NOT_REACHED(); 83 } 84 85 LocalDOMWindow* ScriptState::domWindow() const 86 { 87 v8::HandleScope scope(m_isolate); 88 return toDOMWindow(context()); 89 } 90 91 ScriptState* ScriptState::forMainWorld(LocalFrame* frame) 92 { 93 v8::Isolate* isolate = toIsolate(frame); 94 v8::HandleScope handleScope(isolate); 95 return ScriptState::from(toV8Context(frame, DOMWrapperWorld::mainWorld())); 96 } 97 98 PassRefPtr<ScriptStateForTesting> ScriptStateForTesting::create(v8::Handle<v8::Context> context, PassRefPtr<DOMWrapperWorld> world) 99 { 100 RefPtr<ScriptStateForTesting> scriptState = adoptRef(new ScriptStateForTesting(context, world)); 101 // This ref() is for keeping this ScriptState alive as long as the v8::Context is alive. 102 // This is deref()ed in the weak callback of the v8::Context. 103 scriptState->ref(); 104 return scriptState; 105 } 106 107 ScriptStateForTesting::ScriptStateForTesting(v8::Handle<v8::Context> context, PassRefPtr<DOMWrapperWorld> world) 108 : ScriptState(context, world) 109 { 110 } 111 112 ExecutionContext* ScriptStateForTesting::executionContext() const 113 { 114 return m_executionContext; 115 } 116 117 void ScriptStateForTesting::setExecutionContext(ExecutionContext* executionContext) 118 { 119 m_executionContext = executionContext; 120 } 121 122 } 123