15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/*
25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2008, 2009 Google Inc. All rights reserved.
35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2009 Apple Inc. All rights reserved.
45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Redistribution and use in source and binary forms, with or without
65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * modification, are permitted provided that the following conditions are
75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * met:
85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *     * Redistributions of source code must retain the above copyright
105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * notice, this list of conditions and the following disclaimer.
115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *     * Redistributions in binary form must reproduce the above
125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * copyright notice, this list of conditions and the following disclaimer
135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * in the documentation and/or other materials provided with the
145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * distribution.
155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *     * Neither the name of Google Inc. nor the names of its
165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * contributors may be used to endorse or promote products derived from
175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * this software without specific prior written permission.
185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */
315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "config.h"
3353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "bindings/v8/ScriptController.h"
3453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "V8Event.h"
3653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "V8HTMLElement.h"
37521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)#include "V8Window.h"
38e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)#include "bindings/v8/BindingSecurity.h"
3953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "bindings/v8/NPV8Object.h"
4053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "bindings/v8/ScriptCallStackFactory.h"
4153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "bindings/v8/ScriptSourceCode.h"
4253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "bindings/v8/ScriptValue.h"
4353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "bindings/v8/V8Binding.h"
4453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "bindings/v8/V8GCController.h"
4553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "bindings/v8/V8HiddenPropertyName.h"
4653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "bindings/v8/V8NPObject.h"
4753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "bindings/v8/V8PerContextData.h"
4853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "bindings/v8/V8ScriptRunner.h"
49521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)#include "bindings/v8/V8WindowShell.h"
5053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "bindings/v8/npruntime_impl.h"
5153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "bindings/v8/npruntime_priv.h"
5253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/dom/Document.h"
5353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/dom/Event.h"
5453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/dom/EventListener.h"
5553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/dom/EventNames.h"
5653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/dom/Node.h"
5753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/dom/ScriptableDocumentParser.h"
5853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/dom/UserGestureIndicator.h"
5953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/html/HTMLPlugInElement.h"
6053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/inspector/InspectorInstrumentation.h"
6153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/inspector/ScriptCallStack.h"
6253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/loader/DocumentLoader.h"
6353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/loader/FrameLoader.h"
6453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/loader/FrameLoaderClient.h"
6553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/page/ContentSecurityPolicy.h"
6653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/page/DOMWindow.h"
6753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/page/Frame.h"
6853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/page/Page.h"
6953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/page/Settings.h"
7053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/platform/HistogramSupport.h"
7153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/platform/NotImplemented.h"
7253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/platform/Widget.h"
7353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/platform/chromium/TraceEvent.h"
7453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/plugins/PluginView.h"
75e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)#include "weborigin/SecurityOrigin.h"
7653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "wtf/CurrentTime.h"
7753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "wtf/StdLibExtras.h"
7853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "wtf/StringExtras.h"
7953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "wtf/text/CString.h"
8053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "wtf/text/StringBuilder.h"
8153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "wtf/text/TextPosition.h"
825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)namespace WebCore {
845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool ScriptController::canAccessFromCurrentOrigin(Frame *frame)
865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
8781a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)    return !v8::Context::InContext() || BindingSecurity::shouldAllowAccessToFrame(frame);
885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)ScriptController::ScriptController(Frame* frame)
915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    : m_frame(frame)
925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    , m_sourceURL(0)
93926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    , m_isolate(v8::Isolate::GetCurrent())
94521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    , m_windowShell(V8WindowShell::create(frame, mainThreadNormalWorld(), m_isolate))
955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    , m_paused(false)
96591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    , m_windowScriptNPObject(0)
975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)ScriptController::~ScriptController()
1015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
102926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    clearForClose(true);
1035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void ScriptController::clearScriptObjects()
1065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
107e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch    PluginObjectMap::iterator it = m_pluginObjects.begin();
108e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch    for (; it != m_pluginObjects.end(); ++it) {
109e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch        _NPN_UnregisterObject(it->value);
110e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch        _NPN_ReleaseObject(it->value);
111e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch    }
112e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch    m_pluginObjects.clear();
113e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch
114591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    if (m_windowScriptNPObject) {
115591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch        // Dispose of the underlying V8 object before releasing our reference
116591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch        // to it, so that if a plugin fails to release it properly we will
117591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch        // only leak the NPObject wrapper, not the object, its document, or
118591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch        // anything else they reference.
119591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch        disposeUnderlyingV8Object(m_windowScriptNPObject);
120591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch        _NPN_ReleaseObject(m_windowScriptNPObject);
121591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch        m_windowScriptNPObject = 0;
1225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
125926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)void ScriptController::clearForOutOfMemory()
1265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
127926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    clearForClose(true);
1285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
130926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)void ScriptController::clearForClose(bool destroyGlobal)
1315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
132926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    m_windowShell->clearForClose(destroyGlobal);
133926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    for (IsolatedWorldMap::iterator iter = m_isolatedWorlds.begin(); iter != m_isolatedWorlds.end(); ++iter)
134926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        iter->value->clearForClose(destroyGlobal);
135926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    V8GCController::hintForCollectGarbage();
1365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void ScriptController::clearForClose()
1395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    double start = currentTime();
141926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    clearForClose(false);
1425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    HistogramSupport::histogramCustomCounts("WebCore.ScriptController.clearForClose", (currentTime() - start) * 1000, 0, 10000, 50);
1435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void ScriptController::updateSecurityOrigin()
1465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_windowShell->updateSecurityOrigin();
1485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool ScriptController::processingUserGesture()
1515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return UserGestureIndicator::processingUserGesture();
1535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)v8::Local<v8::Value> ScriptController::callFunction(v8::Handle<v8::Function> function, v8::Handle<v8::Object> receiver, int argc, v8::Handle<v8::Value> args[])
1565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Keep Frame (and therefore ScriptController) alive.
1585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RefPtr<Frame> protect(m_frame);
1595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return ScriptController::callFunctionWithInstrumentation(m_frame ? m_frame->document() : 0, function, receiver, argc, args);
1605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
16293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)ScriptValue ScriptController::callFunctionEvenIfScriptDisabled(v8::Handle<v8::Function> function, v8::Handle<v8::Object> receiver, int argc, v8::Handle<v8::Value> argv[])
16393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){
16493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    // FIXME: This should probably perform the same isPaused check that happens in ScriptController::executeScript.
16593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    return ScriptValue(callFunction(function, receiver, argc, argv));
16693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)}
16793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
16893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)static void resourceInfo(const v8::Handle<v8::Function> function, String& resourceName, int& lineNumber)
1695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    v8::ScriptOrigin origin = function->GetScriptOrigin();
1715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (origin.ResourceName().IsEmpty()) {
1725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        resourceName = "undefined";
1735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        lineNumber = 1;
1745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    } else {
1755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        resourceName = toWebCoreString(origin.ResourceName());
1765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        lineNumber = function->GetScriptLineNumber() + 1;
1775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
18093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)static String resourceString(const v8::Handle<v8::Function> function)
1815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    String resourceName;
1835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    int lineNumber;
1845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    resourceInfo(function, resourceName, lineNumber);
1855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    StringBuilder builder;
1875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    builder.append(resourceName);
1885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    builder.append(':');
1895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    builder.appendNumber(lineNumber);
1905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return builder.toString();
1915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)v8::Local<v8::Value> ScriptController::callFunctionWithInstrumentation(ScriptExecutionContext* context, v8::Handle<v8::Function> function, v8::Handle<v8::Object> receiver, int argc, v8::Handle<v8::Value> args[])
1945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    InspectorInstrumentationCookie cookie;
1965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (InspectorInstrumentation::timelineAgentEnabled(context)) {
1975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        String resourceName;
1985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        int lineNumber;
1995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        resourceInfo(function, resourceName, lineNumber);
2005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        cookie = InspectorInstrumentation::willCallFunction(context, resourceName, lineNumber);
2015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
20393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    v8::Local<v8::Value> result = V8ScriptRunner::callFunction(function, context, receiver, argc, args);
2045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    InspectorInstrumentation::didCallFunction(cookie);
2065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return result;
2075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
20923e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdochv8::Local<v8::Value> ScriptController::compileAndRunScript(const ScriptSourceCode& source, AccessControlStatus corsStatus)
2105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(v8::Context::InContext());
2125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    InspectorInstrumentationCookie cookie = InspectorInstrumentation::willEvaluateScript(m_frame, source.url().isNull() ? String() : source.url().string(), source.startLine());
2145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    v8::Local<v8::Value> result;
2165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
2175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Isolate exceptions that occur when compiling and executing
2185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // the code. These exceptions should not interfere with
2195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // javascript code we might evaluate from C++ when returning
2205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // from here.
2215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        v8::TryCatch tryCatch;
2225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        tryCatch.SetVerbose(true);
2235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
224926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        v8::Handle<v8::String> code = v8String(source.source(), m_isolate);
225e6d4491e48613634a83c1957c72759da80987961Ben Murdoch        OwnPtr<v8::ScriptData> scriptData = V8ScriptRunner::precompileScript(code, source.resource());
2265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // NOTE: For compatibility with WebCore, ScriptSourceCode's line starts at
2285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // 1, whereas v8 starts at 0.
22923e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch        v8::Handle<v8::Script> script = V8ScriptRunner::compileScript(code, source.url(), source.startPosition(), scriptData.get(), m_isolate, corsStatus);
2305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Keep Frame (and therefore ScriptController) alive.
2325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        RefPtr<Frame> protect(m_frame);
23353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        result = V8ScriptRunner::runCompiledScript(script, m_frame->document());
2345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        ASSERT(!tryCatch.HasCaught() || result.IsEmpty());
2355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    InspectorInstrumentation::didEvaluateScript(cookie);
2385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return result;
2405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool ScriptController::initializeMainWorld()
2435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (m_windowShell->isContextInitialized())
2455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return false;
2465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return windowShell(mainThreadNormalWorld())->isContextInitialized();
2475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
249521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)V8WindowShell* ScriptController::existingWindowShell(DOMWrapperWorld* world)
2505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(world);
2525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (world->isMainWorld())
2545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return m_windowShell->isContextInitialized() ? m_windowShell.get() : 0;
2555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // FIXME: Remove this block. See comment with existingWindowShellWorkaroundWorld().
25753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (world == existingWindowShellWorkaroundWorld())
2585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return m_windowShell.get();
2595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    IsolatedWorldMap::iterator iter = m_isolatedWorlds.find(world->worldId());
2615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (iter == m_isolatedWorlds.end())
2625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return 0;
263926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    return iter->value->isContextInitialized() ? iter->value.get() : 0;
2645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
266521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)V8WindowShell* ScriptController::windowShell(DOMWrapperWorld* world)
2675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(world);
2695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
270521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    V8WindowShell* shell = 0;
2715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (world->isMainWorld())
2725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        shell = m_windowShell.get();
2735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    else {
2745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        IsolatedWorldMap::iterator iter = m_isolatedWorlds.find(world->worldId());
2755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (iter != m_isolatedWorlds.end())
276926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            shell = iter->value.get();
2775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        else {
278521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)            OwnPtr<V8WindowShell> isolatedWorldShell = V8WindowShell::create(m_frame, world, m_isolate);
2795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            shell = isolatedWorldShell.get();
280926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            m_isolatedWorlds.set(world->worldId(), isolatedWorldShell.release());
2815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
2825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!shell->isContextInitialized() && shell->initializeIfNeeded()) {
2845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (world->isMainWorld()) {
2855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // FIXME: Remove this if clause. See comment with existingWindowShellWorkaroundWorld().
2865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            m_frame->loader()->dispatchDidClearWindowObjectInWorld(existingWindowShellWorkaroundWorld());
2875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        } else
2885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            m_frame->loader()->dispatchDidClearWindowObjectInWorld(world);
2895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return shell;
2915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool ScriptController::shouldBypassMainWorldContentSecurityPolicy()
2945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
295926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (DOMWrapperWorld* world = isolatedWorldForEnteredContext())
296926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        return world->isolatedWorldHasContentSecurityPolicy();
2975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return false;
2985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)TextPosition ScriptController::eventHandlerPosition() const
3015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
3025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ScriptableDocumentParser* parser = m_frame->document()->scriptableDocumentParser();
3035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (parser)
3045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return parser->textPosition();
3055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return TextPosition::minimumPosition();
3065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
308926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)static inline v8::Local<v8::Context> contextForWorld(ScriptController* scriptController, DOMWrapperWorld* world)
309926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){
31053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    return scriptController->windowShell(world)->context();
311926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}
312926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
3135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)v8::Local<v8::Context> ScriptController::currentWorldContext()
3145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
315926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (!v8::Context::InContext())
316926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        return contextForWorld(this, mainThreadNormalWorld());
317926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
318926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    v8::Handle<v8::Context> context = v8::Context::GetEntered();
319926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    DOMWrapperWorld* isolatedWorld = DOMWrapperWorld::isolatedWorld(context);
320926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (!isolatedWorld)
321926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        return contextForWorld(this, mainThreadNormalWorld());
322926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
323926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    Frame* frame = toFrameIfNotDetached(context);
324926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (!m_frame)
325926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        return v8::Local<v8::Context>();
326926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
327926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (m_frame == frame)
3285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return v8::Local<v8::Context>::New(context);
329926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
330926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    return contextForWorld(this, isolatedWorld);
3315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)v8::Local<v8::Context> ScriptController::mainWorldContext()
3345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
335926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    return contextForWorld(this, mainThreadNormalWorld());
3365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)v8::Local<v8::Context> ScriptController::mainWorldContext(Frame* frame)
3395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
3405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!frame)
3415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return v8::Local<v8::Context>();
3425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
343926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    return contextForWorld(frame->script(), mainThreadNormalWorld());
3445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// Create a V8 object with an interceptor of NPObjectPropertyGetter.
3475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void ScriptController::bindToWindowObject(Frame* frame, const String& key, NPObject* object)
3485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
3493464d02a173573db42f8ee6bb07bb74fabf4f5f2Ben Murdoch    v8::HandleScope handleScope(m_isolate);
3505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    v8::Handle<v8::Context> v8Context = ScriptController::mainWorldContext(frame);
3525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (v8Context.IsEmpty())
3535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
3545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    v8::Context::Scope scope(v8Context);
3565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
357e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch    v8::Handle<v8::Object> value = createV8ObjectForNPObject(object, 0);
3585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Attach to the global object.
3605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    v8::Handle<v8::Object> global = v8Context->Global();
3613464d02a173573db42f8ee6bb07bb74fabf4f5f2Ben Murdoch    global->Set(v8String(key, m_isolate), value);
3625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void ScriptController::enableEval()
3655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
3665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!m_windowShell->isContextInitialized())
3675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
3683464d02a173573db42f8ee6bb07bb74fabf4f5f2Ben Murdoch    v8::HandleScope handleScope(m_isolate);
3695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_windowShell->context()->AllowCodeGenerationFromStrings(true);
3705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void ScriptController::disableEval(const String& errorMessage)
3735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
3745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!m_windowShell->isContextInitialized())
3755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
3763464d02a173573db42f8ee6bb07bb74fabf4f5f2Ben Murdoch    v8::HandleScope handleScope(m_isolate);
37753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    v8::Local<v8::Context> v8Context = m_windowShell->context();
3785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    v8Context->AllowCodeGenerationFromStrings(false);
3793464d02a173573db42f8ee6bb07bb74fabf4f5f2Ben Murdoch    v8Context->SetErrorMessageForCodeGenerationFromStrings(v8String(errorMessage, m_isolate));
3805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)PassScriptInstance ScriptController::createScriptInstanceForWidget(Widget* widget)
3835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
3845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(widget);
3855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
38653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (!widget->isPluginView())
3875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return 0;
3885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
38953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    NPObject* npObject = toPluginView(widget)->scriptableObject();
3905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!npObject)
3915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return 0;
3925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Frame Memory Management for NPObjects
3945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // -------------------------------------
3955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // NPObjects are treated differently than other objects wrapped by JS.
3965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // NPObjects can be created either by the browser (e.g. the main
3975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // window object) or by the plugin (the main plugin object
3985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // for a HTMLEmbedElement). Further, unlike most DOM Objects, the frame
3995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // is especially careful to ensure NPObjects terminate at frame teardown because
4005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // if a plugin leaks a reference, it could leak its objects (or the browser's objects).
4015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    //
4025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // The Frame maintains a list of plugin objects (m_pluginObjects)
4035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // which it can use to quickly find the wrapped embed object.
4045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    //
4055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Inside the NPRuntime, we've added a few methods for registering
4065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // wrapped NPObjects. The purpose of the registration is because
4075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // javascript garbage collection is non-deterministic, yet we need to
4085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // be able to tear down the plugin objects immediately. When an object
4095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // is registered, javascript can use it. When the object is destroyed,
4105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // or when the object's "owning" object is destroyed, the object will
4115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // be un-registered, and the javascript engine must not use it.
4125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    //
4135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Inside the javascript engine, the engine can keep a reference to the
4145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // NPObject as part of its wrapper. However, before accessing the object
4155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // it must consult the _NPN_Registry.
4165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
417e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch    v8::Local<v8::Object> wrapper = createV8ObjectForNPObject(npObject, 0);
4185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
419e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch    // Track the plugin object. We've been given a reference to the object.
420e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch    m_pluginObjects.set(widget, npObject);
4215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return V8ScriptInstance::create(wrapper);
4235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
4245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
425e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdochvoid ScriptController::cleanupScriptObjectsForPlugin(Widget* nativeHandle)
4265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
427e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch    PluginObjectMap::iterator it = m_pluginObjects.find(nativeHandle);
428e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch    if (it == m_pluginObjects.end())
4295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
430e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch    _NPN_UnregisterObject(it->value);
431e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch    _NPN_ReleaseObject(it->value);
432e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch    m_pluginObjects.remove(it);
4335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
4345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)V8Extensions& ScriptController::registeredExtensions()
4365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
4375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    DEFINE_STATIC_LOCAL(V8Extensions, extensions, ());
4385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return extensions;
4395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
4405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void ScriptController::registerExtensionIfNeeded(v8::Extension* extension)
4425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
4435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    const V8Extensions& extensions = registeredExtensions();
4445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (size_t i = 0; i < extensions.size(); ++i) {
4455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (extensions[i] == extension)
4465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return;
4475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
4485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    v8::RegisterExtension(extension);
4495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    registeredExtensions().append(extension);
4505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
4515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static NPObject* createNoScriptObject()
4535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
4545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    notImplemented();
4555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return 0;
4565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
4575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
458e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdochstatic NPObject* createScriptObject(Frame* frame)
4595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
4605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    v8::HandleScope handleScope;
461e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch    v8::Handle<v8::Context> v8Context = ScriptController::mainWorldContext(frame);
4625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (v8Context.IsEmpty())
4635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return createNoScriptObject();
4645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    v8::Context::Scope scope(v8Context);
4667757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    DOMWindow* window = frame->domWindow();
467926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    v8::Handle<v8::Value> global = toV8(window, v8::Handle<v8::Object>(), v8Context->GetIsolate());
4685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(global->IsObject());
469591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch
470e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch    return npCreateV8ScriptObject(0, v8::Handle<v8::Object>::Cast(global), window);
4715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
4725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)NPObject* ScriptController::windowScriptNPObject()
4745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
475591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    if (m_windowScriptNPObject)
476591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch        return m_windowScriptNPObject;
4775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (canExecuteScripts(NotAboutToExecuteScript)) {
4795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // JavaScript is enabled, so there is a JavaScript window object.
4805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Return an NPObject bound to the window object.
481e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch        m_windowScriptNPObject = createScriptObject(m_frame);
482e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch        _NPN_RegisterObject(m_windowScriptNPObject, 0);
4835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    } else {
4845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // JavaScript is not enabled, so we cannot bind the NPObject to the
4855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // JavaScript window object. Instead, we create an NPObject of a
4865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // different class, one which is not bound to a JavaScript object.
487591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch        m_windowScriptNPObject = createNoScriptObject();
4885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
489591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    return m_windowScriptNPObject;
490591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch}
4915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)NPObject* ScriptController::createScriptObjectForPluginElement(HTMLPlugInElement* plugin)
4935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
4945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Can't create NPObjects when JavaScript is disabled.
4955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!canExecuteScripts(NotAboutToExecuteScript))
4965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return createNoScriptObject();
4975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    v8::HandleScope handleScope;
4995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    v8::Handle<v8::Context> v8Context = ScriptController::mainWorldContext(m_frame);
5005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (v8Context.IsEmpty())
5015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return createNoScriptObject();
5025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    v8::Context::Scope scope(v8Context);
5035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5047757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    DOMWindow* window = m_frame->domWindow();
50553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    v8::Handle<v8::Value> v8plugin = toV8(plugin, v8::Handle<v8::Object>(), v8Context->GetIsolate());
5065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!v8plugin->IsObject())
5075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return createNoScriptObject();
5085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
509e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch    return npCreateV8ScriptObject(0, v8::Handle<v8::Object>::Cast(v8plugin), window);
5105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
5115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
51253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)void ScriptController::clearWindowShell()
5135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
5145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    double start = currentTime();
5155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // V8 binding expects ScriptController::clearWindowShell only be called
5165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // when a frame is loading a new page. This creates a new context for the new page.
5175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_windowShell->clearForNavigation();
518926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    for (IsolatedWorldMap::iterator iter = m_isolatedWorlds.begin(); iter != m_isolatedWorlds.end(); ++iter)
519926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        iter->value->clearForNavigation();
520926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    V8GCController::hintForCollectGarbage();
5215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    HistogramSupport::histogramCustomCounts("WebCore.ScriptController.clearWindowShell", (currentTime() - start) * 1000, 0, 10000, 50);
5225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
5235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void ScriptController::setCaptureCallStackForUncaughtExceptions(bool value)
5255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
5265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    v8::V8::SetCaptureStackTraceForUncaughtExceptions(value, ScriptCallStack::maxCallStackSizeToCapture, stackTraceOptions);
5275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
5285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void ScriptController::collectIsolatedContexts(Vector<std::pair<ScriptState*, SecurityOrigin*> >& result)
5305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
5315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    v8::HandleScope handleScope;
5325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (IsolatedWorldMap::iterator it = m_isolatedWorlds.begin(); it != m_isolatedWorlds.end(); ++it) {
533521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        V8WindowShell* isolatedWorldShell = it->value.get();
5345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        SecurityOrigin* origin = isolatedWorldShell->world()->isolatedWorldSecurityOrigin();
5355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (!origin)
5365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            continue;
53753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        v8::Local<v8::Context> v8Context = isolatedWorldShell->context();
5385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (v8Context.IsEmpty())
5395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            continue;
54053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        ScriptState* scriptState = ScriptState::forContext(v8Context);
5415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        result.append(std::pair<ScriptState*, SecurityOrigin*>(scriptState, origin));
5425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
5435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
5445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool ScriptController::setContextDebugId(int debugId)
5465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
5475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(debugId > 0);
5485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!m_windowShell->isContextInitialized())
5495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return false;
5505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    v8::HandleScope scope;
55153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    v8::Local<v8::Context> context = m_windowShell->context();
55253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    return V8PerContextDebugData::setContextDebugData(context, "page", debugId);
5535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
5545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)int ScriptController::contextDebugId(v8::Handle<v8::Context> context)
5565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
55753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    return V8PerContextDebugData::contextDebugId(context);
5585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
5595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void ScriptController::updateDocument()
5615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
5625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // For an uninitialized main window shell, do not incur the cost of context initialization during FrameLoader::init().
5635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if ((!m_windowShell->isContextInitialized() || !m_windowShell->isGlobalInitialized()) && m_frame->loader()->stateMachine()->creatingInitialEmptyDocument())
5645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
5655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!initializeMainWorld())
5675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        windowShell(mainThreadNormalWorld())->updateDocument();
5685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
5695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void ScriptController::namedItemAdded(HTMLDocument* doc, const AtomicString& name)
5715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
5725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    windowShell(mainThreadNormalWorld())->namedItemAdded(doc, name);
5735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
5745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void ScriptController::namedItemRemoved(HTMLDocument* doc, const AtomicString& name)
5765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
5775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    windowShell(mainThreadNormalWorld())->namedItemRemoved(doc, name);
5785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
5795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
58053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)bool ScriptController::canExecuteScripts(ReasonForCallingCanExecuteScripts reason)
58153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
58253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (m_frame->document() && m_frame->document()->isSandboxed(SandboxScripts)) {
58353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        // FIXME: This message should be moved off the console once a solution to https://bugs.webkit.org/show_bug.cgi?id=103274 exists.
58453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        if (reason == AboutToExecuteScript)
58553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            m_frame->document()->addConsoleMessage(SecurityMessageSource, ErrorMessageLevel, "Blocked script execution in '" + m_frame->document()->url().elidedString() + "' because the document's frame is sandboxed and the 'allow-scripts' permission is not set.");
58653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return false;
58753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    }
58853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
58953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (m_frame->document() && m_frame->document()->isViewSource()) {
59053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        ASSERT(m_frame->document()->securityOrigin()->isUnique());
59153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return true;
59253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    }
59353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
59453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    Settings* settings = m_frame->settings();
59553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    const bool allowed = m_frame->loader()->client()->allowScript(settings && settings->isScriptEnabled());
59653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (!allowed && reason == AboutToExecuteScript)
59753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        m_frame->loader()->client()->didNotAllowScript();
59853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    return allowed;
59953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
60053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
60153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)ScriptValue ScriptController::executeScript(const String& script, bool forceUserGesture)
60253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
60353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    UserGestureIndicator gestureIndicator(forceUserGesture ? DefinitelyProcessingNewUserGesture : PossiblyProcessingUserGesture);
60453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    return executeScript(ScriptSourceCode(script, m_frame->document()->url()));
60553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
60653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
60753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)ScriptValue ScriptController::executeScript(const ScriptSourceCode& sourceCode)
60853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
60953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (!canExecuteScripts(AboutToExecuteScript) || isPaused())
61053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return ScriptValue();
61153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
61253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    RefPtr<Frame> protect(m_frame); // Script execution can destroy the frame, and thus the ScriptController.
61353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
61493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    return executeScriptInMainWorld(sourceCode);
61553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
61653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
61793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)bool ScriptController::executeScriptIfJavaScriptURL(const KURL& url)
61853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
61953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (!protocolIsJavaScript(url))
62053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return false;
62153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
62253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (!m_frame->page()
62353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        || !m_frame->document()->contentSecurityPolicy()->allowJavaScriptURLs(m_frame->document()->url(), eventHandlerPosition().m_line))
62453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return true;
62553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
62653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    // We need to hold onto the Frame here because executing script can
62753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    // destroy the frame.
62853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    RefPtr<Frame> protector(m_frame);
62953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    RefPtr<Document> ownerDocument(m_frame->document());
63053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
63153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    const int javascriptSchemeLength = sizeof("javascript:") - 1;
63253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
6335267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    bool locationChangeBefore = m_frame->navigationScheduler()->locationChangePending();
6345267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
63553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    String decodedURL = decodeURLEscapeSequences(url.string());
63653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    ScriptValue result = executeScript(decodedURL.substring(javascriptSchemeLength));
63753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
63853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    // If executing script caused this frame to be removed from the page, we
63953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    // don't want to try to replace its document!
64053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (!m_frame->page())
64153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return true;
64253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
64353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    String scriptResult;
64453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (!result.getString(scriptResult))
64553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return true;
64653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
64781a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)    // We're still in a frame, so there should be a DocumentLoader.
64881a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)    ASSERT(m_frame->document()->loader());
6495267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
6505267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    if (!locationChangeBefore && m_frame->navigationScheduler()->locationChangePending())
6515267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        return true;
65202772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
65381a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)    // DocumentWriter::replaceDocument can cause the DocumentLoader to get deref'ed and possible destroyed,
65481a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)    // so protect it with a RefPtr.
65581a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)    if (RefPtr<DocumentLoader> loader = m_frame->document()->loader())
656591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch        loader->replaceDocument(scriptResult, ownerDocument.get());
65753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    return true;
65853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
65953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
66023e46e0f045bc1935a09565578b448d36cfc5b8cBen MurdochScriptValue ScriptController::executeScriptInMainWorld(const ScriptSourceCode& sourceCode, AccessControlStatus corsStatus)
66193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){
66293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    String sourceURL = sourceCode.url();
66393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    const String* savedSourceURL = m_sourceURL;
66493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    m_sourceURL = &sourceURL;
66593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
66693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    v8::HandleScope handleScope;
66793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    v8::Handle<v8::Context> v8Context = ScriptController::mainWorldContext(m_frame);
66893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    if (v8Context.IsEmpty())
66993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        return ScriptValue();
67093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
67193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    RefPtr<Frame> protect(m_frame);
672e6d4491e48613634a83c1957c72759da80987961Ben Murdoch    if (m_frame->loader()->stateMachine()->isDisplayingInitialEmptyDocument())
673e6d4491e48613634a83c1957c72759da80987961Ben Murdoch        m_frame->loader()->didAccessInitialDocument();
674e6d4491e48613634a83c1957c72759da80987961Ben Murdoch
675e6d4491e48613634a83c1957c72759da80987961Ben Murdoch    v8::Context::Scope scope(v8Context);
67623e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch    v8::Local<v8::Value> object = compileAndRunScript(sourceCode, corsStatus);
67793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
67893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    m_sourceURL = savedSourceURL;
67993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
68093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    if (object.IsEmpty())
68193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        return ScriptValue();
68293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
68393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    return ScriptValue(object);
68493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)}
68593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
68693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)void ScriptController::executeScriptInIsolatedWorld(int worldID, const Vector<ScriptSourceCode>& sources, int extensionGroup, Vector<ScriptValue>* results)
68793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){
68893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    ASSERT(worldID > 0);
68993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
69093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    v8::HandleScope handleScope;
69193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    v8::Local<v8::Array> v8Results;
69293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    {
69393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        v8::HandleScope evaluateHandleScope;
69493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        RefPtr<DOMWrapperWorld> world = DOMWrapperWorld::ensureIsolatedWorld(worldID, extensionGroup);
695521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        V8WindowShell* isolatedWorldShell = windowShell(world.get());
69693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
69793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        if (!isolatedWorldShell->isContextInitialized())
69893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)            return;
69993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
70093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        v8::Local<v8::Context> context = isolatedWorldShell->context();
70193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        v8::Context::Scope contextScope(context);
70293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        v8::Local<v8::Array> resultArray = v8::Array::New(sources.size());
70393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
70493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        for (size_t i = 0; i < sources.size(); ++i) {
70593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)            v8::Local<v8::Value> evaluationResult = compileAndRunScript(sources[i]);
70693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)            if (evaluationResult.IsEmpty())
70793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)                evaluationResult = v8::Local<v8::Value>::New(v8::Undefined());
70893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)            resultArray->Set(i, evaluationResult);
70993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        }
71093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
71193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        v8Results = evaluateHandleScope.Close(resultArray);
71293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    }
71393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
71493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    if (results && !v8Results.IsEmpty()) {
71593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        for (size_t i = 0; i < v8Results->Length(); ++i)
71693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)            results->append(ScriptValue(v8Results->Get(i)));
71793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    }
71893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)}
71993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
7205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} // namespace WebCore
721