5de8de3b50d41746020c94f0c11f2be03be51a2d
[WebKit-https.git] / Source / WebCore / bindings / v8 / V8IsolatedContext.cpp
1 /*
2  * Copyright (C) 2009 Google Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are
6  * met:
7  *
8  *     * Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  *     * Redistributions in binary form must reproduce the above
11  * copyright notice, this list of conditions and the following disclaimer
12  * in the documentation and/or other materials provided with the
13  * distribution.
14  *     * Neither the name of Google Inc. nor the names of its
15  * contributors may be used to endorse or promote products derived from
16  * this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30
31 #include "config.h"
32
33 #include "V8IsolatedContext.h"
34
35 #include "Frame.h"
36 #include "FrameLoaderClient.h"
37 #include "InspectorInstrumentation.h"
38 #include "SecurityOrigin.h"
39 #include "V8DOMWindow.h"
40 #include "V8PerContextData.h"
41 #include "V8Proxy.h"
42 #include <wtf/StringExtras.h>
43
44 namespace WebCore {
45
46 V8IsolatedContext* V8IsolatedContext::isolatedContext()
47 {
48     return reinterpret_cast<V8IsolatedContext*>(getGlobalObject(v8::Context::GetEntered())->GetPointerFromInternalField(V8DOMWindow::enteredIsolatedWorldIndex));
49 }
50
51 void V8IsolatedContext::contextWeakReferenceCallback(v8::Persistent<v8::Value> object, void* isolatedContext)
52 {
53     // Our context is going away.  Time to clean up the world.
54     V8IsolatedContext* context = static_cast<V8IsolatedContext*>(isolatedContext);
55     delete context;
56 }
57
58 static void setInjectedScriptContextDebugId(v8::Handle<v8::Context> targetContext, int debugId)
59 {
60     char buffer[32];
61     if (debugId == -1)
62         snprintf(buffer, sizeof(buffer), "injected");
63     else
64         snprintf(buffer, sizeof(buffer), "injected,%d", debugId);
65     targetContext->SetData(v8::String::New(buffer));
66 }
67
68 V8IsolatedContext::V8IsolatedContext(V8Proxy* proxy, int extensionGroup, int worldId)
69     : m_world(DOMWrapperWorld::create(worldId)),
70       m_frame(proxy->frame())
71 {
72     v8::HandleScope scope;
73     v8::Handle<v8::Context> mainWorldContext = proxy->windowShell()->context();
74     if (mainWorldContext.IsEmpty())
75         return;
76
77     // FIXME: We should be creating a new V8DOMWindowShell here instead of riping out the context.
78     m_context = SharedPersistent<v8::Context>::create(proxy->windowShell()->createNewContext(v8::Handle<v8::Object>(), extensionGroup, m_world->worldId()));
79     if (m_context->get().IsEmpty())
80         return;
81
82     // Run code in the new context.
83     v8::Context::Scope contextScope(m_context->get());
84
85     setInjectedScriptContextDebugId(m_context->get(), ScriptController::contextDebugId(mainWorldContext));
86
87     getGlobalObject(m_context->get())->SetPointerInInternalField(V8DOMWindow::enteredIsolatedWorldIndex, this);
88
89     m_perContextData = V8PerContextData::create(m_context->get());
90     m_perContextData->init();
91
92     // FIXME: This will go away once we have a windowShell for the isolated world.
93     proxy->windowShell()->installDOMWindow(m_context->get(), m_frame->document()->domWindow());
94
95     // Using the default security token means that the canAccess is always
96     // called, which is slow.
97     // FIXME: Use tokens where possible. This will mean keeping track of all
98     //        created contexts so that they can all be updated when the
99     //        document domain
100     //        changes.
101     m_context->get()->UseDefaultSecurityToken();
102
103     m_frame->loader()->client()->didCreateScriptContext(context(), extensionGroup, m_world->worldId());
104 }
105
106 void V8IsolatedContext::destroy()
107 {
108     m_perContextData.clear();
109     m_frame->loader()->client()->willReleaseScriptContext(context(), m_world->worldId());
110     m_context->get().MakeWeak(this, &contextWeakReferenceCallback);
111     m_frame = 0;
112 }
113
114 V8IsolatedContext::~V8IsolatedContext()
115 {
116     m_context->disposeHandle();
117 }
118
119 void V8IsolatedContext::setSecurityOrigin(PassRefPtr<SecurityOrigin> securityOrigin)
120 {
121     if (!m_securityOrigin && InspectorInstrumentation::hasFrontends() && !context().IsEmpty()) {
122         v8::HandleScope handleScope;
123         ScriptState* scriptState = ScriptState::forContext(v8::Local<v8::Context>::New(context()));
124         InspectorInstrumentation::didCreateIsolatedContext(m_frame, scriptState, securityOrigin.get());
125     }
126     m_securityOrigin = securityOrigin;
127 }
128
129 } // namespace WebCore