Changeset 49963 in webkit


Ignore:
Timestamp:
Oct 22, 2009 9:33:56 PM (14 years ago)
Author:
barraclough@apple.com
Message:

WebCore: https://bugs.webkit.org/show_bug.cgi?id=30696
Add support for IsolatedWorlds to JSC bindings.

Patch by Gavin Barraclough <barraclough@apple.com> on 2009-10-16
Reviewed by Sam Weinig & Geoff Garen.

An IsolatedWorld is basically a parallel, separate copy of the window shells and DOM wrapper objects for
a given document. To support isolation this patch:

  • Adds support to the ScriptController to track multiple window shells, one per world.
  • Adds support to Document to support multiple separate wrapper-maps, one per world.
  • Replaces the single global DOM wrapper map (on the WebCoreJSClientData) with separate maps, stored on the (new) IsolatedWorld objects.

In addition to supporting separate copies of these objects, two other features are supported:

  • It is necessary to track the current world on entry into JSC, so that within callbacks out to WebCore we can determine which world (and as such, set of DOM bindings) we should be operating on.
  • EventListeners & Callbacks are run in the world they were registered in. This requires the handler to retain a reference to the world.

No new tests. (Enabled existing isolated world layout tests.)

  • WebCore.base.exp:
  • bindings/js/JSAbstractWorkerCustom.cpp:

(WebCore::JSAbstractWorker::addEventListener):
(WebCore::JSAbstractWorker::removeEventListener):

  • bindings/js/JSCallbackData.cpp:

(WebCore::JSCallbackData::invokeCallback):

  • bindings/js/JSCallbackData.h:

(WebCore::JSCallbackData::JSCallbackData):

  • bindings/js/JSCustomXPathNSResolver.cpp:

(WebCore::JSCustomXPathNSResolver::lookupNamespaceURI):

  • bindings/js/JSDOMApplicationCacheCustom.cpp:

(WebCore::JSDOMApplicationCache::addEventListener):
(WebCore::JSDOMApplicationCache::removeEventListener):

  • bindings/js/JSDOMBinding.cpp:

(WebCore::removeWrappers):
(WebCore::DOMObjectWrapperMap::get):
(WebCore::DOMObjectWrapperMap::set):
(WebCore::DOMObjectWrapperMap::remove):
(WebCore::DOMObjectWrapperMap::take):
(WebCore::IsolatedWorld::IsolatedWorld):
(WebCore::IsolatedWorld::~IsolatedWorld):
(WebCore::EnterIsolatedWorld::EnterIsolatedWorld):
(WebCore::EnterIsolatedWorld::~EnterIsolatedWorld):
(WebCore::JSGlobalDataWorldIterator::JSGlobalDataWorldIterator):
(WebCore::JSGlobalDataWorldIterator::operator bool):
(WebCore::JSGlobalDataWorldIterator::operator*):
(WebCore::JSGlobalDataWorldIterator::operator->):
(WebCore::JSGlobalDataWorldIterator::operator++):
(WebCore::getCurrentWorld):
(WebCore::getNormalWorld):
(WebCore::commonNormalWorld):
(WebCore::commonCurrentWorld):
(WebCore::DOMObjectHashTableMap::mapFor):
(WebCore::DOMObjectWrapperMap::mapFor):
(WebCore::forgetDOMObject):
(WebCore::getCachedDOMNodeWrapper):
(WebCore::forgetDOMNode):
(WebCore::cacheDOMNodeWrapper):
(WebCore::forgetAllDOMNodesForDocument):
(WebCore::forgetWorldOfDOMNodesForDocument):
(WebCore::isObservableThroughDOM):
(WebCore::markDOMNodesForDocument):
(WebCore::markActiveObjectsForContext):
(WebCore::takeWrappers):
(WebCore::updateDOMNodeDocument):
(WebCore::markDOMObjectWrapper):
(WebCore::allowsAccessFromFrame):
(WebCore::printErrorMessageForFrame):
(WebCore::JSC_DebuggerCallFrame_evaluateInWorld):
(WebCore::JSC_callInWorld):
(WebCore::JSC_constructInWorld):
(WebCore::JSC_evaluateInWorld):

  • bindings/js/JSDOMBinding.h:

(WebCore::IsolatedWorld::rememberDocument):
(WebCore::IsolatedWorld::forgetDocument):
(WebCore::IsolatedWorld::rememberScriptController):
(WebCore::IsolatedWorld::forgetScriptController):
(WebCore::DOMObjectHashTableMap::~DOMObjectHashTableMap):
(WebCore::DOMObjectHashTableMap::get):
(WebCore::WebCoreJSClientData::WebCoreJSClientData):
(WebCore::WebCoreJSClientData::currentWorld):
(WebCore::WebCoreJSClientData::normalWorld):
(WebCore::WebCoreJSClientData::rememberWorld):
(WebCore::WebCoreJSClientData::forgetWorld):
(WebCore::debuggerWorld):
(WebCore::pluginWorld):

  • bindings/js/JSDOMGlobalObject.cpp:

(WebCore::JSDOMGlobalObject::createJSAttributeEventListener):
(WebCore::toJSDOMGlobalObject):

  • bindings/js/JSDOMGlobalObject.h:
  • bindings/js/JSDOMWindowBase.cpp:

(WebCore::JSDOMWindowBase::printErrorMessage):
(WebCore::JSDOMWindowBase::commonJSGlobalData):
(WebCore::toJS):
(WebCore::toJSDOMWindow):

  • bindings/js/JSDOMWindowBase.h:
  • bindings/js/JSDOMWindowCustom.cpp:

(WebCore::createWindow):
(WebCore::JSDOMWindow::open):
(WebCore::JSDOMWindow::showModalDialog):
(WebCore::JSDOMWindow::setTimeout):
(WebCore::JSDOMWindow::setInterval):
(WebCore::JSDOMWindow::addEventListener):
(WebCore::JSDOMWindow::removeEventListener):

  • bindings/js/JSDOMWindowShell.cpp:

(WebCore::toJS):
(WebCore::toJSDOMWindowShell):

  • bindings/js/JSDOMWindowShell.h:
  • bindings/js/JSDesktopNotificationsCustom.cpp:

(WebCore::JSNotification::addEventListener):
(WebCore::):

  • bindings/js/JSEventListener.cpp:

(WebCore::JSEventListener::JSEventListener):
(WebCore::JSEventListener::handleEvent):
(WebCore::JSEventListener::reportError):

  • bindings/js/JSEventListener.h:

(WebCore::JSEventListener::create):

  • bindings/js/JSEventSourceCustom.cpp:

(WebCore::JSEventSource::addEventListener):
(WebCore::JSEventSource::removeEventListener):

  • bindings/js/JSEventTarget.cpp:

(WebCore::toJS):

  • bindings/js/JSHTMLDocumentCustom.cpp:

(WebCore::JSHTMLDocument::open):

  • bindings/js/JSHTMLFrameSetElementCustom.cpp:

(WebCore::JSHTMLFrameSetElement::nameGetter):

  • bindings/js/JSInspectorBackendCustom.cpp:

(WebCore::JSInspectorBackend::databaseForId):
(WebCore::JSInspectorBackend::inspectedWindow):
(WebCore::JSInspectorBackend::nodeForId):

  • bindings/js/JSLazyEventListener.cpp:

(WebCore::JSLazyEventListener::JSLazyEventListener):
(WebCore::JSLazyEventListener::parseCode):

  • bindings/js/JSLazyEventListener.h:

(WebCore::JSLazyEventListener::create):

  • bindings/js/JSMessageChannelCustom.cpp:

(WebCore::JSMessageChannel::markChildren):

  • bindings/js/JSMessagePortCustom.cpp:

(WebCore::JSMessagePort::markChildren):
(WebCore::JSMessagePort::addEventListener):
(WebCore::JSMessagePort::removeEventListener):

  • bindings/js/JSNodeCustom.cpp:

(WebCore::JSNode::addEventListener):
(WebCore::JSNode::removeEventListener):
(WebCore::JSNode::markChildren):

  • bindings/js/JSNodeFilterCondition.cpp:

(WebCore::JSNodeFilterCondition::acceptNode):

  • bindings/js/JSQuarantinedObjectWrapper.cpp:

(WebCore::JSQuarantinedObjectWrapper::construct):
(WebCore::JSQuarantinedObjectWrapper::call):

  • bindings/js/JSSVGElementInstanceCustom.cpp:

(WebCore::JSSVGElementInstance::addEventListener):
(WebCore::JSSVGElementInstance::removeEventListener):

  • bindings/js/JSSharedWorkerCustom.cpp:

(WebCore::JSSharedWorker::markChildren):

  • bindings/js/JSWebSocketCustom.cpp:

(WebCore::JSWebSocket::addEventListener):
(WebCore::JSWebSocket::removeEventListener):

  • bindings/js/JSWorkerContextCustom.cpp:

(WebCore::JSWorkerContext::addEventListener):
(WebCore::JSWorkerContext::removeEventListener):
(WebCore::JSWorkerContext::setTimeout):
(WebCore::JSWorkerContext::setInterval):

  • bindings/js/JSXMLHttpRequestConstructor.cpp:

(WebCore::constructXMLHttpRequest):

  • bindings/js/JSXMLHttpRequestCustom.cpp:

(WebCore::JSXMLHttpRequest::markChildren):
(WebCore::JSXMLHttpRequest::addEventListener):
(WebCore::JSXMLHttpRequest::removeEventListener):

  • bindings/js/JSXMLHttpRequestUploadCustom.cpp:

(WebCore::JSXMLHttpRequestUpload::markChildren):
(WebCore::JSXMLHttpRequestUpload::addEventListener):
(WebCore::JSXMLHttpRequestUpload::removeEventListener):

  • bindings/js/ScheduledAction.cpp:

(WebCore::ScheduledAction::create):
(WebCore::ScheduledAction::ScheduledAction):
(WebCore::ScheduledAction::executeFunctionInContext):
(WebCore::ScheduledAction::execute):

  • bindings/js/ScheduledAction.h:

(WebCore::ScheduledAction::ScheduledAction):

  • bindings/js/ScriptCachedFrameData.cpp:

(WebCore::ScriptCachedFrameData::ScriptCachedFrameData):
(WebCore::ScriptCachedFrameData::restore):

  • bindings/js/ScriptController.cpp:

(WebCore::ScriptController::~ScriptController):
(WebCore::ScriptController::evaluateInWorld):
(WebCore::ScriptController::evaluate):
(WebCore::ScriptController::evaluateInIsolatedWorld):
(WebCore::ScriptController::clearWindowShell):
(WebCore::ScriptController::initScript):
(WebCore::ScriptController::processingUserGestureEvent):
(WebCore::ScriptController::attachDebugger):
(WebCore::ScriptController::updateDocument):
(WebCore::ScriptController::bindingRootObject):
(WebCore::ScriptController::createRootObject):
(WebCore::ScriptController::windowScriptNPObject):
(WebCore::ScriptController::jsObjectForPluginElement):

  • bindings/js/ScriptController.h:

(WebCore::ScriptController::windowShell):
(WebCore::ScriptController::existingWindowShell):
(WebCore::ScriptController::globalObject):
(WebCore::ScriptController::forgetWorld):

  • bindings/js/ScriptControllerMac.mm:

(WebCore::ScriptController::windowScriptObject):

  • bindings/js/ScriptEventListener.cpp:

(WebCore::createAttributeEventListener):

  • bindings/js/ScriptFunctionCall.cpp:

(WebCore::ScriptFunctionCall::call):
(WebCore::ScriptFunctionCall::construct):

  • bindings/js/ScriptObjectQuarantine.cpp:

(WebCore::getQuarantinedScriptObject):

  • bindings/js/ScriptState.cpp:

(WebCore::scriptStateFromNode):
(WebCore::scriptStateFromPage):

  • bindings/js/ScriptState.h:
  • bindings/js/WorkerScriptController.cpp:

(WebCore::WorkerScriptController::WorkerScriptController):
(WebCore::WorkerScriptController::evaluate):

  • bindings/objc/DOMInternal.mm:

(-[WebScriptObject _initializeScriptDOMNodeImp]):

  • bindings/objc/WebScriptObject.mm:

(-[WebScriptObject callWebScriptMethod:withArguments:]):
(-[WebScriptObject evaluateWebScript:]):

  • bindings/scripts/CodeGeneratorJS.pm:
  • bridge/NP_jsobject.cpp:

(_NPN_InvokeDefault):
(_NPN_Invoke):
(_NPN_Evaluate):
(_NPN_Construct):

  • bridge/jni/jni_jsobject.mm:

(JavaJSObject::call):
(JavaJSObject::eval):

  • dom/Document.cpp:

(WebCore::Document::createWrapperCache):

  • dom/Document.h:

(WebCore::Document::wrapperCacheMap):
(WebCore::Document::getWrapperCache):

  • inspector/InspectorController.cpp:

(WebCore::InspectorController::startUserInitiatedProfiling):
(WebCore::InspectorController::stopUserInitiatedProfiling):

  • inspector/JavaScriptCallFrame.cpp:

(WebCore::JavaScriptCallFrame::evaluate):

  • loader/FrameLoader.cpp:

(WebCore::FrameLoader::dispatchWindowObjectAvailable):

  • platform/network/mac/AuthenticationMac.mm:
  • xml/XMLHttpRequest.cpp:

(WebCore::XMLHttpRequest::XMLHttpRequest):
(WebCore::XMLHttpRequest::dropProtection):

  • xml/XMLHttpRequest.h:

(WebCore::XMLHttpRequest::create):

WebKit/mac: https://bugs.webkit.org/show_bug.cgi?id=30696
Update to incorporate support for IsolatedWorlds in JSC bindings.

Patch by Gavin Barraclough <barraclough@apple.com> on 2009-10-16
Reviewed by Sam Weinig & Geoff Garen.

  • WebView/WebFrame.mm:

(-[WebFrame _attachScriptDebugger]):
(-[WebFrame _stringByEvaluatingJavaScriptFromString:forceUserGesture:]):
(-[WebFrame globalContext]):

  • WebView/WebScriptDebugDelegate.mm:

(-[WebScriptCallFrame evaluateWebScript:]):

  • WebView/WebView.mm:

(-[WebView aeDescByEvaluatingJavaScriptFromString:]):

WebKit/win: https://bugs.webkit.org/show_bug.cgi?id=30696
Update to incorporate support for IsolatedWorlds in JSC bindings.

Patch by Gavin Barraclough <barraclough@apple.com> on 2009-10-22
Reviewed by Sam Weinig & Geoff Garen.

  • Interfaces/IWebFramePrivate.idl:
  • WebFrame.cpp:

(WebFrame::globalContext):
(WebFrame::windowObjectCleared):
(WebFrame::stringByEvaluatingJavaScriptInIsolatedWorld):

  • WebFrame.h:

WebKitTools: https://bugs.webkit.org/show_bug.cgi?id=30696
Enable isolated-worlds tests on mac.

Patch by Gavin Barraclough <barraclough@apple.com> on 2009-10-22
Reviewed by Sam Weinig & Geoff Garen.

Add private interface for DRT to invoke execution in a given world.

  • DumpRenderTree/LayoutTestController.cpp:

(evaluateScriptInIsolatedWorldCallback):
(LayoutTestController::staticFunctions):

  • DumpRenderTree/LayoutTestController.h:
  • DumpRenderTree/mac/LayoutTestControllerMac.mm:

(LayoutTestController::evaluateScriptInIsolatedWorld):

  • DumpRenderTree/win/LayoutTestControllerWin.cpp:

(LayoutTestController::evaluateScriptInIsolatedWorld):

LayoutTests: https://bugs.webkit.org/show_bug.cgi?id=30696
Enable isolated-worlds tests on mac.

  • Update the results to switch from windows to unix line-endings.
  • Update all-window-prototypes.html to allow for properties on the global object with null prototypes (just skip over them).

Patch by Gavin Barraclough <barraclough@apple.com> on 2009-10-19
Reviewed by Sam Weinig & Geoff Garen.

  • http/tests/security/isolatedWorld/all-window-properties-expected.txt:
  • http/tests/security/isolatedWorld/all-window-prototypes-expected.txt:
  • http/tests/security/isolatedWorld/all-window-prototypes.html:
  • http/tests/security/isolatedWorld/body-properties-expected.txt:
  • http/tests/security/isolatedWorld/body-prototype-expected.txt:
  • http/tests/security/isolatedWorld/document-properties-expected.txt:
  • http/tests/security/isolatedWorld/document-prototype-expected.txt:
  • http/tests/security/isolatedWorld/global-variables-expected.txt:
  • http/tests/security/isolatedWorld/image-properties-expected.txt:
  • http/tests/security/isolatedWorld/image-prototype-expected.txt:
  • http/tests/security/isolatedWorld/location-properties-expected.txt:
  • http/tests/security/isolatedWorld/location-prototype-expected.txt:
  • http/tests/security/isolatedWorld/number-prototype-expected.txt:
  • http/tests/security/isolatedWorld/object-prototype-expected.txt:
  • http/tests/security/isolatedWorld/storage-properties-expected.txt:
  • http/tests/security/isolatedWorld/storage-prototype-expected.txt:
  • http/tests/security/isolatedWorld/string-prototype-expected.txt:
  • http/tests/security/isolatedWorld/window-properties-expected.txt:
  • platform/mac/Skipped:
