diff options
author | Steve Block <steveblock@google.com> | 2010-02-15 12:23:52 +0000 |
---|---|---|
committer | Steve Block <steveblock@google.com> | 2010-02-16 11:48:32 +0000 |
commit | 8a0914b749bbe7da7768e07a7db5c6d4bb09472b (patch) | |
tree | 73f9065f370435d6fde32ae129d458a8c77c8dff /WebCore/bindings/js | |
parent | bf14be70295513b8076f3fa47a268a7e42b2c478 (diff) | |
download | external_webkit-8a0914b749bbe7da7768e07a7db5c6d4bb09472b.zip external_webkit-8a0914b749bbe7da7768e07a7db5c6d4bb09472b.tar.gz external_webkit-8a0914b749bbe7da7768e07a7db5c6d4bb09472b.tar.bz2 |
Merge webkit.org at r54731 : Initial merge by git
Change-Id: Ia79977b6cf3b0b00c06ef39419989b28e57e4f4a
Diffstat (limited to 'WebCore/bindings/js')
34 files changed, 372 insertions, 125 deletions
diff --git a/WebCore/bindings/js/JSAbstractWorkerCustom.cpp b/WebCore/bindings/js/JSAbstractWorkerCustom.cpp index 6eca7bd..61fcf98 100644 --- a/WebCore/bindings/js/JSAbstractWorkerCustom.cpp +++ b/WebCore/bindings/js/JSAbstractWorkerCustom.cpp @@ -50,7 +50,7 @@ JSValue JSAbstractWorker::addEventListener(ExecState* exec, const ArgList& args) if (!listener.isObject()) return jsUndefined(); - impl()->addEventListener(args.at(0).toString(exec), JSEventListener::create(asObject(listener), false, currentWorld(exec)), args.at(2).toBoolean(exec)); + impl()->addEventListener(args.at(0).toString(exec), JSEventListener::create(asObject(listener), this, false, currentWorld(exec)), args.at(2).toBoolean(exec)); return jsUndefined(); } @@ -60,7 +60,7 @@ JSValue JSAbstractWorker::removeEventListener(ExecState* exec, const ArgList& ar if (!listener.isObject()) return jsUndefined(); - impl()->removeEventListener(args.at(0).toString(exec), JSEventListener::create(asObject(listener), false, currentWorld(exec)).get(), args.at(2).toBoolean(exec)); + impl()->removeEventListener(args.at(0).toString(exec), JSEventListener::create(asObject(listener), this, false, currentWorld(exec)).get(), args.at(2).toBoolean(exec)); return jsUndefined(); } diff --git a/WebCore/bindings/js/JSBindingsAllInOne.cpp b/WebCore/bindings/js/JSBindingsAllInOne.cpp index 8a918a3..5a0820b 100644 --- a/WebCore/bindings/js/JSBindingsAllInOne.cpp +++ b/WebCore/bindings/js/JSBindingsAllInOne.cpp @@ -140,6 +140,7 @@ #include "ScriptCallStack.cpp" #include "ScriptController.cpp" #include "ScriptControllerWin.cpp" +#include "ScriptDebugServer.cpp" #include "ScriptEventListener.cpp" #include "ScriptFunctionCall.cpp" #include "ScriptProfiler.cpp" diff --git a/WebCore/bindings/js/JSDOMApplicationCacheCustom.cpp b/WebCore/bindings/js/JSDOMApplicationCacheCustom.cpp index 91ee51a..5637087 100644 --- a/WebCore/bindings/js/JSDOMApplicationCacheCustom.cpp +++ b/WebCore/bindings/js/JSDOMApplicationCacheCustom.cpp @@ -91,7 +91,7 @@ JSValue JSDOMApplicationCache::addEventListener(ExecState* exec, const ArgList& if (!listener.isObject()) return jsUndefined(); - impl()->addEventListener(args.at(0).toString(exec), JSEventListener::create(asObject(listener), false, currentWorld(exec)), args.at(2).toBoolean(exec)); + impl()->addEventListener(args.at(0).toString(exec), JSEventListener::create(asObject(listener), this, false, currentWorld(exec)), args.at(2).toBoolean(exec)); return jsUndefined(); } @@ -101,7 +101,7 @@ JSValue JSDOMApplicationCache::removeEventListener(ExecState* exec, const ArgLis if (!listener.isObject()) return jsUndefined(); - impl()->removeEventListener(args.at(0).toString(exec), JSEventListener::create(asObject(listener), false, currentWorld(exec)).get(), args.at(2).toBoolean(exec)); + impl()->removeEventListener(args.at(0).toString(exec), JSEventListener::create(asObject(listener), this, false, currentWorld(exec)).get(), args.at(2).toBoolean(exec)); return jsUndefined(); } diff --git a/WebCore/bindings/js/JSDOMBinding.cpp b/WebCore/bindings/js/JSDOMBinding.cpp index abba405..d718cba 100644 --- a/WebCore/bindings/js/JSDOMBinding.cpp +++ b/WebCore/bindings/js/JSDOMBinding.cpp @@ -151,9 +151,11 @@ DOMWrapperWorld::DOMWrapperWorld(JSC::JSGlobalData* globalData, bool isNormal) DOMWrapperWorld::~DOMWrapperWorld() { - JSGlobalData::ClientData* clientData = m_globalData->clientData; - ASSERT(clientData); - static_cast<WebCoreJSClientData*>(clientData)->forgetWorld(this); + if (m_globalData) { + JSGlobalData::ClientData* clientData = m_globalData->clientData; + ASSERT(clientData); + static_cast<WebCoreJSClientData*>(clientData)->forgetWorld(this); + } for (HashSet<Document*>::iterator iter = documentsWithWrappers.begin(); iter != documentsWithWrappers.end(); ++iter) forgetWorldOfDOMNodesForDocument(*iter, this); diff --git a/WebCore/bindings/js/JSDOMBinding.h b/WebCore/bindings/js/JSDOMBinding.h index 5456c75..930f9cc 100644 --- a/WebCore/bindings/js/JSDOMBinding.h +++ b/WebCore/bindings/js/JSDOMBinding.h @@ -138,9 +138,13 @@ namespace WebCore { class DOMWrapperWorld : public RefCounted<DOMWrapperWorld> { public: - DOMWrapperWorld(JSC::JSGlobalData*, bool isNormal); + static PassRefPtr<DOMWrapperWorld> create(JSC::JSGlobalData* globalData, bool isNormal) + { + return adoptRef(new DOMWrapperWorld(globalData, isNormal)); + } ~DOMWrapperWorld(); + void detachFromGlobalData() { m_globalData = 0; } void rememberDocument(Document* document) { documentsWithWrappers.add(document); } void forgetDocument(Document* document) { documentsWithWrappers.remove(document); } @@ -150,6 +154,9 @@ namespace WebCore { bool isNormal() const { return m_isNormal; } + protected: + DOMWrapperWorld(JSC::JSGlobalData*, bool isNormal); + private: JSC::JSGlobalData* m_globalData; HashSet<Document*> documentsWithWrappers; @@ -185,13 +192,19 @@ namespace WebCore { public: WebCoreJSClientData(JSC::JSGlobalData* globalData) - : m_normalWorld(globalData, true) + : m_normalWorld(DOMWrapperWorld::create(globalData, true)) + { + m_worldSet.add(m_normalWorld.get()); + } + + virtual ~WebCoreJSClientData() { - m_worldSet.add(&m_normalWorld); + ASSERT(m_worldSet.contains(m_normalWorld.get())); + ASSERT(m_worldSet.size() == 1); + m_normalWorld->detachFromGlobalData(); } - // FIXME: add a destructor to assert m_worldSet only contains m_normalWorld? - DOMWrapperWorld* normalWorld() { return &m_normalWorld; } + DOMWrapperWorld* normalWorld() { return m_normalWorld.get(); } void getAllWorlds(Vector<DOMWrapperWorld*>& worlds) { @@ -212,7 +225,7 @@ namespace WebCore { DOMObjectHashTableMap hashTableMap; private: HashSet<DOMWrapperWorld*> m_worldSet; - DOMWrapperWorld m_normalWorld; + RefPtr<DOMWrapperWorld> m_normalWorld; }; DOMObject* getCachedDOMObjectWrapper(JSC::ExecState*, void* objectHandle); diff --git a/WebCore/bindings/js/JSDOMWindowCustom.cpp b/WebCore/bindings/js/JSDOMWindowCustom.cpp index f7be2c5..b8cd1dc 100644 --- a/WebCore/bindings/js/JSDOMWindowCustom.cpp +++ b/WebCore/bindings/js/JSDOMWindowCustom.cpp @@ -97,7 +97,7 @@ void JSDOMWindow::markChildren(MarkStack& markStack) { Base::markChildren(markStack); - impl()->markEventListeners(markStack); + impl()->markJSEventListeners(markStack); JSGlobalData& globalData = *Heap::heap(this)->globalData(); @@ -666,9 +666,11 @@ static Frame* createWindow(ExecState* exec, Frame* lexicalFrame, Frame* dynamicF ASSERT(lexicalFrame); ASSERT(dynamicFrame); - // Sandboxed iframes cannot open new auxiliary browsing contexts. - if (lexicalFrame && lexicalFrame->loader()->isSandboxed(SandboxNavigation)) - return 0; + if (Document* lexicalDocument = lexicalFrame->document()) { + // Sandboxed iframes cannot open new auxiliary browsing contexts. + if (lexicalDocument->securityOrigin()->isSandboxed(SandboxNavigation)) + return 0; + } ResourceRequest request; @@ -997,7 +999,7 @@ JSValue JSDOMWindow::addEventListener(ExecState* exec, const ArgList& args) if (!listener.isObject()) return jsUndefined(); - impl()->addEventListener(args.at(0).toString(exec), JSEventListener::create(asObject(listener), false, currentWorld(exec)), args.at(2).toBoolean(exec)); + impl()->addEventListener(args.at(0).toString(exec), JSEventListener::create(asObject(listener), this, false, currentWorld(exec)), args.at(2).toBoolean(exec)); return jsUndefined(); } @@ -1011,7 +1013,7 @@ JSValue JSDOMWindow::removeEventListener(ExecState* exec, const ArgList& args) if (!listener.isObject()) return jsUndefined(); - impl()->removeEventListener(args.at(0).toString(exec), JSEventListener::create(asObject(listener), false, currentWorld(exec)).get(), args.at(2).toBoolean(exec)); + impl()->removeEventListener(args.at(0).toString(exec), JSEventListener::create(asObject(listener), this, false, currentWorld(exec)).get(), args.at(2).toBoolean(exec)); return jsUndefined(); } diff --git a/WebCore/bindings/js/JSEventListener.cpp b/WebCore/bindings/js/JSEventListener.cpp index d3b5fe1..61f21be 100644 --- a/WebCore/bindings/js/JSEventListener.cpp +++ b/WebCore/bindings/js/JSEventListener.cpp @@ -31,9 +31,10 @@ using namespace JSC; namespace WebCore { -JSEventListener::JSEventListener(JSObject* function, bool isAttribute, DOMWrapperWorld* isolatedWorld) +JSEventListener::JSEventListener(JSObject* function, JSObject* wrapper, bool isAttribute, DOMWrapperWorld* isolatedWorld) : EventListener(JSEventListenerType) , m_jsFunction(function) + , m_wrapper(wrapper) , m_isAttribute(isAttribute) , m_isolatedWorld(isolatedWorld) { @@ -43,9 +44,10 @@ JSEventListener::~JSEventListener() { } -JSObject* JSEventListener::jsFunction(ScriptExecutionContext*) const +JSObject* JSEventListener::initializeJSFunction(ScriptExecutionContext*) const { - return m_jsFunction; + ASSERT_NOT_REACHED(); + return 0; } void JSEventListener::markJSFunction(MarkStack& markStack) diff --git a/WebCore/bindings/js/JSEventListener.h b/WebCore/bindings/js/JSEventListener.h index 9ba09c6..569c192 100644 --- a/WebCore/bindings/js/JSEventListener.h +++ b/WebCore/bindings/js/JSEventListener.h @@ -22,7 +22,7 @@ #include "EventListener.h" #include "JSDOMWindow.h" -#include <runtime/Protect.h> +#include <runtime/WeakGCPtr.h> namespace WebCore { @@ -30,9 +30,9 @@ namespace WebCore { class JSEventListener : public EventListener { public: - static PassRefPtr<JSEventListener> create(JSC::JSObject* listener, bool isAttribute, DOMWrapperWorld* isolatedWorld) + static PassRefPtr<JSEventListener> create(JSC::JSObject* listener, JSC::JSObject* wrapper, bool isAttribute, DOMWrapperWorld* isolatedWorld) { - return adoptRef(new JSEventListener(listener, isAttribute, isolatedWorld)); + return adoptRef(new JSEventListener(listener, wrapper, isAttribute, isolatedWorld)); } static const JSEventListener* cast(const EventListener* listener) @@ -49,30 +49,61 @@ namespace WebCore { // Returns true if this event listener was created for an event handler attribute, like "onload" or "onclick". bool isAttribute() const { return m_isAttribute; } - virtual JSC::JSObject* jsFunction(ScriptExecutionContext*) const; + JSC::JSObject* jsFunction(ScriptExecutionContext*) const; + DOMWrapperWorld* isolatedWorld() const { return m_isolatedWorld.get(); } + + JSC::JSObject* wrapper() const { return m_wrapper.get(); } + void setWrapper(JSC::JSObject* wrapper) const { m_wrapper = wrapper; } private: + virtual JSC::JSObject* initializeJSFunction(ScriptExecutionContext*) const; virtual void markJSFunction(JSC::MarkStack&); + virtual void invalidateJSFunction(JSC::JSObject*); virtual void handleEvent(ScriptExecutionContext*, Event*); virtual bool reportError(ScriptExecutionContext*, const String& message, const String& url, int lineNumber); virtual bool virtualisAttribute() const; - void clearJSFunctionInline(); protected: - JSEventListener(JSC::JSObject* function, bool isAttribute, DOMWrapperWorld* isolatedWorld); + JSEventListener(JSC::JSObject* function, JSC::JSObject* wrapper, bool isAttribute, DOMWrapperWorld* isolatedWorld); + private: mutable JSC::JSObject* m_jsFunction; + mutable JSC::WeakGCPtr<JSC::JSObject> m_wrapper; + bool m_isAttribute; RefPtr<DOMWrapperWorld> m_isolatedWorld; }; + inline JSC::JSObject* JSEventListener::jsFunction(ScriptExecutionContext* scriptExecutionContext) const + { + if (!m_jsFunction) + m_jsFunction = initializeJSFunction(scriptExecutionContext); + + // Verify that we have a valid wrapper protecting our function from + // garbage collection. + ASSERT(m_wrapper || !m_jsFunction); + if (!m_wrapper) + return 0; + + // Try to verify that m_jsFunction wasn't recycled. (Not exact, since an + // event listener can be almost anything, but this makes test-writing easier). + ASSERT(!m_jsFunction || static_cast<JSC::JSCell*>(m_jsFunction)->isObject()); + + return m_jsFunction; + } + + inline void JSEventListener::invalidateJSFunction(JSC::JSObject* wrapper) + { + m_wrapper.clear(wrapper); + } + // Creates a JS EventListener for an "onXXX" event attribute. - inline PassRefPtr<JSEventListener> createJSAttributeEventListener(JSC::ExecState* exec, JSC::JSValue listener) + inline PassRefPtr<JSEventListener> createJSAttributeEventListener(JSC::ExecState* exec, JSC::JSValue listener, JSC::JSObject* wrapper) { if (!listener.isObject()) return 0; - return JSEventListener::create(asObject(listener), true, currentWorld(exec)); + return JSEventListener::create(asObject(listener), wrapper, true, currentWorld(exec)); } diff --git a/WebCore/bindings/js/JSEventSourceCustom.cpp b/WebCore/bindings/js/JSEventSourceCustom.cpp index 8f0dfb1..dab3285 100644 --- a/WebCore/bindings/js/JSEventSourceCustom.cpp +++ b/WebCore/bindings/js/JSEventSourceCustom.cpp @@ -49,7 +49,7 @@ JSValue JSEventSource::addEventListener(ExecState* exec, const ArgList& args) if (!listener.isObject()) return jsUndefined(); - impl()->addEventListener(args.at(0).toString(exec), JSEventListener::create(asObject(listener), false, currentWorld(exec)).get(), args.at(2).toBoolean(exec)); + impl()->addEventListener(args.at(0).toString(exec), JSEventListener::create(asObject(listener), this, false, currentWorld(exec)).get(), args.at(2).toBoolean(exec)); return jsUndefined(); } @@ -59,7 +59,7 @@ JSValue JSEventSource::removeEventListener(ExecState* exec, const ArgList& args) if (!listener.isObject()) return jsUndefined(); - impl()->removeEventListener(args.at(0).toString(exec), JSEventListener::create(asObject(listener), false, currentWorld(exec)).get(), args.at(2).toBoolean(exec)); + impl()->removeEventListener(args.at(0).toString(exec), JSEventListener::create(asObject(listener), this, false, currentWorld(exec)).get(), args.at(2).toBoolean(exec)); return jsUndefined(); } diff --git a/WebCore/bindings/js/JSInjectedScriptHostCustom.cpp b/WebCore/bindings/js/JSInjectedScriptHostCustom.cpp index 96c5c43..3db894d 100644 --- a/WebCore/bindings/js/JSInjectedScriptHostCustom.cpp +++ b/WebCore/bindings/js/JSInjectedScriptHostCustom.cpp @@ -53,6 +53,7 @@ #include "Node.h" #include "Page.h" #if ENABLE(DOM_STORAGE) +#include "SerializedScriptValue.h" #include "Storage.h" #include "JSStorage.h" #endif @@ -61,6 +62,7 @@ #include <parser/SourceCode.h> #include <runtime/JSArray.h> #include <runtime/JSLock.h> +#include <wtf/RefPtr.h> #include <wtf/Vector.h> #if ENABLE(JAVASCRIPT_DEBUGGER) @@ -195,6 +197,24 @@ JSValue JSInjectedScriptHost::selectDOMStorage(ExecState*, const ArgList& args) } #endif +JSValue JSInjectedScriptHost::reportDidDispatchOnInjectedScript(ExecState* exec, const ArgList& args) +{ + if (args.size() < 3) + return jsUndefined(); + + if (!args.at(0).isInt32()) + return jsUndefined(); + int callId = args.at(0).asInt32(); + + RefPtr<SerializedScriptValue> result(SerializedScriptValue::create(exec, args.at(1))); + + bool isException; + if (!args.at(2).getBoolean(isException)) + return jsUndefined(); + impl()->reportDidDispatchOnInjectedScript(callId, result.get(), isException); + return jsUndefined(); +} + InjectedScript InjectedScriptHost::injectedScriptFor(ScriptState* scriptState) { JSLock lock(SilenceAssertionsOnly); diff --git a/WebCore/bindings/js/JSLazyEventListener.cpp b/WebCore/bindings/js/JSLazyEventListener.cpp index b707991..4fbdaa6 100644 --- a/WebCore/bindings/js/JSLazyEventListener.cpp +++ b/WebCore/bindings/js/JSLazyEventListener.cpp @@ -35,12 +35,11 @@ namespace WebCore { static WTF::RefCountedLeakCounter eventListenerCounter("JSLazyEventListener"); #endif -JSLazyEventListener::JSLazyEventListener(const String& functionName, const String& eventParameterName, const String& code, Node* node, const String& sourceURL, int lineNumber, DOMWrapperWorld* isolatedWorld) - : JSEventListener(0, true, isolatedWorld) +JSLazyEventListener::JSLazyEventListener(const String& functionName, const String& eventParameterName, const String& code, Node* node, const String& sourceURL, int lineNumber, JSObject* wrapper, DOMWrapperWorld* isolatedWorld) + : JSEventListener(0, wrapper, true, isolatedWorld) , m_functionName(functionName) , m_eventParameterName(eventParameterName) , m_code(code) - , m_parsed(false) , m_sourceURL(sourceURL) , m_lineNumber(lineNumber) , m_originalNode(node) @@ -48,8 +47,8 @@ JSLazyEventListener::JSLazyEventListener(const String& functionName, const Strin // We don't retain the original node because we assume it // will stay alive as long as this handler object is around // and we need to avoid a reference cycle. If JS transfers - // this handler to another node, parseCode will be called and - // then originalNode is no longer needed. + // this handler to another node, initializeJSFunction will + // be called and then originalNode is no longer needed. // A JSLazyEventListener can be created with a line number of zero when it is created with // a setAttribute call from JavaScript, so make the line number 1 in that case. @@ -68,79 +67,62 @@ JSLazyEventListener::~JSLazyEventListener() #endif } -JSObject* JSLazyEventListener::jsFunction(ScriptExecutionContext* executionContext) const -{ - parseCode(executionContext); - return m_jsFunction; -} - -void JSLazyEventListener::parseCode(ScriptExecutionContext* executionContext) const +JSObject* JSLazyEventListener::initializeJSFunction(ScriptExecutionContext* executionContext) const { ASSERT(executionContext); ASSERT(executionContext->isDocument()); if (!executionContext) - return; - - if (m_parsed) - return; + return 0; Frame* frame = static_cast<Document*>(executionContext)->frame(); if (!frame) - return; + return 0; ScriptController* scriptController = frame->script(); if (!scriptController->canExecuteScripts()) - return; + return 0; - JSDOMGlobalObject* globalObject = toJSDOMGlobalObject(executionContext, m_isolatedWorld.get()); + JSDOMGlobalObject* globalObject = toJSDOMGlobalObject(executionContext, isolatedWorld()); if (!globalObject) - return; - - // Ensure that 'node' has a JavaScript wrapper to mark the event listener we're creating. - if (m_originalNode) { - JSLock lock(SilenceAssertionsOnly); - // FIXME: Should pass the global object associated with the node - toJS(globalObject->globalExec(), globalObject, m_originalNode); - } + return 0; if (executionContext->isDocument()) { JSDOMWindow* window = static_cast<JSDOMWindow*>(globalObject); Frame* frame = window->impl()->frame(); if (!frame) - return; + return 0; // FIXME: Is this check needed for non-Document contexts? ScriptController* script = frame->script(); if (!script->canExecuteScripts() || script->isPaused()) - return; + return 0; } - m_parsed = true; - ExecState* exec = globalObject->globalExec(); MarkedArgumentBuffer args; args.append(jsNontrivialString(exec, m_eventParameterName)); args.append(jsString(exec, m_code)); - m_jsFunction = constructFunction(exec, args, Identifier(exec, m_functionName), m_sourceURL, m_lineNumber); // FIXME: is globalExec ok? - - JSFunction* listenerAsFunction = static_cast<JSFunction*>(m_jsFunction); - + JSObject* jsFunction = constructFunction(exec, args, Identifier(exec, m_functionName), m_sourceURL, m_lineNumber); // FIXME: is globalExec ok? if (exec->hadException()) { exec->clearException(); + return 0; + } + + JSFunction* listenerAsFunction = static_cast<JSFunction*>(jsFunction); + if (m_originalNode) { + if (!wrapper()) { + // Ensure that 'node' has a JavaScript wrapper to mark the event listener we're creating. + JSLock lock(SilenceAssertionsOnly); + // FIXME: Should pass the global object associated with the node + setWrapper(asObject(toJS(globalObject->globalExec(), globalObject, m_originalNode))); + } - // failed to parse, so let's just make this listener a no-op - m_jsFunction = 0; - } else if (m_originalNode) { // Add the event's home element to the scope // (and the document, and the form - see JSHTMLElement::eventHandlerScope) ScopeChain scope = listenerAsFunction->scope(); - - JSValue thisObj = toJS(exec, globalObject, m_originalNode); - if (thisObj.isObject()) { - static_cast<JSNode*>(asObject(thisObj))->pushEventHandlerScope(exec, scope); - listenerAsFunction->setScope(scope); - } + static_cast<JSNode*>(wrapper())->pushEventHandlerScope(exec, scope); + listenerAsFunction->setScope(scope); } // Since we only parse once, there's no need to keep data used for parsing around anymore. @@ -148,6 +130,7 @@ void JSLazyEventListener::parseCode(ScriptExecutionContext* executionContext) co m_code = String(); m_eventParameterName = String(); m_sourceURL = String(); + return jsFunction; } } // namespace WebCore diff --git a/WebCore/bindings/js/JSLazyEventListener.h b/WebCore/bindings/js/JSLazyEventListener.h index ba26ef6..1b00b75 100644 --- a/WebCore/bindings/js/JSLazyEventListener.h +++ b/WebCore/bindings/js/JSLazyEventListener.h @@ -29,24 +29,21 @@ namespace WebCore { class JSLazyEventListener : public JSEventListener { public: - static PassRefPtr<JSLazyEventListener> create(const String& functionName, const String& eventParameterName, const String& code, Node* node, const String& sourceURL, int lineNumber, DOMWrapperWorld* isolatedWorld) + static PassRefPtr<JSLazyEventListener> create(const String& functionName, const String& eventParameterName, const String& code, Node* node, const String& sourceURL, int lineNumber, JSC::JSObject* wrapper, DOMWrapperWorld* isolatedWorld) { - return adoptRef(new JSLazyEventListener(functionName, eventParameterName, code, node, sourceURL, lineNumber, isolatedWorld)); + return adoptRef(new JSLazyEventListener(functionName, eventParameterName, code, node, sourceURL, lineNumber, wrapper, isolatedWorld)); } virtual ~JSLazyEventListener(); private: - JSLazyEventListener(const String& functionName, const String& eventParameterName, const String& code, Node*, const String& sourceURL, int lineNumber, DOMWrapperWorld* isolatedWorld); + JSLazyEventListener(const String& functionName, const String& eventParameterName, const String& code, Node*, const String& sourceURL, int lineNumber, JSC::JSObject* wrapper, DOMWrapperWorld* isolatedWorld); - virtual JSC::JSObject* jsFunction(ScriptExecutionContext*) const; + virtual JSC::JSObject* initializeJSFunction(ScriptExecutionContext*) const; virtual bool wasCreatedFromMarkup() const { return true; } - void parseCode(ScriptExecutionContext*) const; - mutable String m_functionName; mutable String m_eventParameterName; mutable String m_code; - mutable bool m_parsed; mutable String m_sourceURL; int m_lineNumber; Node* m_originalNode; diff --git a/WebCore/bindings/js/JSMessagePortCustom.cpp b/WebCore/bindings/js/JSMessagePortCustom.cpp index 2c09620..2ee8125 100644 --- a/WebCore/bindings/js/JSMessagePortCustom.cpp +++ b/WebCore/bindings/js/JSMessagePortCustom.cpp @@ -49,7 +49,7 @@ void JSMessagePort::markChildren(MarkStack& markStack) if (MessagePort* entangledPort = m_impl->locallyEntangledPort()) markDOMObjectWrapper(markStack, *Heap::heap(this)->globalData(), entangledPort); - m_impl->markEventListeners(markStack); + m_impl->markJSEventListeners(markStack); } JSValue JSMessagePort::addEventListener(ExecState* exec, const ArgList& args) @@ -58,7 +58,7 @@ JSValue JSMessagePort::addEventListener(ExecState* exec, const ArgList& args) if (!listener.isObject()) return jsUndefined(); - impl()->addEventListener(args.at(0).toString(exec), JSEventListener::create(asObject(listener), false, currentWorld(exec)).get(), args.at(2).toBoolean(exec)); + impl()->addEventListener(args.at(0).toString(exec), JSEventListener::create(asObject(listener), this, false, currentWorld(exec)).get(), args.at(2).toBoolean(exec)); return jsUndefined(); } @@ -68,7 +68,7 @@ JSValue JSMessagePort::removeEventListener(ExecState* exec, const ArgList& args) if (!listener.isObject()) return jsUndefined(); - impl()->removeEventListener(args.at(0).toString(exec), JSEventListener::create(asObject(listener), false, currentWorld(exec)).get(), args.at(2).toBoolean(exec)); + impl()->removeEventListener(args.at(0).toString(exec), JSEventListener::create(asObject(listener), this, false, currentWorld(exec)).get(), args.at(2).toBoolean(exec)); return jsUndefined(); } diff --git a/WebCore/bindings/js/JSNodeCustom.cpp b/WebCore/bindings/js/JSNodeCustom.cpp index 737430e..46a30a4 100644 --- a/WebCore/bindings/js/JSNodeCustom.cpp +++ b/WebCore/bindings/js/JSNodeCustom.cpp @@ -114,7 +114,7 @@ JSValue JSNode::addEventListener(ExecState* exec, const ArgList& args) if (!listener.isObject()) return jsUndefined(); - impl()->addEventListener(args.at(0).toString(exec), JSEventListener::create(asObject(listener), false, currentWorld(exec)), args.at(2).toBoolean(exec)); + impl()->addEventListener(args.at(0).toString(exec), JSEventListener::create(asObject(listener), this, false, currentWorld(exec)), args.at(2).toBoolean(exec)); return jsUndefined(); } @@ -124,7 +124,7 @@ JSValue JSNode::removeEventListener(ExecState* exec, const ArgList& args) if (!listener.isObject()) return jsUndefined(); - impl()->removeEventListener(args.at(0).toString(exec), JSEventListener::create(asObject(listener), false, currentWorld(exec)).get(), args.at(2).toBoolean(exec)); + impl()->removeEventListener(args.at(0).toString(exec), JSEventListener::create(asObject(listener), this, false, currentWorld(exec)).get(), args.at(2).toBoolean(exec)); return jsUndefined(); } @@ -137,7 +137,7 @@ void JSNode::markChildren(MarkStack& markStack) Base::markChildren(markStack); Node* node = m_impl.get(); - node->markEventListeners(markStack); + node->markJSEventListeners(markStack); // Nodes in the document are kept alive by JSDocument::mark, so, if we're in // the document, we need to mark the document, but we don't need to explicitly diff --git a/WebCore/bindings/js/JSSVGElementInstanceCustom.cpp b/WebCore/bindings/js/JSSVGElementInstanceCustom.cpp index 5f26df3..b3bded5 100644 --- a/WebCore/bindings/js/JSSVGElementInstanceCustom.cpp +++ b/WebCore/bindings/js/JSSVGElementInstanceCustom.cpp @@ -52,7 +52,7 @@ JSValue JSSVGElementInstance::addEventListener(ExecState* exec, const ArgList& a if (!listener.isObject()) return jsUndefined(); - impl()->addEventListener(args.at(0).toString(exec), JSEventListener::create(asObject(listener), false, currentWorld(exec)), args.at(2).toBoolean(exec)); + impl()->addEventListener(args.at(0).toString(exec), JSEventListener::create(asObject(listener), this, false, currentWorld(exec)), args.at(2).toBoolean(exec)); return jsUndefined(); } @@ -62,7 +62,7 @@ JSValue JSSVGElementInstance::removeEventListener(ExecState* exec, const ArgList if (!listener.isObject()) return jsUndefined(); - impl()->removeEventListener(args.at(0).toString(exec), JSEventListener::create(asObject(listener), false, currentWorld(exec)).get(), args.at(2).toBoolean(exec)); + impl()->removeEventListener(args.at(0).toString(exec), JSEventListener::create(asObject(listener), this, false, currentWorld(exec)).get(), args.at(2).toBoolean(exec)); return jsUndefined(); } diff --git a/WebCore/bindings/js/JSSVGMatrixCustom.cpp b/WebCore/bindings/js/JSSVGMatrixCustom.cpp index d2d3d6f..59e3f03 100644 --- a/WebCore/bindings/js/JSSVGMatrixCustom.cpp +++ b/WebCore/bindings/js/JSSVGMatrixCustom.cpp @@ -23,7 +23,7 @@ #if ENABLE(SVG) #include "JSSVGMatrix.h" -#include "TransformationMatrix.h" +#include "AffineTransform.h" #include "SVGException.h" #include <runtime/Error.h> @@ -41,19 +41,19 @@ JSValue JSSVGMatrix::multiply(ExecState* exec, const ArgList& args) JSSVGMatrix* matrixObj = static_cast<JSSVGMatrix*>(asObject(args.at(0))); - TransformationMatrix m1(*impl()); - TransformationMatrix m2(*(matrixObj->impl())); + AffineTransform m1(*impl()); + AffineTransform m2(*(matrixObj->impl())); SVGElement* context = JSSVGContextCache::svgContextForDOMObject(this); - return toJS(exec, globalObject(), JSSVGStaticPODTypeWrapper<TransformationMatrix>::create(m1.multLeft(m2)).get(), context); + return toJS(exec, globalObject(), JSSVGStaticPODTypeWrapper<AffineTransform>::create(m1.multLeft(m2)).get(), context); } JSValue JSSVGMatrix::inverse(ExecState* exec, const ArgList&) { - TransformationMatrix imp(*impl()); + AffineTransform imp(*impl()); SVGElement* context = JSSVGContextCache::svgContextForDOMObject(this); - JSValue result = toJS(exec, globalObject(), JSSVGStaticPODTypeWrapper<TransformationMatrix>::create(imp.inverse()).get(), context); + JSValue result = toJS(exec, globalObject(), JSSVGStaticPODTypeWrapper<AffineTransform>::create(imp.inverse()).get(), context); if (!imp.isInvertible()) setDOMException(exec, SVGException::SVG_MATRIX_NOT_INVERTABLE); @@ -63,13 +63,13 @@ JSValue JSSVGMatrix::inverse(ExecState* exec, const ArgList&) JSValue JSSVGMatrix::rotateFromVector(ExecState* exec, const ArgList& args) { - TransformationMatrix imp(*impl()); + AffineTransform imp(*impl()); float x = args.at(0).toFloat(exec); float y = args.at(1).toFloat(exec); SVGElement* context = JSSVGContextCache::svgContextForDOMObject(this); - JSValue result = toJS(exec, globalObject(), JSSVGStaticPODTypeWrapper<TransformationMatrix>::create(imp.rotateFromVector(x, y)).get(), context); + JSValue result = toJS(exec, globalObject(), JSSVGStaticPODTypeWrapper<AffineTransform>::create(imp.rotateFromVector(x, y)).get(), context); if (x == 0.0 || y == 0.0) setDOMException(exec, SVGException::SVG_INVALID_VALUE_ERR); diff --git a/WebCore/bindings/js/JSSVGPODTypeWrapper.h b/WebCore/bindings/js/JSSVGPODTypeWrapper.h index 7c04f22..2efc60e 100644 --- a/WebCore/bindings/js/JSSVGPODTypeWrapper.h +++ b/WebCore/bindings/js/JSSVGPODTypeWrapper.h @@ -46,13 +46,13 @@ public: }; // This file contains JS wrapper objects for SVG datatypes, that are passed around by value -// in WebCore/svg (aka. 'POD types'). For instance SVGMatrix is mapped to TransformationMatrix, and +// in WebCore/svg (aka. 'POD types'). For instance SVGMatrix is mapped to AffineTransform, and // passed around as const reference. SVG DOM demands these objects to be "live", changes to any // of the writable attributes of SVGMatrix need to be reflected in the object which exposed the // SVGMatrix object (i.e. 'someElement.transform.matrix.a = 50.0', in that case 'SVGTransform'). -// The SVGTransform class stores its "TransformationMatrix m_matrix" object on the stack. If it would +// The SVGTransform class stores its "AffineTransform m_matrix" object on the stack. If it would // be stored as pointer we could just build an auto-generated JSSVG* wrapper object around it -// and all changes to that object would automatically affect the TransformationMatrix* object stored +// and all changes to that object would automatically affect the AffineTransform* object stored // in the SVGTransform object. For the sake of efficiency and memory we don't pass around any // primitive values as pointers, so a custom JS wrapper object is needed for all SVG types, that // are internally represented by POD types (SVGRect <-> FloatRect, SVGPoint <-> FloatPoint, ...). diff --git a/WebCore/bindings/js/JSWebSocketCustom.cpp b/WebCore/bindings/js/JSWebSocketCustom.cpp index 238b041..d610f01 100644 --- a/WebCore/bindings/js/JSWebSocketCustom.cpp +++ b/WebCore/bindings/js/JSWebSocketCustom.cpp @@ -65,7 +65,7 @@ JSValue JSWebSocket::addEventListener(ExecState* exec, const ArgList& args) if (!listener.isObject()) return jsUndefined(); - impl()->addEventListener(args.at(0).toString(exec), JSEventListener::create(asObject(listener), false, currentWorld(exec)), args.at(2).toBoolean(exec)); + impl()->addEventListener(args.at(0).toString(exec), JSEventListener::create(asObject(listener), this, false, currentWorld(exec)), args.at(2).toBoolean(exec)); return jsUndefined(); } @@ -75,7 +75,7 @@ JSValue JSWebSocket::removeEventListener(ExecState* exec, const ArgList& args) if (!listener.isObject()) return jsUndefined(); - impl()->removeEventListener(args.at(0).toString(exec), JSEventListener::create(asObject(listener), false, currentWorld(exec)).get(), args.at(2).toBoolean(exec)); + impl()->removeEventListener(args.at(0).toString(exec), JSEventListener::create(asObject(listener), this, false, currentWorld(exec)).get(), args.at(2).toBoolean(exec)); return jsUndefined(); } diff --git a/WebCore/bindings/js/JSWorkerContextCustom.cpp b/WebCore/bindings/js/JSWorkerContextCustom.cpp index ab28674..d6c8dbd 100644 --- a/WebCore/bindings/js/JSWorkerContextCustom.cpp +++ b/WebCore/bindings/js/JSWorkerContextCustom.cpp @@ -60,7 +60,7 @@ void JSWorkerContext::markChildren(MarkStack& markStack) markDOMObjectWrapper(markStack, globalData, impl()->optionalLocation()); markDOMObjectWrapper(markStack, globalData, impl()->optionalNavigator()); - impl()->markEventListeners(markStack); + impl()->markJSEventListeners(markStack); } bool JSWorkerContext::getOwnPropertySlotDelegate(ExecState* exec, const Identifier& propertyName, PropertySlot& slot) @@ -127,7 +127,7 @@ JSValue JSWorkerContext::addEventListener(ExecState* exec, const ArgList& args) if (!listener.isObject()) return jsUndefined(); - impl()->addEventListener(args.at(0).toString(exec), JSEventListener::create(asObject(listener), false, currentWorld(exec)), args.at(2).toBoolean(exec)); + impl()->addEventListener(args.at(0).toString(exec), JSEventListener::create(asObject(listener), this, false, currentWorld(exec)), args.at(2).toBoolean(exec)); return jsUndefined(); } @@ -137,7 +137,7 @@ JSValue JSWorkerContext::removeEventListener(ExecState* exec, const ArgList& arg if (!listener.isObject()) return jsUndefined(); - impl()->removeEventListener(args.at(0).toString(exec), JSEventListener::create(asObject(listener), false, currentWorld(exec)).get(), args.at(2).toBoolean(exec)); + impl()->removeEventListener(args.at(0).toString(exec), JSEventListener::create(asObject(listener), this, false, currentWorld(exec)).get(), args.at(2).toBoolean(exec)); return jsUndefined(); } diff --git a/WebCore/bindings/js/JSXMLHttpRequestCustom.cpp b/WebCore/bindings/js/JSXMLHttpRequestCustom.cpp index d35d53a..e20b6d9 100644 --- a/WebCore/bindings/js/JSXMLHttpRequestCustom.cpp +++ b/WebCore/bindings/js/JSXMLHttpRequestCustom.cpp @@ -56,7 +56,7 @@ void JSXMLHttpRequest::markChildren(MarkStack& markStack) if (XMLHttpRequestUpload* upload = m_impl->optionalUpload()) markDOMObjectWrapper(markStack, *Heap::heap(this)->globalData(), upload); - m_impl->markEventListeners(markStack); + m_impl->markJSEventListeners(markStack); } // Custom functions @@ -153,7 +153,7 @@ JSValue JSXMLHttpRequest::addEventListener(ExecState* exec, const ArgList& args) if (!listener.isObject()) return jsUndefined(); - impl()->addEventListener(args.at(0).toString(exec), JSEventListener::create(asObject(listener), false, currentWorld(exec)), args.at(2).toBoolean(exec)); + impl()->addEventListener(args.at(0).toString(exec), JSEventListener::create(asObject(listener), this, false, currentWorld(exec)), args.at(2).toBoolean(exec)); return jsUndefined(); } @@ -163,7 +163,7 @@ JSValue JSXMLHttpRequest::removeEventListener(ExecState* exec, const ArgList& ar if (!listener.isObject()) return jsUndefined(); - impl()->removeEventListener(args.at(0).toString(exec), JSEventListener::create(asObject(listener), false, currentWorld(exec)).get(), args.at(2).toBoolean(exec)); + impl()->removeEventListener(args.at(0).toString(exec), JSEventListener::create(asObject(listener), this, false, currentWorld(exec)).get(), args.at(2).toBoolean(exec)); return jsUndefined(); } diff --git a/WebCore/bindings/js/JSXMLHttpRequestUploadCustom.cpp b/WebCore/bindings/js/JSXMLHttpRequestUploadCustom.cpp index fa7cfec..857c12d 100644 --- a/WebCore/bindings/js/JSXMLHttpRequestUploadCustom.cpp +++ b/WebCore/bindings/js/JSXMLHttpRequestUploadCustom.cpp @@ -48,7 +48,7 @@ void JSXMLHttpRequestUpload::markChildren(MarkStack& markStack) if (XMLHttpRequest* xmlHttpRequest = m_impl->associatedXMLHttpRequest()) markDOMObjectWrapper(markStack, *Heap::heap(this)->globalData(), xmlHttpRequest); - m_impl->markEventListeners(markStack); + m_impl->markJSEventListeners(markStack); } JSValue JSXMLHttpRequestUpload::addEventListener(ExecState* exec, const ArgList& args) @@ -57,7 +57,7 @@ JSValue JSXMLHttpRequestUpload::addEventListener(ExecState* exec, const ArgList& if (!listener.isObject()) return jsUndefined(); - impl()->addEventListener(args.at(0).toString(exec), JSEventListener::create(asObject(listener), false, currentWorld(exec)), args.at(2).toBoolean(exec)); + impl()->addEventListener(args.at(0).toString(exec), JSEventListener::create(asObject(listener), this, false, currentWorld(exec)), args.at(2).toBoolean(exec)); return jsUndefined(); } @@ -67,7 +67,7 @@ JSValue JSXMLHttpRequestUpload::removeEventListener(ExecState* exec, const ArgLi if (!listener.isObject()) return jsUndefined(); - impl()->removeEventListener(args.at(0).toString(exec), JSEventListener::create(asObject(listener), false, currentWorld(exec)).get(), args.at(2).toBoolean(exec)); + impl()->removeEventListener(args.at(0).toString(exec), JSEventListener::create(asObject(listener), this, false, currentWorld(exec)).get(), args.at(2).toBoolean(exec)); return jsUndefined(); } diff --git a/WebCore/bindings/js/ScriptArray.cpp b/WebCore/bindings/js/ScriptArray.cpp index 2c4075a..caecc40 100644 --- a/WebCore/bindings/js/ScriptArray.cpp +++ b/WebCore/bindings/js/ScriptArray.cpp @@ -53,6 +53,10 @@ static bool handleException(ScriptState* scriptState) bool ScriptArray::set(unsigned index, const ScriptObject& value) { + if (value.scriptState() != m_scriptState) { + ASSERT_NOT_REACHED(); + return false; + } JSLock lock(SilenceAssertionsOnly); jsArray()->put(m_scriptState, index, value.jsObject()); return handleException(m_scriptState); diff --git a/WebCore/bindings/js/ScriptController.cpp b/WebCore/bindings/js/ScriptController.cpp index bd36689..171d4dd 100644 --- a/WebCore/bindings/js/ScriptController.cpp +++ b/WebCore/bindings/js/ScriptController.cpp @@ -155,6 +155,9 @@ ScriptValue ScriptController::evaluate(const ScriptSourceCode& sourceCode) // An DOMWrapperWorld other than the thread's normal world. class IsolatedWorld : public DOMWrapperWorld { public: + static PassRefPtr<IsolatedWorld> create(JSGlobalData* globalData) { return adoptRef(new IsolatedWorld(globalData)); } + +protected: IsolatedWorld(JSGlobalData* globalData) : DOMWrapperWorld(globalData, false) { @@ -162,8 +165,6 @@ public: ASSERT(clientData); static_cast<WebCoreJSClientData*>(clientData)->rememberWorld(this); } - - static PassRefPtr<IsolatedWorld> create(JSGlobalData* globalData) { return adoptRef(new IsolatedWorld(globalData)); } }; PassRefPtr<DOMWrapperWorld> ScriptController::createWorld() diff --git a/WebCore/bindings/js/ScriptDebugServer.cpp b/WebCore/bindings/js/ScriptDebugServer.cpp new file mode 100644 index 0000000..9869775 --- /dev/null +++ b/WebCore/bindings/js/ScriptDebugServer.cpp @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * Copyright (C) 2010 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" + +#if ENABLE(JAVASCRIPT_DEBUGGER) + +#include "ScriptDebugServer.h" + +#include "JavaScriptDebugServer.h" + +namespace WebCore { + +void ScriptDebugServer::recompileAllJSFunctions() +{ + JavaScriptDebugServer::shared().recompileAllJSFunctions(); +} + +void ScriptDebugServer::recompileAllJSFunctionsSoon() +{ + JavaScriptDebugServer::shared().recompileAllJSFunctionsSoon(); +} + +} // namespace WebCore + +#endif // ENABLE(JAVASCRIPT_DEBUGGER) diff --git a/WebCore/bindings/js/ScriptDebugServer.h b/WebCore/bindings/js/ScriptDebugServer.h new file mode 100644 index 0000000..027ffa5 --- /dev/null +++ b/WebCore/bindings/js/ScriptDebugServer.h @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * Copyright (C) 2010 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef ScriptDebugServer_h +#define ScriptDebugServer_h + +#if ENABLE(JAVASCRIPT_DEBUGGER) + +#include <wtf/Noncopyable.h> + +namespace WebCore { + +class ScriptDebugServer : public Noncopyable { +public: + static void recompileAllJSFunctions(); + static void recompileAllJSFunctionsSoon(); +}; + +} // namespace WebCore + +#endif // ENABLE(JAVASCRIPT_DEBUGGER) + +#endif // ScriptDebugServer_h diff --git a/WebCore/bindings/js/ScriptEventListener.cpp b/WebCore/bindings/js/ScriptEventListener.cpp index 4325dc3..fd45546 100644 --- a/WebCore/bindings/js/ScriptEventListener.cpp +++ b/WebCore/bindings/js/ScriptEventListener.cpp @@ -37,6 +37,7 @@ #include "JSNode.h" #include "Frame.h" #include "XSSAuditor.h" +#include <runtime/JSLock.h> using namespace JSC; @@ -58,6 +59,7 @@ PassRefPtr<JSLazyEventListener> createAttributeEventListener(Node* node, Attribu int lineNumber = 1; String sourceURL; + JSObject* wrapper = 0; // FIXME: We should be able to provide accurate source information for frameless documents, too (e.g. for importing nodes from XMLHttpRequest.responseXML). if (Frame* frame = node->document()->frame()) { @@ -72,9 +74,13 @@ PassRefPtr<JSLazyEventListener> createAttributeEventListener(Node* node, Attribu lineNumber = scriptController->eventHandlerLineNumber(); sourceURL = node->document()->url().string(); + + JSC::JSLock lock(SilenceAssertionsOnly); + JSDOMGlobalObject* globalObject = toJSDOMGlobalObject(node->document(), mainThreadNormalWorld()); + wrapper = asObject(toJS(globalObject->globalExec(), globalObject, node)); } - return JSLazyEventListener::create(attr->localName().string(), eventParameterName(node->isSVGElement()), attr->value(), node, sourceURL, lineNumber, mainThreadNormalWorld()); + return JSLazyEventListener::create(attr->localName().string(), eventParameterName(node->isSVGElement()), attr->value(), node, sourceURL, lineNumber, wrapper, mainThreadNormalWorld()); } PassRefPtr<JSLazyEventListener> createAttributeEventListener(Frame* frame, Attribute* attr) @@ -100,15 +106,19 @@ PassRefPtr<JSLazyEventListener> createAttributeEventListener(Frame* frame, Attri lineNumber = scriptController->eventHandlerLineNumber(); sourceURL = frame->document()->url().string(); - return JSLazyEventListener::create(attr->localName().string(), eventParameterName(frame->document()->isSVGDocument()), attr->value(), 0, sourceURL, lineNumber, mainThreadNormalWorld()); + JSObject* wrapper = toJSDOMWindow(frame, mainThreadNormalWorld()); + return JSLazyEventListener::create(attr->localName().string(), eventParameterName(frame->document()->isSVGDocument()), attr->value(), 0, sourceURL, lineNumber, wrapper, mainThreadNormalWorld()); } String getEventListenerHandlerBody(ScriptExecutionContext* context, ScriptState* scriptState, EventListener* eventListener) { - JSC::JSObject* functionObject = eventListener->jsFunction(context); - if (!functionObject) + const JSEventListener* jsListener = JSEventListener::cast(eventListener); + if (!jsListener) + return ""; + JSC::JSObject* jsFunction = jsListener->jsFunction(context); + if (!jsFunction) return ""; - return functionObject->toString(scriptState); + return jsFunction->toString(scriptState); } } // namespace WebCore diff --git a/WebCore/bindings/js/ScriptFunctionCall.cpp b/WebCore/bindings/js/ScriptFunctionCall.cpp index a2284bc..5001d3c 100644 --- a/WebCore/bindings/js/ScriptFunctionCall.cpp +++ b/WebCore/bindings/js/ScriptFunctionCall.cpp @@ -42,8 +42,8 @@ using namespace JSC; namespace WebCore { -ScriptFunctionCall::ScriptFunctionCall(ScriptState* exec, const ScriptObject& thisObject, const String& name) - : m_exec(exec) +ScriptFunctionCall::ScriptFunctionCall(const ScriptObject& thisObject, const String& name) + : m_exec(thisObject.scriptState()) , m_thisObject(thisObject) , m_name(name) { @@ -51,6 +51,10 @@ ScriptFunctionCall::ScriptFunctionCall(ScriptState* exec, const ScriptObject& th void ScriptFunctionCall::appendArgument(const ScriptObject& argument) { + if (argument.scriptState() != m_exec) { + ASSERT_NOT_REACHED(); + return; + } m_arguments.append(argument.jsObject()); } diff --git a/WebCore/bindings/js/ScriptFunctionCall.h b/WebCore/bindings/js/ScriptFunctionCall.h index 7c5074f..9742e8f 100644 --- a/WebCore/bindings/js/ScriptFunctionCall.h +++ b/WebCore/bindings/js/ScriptFunctionCall.h @@ -48,7 +48,7 @@ namespace WebCore { class ScriptFunctionCall { public: - ScriptFunctionCall(ScriptState* exec, const ScriptObject& thisObject, const String& name); + ScriptFunctionCall(const ScriptObject& thisObject, const String& name); virtual ~ScriptFunctionCall() {}; void appendArgument(const ScriptObject&); diff --git a/WebCore/bindings/js/ScriptObject.cpp b/WebCore/bindings/js/ScriptObject.cpp index 03ecfc6..7948219 100644 --- a/WebCore/bindings/js/ScriptObject.cpp +++ b/WebCore/bindings/js/ScriptObject.cpp @@ -70,6 +70,10 @@ bool ScriptObject::set(const String& name, const String& value) bool ScriptObject::set(const char* name, const ScriptObject& value) { + if (value.scriptState() != m_scriptState) { + ASSERT_NOT_REACHED(); + return false; + } JSLock lock(SilenceAssertionsOnly); PutPropertySlot slot; jsObject()->put(m_scriptState, Identifier(m_scriptState, name), value.jsObject(), slot); diff --git a/WebCore/bindings/js/ScriptString.h b/WebCore/bindings/js/ScriptString.h index a33d639..18964b8 100644 --- a/WebCore/bindings/js/ScriptString.h +++ b/WebCore/bindings/js/ScriptString.h @@ -61,7 +61,7 @@ public: JSC::StringBuilder buffer; buffer.append(m_str); buffer.append(s); - m_str = buffer.release(); + m_str = buffer.build(); return *this; } diff --git a/WebCore/bindings/js/ScriptValue.cpp b/WebCore/bindings/js/ScriptValue.cpp index ac92e14..005c329 100644 --- a/WebCore/bindings/js/ScriptValue.cpp +++ b/WebCore/bindings/js/ScriptValue.cpp @@ -29,6 +29,8 @@ #include "config.h" #include "ScriptValue.h" +#include "SerializedScriptValue.h" + #include <JavaScriptCore/APICast.h> #include <JavaScriptCore/JSValueRef.h> @@ -81,4 +83,14 @@ bool ScriptValue::isObject() const return m_value.get().isObject(); } +PassRefPtr<SerializedScriptValue> ScriptValue::serialize(ScriptState* scriptState) +{ + return SerializedScriptValue::create(scriptState, jsValue()); +} + +ScriptValue ScriptValue::deserialize(ScriptState* scriptState, SerializedScriptValue* value) +{ + return ScriptValue(value->deserialize(scriptState, scriptState->lexicalGlobalObject())); +} + } // namespace WebCore diff --git a/WebCore/bindings/js/ScriptValue.h b/WebCore/bindings/js/ScriptValue.h index b1eaa21..9ccb7ac 100644 --- a/WebCore/bindings/js/ScriptValue.h +++ b/WebCore/bindings/js/ScriptValue.h @@ -34,10 +34,12 @@ #include "PlatformString.h" #include "ScriptState.h" #include <runtime/Protect.h> +#include <wtf/PassRefPtr.h> namespace WebCore { class String; +class SerializedScriptValue; class ScriptValue { public: @@ -53,6 +55,9 @@ public: bool isObject() const; bool hasNoValue() const { return m_value == JSC::JSValue(); } + PassRefPtr<SerializedScriptValue> serialize(ScriptState*); + static ScriptValue deserialize(ScriptState*, SerializedScriptValue*); + private: JSC::ProtectedJSValue m_value; }; diff --git a/WebCore/bindings/js/SerializedScriptValue.cpp b/WebCore/bindings/js/SerializedScriptValue.cpp index fd9cb59..fbf8899 100644 --- a/WebCore/bindings/js/SerializedScriptValue.cpp +++ b/WebCore/bindings/js/SerializedScriptValue.cpp @@ -29,14 +29,17 @@ #include "File.h" #include "FileList.h" +#include "ImageData.h" #include "JSDOMGlobalObject.h" #include "JSFile.h" #include "JSFileList.h" +#include "JSImageData.h" #include <JavaScriptCore/APICast.h> #include <runtime/DateInstance.h> #include <runtime/ExceptionHelpers.h> #include <runtime/JSLock.h> #include <runtime/PropertyNameArray.h> +#include <wtf/ByteArray.h> #include <wtf/HashTraits.h> #include <wtf/Vector.h> @@ -165,6 +168,30 @@ private: Vector<String> m_files; }; +class SerializedImageData : public SharedSerializedData { +public: + static PassRefPtr<SerializedImageData> create(const ImageData* imageData) + { + return adoptRef(new SerializedImageData(imageData)); + } + + unsigned width() const { return m_width; } + unsigned height() const { return m_height; } + WTF::ByteArray* data() const { return m_storage.get(); } +private: + SerializedImageData(const ImageData* imageData) + : m_width(imageData->width()) + , m_height(imageData->height()) + { + WTF::ByteArray* array = imageData->data()->data(); + m_storage = WTF::ByteArray::create(array->length()); + memcpy(m_storage->data(), array->data(), array->length()); + } + unsigned m_width; + unsigned m_height; + RefPtr<WTF::ByteArray> m_storage; +}; + SerializedScriptValueData::SerializedScriptValueData(RefPtr<SerializedObject> data) : m_type(ObjectType) , m_sharedData(data) @@ -183,6 +210,12 @@ SerializedScriptValueData::SerializedScriptValueData(const FileList* fileList) { } +SerializedScriptValueData::SerializedScriptValueData(const ImageData* imageData) + : m_type(ImageDataType) + , m_sharedData(SerializedImageData::create(imageData)) +{ +} + SerializedScriptValueData::SerializedScriptValueData(const File* file) : m_type(FileType) , m_string(file->path().crossThreadString()) @@ -204,6 +237,11 @@ SerializedFileList* SharedSerializedData::asFileList() return static_cast<SerializedFileList*>(this); } +SerializedImageData* SharedSerializedData::asImageData() +{ + return static_cast<SerializedImageData*>(this); +} + static const unsigned maximumFilterRecursion = 40000; enum WalkerState { StateUnknown, ArrayStartState, ArrayStartVisitMember, ArrayEndVisitMember, ObjectStartState, ObjectStartVisitMember, ObjectEndVisitMember }; @@ -533,6 +571,8 @@ struct SerializingTreeWalker : public BaseWalker { return SerializedScriptValueData(toFile(obj)); if (obj->inherits(&JSFileList::s_info)) return SerializedScriptValueData(toFileList(obj)); + if (obj->inherits(&JSImageData::s_info)) + return SerializedScriptValueData(toImageData(obj)); CallData unusedData; if (value.getCallData(unusedData) == CallTypeNone) @@ -709,6 +749,14 @@ struct DeserializingTreeWalker : public BaseWalker { result->append(File::create(serializedFileList->item(i))); return toJS(m_exec, static_cast<JSDOMGlobalObject*>(m_globalObject), result.get()); } + case SerializedScriptValueData::ImageDataType: { + if (!m_isDOMGlobalObject) + return jsNull(); + SerializedImageData* serializedImageData = value.asImageData(); + RefPtr<ImageData> result = ImageData::create(serializedImageData->width(), serializedImageData->height()); + memcpy(result->data()->data()->data(), serializedImageData->data()->data(), serializedImageData->data()->length()); + return toJS(m_exec, static_cast<JSDOMGlobalObject*>(m_globalObject), result.get()); + } case SerializedScriptValueData::EmptyType: ASSERT_NOT_REACHED(); return jsNull(); @@ -868,6 +916,7 @@ struct TeardownTreeWalker { case SerializedScriptValueData::EmptyType: case SerializedScriptValueData::FileType: case SerializedScriptValueData::FileListType: + case SerializedScriptValueData::ImageDataType: return true; } ASSERT_NOT_REACHED(); diff --git a/WebCore/bindings/js/SerializedScriptValue.h b/WebCore/bindings/js/SerializedScriptValue.h index 347d8f2..93bd0de 100644 --- a/WebCore/bindings/js/SerializedScriptValue.h +++ b/WebCore/bindings/js/SerializedScriptValue.h @@ -35,8 +35,10 @@ typedef const struct OpaqueJSValue* JSValueRef; namespace WebCore { class File; class FileList; + class ImageData; class SerializedArray; class SerializedFileList; + class SerializedImageData; class SerializedObject; class SharedSerializedData : public RefCounted<SharedSerializedData> { @@ -45,6 +47,7 @@ namespace WebCore { SerializedArray* asArray(); SerializedObject* asObject(); SerializedFileList* asFileList(); + SerializedImageData* asImageData(); }; class SerializedScriptValue; @@ -60,7 +63,8 @@ namespace WebCore { ArrayType, StringType, FileType, - FileListType + FileListType, + ImageDataType }; SerializedType type() const { return m_type; } @@ -86,6 +90,7 @@ namespace WebCore { explicit SerializedScriptValueData(const File*); explicit SerializedScriptValueData(const FileList*); + explicit SerializedScriptValueData(const ImageData*); explicit SerializedScriptValueData(JSC::JSValue value) : m_type(ImmediateType) @@ -141,6 +146,13 @@ namespace WebCore { ASSERT(m_sharedData); return m_sharedData->asFileList(); } + + SerializedImageData* asImageData() const + { + ASSERT(m_type == ImageDataType); + ASSERT(m_sharedData); + return m_sharedData->asImageData(); + } operator bool() const { return m_type != EmptyType; } |