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