Location:
trunk
Files:
83 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r49961 r49963  
     12009-10-19  Gavin Barraclough  <barraclough@apple.com>
     2
     3        Reviewed by Sam Weinig & Geoff Garen.
     4
     5        https://bugs.webkit.org/show_bug.cgi?id=30696
     6        Enable isolated-worlds tests on mac.
     7          * Update the results to switch from windows to unix line-endings.
     8          * Update all-window-prototypes.html to allow for properties on
     9            the global object with null prototypes (just skip over them).
     10
     11        * http/tests/security/isolatedWorld/all-window-properties-expected.txt:
     12        * http/tests/security/isolatedWorld/all-window-prototypes-expected.txt:
     13        * http/tests/security/isolatedWorld/all-window-prototypes.html:
     14        * http/tests/security/isolatedWorld/body-properties-expected.txt:
     15        * http/tests/security/isolatedWorld/body-prototype-expected.txt:
     16        * http/tests/security/isolatedWorld/document-properties-expected.txt:
     17        * http/tests/security/isolatedWorld/document-prototype-expected.txt:
     18        * http/tests/security/isolatedWorld/global-variables-expected.txt:
     19        * http/tests/security/isolatedWorld/image-properties-expected.txt:
     20        * http/tests/security/isolatedWorld/image-prototype-expected.txt:
     21        * http/tests/security/isolatedWorld/location-properties-expected.txt:
     22        * http/tests/security/isolatedWorld/location-prototype-expected.txt:
     23        * http/tests/security/isolatedWorld/number-prototype-expected.txt:
     24        * http/tests/security/isolatedWorld/object-prototype-expected.txt:
     25        * http/tests/security/isolatedWorld/storage-properties-expected.txt:
     26        * http/tests/security/isolatedWorld/storage-prototype-expected.txt:
     27        * http/tests/security/isolatedWorld/string-prototype-expected.txt:
     28        * http/tests/security/isolatedWorld/window-properties-expected.txt:
     29        * platform/mac/Skipped:
     30
    1312009-10-22  Brian Weinstein  <bweinstein@apple.com>
    232
  • trunk/LayoutTests/http/tests/security/isolatedWorld/all-window-prototypes.html

    r49321 r49963  
    66for (p in window) {
    77  var obj = window[p];
    8   if (obj)
    9     obj.__proto__.foo = "FAIL: Visible in isolated world.";
     8  if (obj) {
     9    var proto = obj.__proto__;
     10    if (proto)
     11      proto.foo = "FAIL: Visible in isolated world.";
     12  }
    1013}
    1114
  • trunk/LayoutTests/platform/mac/Skipped

    r49749 r49963  
    7171media/video-error-abort.html
    7272
    73 # This port doesn't support isolated worlds yet.
    74 http/tests/security/isolatedWorld/all-window-properties.html
    75 http/tests/security/isolatedWorld/all-window-prototypes.html
    76 http/tests/security/isolatedWorld/body-properties.html
    77 http/tests/security/isolatedWorld/body-prototype.html
    78 http/tests/security/isolatedWorld/click-event.html
    79 http/tests/security/isolatedWorld/document-open.html
    80 http/tests/security/isolatedWorld/document-properties.html
    81 http/tests/security/isolatedWorld/document-prototype.html
    82 http/tests/security/isolatedWorld/global-variables.html
    83 http/tests/security/isolatedWorld/image-properties.html
    84 http/tests/security/isolatedWorld/image-prototype.html
    85 http/tests/security/isolatedWorld/location-properties.html
    86 http/tests/security/isolatedWorld/location-prototype.html
    87 http/tests/security/isolatedWorld/window-setTimeout-function.html
    88 http/tests/security/isolatedWorld/window-setTimeout-string.html
    89 http/tests/security/isolatedWorld/storage-properties.html
    90 http/tests/security/isolatedWorld/storage-prototype.html
    91 http/tests/security/isolatedWorld/number-prototype.html
    92 http/tests/security/isolatedWorld/object-prototype.html
    93 http/tests/security/isolatedWorld/string-prototype.html
    94 http/tests/security/isolatedWorld/window-properties.html
    95 http/tests/security/isolatedWorld/world-reuse.html
    96 
    9773# New test with questionable results
    9874# See https://bugs.webkit.org/show_bug.cgi?id=28079 for explanation.
  • trunk/WebCore/ChangeLog

    r49962 r49963  
     12009-10-16  Gavin Barraclough  <barraclough@apple.com>
     2
     3        Reviewed by Sam Weinig & Geoff Garen.
     4
     5        https://bugs.webkit.org/show_bug.cgi?id=30696
     6        Add support for IsolatedWorlds to JSC bindings.
     7
     8        An IsolatedWorld is basically a parallel, separate copy of the window shells and DOM wrapper objects for
     9        a given document.  To support isolation this patch:
     10
     11            * Adds support to the ScriptController to track multiple window shells, one per world.
     12            * Adds support to Document to support multiple separate wrapper-maps, one per world.
     13            * Replaces the single global DOM wrapper map (on the WebCoreJSClientData) with separate maps,
     14              stored on the (new) IsolatedWorld objects.
     15
     16        In addition to supporting separate copies of these objects, two other features are supported:
     17
     18            * It is necessary to track the current world on entry into JSC, so that within callbacks out to WebCore
     19              we can determine which world (and as such, set of DOM bindings) we should be operating on.
     20            * EventListeners & Callbacks are run in the world they were registered in.
     21              This requires the handler to retain a reference to the world.
     22
     23        No new tests. (Enabled existing isolated world layout tests.)
     24
     25        * WebCore.base.exp:
     26        * bindings/js/JSAbstractWorkerCustom.cpp:
     27        (WebCore::JSAbstractWorker::addEventListener):
     28        (WebCore::JSAbstractWorker::removeEventListener):
     29        * bindings/js/JSCallbackData.cpp:
     30        (WebCore::JSCallbackData::invokeCallback):
     31        * bindings/js/JSCallbackData.h:
     32        (WebCore::JSCallbackData::JSCallbackData):
     33        * bindings/js/JSCustomXPathNSResolver.cpp:
     34        (WebCore::JSCustomXPathNSResolver::lookupNamespaceURI):
     35        * bindings/js/JSDOMApplicationCacheCustom.cpp:
     36        (WebCore::JSDOMApplicationCache::addEventListener):
     37        (WebCore::JSDOMApplicationCache::removeEventListener):
     38        * bindings/js/JSDOMBinding.cpp:
     39        (WebCore::removeWrappers):
     40        (WebCore::DOMObjectWrapperMap::get):
     41        (WebCore::DOMObjectWrapperMap::set):
     42        (WebCore::DOMObjectWrapperMap::remove):
     43        (WebCore::DOMObjectWrapperMap::take):
     44        (WebCore::IsolatedWorld::IsolatedWorld):
     45        (WebCore::IsolatedWorld::~IsolatedWorld):
     46        (WebCore::EnterIsolatedWorld::EnterIsolatedWorld):
     47        (WebCore::EnterIsolatedWorld::~EnterIsolatedWorld):
     48        (WebCore::JSGlobalDataWorldIterator::JSGlobalDataWorldIterator):
     49        (WebCore::JSGlobalDataWorldIterator::operator bool):
     50        (WebCore::JSGlobalDataWorldIterator::operator*):
     51        (WebCore::JSGlobalDataWorldIterator::operator->):
     52        (WebCore::JSGlobalDataWorldIterator::operator++):
     53        (WebCore::getCurrentWorld):
     54        (WebCore::getNormalWorld):
     55        (WebCore::commonNormalWorld):
     56        (WebCore::commonCurrentWorld):
     57        (WebCore::DOMObjectHashTableMap::mapFor):
     58        (WebCore::DOMObjectWrapperMap::mapFor):
     59        (WebCore::forgetDOMObject):
     60        (WebCore::getCachedDOMNodeWrapper):
     61        (WebCore::forgetDOMNode):
     62        (WebCore::cacheDOMNodeWrapper):
     63        (WebCore::forgetAllDOMNodesForDocument):
     64        (WebCore::forgetWorldOfDOMNodesForDocument):
     65        (WebCore::isObservableThroughDOM):
     66        (WebCore::markDOMNodesForDocument):
     67        (WebCore::markActiveObjectsForContext):
     68        (WebCore::takeWrappers):
     69        (WebCore::updateDOMNodeDocument):
     70        (WebCore::markDOMObjectWrapper):
     71        (WebCore::allowsAccessFromFrame):
     72        (WebCore::printErrorMessageForFrame):
     73        (WebCore::JSC_DebuggerCallFrame_evaluateInWorld):
     74        (WebCore::JSC_callInWorld):
     75        (WebCore::JSC_constructInWorld):
     76        (WebCore::JSC_evaluateInWorld):
     77        * bindings/js/JSDOMBinding.h:
     78        (WebCore::IsolatedWorld::rememberDocument):
     79        (WebCore::IsolatedWorld::forgetDocument):
     80        (WebCore::IsolatedWorld::rememberScriptController):
     81        (WebCore::IsolatedWorld::forgetScriptController):
     82        (WebCore::DOMObjectHashTableMap::~DOMObjectHashTableMap):
     83        (WebCore::DOMObjectHashTableMap::get):
     84        (WebCore::WebCoreJSClientData::WebCoreJSClientData):
     85        (WebCore::WebCoreJSClientData::currentWorld):
     86        (WebCore::WebCoreJSClientData::normalWorld):
     87        (WebCore::WebCoreJSClientData::rememberWorld):
     88        (WebCore::WebCoreJSClientData::forgetWorld):
     89        (WebCore::debuggerWorld):
     90        (WebCore::pluginWorld):
     91        * bindings/js/JSDOMGlobalObject.cpp:
     92        (WebCore::JSDOMGlobalObject::createJSAttributeEventListener):
     93        (WebCore::toJSDOMGlobalObject):
     94        * bindings/js/JSDOMGlobalObject.h:
     95        * bindings/js/JSDOMWindowBase.cpp:
     96        (WebCore::JSDOMWindowBase::printErrorMessage):
     97        (WebCore::JSDOMWindowBase::commonJSGlobalData):
     98        (WebCore::toJS):
     99        (WebCore::toJSDOMWindow):
     100        * bindings/js/JSDOMWindowBase.h:
     101        * bindings/js/JSDOMWindowCustom.cpp:
     102        (WebCore::createWindow):
     103        (WebCore::JSDOMWindow::open):
     104        (WebCore::JSDOMWindow::showModalDialog):
     105        (WebCore::JSDOMWindow::setTimeout):
     106        (WebCore::JSDOMWindow::setInterval):
     107        (WebCore::JSDOMWindow::addEventListener):
     108        (WebCore::JSDOMWindow::removeEventListener):
     109        * bindings/js/JSDOMWindowShell.cpp:
     110        (WebCore::toJS):
     111        (WebCore::toJSDOMWindowShell):
     112        * bindings/js/JSDOMWindowShell.h:
     113        * bindings/js/JSDesktopNotificationsCustom.cpp:
     114        (WebCore::JSNotification::addEventListener):
     115        (WebCore::):
     116        * bindings/js/JSEventListener.cpp:
     117        (WebCore::JSEventListener::JSEventListener):
     118        (WebCore::JSEventListener::handleEvent):
     119        (WebCore::JSEventListener::reportError):
     120        * bindings/js/JSEventListener.h:
     121        (WebCore::JSEventListener::create):
     122        * bindings/js/JSEventSourceCustom.cpp:
     123        (WebCore::JSEventSource::addEventListener):
     124        (WebCore::JSEventSource::removeEventListener):
     125        * bindings/js/JSEventTarget.cpp:
     126        (WebCore::toJS):
     127        * bindings/js/JSHTMLDocumentCustom.cpp:
     128        (WebCore::JSHTMLDocument::open):
     129        * bindings/js/JSHTMLFrameSetElementCustom.cpp:
     130        (WebCore::JSHTMLFrameSetElement::nameGetter):
     131        * bindings/js/JSInspectorBackendCustom.cpp:
     132        (WebCore::JSInspectorBackend::databaseForId):
     133        (WebCore::JSInspectorBackend::inspectedWindow):
     134        (WebCore::JSInspectorBackend::nodeForId):
     135        * bindings/js/JSLazyEventListener.cpp:
     136        (WebCore::JSLazyEventListener::JSLazyEventListener):
     137        (WebCore::JSLazyEventListener::parseCode):
     138        * bindings/js/JSLazyEventListener.h:
     139        (WebCore::JSLazyEventListener::create):
     140        * bindings/js/JSMessageChannelCustom.cpp:
     141        (WebCore::JSMessageChannel::markChildren):
     142        * bindings/js/JSMessagePortCustom.cpp:
     143        (WebCore::JSMessagePort::markChildren):
     144        (WebCore::JSMessagePort::addEventListener):
     145        (WebCore::JSMessagePort::removeEventListener):
     146        * bindings/js/JSNodeCustom.cpp:
     147        (WebCore::JSNode::addEventListener):
     148        (WebCore::JSNode::removeEventListener):
     149        (WebCore::JSNode::markChildren):
     150        * bindings/js/JSNodeFilterCondition.cpp:
     151        (WebCore::JSNodeFilterCondition::acceptNode):
     152        * bindings/js/JSQuarantinedObjectWrapper.cpp:
     153        (WebCore::JSQuarantinedObjectWrapper::construct):
     154        (WebCore::JSQuarantinedObjectWrapper::call):
     155        * bindings/js/JSSVGElementInstanceCustom.cpp:
     156        (WebCore::JSSVGElementInstance::addEventListener):
     157        (WebCore::JSSVGElementInstance::removeEventListener):
     158        * bindings/js/JSSharedWorkerCustom.cpp:
     159        (WebCore::JSSharedWorker::markChildren):
     160        * bindings/js/JSWebSocketCustom.cpp:
     161        (WebCore::JSWebSocket::addEventListener):
     162        (WebCore::JSWebSocket::removeEventListener):
     163        * bindings/js/JSWorkerContextCustom.cpp:
     164        (WebCore::JSWorkerContext::addEventListener):
     165        (WebCore::JSWorkerContext::removeEventListener):
     166        (WebCore::JSWorkerContext::setTimeout):
     167        (WebCore::JSWorkerContext::setInterval):
     168        * bindings/js/JSXMLHttpRequestConstructor.cpp:
     169        (WebCore::constructXMLHttpRequest):
     170        * bindings/js/JSXMLHttpRequestCustom.cpp:
     171        (WebCore::JSXMLHttpRequest::markChildren):
     172        (WebCore::JSXMLHttpRequest::addEventListener):
     173        (WebCore::JSXMLHttpRequest::removeEventListener):
     174        * bindings/js/JSXMLHttpRequestUploadCustom.cpp:
     175        (WebCore::JSXMLHttpRequestUpload::markChildren):
     176        (WebCore::JSXMLHttpRequestUpload::addEventListener):
     177        (WebCore::JSXMLHttpRequestUpload::removeEventListener):
     178        * bindings/js/ScheduledAction.cpp:
     179        (WebCore::ScheduledAction::create):
     180        (WebCore::ScheduledAction::ScheduledAction):
     181        (WebCore::ScheduledAction::executeFunctionInContext):
     182        (WebCore::ScheduledAction::execute):
     183        * bindings/js/ScheduledAction.h:
     184        (WebCore::ScheduledAction::ScheduledAction):
     185        * bindings/js/ScriptCachedFrameData.cpp:
     186        (WebCore::ScriptCachedFrameData::ScriptCachedFrameData):
     187        (WebCore::ScriptCachedFrameData::restore):
     188        * bindings/js/ScriptController.cpp:
     189        (WebCore::ScriptController::~ScriptController):
     190        (WebCore::ScriptController::evaluateInWorld):
     191        (WebCore::ScriptController::evaluate):
     192        (WebCore::ScriptController::evaluateInIsolatedWorld):
     193        (WebCore::ScriptController::clearWindowShell):
     194        (WebCore::ScriptController::initScript):
     195        (WebCore::ScriptController::processingUserGestureEvent):
     196        (WebCore::ScriptController::attachDebugger):
     197        (WebCore::ScriptController::updateDocument):
     198        (WebCore::ScriptController::bindingRootObject):
     199        (WebCore::ScriptController::createRootObject):
     200        (WebCore::ScriptController::windowScriptNPObject):
     201        (WebCore::ScriptController::jsObjectForPluginElement):
     202        * bindings/js/ScriptController.h:
     203        (WebCore::ScriptController::windowShell):
     204        (WebCore::ScriptController::existingWindowShell):
     205        (WebCore::ScriptController::globalObject):
     206        (WebCore::ScriptController::forgetWorld):
     207        * bindings/js/ScriptControllerMac.mm:
     208        (WebCore::ScriptController::windowScriptObject):
     209        * bindings/js/ScriptEventListener.cpp:
     210        (WebCore::createAttributeEventListener):
     211        * bindings/js/ScriptFunctionCall.cpp:
     212        (WebCore::ScriptFunctionCall::call):
     213        (WebCore::ScriptFunctionCall::construct):
     214        * bindings/js/ScriptObjectQuarantine.cpp:
     215        (WebCore::getQuarantinedScriptObject):
     216        * bindings/js/ScriptState.cpp:
     217        (WebCore::scriptStateFromNode):
     218        (WebCore::scriptStateFromPage):
     219        * bindings/js/ScriptState.h:
     220        * bindings/js/WorkerScriptController.cpp:
     221        (WebCore::WorkerScriptController::WorkerScriptController):
     222        (WebCore::WorkerScriptController::evaluate):
     223        * bindings/objc/DOMInternal.mm:
     224        (-[WebScriptObject _initializeScriptDOMNodeImp]):
     225        * bindings/objc/WebScriptObject.mm:
     226        (-[WebScriptObject callWebScriptMethod:withArguments:]):
     227        (-[WebScriptObject evaluateWebScript:]):
     228        * bindings/scripts/CodeGeneratorJS.pm:
     229        * bridge/NP_jsobject.cpp:
     230        (_NPN_InvokeDefault):
     231        (_NPN_Invoke):
     232        (_NPN_Evaluate):
     233        (_NPN_Construct):
     234        * bridge/jni/jni_jsobject.mm:
     235        (JavaJSObject::call):
     236        (JavaJSObject::eval):
     237        * dom/Document.cpp:
     238        (WebCore::Document::createWrapperCache):
     239        * dom/Document.h:
     240        (WebCore::Document::wrapperCacheMap):
     241        (WebCore::Document::getWrapperCache):
     242        * inspector/InspectorController.cpp:
     243        (WebCore::InspectorController::startUserInitiatedProfiling):
     244        (WebCore::InspectorController::stopUserInitiatedProfiling):
     245        * inspector/JavaScriptCallFrame.cpp:
     246        (WebCore::JavaScriptCallFrame::evaluate):
     247        * loader/FrameLoader.cpp:
     248        (WebCore::FrameLoader::dispatchWindowObjectAvailable):
     249        * platform/network/mac/AuthenticationMac.mm:
     250        * xml/XMLHttpRequest.cpp:
     251        (WebCore::XMLHttpRequest::XMLHttpRequest):
     252        (WebCore::XMLHttpRequest::dropProtection):
     253        * xml/XMLHttpRequest.h:
     254        (WebCore::XMLHttpRequest::create):
     255
    12562009-10-22  Joseph Pecoraro  <joepeck@webkit.org>
    2257
  • trunk/WebCore/WebCore.base.exp

    r49843 r49963  
    273273__ZN7WebCore13TypingCommand39insertParagraphSeparatorInQuotedContentEPNS_8DocumentE
    274274__ZN7WebCore13toDeviceSpaceERKNS_9FloatRectEP8NSWindow
    275 __ZN7WebCore13toJSDOMWindowEPNS_5FrameE
    276275__ZN7WebCore14CachedResource12removeClientEPNS_20CachedResourceClientE
    277276__ZN7WebCore14CachedResource9addClientEPNS_20CachedResourceClientE
     
    371370__ZN7WebCore16NavigationActionC1ERKNS_4KURLENS_14NavigationTypeE
    372371__ZN7WebCore16NavigationActionC1Ev
    373 __ZN7WebCore16ScriptController10initScriptEv
     372__ZN7WebCore16ScriptController10initScriptEPNS_15DOMWrapperWorldE
    374373__ZN7WebCore16ScriptController13executeScriptERKNS_6StringEb
    375374__ZN7WebCore16ScriptController18windowScriptObjectEv
     375__ZN7WebCore16ScriptController28executeScriptInIsolatedWorldEjRKNS_6StringEb
    376376__ZN7WebCore16VisibleSelectionC1EPKNS_5RangeENS_9EAffinityE
    377377__ZN7WebCore16VisibleSelectionC1ERKNS_15VisiblePositionES3_
     
    387387__ZN7WebCore17HistoryController26saveDocumentAndScrollStateEv
    388388__ZN7WebCore17HTMLPlugInElement11getNPObjectEv
     389__ZN7WebCore21mainThreadNormalWorldEv
    389390__ZN7WebCore17equalIgnoringCaseEPNS_10StringImplES1_
    390391__ZN7WebCore18deprecatedParseURLERKNS_6StringE
     
    455456__ZN7WebCore33setDefaultThreadViolationBehaviorENS_23ThreadViolationBehaviorENS_20ThreadViolationRoundE
    456457__ZN7WebCore36InitializeLoggingChannelsIfNecessaryEv
     458__ZN7WebCore33DebuggerCallFrame_evaluateInWorldERKN3JSC17DebuggerCallFrameERKNS0_7UStringERNS0_7JSValueE
    457459__ZN7WebCore3macERKNS_10CredentialE
    458460__ZN7WebCore3macERKNS_23AuthenticationChallengeE
  • trunk/WebCore/bindings/ScriptControllerBase.cpp

    r49434 r49963  
    5454}
    5555
     56ScriptValue ScriptController::executeScriptInIsolatedWorld(unsigned worldID, const String& script, bool forceUserGesture)
     57{
     58    ScriptSourceCode sourceCode(script, forceUserGesture ? KURL() : m_frame->loader()->url());
     59
     60    if (!isEnabled() || isPaused())
     61        return ScriptValue();
     62
     63    bool wasInExecuteScript = m_inExecuteScript;
     64    m_inExecuteScript = true;
     65
     66    ScriptValue result = evaluateInIsolatedWorld(worldID, sourceCode);
     67
     68    if (!wasInExecuteScript) {
     69        m_inExecuteScript = false;
     70        Document::updateStyleForAllDocuments();
     71    }
     72
     73    return result;
     74}
     75
     76ScriptValue ScriptController::executeScriptInIsolatedWorld(DOMWrapperWorld* world, const String& script, bool forceUserGesture)
     77{
     78    ScriptSourceCode sourceCode(script, forceUserGesture ? KURL() : m_frame->loader()->url());
     79
     80    if (!isEnabled() || isPaused())
     81        return ScriptValue();
     82
     83    bool wasInExecuteScript = m_inExecuteScript;
     84    m_inExecuteScript = true;
     85
     86    ScriptValue result = evaluateInWorld(sourceCode, world);
     87
     88    if (!wasInExecuteScript) {
     89        m_inExecuteScript = false;
     90        Document::updateStyleForAllDocuments();
     91    }
     92
     93    return result;
     94}
     95
    5696bool ScriptController::executeIfJavaScriptURL(const KURL& url, bool userGesture, bool replaceDocument)
    5797{
  • trunk/WebCore/bindings/js/JSAbstractWorkerCustom.cpp

    r49539 r49963  
    5151        return jsUndefined();
    5252
    53     impl()->addEventListener(args.at(0).toString(exec), JSEventListener::create(asObject(listener), false), args.at(2).toBoolean(exec));
     53    impl()->addEventListener(args.at(0).toString(exec), JSEventListener::create(asObject(listener), false, currentWorld(exec)), args.at(2).toBoolean(exec));
    5454    return jsUndefined();
    5555}
     
    6161        return jsUndefined();
    6262
    63     impl()->removeEventListener(args.at(0).toString(exec), JSEventListener::create(asObject(listener), false).get(), args.at(2).toBoolean(exec));
     63    impl()->removeEventListener(args.at(0).toString(exec), JSEventListener::create(asObject(listener), false, currentWorld(exec)).get(), args.at(2).toBoolean(exec));
    6464    return jsUndefined();
    6565}
  • trunk/WebCore/bindings/js/JSCallbackData.cpp

    r49280 r49963  
    4949    ExecState* exec = globalObject()->globalExec();
    5050   
    51     JSValue function = callback()->get(exec, Identifier(exec, "handleEvent"));
     51    JSValue function;
     52    {
     53        // Switch worlds, just in case handleEvent is a getter and causes JS execution!
     54        EnterDOMWrapperWorld worldEntry(exec, m_isolatedWorld.get());
     55        function = callback()->get(exec, Identifier(exec, "handleEvent"));
     56    }
    5257    CallData callData;
    5358    CallType callType = function.getCallData(callData);
     
    6065   
    6166    globalObject()->globalData()->timeoutChecker.start();
    62     JSValue result = call(exec, function, callType, callData, callback(), args);
     67    JSValue result = callInWorld(exec, function, callType, callData, callback(), args, m_isolatedWorld.get());
    6368    globalObject()->globalData()->timeoutChecker.stop();
    6469
  • trunk/WebCore/bindings/js/JSCallbackData.h

    r49280 r49963  
    3030#define JSCallbackData_h
    3131
     32#include "JSDOMBinding.h"
    3233#include "JSDOMGlobalObject.h"
    3334#include <runtime/JSObject.h>
     
    4849        : m_callback(callback)
    4950        , m_globalObject(globalObject)
     51        , m_isolatedWorld(currentWorld(globalObject->globalExec()))
    5052    {
    5153    }
     
    6466    JSC::ProtectedPtr<JSC::JSObject> m_callback;
    6567    JSC::ProtectedPtr<JSDOMGlobalObject> m_globalObject;
     68    RefPtr<DOMWrapperWorld> m_isolatedWorld;
    6669};
    6770
  • trunk/WebCore/bindings/js/JSCustomXPathNSResolver.cpp

    r48530 r49963  
    9191
    9292    m_globalObject->globalData()->timeoutChecker.start();
    93     JSValue retval = call(exec, function, callType, callData, m_customResolver, args);
     93    JSValue retval = callInWorld(exec, function, callType, callData, m_customResolver, args, currentWorld(m_globalObject->globalExec()));
    9494    m_globalObject->globalData()->timeoutChecker.stop();
    9595
  • trunk/WebCore/bindings/js/JSDOMApplicationCacheCustom.cpp

    r49539 r49963  
    9292        return jsUndefined();
    9393
    94     impl()->addEventListener(args.at(0).toString(exec), JSEventListener::create(asObject(listener), false), args.at(2).toBoolean(exec));
     94    impl()->addEventListener(args.at(0).toString(exec), JSEventListener::create(asObject(listener), false, currentWorld(exec)), args.at(2).toBoolean(exec));
    9595    return jsUndefined();
    9696}
     
    102102        return jsUndefined();
    103103
    104     impl()->removeEventListener(args.at(0).toString(exec), JSEventListener::create(asObject(listener), false).get(), args.at(2).toBoolean(exec));
     104    impl()->removeEventListener(args.at(0).toString(exec), JSEventListener::create(asObject(listener), false, currentWorld(exec)).get(), args.at(2).toBoolean(exec));
    105105    return jsUndefined();
    106106}
  • trunk/WebCore/bindings/js/JSDOMBinding.cpp

    r49723 r49963  
    2121#include "config.h"
    2222#include "JSDOMBinding.h"
     23
     24#include "debugger/DebuggerCallFrame.h"
    2325
    2426#include "ActiveDOMObject.h"
     
    4547#include "RangeException.h"
    4648#include "ScriptController.h"
     49#include "Settings.h"
    4750#include "XMLHttpRequestException.h"
    4851#include <runtime/Error.h>
     
    7376
    7477typedef Document::JSWrapperCache JSWrapperCache;
     78typedef Document::JSWrapperCacheMap JSWrapperCacheMap;
    7579
    7680// For debugging, keep a set of wrappers currently registered, and check that
     
    8185static void removeWrapper(DOMObject* wrapper);
    8286static void removeWrappers(const JSWrapperCache& wrappers);
     87static void removeWrappers(const DOMObjectWrapperMap& wrappers);
    8388
    8489#ifdef NDEBUG
     
    9398
    9499static inline void removeWrappers(const JSWrapperCache&)
     100{
     101}
     102
     103static inline void removeWrappers(const DOMObjectWrapperMap&)
    95104{
    96105}
     
    125134static void removeWrappers(const JSWrapperCache& wrappers)
    126135{
    127     for (JSWrapperCache::const_iterator it = wrappers.begin(); it != wrappers.end(); ++it)
     136    JSWrapperCache::const_iterator wrappersEnd = wrappers.end();
     137    for (JSWrapperCache::const_iterator it = wrappers.begin(); it != wrappersEnd; ++it)
    128138        removeWrapper(it->second);
    129139}
    130140
     141static inline void removeWrappers(const DOMObjectWrapperMap& wrappers)
     142{
     143    DOMObjectWrapperMap::const_iterator wrappersEnd = wrappers.end();
     144    for (DOMObjectWrapperMap::const_iterator it = wrappers.begin(); it != wrappersEnd; ++it)
     145        removeWrapper(it->second);
     146}
     147
    131148DOMObject::~DOMObject()
    132149{
     
    136153#endif
    137154
    138 class DOMObjectWrapperMap {
     155DOMWrapperWorld::DOMWrapperWorld(JSC::JSGlobalData* globalData)
     156    : m_globalData(globalData)
     157{
     158}
     159
     160DOMWrapperWorld::~DOMWrapperWorld()
     161{
     162    JSGlobalData::ClientData* clientData = m_globalData->clientData;
     163    ASSERT(clientData);
     164    static_cast<WebCoreJSClientData*>(clientData)->forgetWorld(this);
     165
     166    removeWrappers(m_wrappers);
     167
     168    for (HashSet<Document*>::iterator iter = documentsWithWrappers.begin(); iter != documentsWithWrappers.end(); ++iter)
     169        forgetWorldOfDOMNodesForDocument(*iter, this);
     170    for (HashSet<ScriptController*>::iterator iter = scriptControllersWithShells.begin(); iter != scriptControllersWithShells.end(); ++iter)
     171        (*iter)->forgetWorld(this);
     172}
     173
     174EnterDOMWrapperWorld::EnterDOMWrapperWorld(JSC::JSGlobalData& globalData, DOMWrapperWorld* isolatedWorld)
     175{
     176    JSGlobalData::ClientData* clientData = globalData.clientData;
     177    ASSERT(clientData);
     178    m_clientData = static_cast<WebCoreJSClientData*>(clientData);
     179    m_clientData->m_worldStack.append(isolatedWorld);
     180}
     181
     182EnterDOMWrapperWorld::EnterDOMWrapperWorld(JSC::ExecState* exec, DOMWrapperWorld* isolatedWorld)
     183{
     184    JSGlobalData::ClientData* clientData = exec->globalData().clientData;
     185    ASSERT(clientData);
     186    m_clientData = static_cast<WebCoreJSClientData*>(clientData);
     187    m_clientData->m_worldStack.append(isolatedWorld);
     188}
     189
     190EnterDOMWrapperWorld::~EnterDOMWrapperWorld()
     191{
     192    m_clientData->m_worldStack.removeLast();
     193}
     194
     195class JSGlobalDataWorldIterator {
    139196public:
    140     static DOMObjectWrapperMap& mapFor(JSGlobalData&);
    141 
    142     DOMObject* get(void* objectHandle)
     197    JSGlobalDataWorldIterator(JSGlobalData* globalData)
     198        : m_pos(static_cast<WebCoreJSClientData*>(globalData->clientData)->m_worldSet.begin())
     199        , m_end(static_cast<WebCoreJSClientData*>(globalData->clientData)->m_worldSet.end())
    143200    {
    144         return m_map.get(objectHandle);
    145     }
    146 
    147     void set(void* objectHandle, DOMObject* wrapper)
     201    }
     202
     203    operator bool()
    148204    {
     205        return m_pos != m_end;
     206    }
     207
     208    DOMWrapperWorld* operator*()
     209    {
     210        ASSERT(m_pos != m_end);
     211        return *m_pos;
     212    }
     213
     214    DOMWrapperWorld* operator->()
     215    {
     216        ASSERT(m_pos != m_end);
     217        return *m_pos;
     218    }
     219
     220    JSGlobalDataWorldIterator& operator++()
     221    {
     222        ++m_pos;
     223        return *this;
     224    }
     225
     226private:
     227    HashSet<DOMWrapperWorld*>::iterator m_pos;
     228    HashSet<DOMWrapperWorld*>::iterator m_end;
     229};
     230
     231static inline DOMWrapperWorld* currentWorld(JSC::JSGlobalData& globalData)
     232{
     233    JSGlobalData::ClientData* clientData = globalData.clientData;
     234    ASSERT(clientData);
     235    return static_cast<WebCoreJSClientData*>(clientData)->currentWorld();
     236}
     237
     238DOMWrapperWorld* currentWorld(JSC::ExecState* exec)
     239{
     240    return currentWorld(exec->globalData());
     241}
     242
     243DOMWrapperWorld* normalWorld(JSC::JSGlobalData& globalData)
     244{
     245    JSGlobalData::ClientData* clientData = globalData.clientData;
     246    ASSERT(clientData);
     247    return static_cast<WebCoreJSClientData*>(clientData)->normalWorld();
     248}
     249
     250DOMWrapperWorld* mainThreadNormalWorld()
     251{
     252    ASSERT(isMainThread());
     253    return normalWorld(*JSDOMWindow::commonJSGlobalData());
     254}
     255
     256DOMWrapperWorld* mainThreadCurrentWorld()
     257{
     258    ASSERT(isMainThread());
     259
     260    JSGlobalData::ClientData* clientData = JSDOMWindowBase::commonJSGlobalData()->clientData;
     261    ASSERT(clientData);
     262    return static_cast<WebCoreJSClientData*>(clientData)->currentWorld();
     263}
     264
     265DOMObjectHashTableMap& DOMObjectHashTableMap::mapFor(JSGlobalData& globalData)
     266{
     267    JSGlobalData::ClientData* clientData = globalData.clientData;
     268    ASSERT(clientData);
     269    return static_cast<WebCoreJSClientData*>(clientData)->hashTableMap;
     270}
     271
     272const JSC::HashTable* getHashTableForGlobalData(JSGlobalData& globalData, const JSC::HashTable* staticTable)
     273{
     274    return DOMObjectHashTableMap::mapFor(globalData).get(staticTable);
     275}
     276
     277//inline DOMObjectWrapperMap& DOMObjectWrapperMap::mapFor(JSGlobalData& globalData)
     278inline DOMObjectWrapperMap& DOMObjectWrapperMapFor(JSGlobalData& globalData)
     279{
     280    return currentWorld(globalData)->m_wrappers;
     281}
     282
     283DOMObject* getCachedDOMObjectWrapper(JSGlobalData& globalData, void* objectHandle)
     284{
     285    return DOMObjectWrapperMapFor(globalData).get(objectHandle);
     286}
     287
     288void cacheDOMObjectWrapper(JSGlobalData& globalData, void* objectHandle, DOMObject* wrapper)
     289{
     290    addWrapper(wrapper);
     291    DOMObjectWrapperMapFor(globalData).set(objectHandle, wrapper);
     292}
     293
     294JSNode* getCachedDOMNodeWrapper(Document* document, Node* node)
     295{
     296    if (document)
     297        return document->getWrapperCache(mainThreadCurrentWorld())->get(node);
     298    return static_cast<JSNode*>(DOMObjectWrapperMapFor(*JSDOMWindow::commonJSGlobalData()).get(node));
     299}
     300
     301void forgetDOMObject(DOMObject* wrapper, void* objectHandle)
     302{
     303    JSC::JSGlobalData* globalData = Heap::heap(wrapper)->globalData();
     304    for (JSGlobalDataWorldIterator worldIter(globalData); worldIter; ++worldIter) {
     305        DOMObjectWrapperMap& wrappers = worldIter->m_wrappers;
     306        DOMObjectWrapperMap::iterator iter = wrappers.find(objectHandle);
     307        if ((iter != wrappers.end()) && (iter->second == wrapper)) {
     308            removeWrapper(wrapper);
     309            wrappers.remove(iter);
     310            return;
     311        }
     312    }
     313
     314    // If the world went away, it should have removed this wrapper from the set.
     315    ASSERT(!wrapperSet().contains(wrapper));
     316}
     317
     318void forgetDOMNode(DOMObject* wrapper, Node* node, Document* document)
     319{
     320    if (!document) {
     321        forgetDOMObject(wrapper, node);
     322        return;
     323    }
     324
     325    JSWrapperCacheMap& wrapperCacheMap = document->wrapperCacheMap();
     326    for (JSWrapperCacheMap::iterator wrappersIter = wrapperCacheMap.begin(); wrappersIter != wrapperCacheMap.end(); ++wrappersIter) {
     327        JSWrapperCache* wrappers = wrappersIter->second;
     328        JSWrapperCache::iterator iter = wrappers->find(node);
     329        if ((iter != wrappers->end()) && (iter->second == wrapper)) {
     330            wrappers->remove(iter);
     331            removeWrapper(wrapper);
     332            return;
     333        }
     334    }
     335
     336    // If the world went away, it should have removed this wrapper from the set.
     337    ASSERT(!wrapperSet().contains(wrapper));
     338}
     339
     340void cacheDOMNodeWrapper(Document* document, Node* node, JSNode* wrapper)
     341{
     342    if (!document) {
    149343        addWrapper(wrapper);
    150         m_map.set(objectHandle, wrapper);
    151     }
    152 
    153     void remove(void* objectHandle)
    154     {
    155         removeWrapper(m_map.take(objectHandle));
    156     }
    157 
    158 private:
    159     HashMap<void*, DOMObject*> m_map;
    160 };
    161 
    162 // Map from static HashTable instances to per-GlobalData ones.
    163 class DOMObjectHashTableMap {
    164 public:
    165     static DOMObjectHashTableMap& mapFor(JSGlobalData&);
    166 
    167     ~DOMObjectHashTableMap()
    168     {
    169         HashMap<const JSC::HashTable*, JSC::HashTable>::iterator mapEnd = m_map.end();
    170         for (HashMap<const JSC::HashTable*, JSC::HashTable>::iterator iter = m_map.begin(); iter != m_map.end(); ++iter)
    171             iter->second.deleteTable();
    172     }
    173 
    174     const JSC::HashTable* get(const JSC::HashTable* staticTable)
    175     {
    176         HashMap<const JSC::HashTable*, JSC::HashTable>::iterator iter = m_map.find(staticTable);
    177         if (iter != m_map.end())
    178             return &iter->second;
    179         return &m_map.set(staticTable, JSC::HashTable(*staticTable)).first->second;
    180     }
    181 
    182 private:
    183     HashMap<const JSC::HashTable*, JSC::HashTable> m_map;
    184 };
    185 
    186 class WebCoreJSClientData : public JSGlobalData::ClientData {
    187 public:
    188     DOMObjectHashTableMap hashTableMap;
    189     DOMObjectWrapperMap wrapperMap;
    190 };
    191 
    192 DOMObjectHashTableMap& DOMObjectHashTableMap::mapFor(JSGlobalData& globalData)
    193 {
    194     JSGlobalData::ClientData* clientData = globalData.clientData;
    195     if (!clientData) {
    196         clientData = new WebCoreJSClientData;
    197         globalData.clientData = clientData;
    198     }
    199     return static_cast<WebCoreJSClientData*>(clientData)->hashTableMap;
    200 }
    201 
    202 const JSC::HashTable* getHashTableForGlobalData(JSGlobalData& globalData, const JSC::HashTable* staticTable)
    203 {
    204     return DOMObjectHashTableMap::mapFor(globalData).get(staticTable);
    205 }
    206 
    207 inline DOMObjectWrapperMap& DOMObjectWrapperMap::mapFor(JSGlobalData& globalData)
    208 {
    209     JSGlobalData::ClientData* clientData = globalData.clientData;
    210     if (!clientData) {
    211         clientData = new WebCoreJSClientData;
    212         globalData.clientData = clientData;
    213     }
    214     return static_cast<WebCoreJSClientData*>(clientData)->wrapperMap;
    215 }
    216 
    217 DOMObject* getCachedDOMObjectWrapper(JSGlobalData& globalData, void* objectHandle)
    218 {
    219     return DOMObjectWrapperMap::mapFor(globalData).get(objectHandle);
    220 }
    221 
    222 void cacheDOMObjectWrapper(JSGlobalData& globalData, void* objectHandle, DOMObject* wrapper)
    223 {
    224     DOMObjectWrapperMap::mapFor(globalData).set(objectHandle, wrapper);
    225 }
    226 
    227 void forgetDOMObject(JSGlobalData& globalData, void* objectHandle)
    228 {
    229     DOMObjectWrapperMap::mapFor(globalData).remove(objectHandle);
    230 }
    231 
    232 JSNode* getCachedDOMNodeWrapper(Document* document, Node* node)
    233 {
    234     if (!document)
    235         return static_cast<JSNode*>(DOMObjectWrapperMap::mapFor(*JSDOMWindow::commonJSGlobalData()).get(node));
    236     return document->wrapperCache().get(node);
    237 }
    238 
    239 void forgetDOMNode(Document* document, Node* node)
    240 {
    241     if (!document) {
    242         DOMObjectWrapperMap::mapFor(*JSDOMWindow::commonJSGlobalData()).remove(node);
    243         return;
    244     }
    245     removeWrapper(document->wrapperCache().take(node));
    246 }
    247 
    248 void cacheDOMNodeWrapper(Document* document, Node* node, JSNode* wrapper)
    249 {
    250     if (!document) {
    251         DOMObjectWrapperMap::mapFor(*JSDOMWindow::commonJSGlobalData()).set(node, wrapper);
     344        DOMObjectWrapperMapFor(*JSDOMWindow::commonJSGlobalData()).set(node, wrapper);
    252345        return;
    253346    }
    254347    addWrapper(wrapper);
    255     document->wrapperCache().set(node, wrapper);
     348    document->getWrapperCache(mainThreadCurrentWorld())->set(node, wrapper);
    256349}
    257350
     
    259352{
    260353    ASSERT(document);
    261     removeWrappers(document->wrapperCache());
    262 }
    263 
    264 static inline bool isObservableThroughDOM(JSNode* jsNode)
     354    JSWrapperCacheMap& wrapperCacheMap = document->wrapperCacheMap();
     355    JSWrapperCacheMap::const_iterator wrappersMapEnd = wrapperCacheMap.end();
     356    for (JSWrapperCacheMap::const_iterator wrappersMapIter = wrapperCacheMap.begin(); wrappersMapIter != wrappersMapEnd; ++wrappersMapIter) {
     357        JSWrapperCache* wrappers = wrappersMapIter->second;
     358        removeWrappers(*wrappers);
     359        delete wrappers;
     360        wrappersMapIter->first->forgetDocument(document);
     361    }
     362}
     363
     364void forgetWorldOfDOMNodesForDocument(Document* document, DOMWrapperWorld* world)
     365{
     366    JSWrapperCache* wrappers = document->wrapperCacheMap().take(world);
     367    ASSERT(wrappers); // 'world' should only know about 'document' if 'document' knows about 'world'!
     368    removeWrappers(*wrappers);
     369    delete wrappers;
     370}
     371
     372static inline bool isObservableThroughDOM(JSNode* jsNode, DOMWrapperWorld* world)
    265373{
    266374    // Certain conditions implicitly make a JS DOM node wrapper observable
     
    288396        if (node->isElementNode()) {
    289397            if (NamedNodeMap* attributes = static_cast<Element*>(node)->attributeMap()) {
    290                 if (DOMObject* wrapper = getCachedDOMObjectWrapper(*jsNode->globalObject()->globalData(), attributes)) {
     398                if (DOMObject* wrapper = world->m_wrappers.get(attributes)) {
    291399                    if (wrapper->hasCustomProperties())
    292400                        return true;
     
    295403            if (node->isStyledElement()) {
    296404                if (CSSMutableStyleDeclaration* style = static_cast<StyledElement*>(node)->inlineStyleDecl()) {
    297                     if (DOMObject* wrapper = getCachedDOMObjectWrapper(*jsNode->globalObject()->globalData(), style)) {
     405                    if (DOMObject* wrapper = world->m_wrappers.get(style)) {
    298406                        if (wrapper->hasCustomProperties())
    299407                            return true;
     
    303411            if (static_cast<Element*>(node)->hasTagName(canvasTag)) {
    304412                if (CanvasRenderingContext* context = static_cast<HTMLCanvasElement*>(node)->renderingContext()) {
    305                     if (DOMObject* wrapper = getCachedDOMObjectWrapper(*jsNode->globalObject()->globalData(), context)) {
     413                    if (DOMObject* wrapper = world->m_wrappers.get(context)) {
    306414                        if (wrapper->hasCustomProperties())
    307415                            return true;
     
    334442}
    335443
    336 void markDOMNodesForDocument(MarkStack& markStack, Document* doc)
    337 {
    338     JSWrapperCache& nodeDict = doc->wrapperCache();
    339     JSWrapperCache::iterator nodeEnd = nodeDict.end();
    340     for (JSWrapperCache::iterator nodeIt = nodeDict.begin(); nodeIt != nodeEnd; ++nodeIt) {
    341         JSNode* jsNode = nodeIt->second;
    342         if (isObservableThroughDOM(jsNode))
    343             markStack.append(jsNode);
     444void markDOMNodesForDocument(MarkStack& markStack, Document* document)
     445{
     446    JSWrapperCacheMap& wrapperCacheMap = document->wrapperCacheMap();
     447    for (JSWrapperCacheMap::iterator wrappersIter = wrapperCacheMap.begin(); wrappersIter != wrapperCacheMap.end(); ++wrappersIter) {
     448        DOMWrapperWorld* world = wrappersIter->first;
     449        JSWrapperCache* nodeDict = wrappersIter->second;
     450
     451        JSWrapperCache::iterator nodeEnd = nodeDict->end();
     452        for (JSWrapperCache::iterator nodeIt = nodeDict->begin(); nodeIt != nodeEnd; ++nodeIt) {
     453            JSNode* jsNode = nodeIt->second;
     454            if (isObservableThroughDOM(jsNode, world))
     455                markStack.append(jsNode);
     456        }
    344457    }
    345458}
     
    354467    for (HashMap<ActiveDOMObject*, void*>::const_iterator iter = activeObjects.begin(); iter != activeObjectsEnd; ++iter) {
    355468        if (iter->first->hasPendingActivity()) {
    356             DOMObject* wrapper = getCachedDOMObjectWrapper(globalData, iter->second);
    357469            // Generally, an active object with pending activity must have a wrapper to mark its listeners.
    358470            // However, some ActiveDOMObjects don't have JS wrappers (timers created by setTimeout is one example).
    359471            // FIXME: perhaps need to make sure even timers have a markable 'wrapper'.
    360             if (wrapper)
    361                 markStack.append(wrapper);
     472            markDOMObjectWrapper(markStack, globalData, iter->second);
    362473        }
    363474    }
     
    367478    for (HashSet<MessagePort*>::const_iterator iter = messagePorts.begin(); iter != portsEnd; ++iter) {
    368479        // If the message port is remotely entangled, then always mark it as in-use because we can't determine reachability across threads.
    369         if (!(*iter)->locallyEntangledPort() || (*iter)->hasPendingActivity()) {
    370             DOMObject* wrapper = getCachedDOMObjectWrapper(globalData, *iter);
    371             if (wrapper)
    372                 markStack.append(wrapper);
     480        if (!(*iter)->locallyEntangledPort() || (*iter)->hasPendingActivity())
     481            markDOMObjectWrapper(markStack, globalData, *iter);
     482    }
     483}
     484
     485typedef std::pair<JSNode*, DOMWrapperWorld*> WrapperAndWorld;
     486typedef WTF::Vector<WrapperAndWorld, 8> WrapperSet;
     487
     488static inline void takeWrappers(Node* node, Document* document, WrapperSet& wrapperSet)
     489{
     490    if (document) {
     491        JSWrapperCacheMap& wrapperCacheMap = document->wrapperCacheMap();
     492        for (JSWrapperCacheMap::iterator iter = wrapperCacheMap.begin(); iter != wrapperCacheMap.end(); ++iter) {
     493            if (JSNode* wrapper = iter->second->take(node)) {
     494                removeWrapper(wrapper);
     495                wrapperSet.append(WrapperAndWorld(wrapper, iter->first));
     496            }
    373497        }
     498    } else {
     499        for (JSGlobalDataWorldIterator worldIter(JSDOMWindow::commonJSGlobalData()); worldIter; ++worldIter) {
     500            DOMWrapperWorld* world = *worldIter;
     501            if (JSNode* wrapper = static_cast<JSNode*>(world->m_wrappers.take(node))) {
     502                removeWrapper(wrapper);
     503                wrapperSet.append(WrapperAndWorld(wrapper, world));
     504            }
     505        }
    374506    }
    375507}
     
    378510{
    379511    ASSERT(oldDocument != newDocument);
    380     JSNode* wrapper = getCachedDOMNodeWrapper(oldDocument, node);
    381     if (!wrapper)
    382         return;
    383     removeWrapper(wrapper);
    384     cacheDOMNodeWrapper(newDocument, node, wrapper);
    385     forgetDOMNode(oldDocument, node);
    386     addWrapper(wrapper);
     512
     513    WrapperSet wrapperSet;
     514    takeWrappers(node, oldDocument, wrapperSet);
     515
     516    for (unsigned i = 0; i < wrapperSet.size(); ++i) {
     517        JSNode* wrapper = wrapperSet[i].first;
     518        if (newDocument)
     519            newDocument->getWrapperCache(wrapperSet[i].second)->set(node, wrapper);
     520        else
     521            wrapperSet[i].second->m_wrappers.set(node, wrapper);
     522        addWrapper(wrapper);
     523    }
    387524}
    388525
     
    394531    if (!object)
    395532        return;
    396     DOMObject* wrapper = getCachedDOMObjectWrapper(globalData, object);
    397     if (!wrapper)
    398         return;
    399     markStack.append(wrapper);
     533
     534    for (JSGlobalDataWorldIterator worldIter(&globalData); worldIter; ++worldIter) {
     535        if (DOMObject* wrapper = worldIter->m_wrappers.get(object))
     536            markStack.append(wrapper);
     537    }
    400538}
    401539
     
    544682    if (!frame)
    545683        return false;
    546     JSDOMWindow* window = toJSDOMWindow(frame);
     684    JSDOMWindow* window = toJSDOMWindow(frame, currentWorld(exec));
    547685    return window && window->allowsAccessFrom(exec);
    548686}
     
    552690    if (!frame)
    553691        return false;
    554     JSDOMWindow* window = toJSDOMWindow(frame);
     692    JSDOMWindow* window = toJSDOMWindow(frame, currentWorld(exec));
    555693    return window && window->allowsAccessFrom(exec, message);
    556694}
     
    566704    if (!frame)
    567705        return;
    568     if (JSDOMWindow* window = toJSDOMWindow(frame))
    569         window->printErrorMessage(message);
     706    if (message.isEmpty())
     707        return;
     708
     709    Settings* settings = frame->settings();
     710    if (!settings)
     711        return;
     712    if (settings->privateBrowsingEnabled())
     713        return;
     714
     715    frame->domWindow()->console()->addMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, message, 1, String()); // FIXME: provide a real line number and source URL.
    570716}
    571717
     
    665811}
    666812
     813JSValue DebuggerCallFrame_evaluateInWorld(const JSC::DebuggerCallFrame& debuggerCallFrame, const UString& script, JSValue& exception)
     814{
     815    EnterDOMWrapperWorld worldEntry(debuggerCallFrame.dynamicGlobalObject()->globalExec(), debuggerWorld());
     816    return debuggerCallFrame.evaluate(script, exception);
     817}
     818
     819JSValue callInWorld(ExecState* exec, JSValue function, CallType callType, const CallData& callData, JSValue thisValue, const ArgList& args, DOMWrapperWorld* isolatedWorld)
     820{
     821    EnterDOMWrapperWorld worldEntry(exec, isolatedWorld);
     822    return JSC::call(exec, function, callType, callData, thisValue, args);
     823}
     824
     825JSObject* constructInWorld(ExecState* exec, JSValue object, ConstructType constructType, const ConstructData& constructData, const ArgList& args, DOMWrapperWorld* isolatedWorld)
     826{
     827    EnterDOMWrapperWorld worldEntry(exec, isolatedWorld);
     828    return JSC::construct(exec, object, constructType, constructData, args);
     829}
     830
     831Completion evaluateInWorld(ExecState* exec, ScopeChain& scopeChain, const SourceCode& sourceCode, JSValue thisValue, DOMWrapperWorld* isolatedWorld)
     832{
     833    EnterDOMWrapperWorld worldEntry(exec, isolatedWorld);
     834    return JSC::evaluate(exec, scopeChain, sourceCode, thisValue);
     835}
     836
    667837} // namespace WebCore
  • trunk/WebCore/bindings/js/JSDOMBinding.h

    r49835 r49963  
    3131namespace JSC {
    3232    class JSGlobalData;
     33    class DebuggerCallFrame;
    3334}
    3435
     
    3738    class Document;
    3839    class Frame;
     40    class JSNode;
    3941    class KURL;
    4042    class Node;
    4143    class String;
    42     class JSNode;
     44    class ScriptController;
    4345
    4446    typedef int ExceptionCode;
     
    137139    };
    138140
     141    typedef HashMap<void*, DOMObject*> DOMObjectWrapperMap;
     142
     143    class DOMWrapperWorld : public RefCounted<DOMWrapperWorld> {
     144    public:
     145        DOMWrapperWorld(JSC::JSGlobalData*);
     146        ~DOMWrapperWorld();
     147
     148        void rememberDocument(Document* document) { documentsWithWrappers.add(document); }
     149        void forgetDocument(Document* document) { documentsWithWrappers.remove(document); }
     150        void rememberScriptController(ScriptController* scriptController) { scriptControllersWithShells.add(scriptController); }
     151        void forgetScriptController(ScriptController* scriptController) { scriptControllersWithShells.remove(scriptController); }
     152
     153        // FIXME: can we make this private?
     154        DOMObjectWrapperMap m_wrappers;
     155
     156    private:
     157        JSC::JSGlobalData* m_globalData;
     158        HashSet<Document*> documentsWithWrappers;
     159        HashSet<ScriptController*> scriptControllersWithShells;
     160    };
     161
     162    // Map from static HashTable instances to per-GlobalData ones.
     163    class DOMObjectHashTableMap {
     164    public:
     165        static DOMObjectHashTableMap& mapFor(JSC::JSGlobalData&);
     166
     167        ~DOMObjectHashTableMap()
     168        {
     169            HashMap<const JSC::HashTable*, JSC::HashTable>::iterator mapEnd = m_map.end();
     170            for (HashMap<const JSC::HashTable*, JSC::HashTable>::iterator iter = m_map.begin(); iter != m_map.end(); ++iter)
     171                iter->second.deleteTable();
     172        }
     173
     174        const JSC::HashTable* get(const JSC::HashTable* staticTable)
     175        {
     176            HashMap<const JSC::HashTable*, JSC::HashTable>::iterator iter = m_map.find(staticTable);
     177            if (iter != m_map.end())
     178                return &iter->second;
     179            return &m_map.set(staticTable, JSC::HashTable(*staticTable)).first->second;
     180        }
     181
     182    private:
     183        HashMap<const JSC::HashTable*, JSC::HashTable> m_map;
     184    };
     185
     186    class WebCoreJSClientData : public JSC::JSGlobalData::ClientData {
     187        friend class EnterDOMWrapperWorld;
     188        friend class JSGlobalDataWorldIterator;
     189
     190    public:
     191        WebCoreJSClientData(JSC::JSGlobalData* globalData)
     192            : m_normalWorld(globalData)
     193        {
     194            m_worldStack.append(&m_normalWorld);
     195            m_worldSet.add(&m_normalWorld);
     196        }
     197        // FIXME: add a destructor to assert m_worldSet only contains m_normalWorld?
     198
     199        DOMWrapperWorld* currentWorld() { return m_worldStack.last(); }
     200        DOMWrapperWorld* normalWorld() { return &m_normalWorld; }
     201
     202        void rememberWorld(DOMWrapperWorld* world)
     203        {
     204            ASSERT(!m_worldSet.contains(world));
     205            m_worldSet.add(world);
     206        }
     207        void forgetWorld(DOMWrapperWorld* world)
     208        {
     209            ASSERT(m_worldSet.contains(world));
     210            m_worldSet.remove(world);
     211        }
     212
     213        DOMObjectHashTableMap hashTableMap;
     214    private:
     215        Vector<DOMWrapperWorld*> m_worldStack;
     216        HashSet<DOMWrapperWorld*> m_worldSet;
     217        DOMWrapperWorld m_normalWorld;
     218    };
     219
     220    class EnterDOMWrapperWorld {
     221    public:
     222        EnterDOMWrapperWorld(JSC::JSGlobalData&, DOMWrapperWorld*);
     223        EnterDOMWrapperWorld(JSC::ExecState*, DOMWrapperWorld*);
     224        ~EnterDOMWrapperWorld();
     225
     226    private:
     227        WebCoreJSClientData* m_clientData;
     228    };
     229
    139230    DOMObject* getCachedDOMObjectWrapper(JSC::JSGlobalData&, void* objectHandle);
    140231    void cacheDOMObjectWrapper(JSC::JSGlobalData&, void* objectHandle, DOMObject* wrapper);
    141     void forgetDOMObject(JSC::JSGlobalData&, void* objectHandle);
     232    void forgetDOMNode(DOMObject* wrapper, Node* node, Document* document);
     233    void forgetDOMObject(DOMObject* wrapper, void* objectHandle);
    142234
    143235    JSNode* getCachedDOMNodeWrapper(Document*, Node*);
    144236    void cacheDOMNodeWrapper(Document*, Node*, JSNode* wrapper);
    145     void forgetDOMNode(Document*, Node*);
    146237    void forgetAllDOMNodesForDocument(Document*);
     238    void forgetWorldOfDOMNodesForDocument(Document*, DOMWrapperWorld*);
    147239    void updateDOMNodeDocument(Node*, Document* oldDocument, Document* newDocument);
    148240    void markDOMNodesForDocument(JSC::MarkStack&, Document*);
     
    154246    JSC::Structure* getCachedDOMStructure(JSC::ExecState*, const JSC::ClassInfo*);
    155247    JSC::Structure* cacheDOMStructure(JSC::ExecState*, NonNullPassRefPtr<JSC::Structure>, const JSC::ClassInfo*);
     248
     249    DOMWrapperWorld* currentWorld(JSC::ExecState*);
     250    DOMWrapperWorld* normalWorld(JSC::JSGlobalData&);
     251    DOMWrapperWorld* mainThreadCurrentWorld();
     252    DOMWrapperWorld* mainThreadNormalWorld();
     253    inline DOMWrapperWorld* debuggerWorld() { return mainThreadNormalWorld(); }
     254    inline DOMWrapperWorld* pluginWorld() { return mainThreadNormalWorld(); }
    156255
    157256    JSC::JSObject* getCachedDOMConstructor(JSC::ExecState*, const JSC::ClassInfo*);
     
    306405    KURL completeURL(JSC::ExecState*, const String& relativeURL);
    307406
     407    JSC::JSValue DebuggerCallFrame_evaluateInWorld(const JSC::DebuggerCallFrame& debuggerCallFrame, const JSC::UString& script, JSC::JSValue& exception);
     408    JSC::JSValue callInWorld(JSC::ExecState*, JSC::JSValue function, JSC::CallType, const JSC::CallData&, JSC::JSValue thisValue, const JSC::ArgList&, DOMWrapperWorld*);
     409    JSC::JSObject* constructInWorld(JSC::ExecState* exec, JSC::JSValue object, JSC::ConstructType constructType, const JSC::ConstructData& constructData, const JSC::ArgList& args, DOMWrapperWorld*);
     410    JSC::Completion evaluateInWorld(JSC::ExecState*, JSC::ScopeChain&, const JSC::SourceCode&, JSC::JSValue thisValue, DOMWrapperWorld*);
     411
    308412} // namespace WebCore
    309413
  • trunk/WebCore/bindings/js/JSDOMGlobalObject.cpp

    r49326 r49963  
    6464        return 0;
    6565
    66     return JSEventListener::create(asObject(val), true).get();
     66    return JSEventListener::create(asObject(val), true, currentWorld(globalExec())).get();
    6767}
    6868
     
    8282}
    8383
    84 JSDOMGlobalObject* toJSDOMGlobalObject(Document* document)
     84JSDOMGlobalObject* toJSDOMGlobalObject(Document* document, JSC::ExecState* exec)
    8585{
    86     return toJSDOMWindow(document->frame());
     86    return toJSDOMWindow(document->frame(), currentWorld(exec));
    8787}
    8888
    89 JSDOMGlobalObject* toJSDOMGlobalObject(ScriptExecutionContext* scriptExecutionContext)
     89JSDOMGlobalObject* toJSDOMGlobalObject(ScriptExecutionContext* scriptExecutionContext, JSC::ExecState* exec)
    9090{
    9191    if (scriptExecutionContext->isDocument())
    92         return toJSDOMGlobalObject(static_cast<Document*>(scriptExecutionContext));
     92        return toJSDOMGlobalObject(static_cast<Document*>(scriptExecutionContext), exec);
     93
     94#if ENABLE(WORKERS)
     95    if (scriptExecutionContext->isWorkerContext())
     96        return static_cast<WorkerContext*>(scriptExecutionContext)->script()->workerContextWrapper();
     97#endif
     98
     99    ASSERT_NOT_REACHED();
     100    return 0;
     101}
     102
     103JSDOMGlobalObject* toJSDOMGlobalObject(Document* document, DOMWrapperWorld* world)
     104{
     105    return toJSDOMWindow(document->frame(), world);
     106}
     107
     108JSDOMGlobalObject* toJSDOMGlobalObject(ScriptExecutionContext* scriptExecutionContext, DOMWrapperWorld* world)
     109{
     110    if (scriptExecutionContext->isDocument())
     111        return toJSDOMGlobalObject(static_cast<Document*>(scriptExecutionContext), world);
    93112
    94113#if ENABLE(WORKERS)
  • trunk/WebCore/bindings/js/JSDOMGlobalObject.h

    r48952 r49963  
    3434    class Document;
    3535    class Event;
     36    class DOMWrapperWorld;
    3637    class JSLazyEventListener;
    3738    class JSEventListener;
     
    103104    }
    104105
    105     JSDOMGlobalObject* toJSDOMGlobalObject(Document*);
    106     JSDOMGlobalObject* toJSDOMGlobalObject(ScriptExecutionContext*);
     106    JSDOMGlobalObject* toJSDOMGlobalObject(Document*, JSC::ExecState*);
     107    JSDOMGlobalObject* toJSDOMGlobalObject(ScriptExecutionContext*, JSC::ExecState*);
     108
     109    JSDOMGlobalObject* toJSDOMGlobalObject(Document*, DOMWrapperWorld*);
     110    JSDOMGlobalObject* toJSDOMGlobalObject(ScriptExecutionContext*, DOMWrapperWorld*);
    107111
    108112} // namespace WebCore
  • trunk/WebCore/bindings/js/JSDOMWindowBase.cpp

    r48952 r49963  
    5454}
    5555
    56 void JSDOMWindowBase::updateDocument()
     56void JSDOMWindowBase::updateDocument(DOMWrapperWorld* world)
    5757{
    5858    ASSERT(d()->impl->document());
    5959    ExecState* exec = globalExec();
     60    EnterDOMWrapperWorld worldEntry(exec, world);
    6061    symbolTablePutWithAttributes(Identifier(exec, "document"), toJS(exec, this, d()->impl->document()), DontDelete | ReadOnly);
    6162}
     
    8081void JSDOMWindowBase::printErrorMessage(const String& message) const
    8182{
    82     if (message.isEmpty())
    83         return;
    84 
    85     Frame* frame = impl()->frame();
    86     if (!frame)
    87         return;
    88 
    89     Settings* settings = frame->settings();
    90     if (!settings)
    91         return;
    92    
    93     if (settings->privateBrowsingEnabled())
    94         return;
    95 
    96     impl()->console()->addMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, message, 1, String()); // FIXME: provide a real line number and source URL.
     83    printErrorMessageForFrame(impl()->frame(), message);
    9784}
    9885
     
    158145JSGlobalData* JSDOMWindowBase::commonJSGlobalData()
    159146{
    160     static JSGlobalData* globalData;
     147    ASSERT(isMainThread());
     148
     149    static JSGlobalData* globalData = 0;
    161150    if (!globalData) {
    162151        globalData = JSGlobalData::createLeaked().releaseRef();
     
    165154        globalData->mainThreadOnly = true;
    166155#endif
     156        globalData->clientData = new WebCoreJSClientData(globalData);
    167157    }
    168158
     
    182172}
    183173
    184 JSValue toJS(ExecState*, DOMWindow* domWindow)
     174JSValue toJS(ExecState* exec, DOMWindow* domWindow)
    185175{
    186176    if (!domWindow)
     
    189179    if (!frame)
    190180        return jsNull();
    191     return frame->script()->windowShell();
    192 }
    193 
    194 JSDOMWindow* toJSDOMWindow(Frame* frame)
     181    return frame->script()->windowShell(currentWorld(exec));
     182}
     183
     184JSDOMWindow* toJSDOMWindow(Frame* frame, DOMWrapperWorld* world)
    195185{
    196186    if (!frame)
    197187        return 0;
    198     return frame->script()->windowShell()->window();
     188    return frame->script()->windowShell(world)->window();
    199189}
    200190
  • trunk/WebCore/bindings/js/JSDOMWindowBase.h

    r48952 r49963  
    3333    class Event;
    3434    class Frame;
     35    class DOMWrapperWorld;
    3536    class JSDOMWindow;
    3637    class JSDOMWindowShell;
     
    4748
    4849    public:
    49         void updateDocument();
     50        void updateDocument(DOMWrapperWorld*);
    5051
    5152        DOMWindow* impl() const { return d()->impl.get(); }
     
    103104
    104105    // Returns JSDOMWindow or 0
    105     JSDOMWindow* toJSDOMWindow(Frame*);
     106    JSDOMWindow* toJSDOMWindow(Frame*, DOMWrapperWorld*);
    106107    JSDOMWindow* toJSDOMWindow(JSC::JSValue);
    107108
  • trunk/WebCore/bindings/js/JSDOMWindowCustom.cpp

    r49843 r49963  
    772772    newFrame->page()->setOpenedByDOM();
    773773
    774     JSDOMWindow* newWindow = toJSDOMWindow(newFrame);
     774    // FIXME: If a window is created from an isolated world, what are the consequences of this? 'dialogArguments' only appears back in the normal world?
     775    JSDOMWindow* newWindow = toJSDOMWindow(newFrame, normalWorld(exec->globalData()));
    775776
    776777    if (dialogArgs)
     
    832833            return jsUndefined();
    833834
    834         const JSDOMWindow* targetedWindow = toJSDOMWindow(frame);
     835        const JSDOMWindow* targetedWindow = toJSDOMWindow(frame, currentWorld(exec));
    835836        if (!completedURL.isEmpty() && (!protocolIsJavaScript(completedURL) || (targetedWindow && targetedWindow->allowsAccessFrom(exec)))) {
    836837            bool userGesture = processingUserGesture(exec);
     
    933934        return jsUndefined();
    934935
    935     JSDOMWindow* dialogWindow = toJSDOMWindow(dialogFrame);
     936    JSDOMWindow* dialogWindow = toJSDOMWindow(dialogFrame, currentWorld(exec));
    936937    dialogFrame->page()->chrome()->runModal();
    937938
     
    976977JSValue JSDOMWindow::setTimeout(ExecState* exec, const ArgList& args)
    977978{
    978     ScheduledAction* action = ScheduledAction::create(exec, args);
     979    ScheduledAction* action = ScheduledAction::create(exec, args, currentWorld(exec));
    979980    if (exec->hadException())
    980981        return jsUndefined();
     
    985986JSValue JSDOMWindow::setInterval(ExecState* exec, const ArgList& args)
    986987{
    987     ScheduledAction* action = ScheduledAction::create(exec, args);
     988    ScheduledAction* action = ScheduledAction::create(exec, args, currentWorld(exec));
    988989    if (exec->hadException())
    989990        return jsUndefined();
     
    10531054        return jsUndefined();
    10541055
    1055     impl()->addEventListener(args.at(0).toString(exec), JSEventListener::create(asObject(listener), false), args.at(2).toBoolean(exec));
     1056    impl()->addEventListener(args.at(0).toString(exec), JSEventListener::create(asObject(listener), false, currentWorld(exec)), args.at(2).toBoolean(exec));
    10561057    return jsUndefined();
    10571058}
     
    10671068        return jsUndefined();
    10681069
    1069     impl()->removeEventListener(args.at(0).toString(exec), JSEventListener::create(asObject(listener), false).get(), args.at(2).toBoolean(exec));
     1070    impl()->removeEventListener(args.at(0).toString(exec), JSEventListener::create(asObject(listener), false, currentWorld(exec)).get(), args.at(2).toBoolean(exec));
    10701071    return jsUndefined();
    10711072}
  • trunk/WebCore/bindings/js/JSDOMWindowShell.cpp

    r48542 r49963  
    172172// ----
    173173
    174 JSValue toJS(ExecState*, Frame* frame)
     174JSValue toJS(ExecState* exec, Frame* frame)
    175175{
    176176    if (!frame)
    177177        return jsNull();
    178     return frame->script()->windowShell();
     178    return frame->script()->windowShell(currentWorld(exec));
    179179}
    180180
    181 JSDOMWindowShell* toJSDOMWindowShell(Frame* frame)
     181JSDOMWindowShell* toJSDOMWindowShell(Frame* frame, DOMWrapperWorld* isolatedWorld)
    182182{
    183183    if (!frame)
    184184        return 0;
    185     return frame->script()->windowShell();
     185    return frame->script()->windowShell(isolatedWorld);
    186186}
    187187
  • trunk/WebCore/bindings/js/JSDOMWindowShell.h

    r49835 r49963  
    8989
    9090    JSC::JSValue toJS(JSC::ExecState*, Frame*);
    91     JSDOMWindowShell* toJSDOMWindowShell(Frame*);
     91    JSDOMWindowShell* toJSDOMWindowShell(Frame*, DOMWrapperWorld*);
    9292
    9393} // namespace WebCore
  • trunk/WebCore/bindings/js/JSDesktopNotificationsCustom.cpp

    r49539 r49963  
    6868        return jsUndefined();
    6969
    70     impl()->addEventListener(args.at(0).toString(exec), JSEventListener::create(asObject(listener)), false), args.at(2).toBoolean(exec));
     70    impl()->addEventListener(args.at(0).toString(exec), JSEventListener::create(asObject(listener)), false, currentWorld(exec)), args.at(2).toBoolean(exec));
    7171    return jsUndefined();
    7272}
     
    7878        return jsUndefined();
    7979
    80     impl()->removeEventListener(args.at(0).toString(exec), JSEventListener::create(asObject(listener), false).get(), args.at(2).toBoolean(exec));
     80    impl()->removeEventListener(args.at(0).toString(exec), JSEventListener::create(asObject(listener), false, currentWorld(exec)).get(), args.at(2).toBoolean(exec));
    8181    return jsUndefined();
    8282}
  • trunk/WebCore/bindings/js/JSEventListener.cpp

    r48884 r49963  
    3232namespace WebCore {
    3333
    34 JSEventListener::JSEventListener(JSObject* function, bool isAttribute)
     34JSEventListener::JSEventListener(JSObject* function, bool isAttribute, DOMWrapperWorld* isolatedWorld)
    3535    : EventListener(JSEventListenerType)
    3636    , m_jsFunction(function)
    3737    , m_isAttribute(isAttribute)
     38    , m_isolatedWorld(isolatedWorld)
    3839{
    3940}
     
    6667        return;
    6768
    68     JSDOMGlobalObject* globalObject = toJSDOMGlobalObject(scriptExecutionContext);
     69    JSDOMGlobalObject* globalObject = toJSDOMGlobalObject(scriptExecutionContext, m_isolatedWorld.get());
    6970    if (!globalObject)
    7071        return;
     
    8788    ExecState* exec = globalObject->globalExec();
    8889
    89     JSValue handleEventFunction = jsFunction->get(exec, Identifier(exec, "handleEvent"));
     90    JSValue handleEventFunction;
     91    {
     92        // Switch worlds, just in case handleEvent is a getter and causes JS execution!
     93        EnterDOMWrapperWorld worldEntry(exec, m_isolatedWorld.get());
     94        handleEventFunction = jsFunction->get(exec, Identifier(exec, "handleEvent"));
     95    }
    9096    CallData callData;
    9197    CallType callType = handleEventFunction.getCallData(callData);
     
    109115        globalData->timeoutChecker.start();
    110116        JSValue retval = handleEventFunction
    111             ? call(exec, handleEventFunction, callType, callData, jsFunction, args)
    112             : call(exec, jsFunction, callType, callData, toJS(exec, globalObject, event->currentTarget()), args);
     117            ? callInWorld(exec, handleEventFunction, callType, callData, jsFunction, args, m_isolatedWorld.get())
     118            : callInWorld(exec, jsFunction, callType, callData, toJS(exec, globalObject, event->currentTarget()), args, m_isolatedWorld.get());
    113119        globalData->timeoutChecker.stop();
    114120
     
    141147        return false;
    142148
    143     JSDOMGlobalObject* globalObject = toJSDOMGlobalObject(context);
     149    JSDOMGlobalObject* globalObject = toJSDOMGlobalObject(context, m_isolatedWorld.get());
    144150    ExecState* exec = globalObject->globalExec();
    145151
     
    161167
    162168    globalData->timeoutChecker.start();
    163     JSValue returnValue = call(exec, jsFunction, callType, callData, thisValue, args);
     169    JSValue returnValue = callInWorld(exec, jsFunction, callType, callData, thisValue, args, m_isolatedWorld.get());
    164170    globalData->timeoutChecker.stop();
    165171
  • trunk/WebCore/bindings/js/JSEventListener.h

    r48884 r49963  
    3131    class JSEventListener : public EventListener {
    3232    public:
    33         static PassRefPtr<JSEventListener> create(JSC::JSObject* listener, bool isAttribute)
     33        static PassRefPtr<JSEventListener> create(JSC::JSObject* listener, bool isAttribute, DOMWrapperWorld* isolatedWorld)
    3434        {
    35             return adoptRef(new JSEventListener(listener, isAttribute));
     35            return adoptRef(new JSEventListener(listener, isAttribute, isolatedWorld));
    3636        }
    3737
     
    6060
    6161    protected:
    62         JSEventListener(JSC::JSObject* function, bool isAttribute);
     62        JSEventListener(JSC::JSObject* function, bool isAttribute, DOMWrapperWorld* isolatedWorld);
    6363
    6464        mutable JSC::JSObject* m_jsFunction;
    6565        bool m_isAttribute;
     66        RefPtr<DOMWrapperWorld> m_isolatedWorld;
    6667    };
    6768
  • trunk/WebCore/bindings/js/JSEventSourceCustom.cpp

    r49539 r49963  
    5050        return jsUndefined();
    5151
    52     impl()->addEventListener(args.at(0).toString(exec), JSEventListener::create(asObject(listener), false).get(), args.at(2).toBoolean(exec));
     52    impl()->addEventListener(args.at(0).toString(exec), JSEventListener::create(asObject(listener), false, currentWorld(exec)).get(), args.at(2).toBoolean(exec));
    5353    return jsUndefined();
    5454}
     
    6060        return jsUndefined();
    6161
    62     impl()->removeEventListener(args.at(0).toString(exec), JSEventListener::create(asObject(listener), false).get(), args.at(2).toBoolean(exec));
     62    impl()->removeEventListener(args.at(0).toString(exec), JSEventListener::create(asObject(listener), false, currentWorld(exec)).get(), args.at(2).toBoolean(exec));
    6363    return jsUndefined();
    6464}
  • trunk/WebCore/bindings/js/JSEventTarget.cpp

    r48270 r49963  
    129129
    130130    if (DedicatedWorkerContext* workerContext = target->toDedicatedWorkerContext())
    131         return toJSDOMGlobalObject(workerContext);
     131        return toJSDOMGlobalObject(workerContext, exec);
    132132#endif
    133133
     
    137137
    138138    if (SharedWorkerContext* workerContext = target->toSharedWorkerContext())
    139         return toJSDOMGlobalObject(workerContext);
     139        return toJSDOMGlobalObject(workerContext, exec);
    140140#endif
    141141
  • trunk/WebCore/bindings/js/JSHTMLDocumentCustom.cpp

    r43122 r49963  
    106106        Frame* frame = static_cast<HTMLDocument*>(impl())->frame();
    107107        if (frame) {
    108             JSDOMWindowShell* wrapper = toJSDOMWindowShell(frame);
     108            JSDOMWindowShell* wrapper = toJSDOMWindowShell(frame, currentWorld(exec));
    109109            if (wrapper) {
    110110                JSValue function = wrapper->get(exec, Identifier(exec, "open"));
     
    113113                if (callType == CallTypeNone)
    114114                    return throwError(exec, TypeError);
    115                 return call(exec, function, callType, callData, wrapper, args);
     115                return callInWorld(exec, function, callType, callData, wrapper, args, currentWorld(exec));
    116116            }
    117117        }
  • trunk/WebCore/bindings/js/JSHTMLFrameSetElementCustom.cpp

    r43187 r49963  
    4848}
    4949
    50 JSValue JSHTMLFrameSetElement::nameGetter(ExecState*, const Identifier& propertyName, const PropertySlot& slot)
     50JSValue JSHTMLFrameSetElement::nameGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot)
    5151{
    5252    JSHTMLElement* thisObj = static_cast<JSHTMLElement*>(asObject(slot.slotBase()));
     
    5555    Node* frame = element->children()->namedItem(propertyName);
    5656    if (Document* doc = static_cast<HTMLFrameElement*>(frame)->contentDocument()) {
    57         if (JSDOMWindowShell* window = toJSDOMWindowShell(doc->frame()))
     57        if (JSDOMWindowShell* window = toJSDOMWindowShell(doc->frame(), currentWorld(exec)))
    5858            return window;
    5959    }
  • trunk/WebCore/bindings/js/JSInspectorBackendCustom.cpp

    r49615 r49963  
    132132    if (!database)
    133133        return jsUndefined();
    134     JSDOMWindow* inspectedWindow = toJSDOMWindow(ic->inspectedPage()->mainFrame());
     134    // Could use currentWorld(exec) ... but which exec!  The following mixed use of exec & inspectedWindow->globalExec() scares me!
     135    JSDOMWindow* inspectedWindow = toJSDOMWindow(ic->inspectedPage()->mainFrame(), debuggerWorld());
    135136    return JSInspectedObjectWrapper::wrap(inspectedWindow->globalExec(), toJS(exec, database));
    136137}
     
    142143    if (!ic)
    143144        return jsUndefined();
    144     JSDOMWindow* inspectedWindow = toJSDOMWindow(ic->inspectedPage()->mainFrame());
     145    JSDOMWindow* inspectedWindow = toJSDOMWindow(ic->inspectedPage()->mainFrame(), debuggerWorld());
    145146    return JSInspectedObjectWrapper::wrap(inspectedWindow->globalExec(), inspectedWindow);
    146147}
     
    267268
    268269    JSLock lock(SilenceAssertionsOnly);
    269     JSDOMWindow* inspectedWindow = toJSDOMWindow(ic->inspectedPage()->mainFrame());
     270    JSDOMWindow* inspectedWindow = toJSDOMWindow(ic->inspectedPage()->mainFrame(), debuggerWorld());
    270271    return JSInspectedObjectWrapper::wrap(inspectedWindow->globalExec(), toJS(exec, deprecatedGlobalObjectForPrototype(inspectedWindow->globalExec()), node));
    271272}
  • trunk/WebCore/bindings/js/JSLazyEventListener.cpp

    r48884 r49963  
    3636#endif
    3737
    38 JSLazyEventListener::JSLazyEventListener(const String& functionName, const String& eventParameterName, const String& code, Node* node, const String& sourceURL, int lineNumber)
    39     : JSEventListener(0, true)
     38JSLazyEventListener::JSLazyEventListener(const String& functionName, const String& eventParameterName, const String& code, Node* node, const String& sourceURL, int lineNumber, DOMWrapperWorld* isolatedWorld)
     39    : JSEventListener(0, true, isolatedWorld)
    4040    , m_functionName(functionName)
    4141    , m_eventParameterName(eventParameterName)
     
    9393        return;
    9494
    95     JSDOMGlobalObject* globalObject = toJSDOMGlobalObject(executionContext);
     95    JSDOMGlobalObject* globalObject = toJSDOMGlobalObject(executionContext, m_isolatedWorld.get());
    9696    if (!globalObject)
    9797        return;
  • trunk/WebCore/bindings/js/JSLazyEventListener.h

    r48884 r49963  
    3030    class JSLazyEventListener : public JSEventListener {
    3131    public:
    32         static PassRefPtr<JSLazyEventListener> create(const String& functionName, const String& eventParameterName, const String& code, Node* node, const String& sourceURL, int lineNumber)
     32        static PassRefPtr<JSLazyEventListener> create(const String& functionName, const String& eventParameterName, const String& code, Node* node, const String& sourceURL, int lineNumber, DOMWrapperWorld* isolatedWorld)
    3333        {
    34             return adoptRef(new JSLazyEventListener(functionName, eventParameterName, code, node, sourceURL, lineNumber));
     34            return adoptRef(new JSLazyEventListener(functionName, eventParameterName, code, node, sourceURL, lineNumber, isolatedWorld));
    3535        }
    3636        virtual ~JSLazyEventListener();
    3737
    3838    private:
    39         JSLazyEventListener(const String& functionName, const String& eventParameterName, const String& code, Node*, const String& sourceURL, int lineNumber);
     39        JSLazyEventListener(const String& functionName, const String& eventParameterName, const String& code, Node*, const String& sourceURL, int lineNumber, DOMWrapperWorld* isolatedWorld);
    4040
    4141        virtual JSC::JSObject* jsFunction(ScriptExecutionContext*) const;
  • trunk/WebCore/bindings/js/JSMessageChannelCustom.cpp

    r47022 r49963  
    3737    Base::markChildren(markStack);
    3838
    39     if (MessagePort* port = m_impl->port1()) {
    40         DOMObject* wrapper = getCachedDOMObjectWrapper(*Heap::heap(this)->globalData(), port);
    41         if (wrapper)
    42             markStack.append(wrapper);
    43     }
     39    if (MessagePort* port = m_impl->port1())
     40        markDOMObjectWrapper(markStack, *Heap::heap(this)->globalData(), port);
    4441
    45     if (MessagePort* port = m_impl->port2()) {
    46         DOMObject* wrapper = getCachedDOMObjectWrapper(*Heap::heap(this)->globalData(), port);
    47         if (wrapper)
    48             markStack.append(wrapper);
    49     }
     42    if (MessagePort* port = m_impl->port2())
     43        markDOMObjectWrapper(markStack, *Heap::heap(this)->globalData(), port);
    5044}
    5145
  • trunk/WebCore/bindings/js/JSMessagePortCustom.cpp

    r49539 r49963  
    4747
    4848    // If we have a locally entangled port, we can directly mark it as reachable. Ports that are remotely entangled are marked in-use by markActiveObjectsForContext().
    49     if (MessagePort* entangledPort = m_impl->locallyEntangledPort()) {
    50         DOMObject* wrapper = getCachedDOMObjectWrapper(*Heap::heap(this)->globalData(), entangledPort);
    51         if (wrapper)
    52             markStack.append(wrapper);
    53     }
     49    if (MessagePort* entangledPort = m_impl->locallyEntangledPort())
     50        markDOMObjectWrapper(markStack, *Heap::heap(this)->globalData(), entangledPort);
    5451
    5552    m_impl->markEventListeners(markStack);
     
    6259        return jsUndefined();
    6360
    64     impl()->addEventListener(args.at(0).toString(exec), JSEventListener::create(asObject(listener), false).get(), args.at(2).toBoolean(exec));
     61    impl()->addEventListener(args.at(0).toString(exec), JSEventListener::create(asObject(listener), false, currentWorld(exec)).get(), args.at(2).toBoolean(exec));
    6562    return jsUndefined();
    6663}
     
    7269        return jsUndefined();
    7370
    74     impl()->removeEventListener(args.at(0).toString(exec), JSEventListener::create(asObject(listener), false).get(), args.at(2).toBoolean(exec));
     71    impl()->removeEventListener(args.at(0).toString(exec), JSEventListener::create(asObject(listener), false, currentWorld(exec)).get(), args.at(2).toBoolean(exec));
    7572    return jsUndefined();
    7673}
  • trunk/WebCore/bindings/js/JSNodeCustom.cpp

    r49539 r49963  
    115115        return jsUndefined();
    116116
    117     impl()->addEventListener(args.at(0).toString(exec), JSEventListener::create(asObject(listener), false), args.at(2).toBoolean(exec));
     117    impl()->addEventListener(args.at(0).toString(exec), JSEventListener::create(asObject(listener), false, currentWorld(exec)), args.at(2).toBoolean(exec));
    118118    return jsUndefined();
    119119}
     
    125125        return jsUndefined();
    126126
    127     impl()->removeEventListener(args.at(0).toString(exec), JSEventListener::create(asObject(listener), false).get(), args.at(2).toBoolean(exec));
     127    impl()->removeEventListener(args.at(0).toString(exec), JSEventListener::create(asObject(listener), false, currentWorld(exec)).get(), args.at(2).toBoolean(exec));
    128128    return jsUndefined();
    129129}
     
    144144    // mark any other nodes.
    145145    if (node->inDocument()) {
    146         if (Document* doc = node->ownerDocument()) {
    147             if (DOMObject* docWrapper = getCachedDOMObjectWrapper(*Heap::heap(this)->globalData(), doc))
    148                 markStack.append(docWrapper);
    149         }
     146        if (Document* doc = node->ownerDocument())
     147            markDOMObjectWrapper(markStack, *Heap::heap(this)->globalData(), doc);
    150148        return;
    151149    }
  • trunk/WebCore/bindings/js/JSNodeFilterCondition.cpp

    r47022 r49963  
    6767        return NodeFilter::FILTER_REJECT;
    6868
    69     JSValue result = call(exec, m_filter, callType, callData, m_filter, args);
     69    JSValue result = callInWorld(exec, m_filter, callType, callData, m_filter, args, currentWorld(exec));
    7070    if (exec->hadException())
    7171        return NodeFilter::FILTER_REJECT;
  • trunk/WebCore/bindings/js/JSQuarantinedObjectWrapper.cpp

    r48836 r49963  
    2727#include "JSQuarantinedObjectWrapper.h"
    2828
     29#include "JSDOMBinding.h"
     30
    2931#include <runtime/JSGlobalObject.h>
    3032
     
    244246    ASSERT(unwrappedConstructType != ConstructTypeNone);
    245247
    246     JSValue unwrappedResult = JSC::construct(wrapper->unwrappedExecState(), wrapper->m_unwrappedObject, unwrappedConstructType, unwrappedConstructData, preparedArgs);
     248    // FIXME: Quarantined objects are all in the debuggerWorld(), for now. Instead, we should remove the quarantined objects, & replace them with an isolated world?
     249    JSValue unwrappedResult = constructInWorld(wrapper->unwrappedExecState(), wrapper->m_unwrappedObject, unwrappedConstructType, unwrappedConstructData, preparedArgs, debuggerWorld());
    247250
    248251    JSValue resultValue = wrapper->wrapOutgoingValue(wrapper->unwrappedExecState(), unwrappedResult);
     
    294297    ASSERT(unwrappedCallType != CallTypeNone);
    295298
    296     JSValue unwrappedResult = JSC::call(wrapper->unwrappedExecState(), wrapper->m_unwrappedObject, unwrappedCallType, unwrappedCallData, preparedThisValue, preparedArgs);
     299    // FIXME: Quarantined objects are all in the debuggerWorld(), for now. Instead, we should remove the quarantined objects, & replace them with an isolated world?
     300    JSValue unwrappedResult = callInWorld(wrapper->unwrappedExecState(), wrapper->m_unwrappedObject, unwrappedCallType, unwrappedCallData, preparedThisValue, preparedArgs, debuggerWorld());
    297301
    298302    JSValue result = wrapper->wrapOutgoingValue(wrapper->unwrappedExecState(), unwrappedResult);
  • trunk/WebCore/bindings/js/JSSVGElementInstanceCustom.cpp

    r49539 r49963  
    5555        return jsUndefined();
    5656
    57     impl()->addEventListener(args.at(0).toString(exec), JSEventListener::create(asObject(listener), false), args.at(2).toBoolean(exec));
     57    impl()->addEventListener(args.at(0).toString(exec), JSEventListener::create(asObject(listener), false, currentWorld(exec)), args.at(2).toBoolean(exec));
    5858    return jsUndefined();
    5959}
     
    6565        return jsUndefined();
    6666
    67     impl()->removeEventListener(args.at(0).toString(exec), JSEventListener::create(asObject(listener), false).get(), args.at(2).toBoolean(exec));
     67    impl()->removeEventListener(args.at(0).toString(exec), JSEventListener::create(asObject(listener), false, currentWorld(exec)).get(), args.at(2).toBoolean(exec));
    6868    return jsUndefined();
    6969}
  • trunk/WebCore/bindings/js/JSSharedWorkerCustom.cpp

    r47022 r49963  
    4646    Base::markChildren(markStack);
    4747
    48     if (MessagePort* port = impl()->port()) {
    49         DOMObject* wrapper = getCachedDOMObjectWrapper(*Heap::heap(this)->globalData(), port);
    50         if (wrapper)
    51             markStack.append(wrapper);
    52     }
     48    if (MessagePort* port = impl()->port())
     49        markDOMObjectWrapper(markStack, *Heap::heap(this)->globalData(), port);
    5350}
    5451
  • trunk/WebCore/bindings/js/JSWebSocketCustom.cpp

    r49539 r49963  
    6767        return jsUndefined();
    6868
    69     impl()->addEventListener(args.at(0).toString(exec), JSEventListener::create(asObject(listener), false), args.at(2).toBoolean(exec));
     69    impl()->addEventListener(args.at(0).toString(exec), JSEventListener::create(asObject(listener), false, currentWorld(exec)), args.at(2).toBoolean(exec));
    7070    return jsUndefined();
    7171}
     
    7777        return jsUndefined();
    7878
    79     impl()->removeEventListener(args.at(0).toString(exec), JSEventListener::create(asObject(listener), false).get(), args.at(2).toBoolean(exec));
     79    impl()->removeEventListener(args.at(0).toString(exec), JSEventListener::create(asObject(listener), false, currentWorld(exec)).get(), args.at(2).toBoolean(exec));
    8080    return jsUndefined();
    8181}
  • trunk/WebCore/bindings/js/JSWorkerContextCustom.cpp

    r48884 r49963  
    123123        return jsUndefined();
    124124
    125     impl()->addEventListener(args.at(0).toString(exec), JSEventListener::create(asObject(listener), false), args.at(2).toBoolean(exec));
     125    impl()->addEventListener(args.at(0).toString(exec), JSEventListener::create(asObject(listener), false, currentWorld(exec)), args.at(2).toBoolean(exec));
    126126    return jsUndefined();
    127127}
     
    133133        return jsUndefined();
    134134
    135     impl()->removeEventListener(args.at(0).toString(exec), JSEventListener::create(asObject(listener), false).get(), args.at(2).toBoolean(exec));
     135    impl()->removeEventListener(args.at(0).toString(exec), JSEventListener::create(asObject(listener), false, currentWorld(exec)).get(), args.at(2).toBoolean(exec));
    136136    return jsUndefined();
    137137}
     
    139139JSValue JSWorkerContext::setTimeout(ExecState* exec, const ArgList& args)
    140140{
    141     ScheduledAction* action = ScheduledAction::create(exec, args);
     141    ScheduledAction* action = ScheduledAction::create(exec, args, currentWorld(exec));
    142142    if (exec->hadException())
    143143        return jsUndefined();
     
    148148JSValue JSWorkerContext::setInterval(ExecState* exec, const ArgList& args)
    149149{
    150     ScheduledAction* action = ScheduledAction::create(exec, args);
     150    ScheduledAction* action = ScheduledAction::create(exec, args, currentWorld(exec));
    151151    if (exec->hadException())
    152152        return jsUndefined();
  • trunk/WebCore/bindings/js/JSXMLHttpRequestCustom.cpp

    r49539 r49963  
    5454    Base::markChildren(markStack);
    5555
    56     if (XMLHttpRequestUpload* upload = m_impl->optionalUpload()) {
    57         DOMObject* wrapper = getCachedDOMObjectWrapper(*Heap::heap(this)->globalData(), upload);
    58         if (wrapper)
    59             markStack.append(wrapper);
    60     }
     56    if (XMLHttpRequestUpload* upload = m_impl->optionalUpload())
     57        markDOMObjectWrapper(markStack, *Heap::heap(this)->globalData(), upload);
    6158
    6259    m_impl->markEventListeners(markStack);
     
    157154        return jsUndefined();
    158155
    159     impl()->addEventListener(args.at(0).toString(exec), JSEventListener::create(asObject(listener), false), args.at(2).toBoolean(exec));
     156    impl()->addEventListener(args.at(0).toString(exec), JSEventListener::create(asObject(listener), false, currentWorld(exec)), args.at(2).toBoolean(exec));
    160157    return jsUndefined();
    161158}
     
    167164        return jsUndefined();
    168165
    169     impl()->removeEventListener(args.at(0).toString(exec), JSEventListener::create(asObject(listener), false).get(), args.at(2).toBoolean(exec));
     166    impl()->removeEventListener(args.at(0).toString(exec), JSEventListener::create(asObject(listener), false, currentWorld(exec)).get(), args.at(2).toBoolean(exec));
    170167    return jsUndefined();
    171168}
  • trunk/WebCore/bindings/js/JSXMLHttpRequestUploadCustom.cpp

    r49539 r49963  
    4646    Base::markChildren(markStack);
    4747
    48     if (XMLHttpRequest* xmlHttpRequest = m_impl->associatedXMLHttpRequest()) {
    49         DOMObject* wrapper = getCachedDOMObjectWrapper(*Heap::heap(this)->globalData(), xmlHttpRequest);
    50         if (wrapper)
    51             markStack.append(wrapper);
    52     }
     48    if (XMLHttpRequest* xmlHttpRequest = m_impl->associatedXMLHttpRequest())
     49        markDOMObjectWrapper(markStack, *Heap::heap(this)->globalData(), xmlHttpRequest);
    5350
    5451    m_impl->markEventListeners(markStack);
     
    6158        return jsUndefined();
    6259
    63     impl()->addEventListener(args.at(0).toString(exec), JSEventListener::create(asObject(listener), false), args.at(2).toBoolean(exec));
     60    impl()->addEventListener(args.at(0).toString(exec), JSEventListener::create(asObject(listener), false, currentWorld(exec)), args.at(2).toBoolean(exec));
    6461    return jsUndefined();
    6562}
     
    7168        return jsUndefined();
    7269
    73     impl()->removeEventListener(args.at(0).toString(exec), JSEventListener::create(asObject(listener), false).get(), args.at(2).toBoolean(exec));
     70    impl()->removeEventListener(args.at(0).toString(exec), JSEventListener::create(asObject(listener), false, currentWorld(exec)).get(), args.at(2).toBoolean(exec));
    7471    return jsUndefined();
    7572}
  • trunk/WebCore/bindings/js/ScheduledAction.cpp

    r49372 r49963  
    4848namespace WebCore {
    4949
    50 ScheduledAction* ScheduledAction::create(ExecState* exec, const ArgList& args)
     50ScheduledAction* ScheduledAction::create(ExecState* exec, const ArgList& args, DOMWrapperWorld* isolatedWorld)
    5151{
    5252    JSValue v = args.at(0);
     
    5656        if (exec->hadException())
    5757            return 0;
    58         return new ScheduledAction(string);
     58        return new ScheduledAction(string, isolatedWorld);
    5959    }
    6060    ArgList argsTail;
    6161    args.getSlice(2, argsTail);
    62     return new ScheduledAction(v, argsTail);
     62    return new ScheduledAction(v, argsTail, isolatedWorld);
    6363}
    6464
    65 ScheduledAction::ScheduledAction(JSValue function, const ArgList& args)
     65ScheduledAction::ScheduledAction(JSValue function, const ArgList& args, DOMWrapperWorld* isolatedWorld)
    6666    : m_function(function)
     67    , m_isolatedWorld(isolatedWorld)
    6768{
    6869    ArgList::const_iterator end = args.end();
     
    103104
    104105    globalObject->globalData()->timeoutChecker.start();
    105     call(exec, m_function, callType, callData, thisValue, args);
     106    callInWorld(exec, m_function, callType, callData, thisValue, args, m_isolatedWorld.get());
    106107    globalObject->globalData()->timeoutChecker.stop();
    107108
     
    112113void ScheduledAction::execute(Document* document)
    113114{
    114     JSDOMWindow* window = toJSDOMWindow(document->frame());
     115    JSDOMWindow* window = toJSDOMWindow(document->frame(), m_isolatedWorld.get());
    115116    if (!window)
    116117        return;
     
    126127        Document::updateStyleForAllDocuments();
    127128    } else
    128         frame->script()->executeScript(m_code);
     129        frame->script()->executeScriptInIsolatedWorld(m_isolatedWorld.get(), m_code);
    129130
    130131    frame->script()->setProcessingTimerCallback(false);
  • trunk/WebCore/bindings/js/ScheduledAction.h

    r49734 r49963  
    2222
    2323#include "PlatformString.h"
     24#include <JSDOMBinding.h>
    2425#include <runtime/JSCell.h>
    2526#include <runtime/Protect.h>
     
    4243    class ScheduledAction {
    4344    public:
    44         static ScheduledAction* create(JSC::ExecState*, const JSC::ArgList&);
     45        static ScheduledAction* create(JSC::ExecState*, const JSC::ArgList&, DOMWrapperWorld* isolatedWorld);
    4546
    4647        void execute(ScriptExecutionContext*);
    4748
    4849    private:
    49         ScheduledAction(JSC::JSValue function, const JSC::ArgList&);
    50         ScheduledAction(const String& code)
     50        ScheduledAction(JSC::JSValue function, const JSC::ArgList&, DOMWrapperWorld* isolatedWorld);
     51        ScheduledAction(const String& code, DOMWrapperWorld* isolatedWorld)
    5152            : m_code(code)
     53            , m_isolatedWorld(isolatedWorld)
    5254        {
    5355        }
     
    6264        Vector<JSC::ProtectedJSValue> m_args;
    6365        String m_code;
     66        RefPtr<DOMWrapperWorld> m_isolatedWorld;
    6467    };
    6568
  • trunk/WebCore/bindings/js/ScriptCachedFrameData.cpp

    r49134 r49963  
    4949
    5050    ScriptController* scriptController = frame->script();
    51     if (scriptController->haveWindowShell()) {
    52         m_window = scriptController->windowShell()->window();
     51    // FIXME: explicitly save and restore isolated worlds' global objects when using the back/forward cache. <rdar://problem/7328111>
     52    if (JSDOMWindowShell* windowShell = scriptController->existingWindowShell(mainThreadNormalWorld())) {
     53        m_window = windowShell->window();
    5354        scriptController->attachDebugger(0);
    5455    }
     
    7172
    7273    ScriptController* scriptController = frame->script();
    73     if (scriptController->haveWindowShell()) {
    74         JSDOMWindowShell* windowShell = scriptController->windowShell();
    75         if (m_window) {
     74    // FIXME: explicitly save and restore isolated worlds' global objects when using the back/forward cache. <rdar://problem/7328111>
     75    if (JSDOMWindowShell* windowShell = scriptController->existingWindowShell(mainThreadNormalWorld())) {
     76        if (m_window)
    7677            windowShell->setWindow(m_window.get());
    77         } else {
     78        else {
    7879            windowShell->setWindow(frame->domWindow());
    7980            scriptController->attachDebugger(page->debugger());
  • trunk/WebCore/bindings/js/ScriptController.cpp

    r49827 r49963  
    2222#include "ScriptController.h"
    2323
     24#include "CString.h"
    2425#include "Event.h"
    2526#include "EventNames.h"
     
    7273ScriptController::~ScriptController()
    7374{
    74     if (m_windowShell) {
    75         m_windowShell = 0;
     75    if (!m_windowShells.isEmpty()) {
     76        for (ShellMap::iterator iter = m_windowShells.begin(); iter != m_windowShells.end(); ++iter)
     77            iter->first->forgetScriptController(this);
     78
     79        m_windowShells.clear();
    7680   
    7781        // It's likely that releasing the global object has created a lot of garbage.
     
    8286}
    8387
    84 ScriptValue ScriptController::evaluate(const ScriptSourceCode& sourceCode)
     88ScriptValue ScriptController::evaluateInWorld(const ScriptSourceCode& sourceCode, DOMWrapperWorld* world)
    8589{
    8690    const SourceCode& jsSourceCode = sourceCode.jsSourceCode();
     
    9599    // if there was none, an error occured or the type couldn't be converted.
    96100
    97     initScriptIfNeeded();
    98101    // inlineCode is true for <a href="javascript:doSomething()">
    99102    // and false for <script>doSomething()</script>. Check if it has the
    100103    // expected value in all cases.
    101104    // See smart window.open policy for where this is used.
    102     ExecState* exec = m_windowShell->window()->globalExec();
     105    JSDOMWindowShell* shell = windowShell(world);
     106    ExecState* exec = shell->window()->globalExec();
    103107    const String* savedSourceURL = m_sourceURL;
    104108    m_sourceURL = &sourceURL;
     
    108112    RefPtr<Frame> protect = m_frame;
    109113
    110     m_windowShell->window()->globalData()->timeoutChecker.start();
    111     Completion comp = JSC::evaluate(exec, exec->dynamicGlobalObject()->globalScopeChain(), jsSourceCode, m_windowShell);
    112     m_windowShell->window()->globalData()->timeoutChecker.stop();
     114    exec->globalData().timeoutChecker.start();
     115    Completion comp = WebCore::evaluateInWorld(exec, exec->dynamicGlobalObject()->globalScopeChain(), jsSourceCode, shell, world);
     116    exec->globalData().timeoutChecker.stop();
    113117
    114118    // Evaluating the JavaScript could cause the frame to be deallocated
     
    128132}
    129133
    130 void ScriptController::evaluateInIsolatedWorld(unsigned /* worldID */, const Vector<ScriptSourceCode>& sourceCode)
    131 {
    132     // FIXME: Actually support isolated worlds!
     134ScriptValue ScriptController::evaluate(const ScriptSourceCode& sourceCode)
     135{
     136    return evaluateInWorld(sourceCode, mainThreadNormalWorld());
     137}
     138
     139// An DOMWrapperWorld other than the thread's normal world.
     140class IsolatedWorld : public DOMWrapperWorld {
     141public:
     142    IsolatedWorld(JSGlobalData* globalData)
     143        : DOMWrapperWorld(globalData)
     144    {
     145        JSGlobalData::ClientData* clientData = globalData->clientData;
     146        ASSERT(clientData);
     147        static_cast<WebCoreJSClientData*>(clientData)->rememberWorld(this);
     148    }
     149
     150    static PassRefPtr<IsolatedWorld> create(JSGlobalData* globalData) { return adoptRef(new IsolatedWorld(globalData)); }
     151};
     152
     153static PassRefPtr<IsolatedWorld> findWorld(unsigned worldID)
     154{
     155    if (!worldID)
     156        return IsolatedWorld::create(JSDOMWindow::commonJSGlobalData());
     157
     158    typedef HashMap<unsigned, RefPtr<IsolatedWorld> > WorldMap;
     159    DEFINE_STATIC_LOCAL(WorldMap, isolatedWorlds, ());
     160
     161    WorldMap::iterator iter = isolatedWorlds.find(worldID);
     162    if (iter != isolatedWorlds.end())
     163        return iter->second;
     164
     165    RefPtr<IsolatedWorld> newWorld = IsolatedWorld::create(JSDOMWindow::commonJSGlobalData());
     166    isolatedWorlds.add(worldID, newWorld);
     167    return newWorld;
     168}
     169
     170ScriptValue ScriptController::evaluateInIsolatedWorld(unsigned worldID, const ScriptSourceCode& sourceCode)
     171{
     172    RefPtr<DOMWrapperWorld> world = findWorld(worldID);
     173    return evaluateInWorld(sourceCode, world.get());
     174}
     175
     176void ScriptController::evaluateInIsolatedWorld(unsigned worldID, const Vector<ScriptSourceCode>& sourceCode)
     177{
     178    RefPtr<DOMWrapperWorld> world = findWorld(worldID);
     179
    133180    unsigned size = sourceCode.size();
    134181    for (unsigned i = 0; i < size; ++i)
    135         evaluate(sourceCode[i]);
     182        evaluateInWorld(sourceCode[i], world.get());
    136183}
    137184
    138185void ScriptController::clearWindowShell()
    139186{
    140     if (!m_windowShell)
     187    if (m_windowShells.isEmpty())
    141188        return;
    142189
     
    144191
    145192    // Clear the debugger from the current window before setting the new window.
     193    DOMWrapperWorld* debugWorld = debuggerWorld();
    146194    attachDebugger(0);
    147195
    148     m_windowShell->window()->willRemoveFromWindowShell();
    149     m_windowShell->setWindow(m_frame->domWindow());
    150 
    151     if (Page* page = m_frame->page()) {
    152         attachDebugger(page->debugger());
    153         m_windowShell->window()->setProfileGroup(page->group().identifier());
     196    for (ShellMap::iterator iter = m_windowShells.begin(); iter != m_windowShells.end(); ++iter) {
     197        DOMWrapperWorld* world = iter->first;
     198        JSDOMWindowShell* windowShell = iter->second;
     199        windowShell->window()->willRemoveFromWindowShell();
     200        windowShell->setWindow(m_frame->domWindow());
     201
     202        if (Page* page = m_frame->page()) {
     203            if (world == debugWorld)
     204                attachDebugger(page->debugger());
     205            windowShell->window()->setProfileGroup(page->group().identifier());
     206        }
    154207    }
    155208
     
    158211}
    159212
    160 void ScriptController::initScript()
    161 {
    162     if (m_windowShell)
    163         return;
    164 
    165     JSLock lock(SilenceAssertionsOnly);
    166 
    167     m_windowShell = new JSDOMWindowShell(m_frame->domWindow());
    168     m_windowShell->window()->updateDocument();
     213JSDOMWindowShell* ScriptController::initScript(DOMWrapperWorld* world)
     214{
     215    ASSERT(!m_windowShells.contains(world));
     216
     217    JSLock lock(SilenceAssertionsOnly);
     218
     219    JSDOMWindowShell* windowShell = new JSDOMWindowShell(m_frame->domWindow());
     220    m_windowShells.add(world, windowShell);
     221    world->rememberScriptController(this);
     222    windowShell->window()->updateDocument(world);
    169223
    170224    if (Page* page = m_frame->page()) {
    171         attachDebugger(page->debugger());
    172         m_windowShell->window()->setProfileGroup(page->group().identifier());
    173     }
    174 
    175     m_frame->loader()->dispatchWindowObjectAvailable();
     225        if (world == debuggerWorld())
     226            attachDebugger(page->debugger());
     227        windowShell->window()->setProfileGroup(page->group().identifier());
     228    }
     229
     230    {
     231        EnterDOMWrapperWorld worldEntry(*JSDOMWindow::commonJSGlobalData(), world);
     232        m_frame->loader()->dispatchWindowObjectAvailable();
     233    }
     234
     235    return windowShell;
    176236}
    177237
     
    183243bool ScriptController::processingUserGestureEvent() const
    184244{
    185     if (!m_windowShell)
     245    JSDOMWindowShell* shell = existingWindowShell(mainThreadNormalWorld());
     246    if (!shell)
    186247        return false;
    187248
    188     if (Event* event = m_windowShell->window()->currentEvent()) {
     249    if (Event* event = shell->window()->currentEvent()) {
    189250        if (event->createdByDOM())
    190251            return false;
     
    244305void ScriptController::attachDebugger(JSC::Debugger* debugger)
    245306{
    246     if (!m_windowShell)
     307    // FIXME: Should be able to debug isolated worlds.
     308    JSDOMWindowShell* shell = existingWindowShell(debuggerWorld());
     309    if (!shell)
    247310        return;
    248311
     312    JSDOMWindow* globalObject = shell->window();
    249313    if (debugger)
    250         debugger->attach(m_windowShell->window());
    251     else if (JSC::Debugger* currentDebugger = m_windowShell->window()->debugger())
    252         currentDebugger->detach(m_windowShell->window());
     314        debugger->attach(globalObject);
     315    else if (JSC::Debugger* currentDebugger = globalObject->debugger())
     316        currentDebugger->detach(globalObject);
    253317}
    254318
     
    259323
    260324    JSLock lock(SilenceAssertionsOnly);
    261     if (m_windowShell)
    262         m_windowShell->window()->updateDocument();
     325    for (ShellMap::iterator iter = m_windowShells.begin(); iter != m_windowShells.end(); ++iter)
     326        iter->second->window()->updateDocument(iter->first);
    263327}
    264328
     
    275339    if (!m_bindingRootObject) {
    276340        JSLock lock(SilenceAssertionsOnly);
    277         m_bindingRootObject = Bindings::RootObject::create(0, globalObject());
     341        m_bindingRootObject = Bindings::RootObject::create(0, globalObject(pluginWorld()));
    278342    }
    279343    return m_bindingRootObject.get();
     
    286350        return it->second;
    287351
    288     RefPtr<Bindings::RootObject> rootObject = Bindings::RootObject::create(nativeHandle, globalObject());
     352    RefPtr<Bindings::RootObject> rootObject = Bindings::RootObject::create(nativeHandle, globalObject(pluginWorld()));
    289353
    290354    m_rootObjects.set(nativeHandle, rootObject);
     
    301365            // Return an NPObject bound to the window object.
    302366            JSC::JSLock lock(SilenceAssertionsOnly);
    303             JSObject* win = windowShell()->window();
     367            JSObject* win = windowShell(pluginWorld())->window();
    304368            ASSERT(win);
    305369            Bindings::RootObject* root = bindingRootObject();
     
    335399    // Create a JSObject bound to this element
    336400    JSLock lock(SilenceAssertionsOnly);
    337     ExecState* exec = globalObject()->globalExec();
    338     JSValue jsElementValue = toJS(exec, globalObject(), plugin);
     401    JSDOMWindow* globalObj = globalObject(pluginWorld());
     402    // FIXME: is normal okay? - used for NP plugins?
     403    JSValue jsElementValue = toJS(globalObj->globalExec(), globalObj, plugin);
    339404    if (!jsElementValue || !jsElementValue.isObject())
    340405        return 0;
  • trunk/WebCore/bindings/js/ScriptController.h

    r49372 r49963  
    6464
    6565class ScriptController {
     66    typedef WTF::HashMap<DOMWrapperWorld*, JSC::ProtectedPtr<JSDOMWindowShell> > ShellMap;
     67
    6668public:
    6769    ScriptController(Frame*);
    6870    ~ScriptController();
    6971
    70     bool haveWindowShell() const { return m_windowShell; }
    71     JSDOMWindowShell* windowShell()
     72    JSDOMWindowShell* windowShell(DOMWrapperWorld* world)
    7273    {
    73         initScriptIfNeeded();
    74         return m_windowShell;
     74        ShellMap::iterator iter = m_windowShells.find(world);
     75        return (iter != m_windowShells.end()) ? iter->second.get() : initScript(world);
    7576    }
    76 
    77     JSDOMWindow* globalObject()
     77    JSDOMWindowShell* existingWindowShell(DOMWrapperWorld* world) const
    7878    {
    79         initScriptIfNeeded();
    80         return m_windowShell->window();
     79        ShellMap::const_iterator iter = m_windowShells.find(world);
     80        return (iter != m_windowShells.end()) ? iter->second.get() : 0;
     81    }
     82    JSDOMWindow* globalObject(DOMWrapperWorld* world)
     83    {
     84        return windowShell(world)->window();
     85    }
     86    void forgetWorld(DOMWrapperWorld* world)
     87    {
     88        m_windowShells.remove(world);
    8189    }
    8290
    8391    ScriptValue executeScript(const ScriptSourceCode&);
    8492    ScriptValue executeScript(const String& script, bool forceUserGesture = false);
     93    ScriptValue executeScriptInIsolatedWorld(unsigned worldID, const String& script, bool forceUserGesture = false);
     94    ScriptValue executeScriptInIsolatedWorld(DOMWrapperWorld* world, const String& script, bool forceUserGesture = false);
    8595
    8696    // Returns true if argument is a JavaScript URL.
     
    8898
    8999    ScriptValue evaluate(const ScriptSourceCode&);
    90     void evaluateInIsolatedWorld(unsigned worldID, const Vector<ScriptSourceCode>&);
     100    ScriptValue evaluateInWorld(const ScriptSourceCode&, DOMWrapperWorld*);
     101    ScriptValue evaluateInIsolatedWorld(unsigned /*worldID*/, const ScriptSourceCode&);
     102    void evaluateInIsolatedWorld(unsigned /*worldID*/, const Vector<ScriptSourceCode>&);
    91103
    92104    void setEventHandlerLineNumber(int lineno) { m_handlerLineNumber = lineno; }
     
    145157
    146158private:
    147     void initScriptIfNeeded()
    148     {
    149         if (!m_windowShell)
    150             initScript();
    151     }
    152     void initScript();
     159    JSDOMWindowShell* initScript(DOMWrapperWorld* world);
    153160
    154161    void disconnectPlatformScriptObjects();
     
    157164    bool isJavaScriptAnchorNavigation() const;
    158165
    159     JSC::ProtectedPtr<JSDOMWindowShell> m_windowShell;
     166    ShellMap m_windowShells;
    160167    Frame* m_frame;
    161168    int m_handlerLineNumber;
  • trunk/WebCore/bindings/js/ScriptControllerMac.mm

    r46431 r49963  
    115115        JSC::JSLock lock(JSC::SilenceAssertionsOnly);
    116116        JSC::Bindings::RootObject* root = bindingRootObject();
    117         m_windowScriptObject = [WebScriptObject scriptObjectForJSObject:toRef(windowShell()) originRootObject:root rootObject:root];
     117        m_windowScriptObject = [WebScriptObject scriptObjectForJSObject:toRef(windowShell(pluginWorld())) originRootObject:root rootObject:root];
    118118    }
    119119
  • trunk/WebCore/bindings/js/ScriptEventListener.cpp

    r48887 r49963  
    7272    }
    7373
    74     return JSLazyEventListener::create(attr->localName().string(), eventParameterName(node->isSVGElement()), attr->value(), node, sourceURL, lineNumber);
     74    return JSLazyEventListener::create(attr->localName().string(), eventParameterName(node->isSVGElement()), attr->value(), node, sourceURL, lineNumber, mainThreadNormalWorld());
    7575}
    7676
     
    9494    lineNumber = scriptController->eventHandlerLineNumber();
    9595    sourceURL = frame->document()->url().string();
    96     return JSLazyEventListener::create(attr->localName().string(), eventParameterName(frame->document()->isSVGDocument()), attr->value(), 0, sourceURL, lineNumber);
     96    return JSLazyEventListener::create(attr->localName().string(), eventParameterName(frame->document()->isSVGDocument()), attr->value(), 0, sourceURL, lineNumber, mainThreadNormalWorld());
    9797}
    9898
  • trunk/WebCore/bindings/js/ScriptFunctionCall.cpp

    r46490 r49963  
    124124        return ScriptValue();
    125125
    126     JSValue result = JSC::call(m_exec, function, callType, callData, thisObject, m_arguments);
     126    // FIXME: Should this function take a worldID? - only used by inspector?
     127    JSValue result = callInWorld(m_exec, function, callType, callData, thisObject, m_arguments, debuggerWorld());
    127128    if (m_exec->hadException()) {
    128129        if (reportExceptions)
     
    162163        return ScriptObject();
    163164
    164     JSValue result = JSC::construct(m_exec, constructor, constructType, constructData, m_arguments);
     165    // FIXME: Currently this method constructs objects in debuggerWorld().  We could use the current world, or pass a worldID to this function?
     166    JSValue result = constructInWorld(m_exec, constructor, constructType, constructData, m_arguments, debuggerWorld());
    165167    if (m_exec->hadException()) {
    166168        if (reportExceptions)
  • trunk/WebCore/bindings/js/ScriptObjectQuarantine.cpp

    r48430 r49963  
    7373        return false;
    7474
    75     JSDOMGlobalObject* globalObject = toJSDOMWindow(frame);
     75    JSDOMGlobalObject* globalObject = toJSDOMWindow(frame, debuggerWorld());
    7676    ExecState* exec = globalObject->globalExec();
    7777
     
    9090    ASSERT(frame);
    9191
    92     JSDOMGlobalObject* globalObject = toJSDOMWindow(frame);
     92    JSDOMGlobalObject* globalObject = toJSDOMWindow(frame, debuggerWorld());
    9393    ExecState* exec = globalObject->globalExec();
    9494
     
    117117    ASSERT(domWindow);
    118118
    119     JSDOMWindow* window = toJSDOMWindow(domWindow->frame());
     119    JSDOMWindow* window = toJSDOMWindow(domWindow->frame(), debuggerWorld());
    120120    ExecState* exec = window->globalExec();
    121121
  • trunk/WebCore/bindings/js/ScriptState.cpp

    r42901 r49963  
    3333
    3434#include "Frame.h"
     35#include "JSDOMWindowBase.h"
    3536#include "Node.h"
    3637#include "Page.h"
     
    5051    if (!frame->script()->isEnabled())
    5152        return 0;
    52     return frame->script()->globalObject()->globalExec();
     53    return frame->script()->globalObject(mainThreadCurrentWorld())->globalExec();
    5354}
    5455
    5556ScriptState* scriptStateFromPage(Page* page)
    5657{
    57     return page->mainFrame()->script()->globalObject()->globalExec();
     58    return page->mainFrame()->script()->globalObject(mainThreadCurrentWorld())->globalExec();
    5859}
    5960
  • trunk/WebCore/bindings/js/ScriptState.h

    r42903 r49963  
    3636
    3737namespace WebCore {
     38    class DOMWrapperWorld;
    3839    class Node;
    3940    class Page;
  • trunk/WebCore/bindings/js/WorkerScriptController.cpp

    r46890 r49963  
    5353    , m_executionForbidden(false)
    5454{
     55    m_globalData->clientData = new WebCoreJSClientData(m_globalData.get());
    5556}
    5657
     
    123124    ExecState* exec = m_workerContextWrapper->globalExec();
    124125    m_workerContextWrapper->globalData()->timeoutChecker.start();
    125     Completion comp = JSC::evaluate(exec, exec->dynamicGlobalObject()->globalScopeChain(), sourceCode.jsSourceCode(), m_workerContextWrapper);
     126    Completion comp = evaluateInWorld(exec, exec->dynamicGlobalObject()->globalScopeChain(), sourceCode.jsSourceCode(), m_workerContextWrapper, currentWorld(exec));
    126127    m_workerContextWrapper->globalData()->timeoutChecker.stop();
    127128
  • trunk/WebCore/bindings/js/WorkerScriptController.h

    r45891 r49963  
    6363
    6464        void forbidExecution();
     65
     66        JSC::JSGlobalData* globalData() { return m_globalData.get(); }
     67
    6568    private:
    6669        void initScriptIfNeeded()
  • trunk/WebCore/bindings/objc/DOMInternal.mm

    r48513 r49963  
    113113        return;
    114114
    115     // The global object which should own this node.
    116     WebCore::JSDOMGlobalObject* globalObject = frame->script()->globalObject();
     115    // The global object which should own this node - FIXME: does this need to be isolated-world aware?
     116    WebCore::JSDOMGlobalObject* globalObject = frame->script()->globalObject(WebCore::mainThreadNormalWorld());
    117117    JSC::ExecState *exec = globalObject->globalExec();
    118118
  • trunk/WebCore/bindings/objc/WebScriptObject.mm

    r46431 r49963  
    300300
    301301    [self _rootObject]->globalObject()->globalData()->timeoutChecker.start();
    302     JSValue result = call(exec, function, callType, callData, [self _imp], argList);
     302    JSValue result = callInWorld(exec, function, callType, callData, [self _imp], argList, pluginWorld());
    303303    [self _rootObject]->globalObject()->globalData()->timeoutChecker.stop();
    304304
     
    329329   
    330330    [self _rootObject]->globalObject()->globalData()->timeoutChecker.start();
    331     Completion completion = JSC::evaluate([self _rootObject]->globalObject()->globalExec(), [self _rootObject]->globalObject()->globalScopeChain(), makeSource(String(script)));
     331    Completion completion = evaluateInWorld([self _rootObject]->globalObject()->globalExec(), [self _rootObject]->globalObject()->globalScopeChain(), makeSource(String(script)), JSC::JSValue(), pluginWorld());
    332332    [self _rootObject]->globalObject()->globalData()->timeoutChecker.stop();
    333333    ComplType type = completion.complType();
  • trunk/WebCore/bindings/scripts/CodeGeneratorJS.pm

    r49841 r49963  
    11891189        }
    11901190
    1191         if ($interfaceName eq "Node") {
    1192              push(@implContent, "    forgetDOMNode(impl()->document(), impl());\n");
    1193         } else {
    1194             if ($podType) {
    1195                 my $animatedType = $implClassName;
    1196                 $animatedType =~ s/SVG/SVGAnimated/;
    1197 
    1198                 # Special case for JSSVGNumber
    1199                 if ($codeGenerator->IsSVGAnimatedType($animatedType) and $podType ne "float") {
    1200                     push(@implContent, "    JSSVGDynamicPODTypeWrapperCache<$podType, $animatedType>::forgetWrapper(m_impl.get());\n");
     1191        if (!$dataNode->extendedAttributes->{"ExtendsDOMGlobalObject"}) {
     1192            if ($interfaceName eq "Node") {
     1193                 push(@implContent, "    forgetDOMNode(this, impl(), impl()->document());\n");
     1194            } else {
     1195                if ($podType) {
     1196                    my $animatedType = $implClassName;
     1197                    $animatedType =~ s/SVG/SVGAnimated/;
     1198
     1199                    # Special case for JSSVGNumber
     1200                    if ($codeGenerator->IsSVGAnimatedType($animatedType) and $podType ne "float") {
     1201                        push(@implContent, "    JSSVGDynamicPODTypeWrapperCache<$podType, $animatedType>::forgetWrapper(m_impl.get());\n");
     1202                    }
    12011203                }
     1204                push(@implContent, "    forgetDOMObject(this, impl());\n");
    12021205            }
    1203             push(@implContent, "    forgetDOMObject(*Heap::heap(this)->globalData(), impl());\n");
    12041206        }
    12051207
     
    12111213    if ($interfaceName eq "Document") {
    12121214        push(@implContent, "${className}::~$className()\n");
    1213         push(@implContent, "{\n    forgetDOMObject(*Heap::heap(this)->globalData(), static_cast<${implClassName}*>(impl()));\n}\n\n");
     1215        push(@implContent, "{\n    forgetDOMObject(this, static_cast<${implClassName}*>(impl()));\n}\n\n");
    12141216    }
    12151217
     
    14771479                                $implIncludes{"Frame.h"} = 1;
    14781480                                $implIncludes{"JSDOMGlobalObject.h"} = 1;
    1479                                 push(@implContent, "    JSDOMGlobalObject* globalObject = toJSDOMGlobalObject(imp->scriptExecutionContext());\n");
     1481                                push(@implContent, "    JSDOMGlobalObject* globalObject = toJSDOMGlobalObject(imp->scriptExecutionContext(), exec);\n");
    14801482                                push(@implContent, "    if (!globalObject)\n");
    14811483                                push(@implContent, "        return;\n");
  • trunk/WebCore/bridge/NP_jsobject.cpp

    r46431 r49963  
    3535#include "c_instance.h"
    3636#include "IdentifierRep.h"
     37#include "JSDOMBinding.h"
    3738#include "npruntime_impl.h"
    3839#include "npruntime_priv.h"
     
    124125        ProtectedPtr<JSGlobalObject> globalObject = rootObject->globalObject();
    125126        globalObject->globalData()->timeoutChecker.start();
    126         JSValue resultV = call(exec, function, callType, callData, function, argList);
     127        JSValue resultV = callInWorld(exec, function, callType, callData, function, argList, pluginWorld());
    127128        globalObject->globalData()->timeoutChecker.stop();
    128129
     
    174175        ProtectedPtr<JSGlobalObject> globalObject = rootObject->globalObject();
    175176        globalObject->globalData()->timeoutChecker.start();
    176         JSValue resultV = call(exec, function, callType, callData, obj->imp, argList);
     177        JSValue resultV = callInWorld(exec, function, callType, callData, obj->imp, argList, pluginWorld());
    177178        globalObject->globalData()->timeoutChecker.stop();
    178179
     
    204205        ProtectedPtr<JSGlobalObject> globalObject = rootObject->globalObject();
    205206        globalObject->globalData()->timeoutChecker.start();
    206         Completion completion = JSC::evaluate(globalObject->globalExec(), globalObject->globalScopeChain(), makeSource(scriptString));
     207        Completion completion = evaluateInWorld(globalObject->globalExec(), globalObject->globalScopeChain(), makeSource(scriptString), JSC::JSValue(), pluginWorld());
    207208        globalObject->globalData()->timeoutChecker.stop();
    208209        ComplType type = completion.complType();
     
    444445        ProtectedPtr<JSGlobalObject> globalObject = rootObject->globalObject();
    445446        globalObject->globalData()->timeoutChecker.start();
    446         JSValue resultV = construct(exec, constructor, constructType, constructData, argList);
     447        JSValue resultV = constructInWorld(exec, constructor, constructType, constructData, argList, pluginWorld());
    447448        globalObject->globalData()->timeoutChecker.stop();
    448449       
  • trunk/WebCore/bridge/jni/jni_jsobject.mm

    r47236 r49963  
    3030
    3131#include "Frame.h"
     32#include "JSDOMBinding.h"
    3233#include "ScriptController.h"
    3334#include "StringSourceProvider.h"
     
    303304    getListFromJArray(exec, args, argList);
    304305    rootObject->globalObject()->globalData()->timeoutChecker.start();
    305     JSValue result = JSC::call(exec, function, callType, callData, _imp, argList);
     306    JSValue result = WebCore::callInWorld(exec, function, callType, callData, _imp, argList, WebCore::pluginWorld());
    306307    rootObject->globalObject()->globalData()->timeoutChecker.stop();
    307308
     
    322323
    323324    rootObject->globalObject()->globalData()->timeoutChecker.start();
    324     Completion completion = JSC::evaluate(rootObject->globalObject()->globalExec(), rootObject->globalObject()->globalScopeChain(), makeSource(JavaString(script)));
     325    Completion completion = WebCore::evaluateInWorld(rootObject->globalObject()->globalExec(), rootObject->globalObject()->globalScopeChain(), makeSource(JavaString(script)), JSC::JSValue(), WebCore::pluginWorld());
    325326    rootObject->globalObject()->globalData()->timeoutChecker.stop();
    326327    ComplType type = completion.complType();
  • trunk/WebCore/dom/Document.cpp

    r49827 r49963  
    512512}
    513513
     514Document::JSWrapperCache* Document::createWrapperCache(DOMWrapperWorld* world)
     515{
     516    JSWrapperCache* wrapperCache = new JSWrapperCache();
     517    m_wrapperCacheMap.set(world, wrapperCache);
     518    world->rememberDocument(this);
     519    return wrapperCache;
     520}
     521
    514522void Document::resetLinkColor()
    515523{
  • trunk/WebCore/dom/Document.h

    r49507 r49963  
    8080    class InspectorTimelineAgent;
    8181    class IntPoint;
     82    class DOMWrapperWorld;
    8283    class JSNode;
    8384    class MouseEventWithHitTestResults;
     
    820821
    821822    typedef HashMap<WebCore::Node*, JSNode*> JSWrapperCache;
    822     JSWrapperCache& wrapperCache() { return m_wrapperCache; }
     823    typedef HashMap<DOMWrapperWorld*, JSWrapperCache*> JSWrapperCacheMap;
     824    JSWrapperCacheMap& wrapperCacheMap() { return m_wrapperCacheMap; }
     825    JSWrapperCache* getWrapperCache(DOMWrapperWorld* world)
     826    {
     827        if (JSWrapperCache* wrapperCache = m_wrapperCacheMap.get(world))
     828            return wrapperCache;
     829        return createWrapperCache(world);
     830    }
     831    JSWrapperCache* createWrapperCache(DOMWrapperWorld*);
    823832
    824833    virtual void finishedParsing();
     
    11381147    unsigned m_numNodeListCaches;
    11391148
    1140     JSWrapperCache m_wrapperCache;
     1149    JSWrapperCacheMap m_wrapperCacheMap;
    11411150
    11421151#if ENABLE(DATABASE)
  • trunk/WebCore/dom/ScriptExecutionContext.cpp

    r44915 r49963  
    3030#include "ActiveDOMObject.h"
    3131#include "Document.h"
     32#include "JSDOMWindow.h"
    3233#include "MessagePort.h"
    3334#include "SecurityOrigin.h"
     
    196197}
    197198
     199JSC::JSGlobalData* ScriptExecutionContext::globalData()
     200{
     201     if (isDocument())
     202        return JSDOMWindow::commonJSGlobalData();
     203
     204#if ENABLE(WORKERS)
     205    if (isWorkerContext())
     206        return static_cast<WorkerContext*>(this)->script()->globalData();
     207#endif
     208
     209    ASSERT_NOT_REACHED();
     210    return 0;
     211}
     212
    198213} // namespace WebCore
  • trunk/WebCore/dom/ScriptExecutionContext.h

    r48430 r49963  
    105105        DOMTimer* findTimeout(int timeoutId);
    106106
     107        JSC::JSGlobalData* globalData();
     108
    107109    protected:
    108110        // Explicitly override the security origin for this script context.
  • trunk/WebCore/inspector/InspectorController.cpp

    r49954 r49963  
    14451445    UString title = getCurrentUserInitiatedProfileName(true);
    14461446
    1447     ExecState* scriptState = toJSDOMWindow(m_inspectedPage->mainFrame())->globalExec();
     1447    ExecState* scriptState = toJSDOMWindow(m_inspectedPage->mainFrame(), debuggerWorld())->globalExec();
    14481448    Profiler::profiler()->startProfiling(scriptState, title);
    14491449
     
    14621462    UString title = getCurrentUserInitiatedProfileName();
    14631463
    1464     ExecState* scriptState = toJSDOMWindow(m_inspectedPage->mainFrame())->globalExec();
     1464    ExecState* scriptState = toJSDOMWindow(m_inspectedPage->mainFrame(), debuggerWorld())->globalExec();
    14651465    RefPtr<Profile> profile = Profiler::profiler()->stopProfiling(scriptState, title);
    14661466    if (profile)
  • trunk/WebCore/inspector/JavaScriptCallFrame.cpp

    r46431 r49963  
    2626#include "config.h"
    2727#include "JavaScriptCallFrame.h"
     28#include "JSDOMBinding.h"
    2829
    2930#if ENABLE(JAVASCRIPT_DEBUGGER)
     
    106107
    107108    JSLock lock(SilenceAssertionsOnly);
    108     return m_debuggerCallFrame.evaluate(script, exception);
     109    return DebuggerCallFrame_evaluateInWorld(m_debuggerCallFrame, script, exception);
    109110}
    110111
  • trunk/WebCore/loader/FrameLoader.cpp

    r49829 r49963  
    38463846void FrameLoader::dispatchWindowObjectAvailable()
    38473847{
    3848     if (!m_frame->script()->isEnabled() || !m_frame->script()->haveWindowShell())
     3848    // FIXME: should this be isolated-worlds-aware?
     3849    if (!m_frame->script()->isEnabled() || !m_frame->script()->existingWindowShell(mainThreadNormalWorld()))
    38493850        return;
    38503851
  • trunk/WebCore/plugins/PluginView.cpp

    r49732 r49963  
    395395    JSLock lock(JSC::SilenceAssertionsOnly);
    396396
    397     ExecState* exec = proxy->globalObject()->globalExec();
     397    ExecState* exec = proxy->globalObject(pluginWorld())->globalExec();
    398398    UString ustring = result.toString(exec);
    399399    exec->clearException();
  • trunk/WebCore/xml/XMLHttpRequest.cpp

    r48739 r49963  
    605605    // can't be recouped until the load is done, so only
    606606    // report the extra cost at that point.
    607 
    608     if (JSDOMGlobalObject* globalObject = toJSDOMGlobalObject(scriptExecutionContext()))
    609         if (DOMObject* wrapper = getCachedDOMObjectWrapper(*globalObject->globalData(), this))
    610             JSC::Heap::heap(wrapper)->reportExtraMemoryCost(m_responseText.size() * 2);
     607    if (DOMObject* wrapper = getCachedDOMObjectWrapper(*scriptExecutionContext()->globalData(), this))
     608        JSC::Heap::heap(wrapper)->reportExtraMemoryCost(m_responseText.size() * 2);
    611609#endif
    612610
  • trunk/WebCore/xml/XMLHttpRequest.h

    r48701 r49963  
    2727#include "EventTarget.h"
    2828#include "FormData.h"
     29#include "JSDOMBinding.h"
    2930#include "ResourceResponse.h"
    3031#include "ScriptString.h"
    3132#include "ThreadableLoaderClient.h"
    3233#include <wtf/OwnPtr.h>
     34#include <runtime/Protect.h>
    3335
    3436namespace WebCore {
     
    183185    String m_lastSendURL;
    184186    ExceptionCode m_exceptionCode;
    185    
     187
    186188    EventTargetData m_eventTargetData;
    187189};
  • trunk/WebKit/mac/ChangeLog

    r49948 r49963  
     12009-10-16  Gavin Barraclough  <barraclough@apple.com>
     2
     3        Reviewed by Sam Weinig & Geoff Garen.
     4
     5        https://bugs.webkit.org/show_bug.cgi?id=30696
     6        Update to incorporate support for IsolatedWorlds in JSC bindings.
     7
     8        * WebView/WebFrame.mm:
     9        (-[WebFrame _attachScriptDebugger]):
     10        (-[WebFrame _stringByEvaluatingJavaScriptFromString:forceUserGesture:]):
     11        (-[WebFrame globalContext]):
     12        * WebView/WebScriptDebugDelegate.mm:
     13        (-[WebScriptCallFrame evaluateWebScript:]):
     14        * WebView/WebView.mm:
     15        (-[WebView aeDescByEvaluatingJavaScriptFromString:]):
     16
    1172009-10-22  Eric Carlson  <eric.carlson@apple.com>
    218
  • trunk/WebKit/mac/WebView/WebFrame.mm

    r49372 r49963  
    8686#import <WebCore/visible_units.h>
    8787#import <runtime/JSLock.h>
     88#import <runtime/JSObject.h>
    8889#import <runtime/JSValue.h>
    8990#import <wtf/CurrentTime.h>
     
    271272
    272273    // Calling ScriptController::globalObject() would create a window shell, and dispatch corresponding callbacks, which may be premature
    273     //  if the script debugger is attached before a document is created.
    274     if (!scriptController->haveWindowShell())
     274    // if the script debugger is attached before a document is created.  These calls use the debuggerWorld(), we will need to pass a world
     275    // to be able to debug isolated worlds.
     276    if (!scriptController->existingWindowShell(debuggerWorld()))
    275277        return;
    276278
    277     JSGlobalObject* globalObject = scriptController->globalObject();
     279    JSGlobalObject* globalObject = scriptController->globalObject(debuggerWorld());
    278280    if (!globalObject)
    279281        return;
     
    608610
    609611    JSLock lock(SilenceAssertionsOnly);
    610     return String(result.toString(_private->coreFrame->script()->globalObject()->globalExec()));
     612    return String(result.toString(_private->coreFrame->script()->globalObject(mainThreadNormalWorld())->globalExec()));
    611613}
    612614
     
    12031205}
    12041206
     1207- (NSString *)_stringByEvaluatingJavaScriptInIsolatedWorld:(unsigned)worldID WithGlobalObject:(JSObjectRef)globalObjectRef FromString:(NSString *)string
     1208{
     1209    // Start off with some guess at a frame and a global object, we'll try to do better...!
     1210    JSDOMWindow* anyWorldGlobalObject = _private->coreFrame->script()->globalObject(mainThreadNormalWorld());
     1211
     1212    // The global object is probably a shell object? - if so, we know how to use this!
     1213    JSC::JSObject* globalObjectObj = toJS(globalObjectRef);
     1214    if (!strcmp(globalObjectObj->classInfo()->className, "JSDOMWindowShell"))
     1215        anyWorldGlobalObject = static_cast<JSDOMWindowShell*>(globalObjectObj)->window();
     1216
     1217    // Get the frame frome the global object we've settled on.
     1218    Frame* frame = anyWorldGlobalObject->impl()->frame();
     1219    ASSERT(frame->document());
     1220    JSValue result = frame->script()->executeScriptInIsolatedWorld(worldID, string, true).jsValue();
     1221
     1222    if (!frame) // In case the script removed our frame from the page.
     1223        return @"";
     1224
     1225    // This bizarre set of rules matches behavior from WebKit for Safari 2.0.
     1226    // If you don't like it, use -[WebScriptObject evaluateWebScript:] or
     1227    // JSEvaluateScript instead, since they have less surprising semantics.
     1228    if (!result || !result.isBoolean() && !result.isString() && !result.isNumber())
     1229        return @"";
     1230
     1231    JSLock lock(SilenceAssertionsOnly);
     1232    return String(result.toString(anyWorldGlobalObject->globalExec()));
     1233}
     1234
    12051235@end
    12061236
     
    14341464    if (!coreFrame)
    14351465        return 0;
    1436     return toGlobalRef(coreFrame->script()->globalObject()->globalExec());
     1466    return toGlobalRef(coreFrame->script()->globalObject(mainThreadNormalWorld())->globalExec());
    14371467}
    14381468
  • trunk/WebKit/mac/WebView/WebFramePrivate.h

    r48946 r49963  
    9797#endif
    9898
     99- (NSString *)_stringByEvaluatingJavaScriptInIsolatedWorld:(unsigned)worldID WithGlobalObject:(JSObjectRef)globalObject FromString:(NSString *)string;
     100
    99101// Pause a given CSS animation or transition on the target node at a specific time.
    100102// If the animation or transition is already paused, it will update its pause time.
  • trunk/WebKit/mac/WebView/WebScriptDebugDelegate.mm

    r46431 r49963  
    250250
    251251    JSValue exception;
    252     JSValue result = _private->debuggerCallFrame->evaluate(String(script), exception);
     252    JSValue result = DebuggerCallFrame_evaluateInWorld(*_private->debuggerCallFrame, String(script), exception);
    253253    if (exception)
    254254        return [self _convertValueToObjcValue:exception];
  • trunk/WebKit/mac/WebView/WebView.mm

    r49843 r49963  
    41684168        return 0;
    41694169    JSLock lock(SilenceAssertionsOnly);
    4170     return aeDescFromJSValue(coreFrame->script()->globalObject()->globalExec(), result);
     4170    return aeDescFromJSValue(coreFrame->script()->globalObject(mainThreadNormalWorld())->globalExec(), result);
    41714171}
    41724172
  • trunk/WebKit/win/ChangeLog

    r49843 r49963  
     12009-10-22  Gavin Barraclough  <barraclough@apple.com>
     2
     3        Reviewed by Sam Weinig & Geoff Garen.
     4
     5        https://bugs.webkit.org/show_bug.cgi?id=30696
     6        Update to incorporate support for IsolatedWorlds in JSC bindings.
     7
     8        * Interfaces/IWebFramePrivate.idl:
     9        * WebFrame.cpp:
     10        (WebFrame::globalContext):
     11        (WebFrame::windowObjectCleared):
     12        (WebFrame::stringByEvaluatingJavaScriptInIsolatedWorld):
     13        * WebFrame.h:
     14
    1152009-10-20  Fumitoshi Ukai  <ukai@chromium.org>
    216
  • trunk/WebKit/win/Interfaces/IWebFramePrivate.idl

    r48946 r49963  
    9494
    9595    HRESULT allowsFollowingLink([in] BSTR url, [out, retval] BOOL* result);
     96
     97    HRESULT stringByEvaluatingJavaScriptInIsolatedWorld([in] unsigned worldID, [in] OLE_HANDLE jsGlobalObject, [in] BSTR script, [out, retval] BSTR* result);
    9698}
  • trunk/WebKit/win/WebFrame.cpp

    r49284 r49963  
    9797#include <WebCore/SecurityOrigin.h>
    9898#include <JavaScriptCore/APICast.h>
     99#include <JavaScriptCore/JSLock.h>
     100#include <JavaScriptCore/JSObject.h>
     101#include <JavaScriptCore/JSValue.h>
    99102#include <wtf/MathExtras.h>
    100103#pragma warning(pop)
     
    116119using namespace WebCore;
    117120using namespace HTMLNames;
     121
     122using JSC::JSGlobalObject;
     123using JSC::JSLock;
     124using JSC::JSValue;
     125using JSC::SilenceAssertionsOnly;
    118126
    119127#define FLASH_REDRAW 0
     
    480488        return 0;
    481489
    482     return toGlobalRef(coreFrame->script()->globalObject()->globalExec());
     490    return toGlobalRef(coreFrame->script()->globalObject(mainThreadNormalWorld())->globalExec());
    483491}
    484492
     
    17031711    COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
    17041712    if (SUCCEEDED(d->webView->frameLoadDelegate(&frameLoadDelegate))) {
    1705         JSContextRef context = toRef(coreFrame->script()->globalObject()->globalExec());
    1706         JSObjectRef windowObject = toRef(coreFrame->script()->globalObject());
     1713        JSContextRef context = toRef(coreFrame->script()->globalObject(mainThreadNormalWorld())->globalExec());
     1714        JSObjectRef windowObject = toRef(coreFrame->script()->globalObject(mainThreadNormalWorld()));
    17071715        ASSERT(windowObject);
    17081716
     
    21492157}
    21502158
     2159HRESULT STDMETHODCALLTYPE WebFrame::stringByEvaluatingJavaScriptInIsolatedWorld(
     2160    /* [in] */ unsigned int worldID,
     2161    /* [in] */ OLE_HANDLE jsGlobalObject,
     2162    /* [in] */ BSTR script,
     2163    /* [retval][out] */ BSTR* evaluationResult)
     2164{
     2165    if (!evaluationResult)
     2166        return E_POINTER;
     2167    *evaluationResult = 0;
     2168
     2169    Frame* coreFrame = core(this);
     2170    JSObjectRef globalObjectRef = reinterpret_cast<JSObjectRef>(jsGlobalObject);
     2171    String string = String(script, SysStringLen(script));
     2172
     2173    // Start off with some guess at a frame and a global object, we'll try to do better...!
     2174    JSDOMWindow* anyWorldGlobalObject = coreFrame->script()->globalObject(mainThreadNormalWorld());
     2175
     2176    // The global object is probably a shell object? - if so, we know how to use this!
     2177    JSC::JSObject* globalObjectObj = toJS(globalObjectRef);
     2178    if (!strcmp(globalObjectObj->classInfo()->className, "JSDOMWindowShell"))
     2179        anyWorldGlobalObject = static_cast<JSDOMWindowShell*>(globalObjectObj)->window();
     2180
     2181    // Get the frame frome the global object we've settled on.
     2182    Frame* frame = anyWorldGlobalObject->impl()->frame();
     2183    ASSERT(frame->document());
     2184    JSValue result = frame->script()->executeScriptInIsolatedWorld(worldID, string, true).jsValue();
     2185
     2186    if (!frame) // In case the script removed our frame from the page.
     2187        return S_OK;
     2188
     2189    // This bizarre set of rules matches behavior from WebKit for Safari 2.0.
     2190    // If you don't like it, use -[WebScriptObject evaluateWebScript:] or
     2191    // JSEvaluateScript instead, since they have less surprising semantics.
     2192    if (!result || !result.isBoolean() && !result.isString() && !result.isNumber())
     2193        return S_OK;
     2194
     2195    JSLock lock(SilenceAssertionsOnly);
     2196    String resultString = String(result.toString(anyWorldGlobalObject->globalExec()));
     2197    *evaluationResult = BString(resultString).release();
     2198
     2199    return S_OK;
     2200}
     2201
    21512202void WebFrame::unmarkAllMisspellings()
    21522203{
  • trunk/WebKit/win/WebFrame.h

    r48946 r49963  
    244244        /* [in] */ BSTR url,
    245245        /* [retval][out] */ BOOL* result);
     246
     247    virtual HRESULT STDMETHODCALLTYPE stringByEvaluatingJavaScriptInIsolatedWorld(
     248        /* [in] */ unsigned int worldID,
     249        /* [in] */ OLE_HANDLE jsGlobalObject,
     250        /* [in] */ BSTR script,
     251        /* [retval][out] */ BSTR* evaluationResult);
    246252
    247253    // IWebDocumentText
  • trunk/WebKitTools/ChangeLog

    r49931 r49963  
     12009-10-22  Gavin Barraclough  <barraclough@apple.com>
     2
     3        Reviewed by Sam Weinig & Geoff Garen.
     4
     5        https://bugs.webkit.org/show_bug.cgi?id=30696
     6        Enable isolated-worlds tests on mac.
     7
     8        Add private interface for DRT to invoke execution in a given world.
     9
     10        * DumpRenderTree/LayoutTestController.cpp:
     11        (evaluateScriptInIsolatedWorldCallback):
     12        (LayoutTestController::staticFunctions):
     13        * DumpRenderTree/LayoutTestController.h:
     14        * DumpRenderTree/mac/LayoutTestControllerMac.mm:
     15        (LayoutTestController::evaluateScriptInIsolatedWorld):
     16        * DumpRenderTree/win/LayoutTestControllerWin.cpp:
     17        (LayoutTestController::evaluateScriptInIsolatedWorld):
     18
    1192009-10-21  Eric Seidel  <eric@webkit.org>
    220
  • trunk/WebKitTools/DumpRenderTree/LayoutTestController.cpp

    r49564 r49963  
    3232#include "WorkQueue.h"
    3333#include "WorkQueueItem.h"
     34#include <JavaScriptCore/JSContextRef.h>
    3435#include <JavaScriptCore/JSObjectRef.h>
    3536#include <JavaScriptCore/JSRetainPtr.h>
     
    979980}
    980981
     982static JSValueRef evaluateScriptInIsolatedWorldCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
     983{
     984    LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
     985    double worldID = JSValueToNumber(context, arguments[0], exception);
     986    ASSERT(!*exception);
     987    JSRetainPtr<JSStringRef> script(Adopt, JSValueToStringCopy(context, arguments[1], exception));
     988    ASSERT(!*exception);
     989
     990    controller->evaluateScriptInIsolatedWorld(static_cast<unsigned>(worldID), JSContextGetGlobalObject(context), script.get());
     991    return JSValueMakeUndefined(context);
     992}
     993
    981994static JSValueRef elementDoesAutoCompleteForElementWithIdCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
    982995{
     
    11871200        { "encodeHostName", encodeHostNameCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
    11881201        { "evaluateInWebInspector", evaluateInWebInspectorCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
     1202        { "evaluateScriptInIsolatedWorld", evaluateScriptInIsolatedWorldCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
    11891203        { "execCommand", execCommandCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
    11901204        { "grantDesktopNotificationPermission", grantDesktopNotificationPermissionCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
  • trunk/WebKitTools/DumpRenderTree/LayoutTestController.h

    r49564 r49963  
    214214    void closeWebInspector();
    215215    void evaluateInWebInspector(long callId, JSStringRef script);
     216    void evaluateScriptInIsolatedWorld(unsigned worldId, JSObjectRef globalObject, JSStringRef script);
    216217
    217218    void setPOSIXLocale(JSStringRef locale);
  • trunk/WebKitTools/DumpRenderTree/mac/LayoutTestControllerMac.mm

    r49613 r49963  
    516516    [[[mainFrame webView] inspector] evaluateInFrontend:nil callId:callId script:scriptNS];
    517517}
     518
     519void LayoutTestController::evaluateScriptInIsolatedWorld(unsigned worldID, JSObjectRef globalObject, JSStringRef script)
     520{
     521    RetainPtr<CFStringRef> scriptCF(AdoptCF, JSStringCopyCFString(kCFAllocatorDefault, script));
     522    NSString *scriptNS = (NSString *)scriptCF.get();
     523    [mainFrame _stringByEvaluatingJavaScriptInIsolatedWorld:worldID WithGlobalObject:globalObject FromString:scriptNS];
     524}
  • trunk/WebKitTools/DumpRenderTree/win/LayoutTestControllerWin.cpp

    r49613 r49963  
    948948}
    949949
     950void LayoutTestController::evaluateScriptInIsolatedWorld(unsigned worldId, JSObjectRef globalObject, JSStringRef script)
     951{
     952    COMPtr<IWebFramePrivate> framePrivate(Query, frame);
     953    if (!framePrivate)
     954        return;
     955
     956    BSTR result;
     957    if (FAILED(framePrivate->stringByEvaluatingJavaScriptInIsolatedWorld(worldId, reinterpret_cast<OLE_HANDLE>(globalObject), bstrT(script).GetBSTR(), &result)))
     958        return;
     959    SysFreeString(result);
     960}
     961
    950962void LayoutTestController::removeAllVisitedLinks()
    951963{
Note: See TracChangeset for help on using the changeset viewer.