diff options
Diffstat (limited to 'src/3rdparty/webkit/WebCore/bindings')
192 files changed, 8188 insertions, 5955 deletions
diff --git a/src/3rdparty/webkit/WebCore/bindings/ScriptControllerBase.cpp b/src/3rdparty/webkit/WebCore/bindings/ScriptControllerBase.cpp index 7dc68ef..0467f2d 100644 --- a/src/3rdparty/webkit/WebCore/bindings/ScriptControllerBase.cpp +++ b/src/3rdparty/webkit/WebCore/bindings/ScriptControllerBase.cpp @@ -22,6 +22,7 @@ #include "ScriptController.h" #include "Frame.h" +#include "FrameLoaderClient.h" #include "Page.h" #include "ScriptSourceCode.h" #include "ScriptValue.h" @@ -30,6 +31,19 @@ namespace WebCore { +bool ScriptController::canExecuteScripts(ReasonForCallingCanExecuteScripts reason) +{ + // FIXME: We should get this information from the document instead of the frame. + if (m_frame->loader()->isSandboxed(SandboxScripts)) + return false; + + Settings* settings = m_frame->settings(); + const bool allowed = m_frame->loader()->client()->allowJavaScript(settings && settings->isJavaScriptEnabled()); + if (!allowed && reason == AboutToExecuteScript) + m_frame->loader()->client()->didNotAllowScript(); + return allowed; +} + ScriptValue ScriptController::executeScript(const String& script, bool forceUserGesture) { return executeScript(ScriptSourceCode(script, forceUserGesture ? KURL() : m_frame->loader()->url())); @@ -37,7 +51,7 @@ ScriptValue ScriptController::executeScript(const String& script, bool forceUser ScriptValue ScriptController::executeScript(const ScriptSourceCode& sourceCode) { - if (!isEnabled() || isPaused()) + if (!canExecuteScripts(AboutToExecuteScript) || isPaused()) return ScriptValue(); bool wasInExecuteScript = m_inExecuteScript; @@ -73,8 +87,15 @@ bool ScriptController::executeIfJavaScriptURL(const KURL& url, bool userGesture, result = executeScript(script, userGesture); String scriptResult; +#if USE(JSC) + JSDOMWindowShell* shell = windowShell(mainThreadNormalWorld()); + JSC::ExecState* exec = shell->window()->globalExec(); + if (!result.getString(exec, scriptResult)) + return true; +#else if (!result.getString(scriptResult)) return true; +#endif // FIXME: We should always replace the document, but doing so // synchronously can cause crashes: diff --git a/src/3rdparty/webkit/WebCore/bindings/generic/BindingDOMWindow.h b/src/3rdparty/webkit/WebCore/bindings/generic/BindingDOMWindow.h new file mode 100644 index 0000000..d6d3087 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/bindings/generic/BindingDOMWindow.h @@ -0,0 +1,126 @@ +/* + * 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: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "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 THE COPYRIGHT + * OWNER 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 BindingDOMWindow_h +#define BindingDOMWindow_h + +#include "Frame.h" +#include "FrameLoadRequest.h" +#include "GenericBinding.h" +#include "Page.h" +#include "SecurityOrigin.h" + +namespace WebCore { + +template <class Binding> +class BindingDOMWindow { +public: + typedef typename Binding::Value BindingValue; + + static Frame* createWindow(State<Binding>*, + Frame* callingFrame, + Frame* enteredFrame, + Frame* openerFrame, + const String& url, + const String& frameName, + const WindowFeatures& windowFeatures, + BindingValue dialogArgs); +}; + +// Implementations of templated methods must be in this file. + +template <class Binding> +Frame* BindingDOMWindow<Binding>::createWindow(State<Binding>* state, + Frame* callingFrame, + Frame* enteredFrame, + Frame* openerFrame, + const String& url, + const String& frameName, + const WindowFeatures& windowFeatures, + BindingValue dialogArgs) +{ + ASSERT(callingFrame); + ASSERT(enteredFrame); + + if (Document* callingDocument = callingFrame->document()) { + // Sandboxed iframes cannot open new auxiliary browsing contexts. + if (callingDocument->securityOrigin()->isSandboxed(SandboxNavigation)) + return 0; + } + + ResourceRequest request; + + // For whatever reason, Firefox uses the entered frame to determine + // the outgoingReferrer. We replicate that behavior here. + String referrer = enteredFrame->loader()->outgoingReferrer(); + request.setHTTPReferrer(referrer); + FrameLoader::addHTTPOriginIfNeeded(request, enteredFrame->loader()->outgoingOrigin()); + FrameLoadRequest frameRequest(request, frameName); + + // FIXME: It's much better for client API if a new window starts with a URL, + // here where we know what URL we are going to open. Unfortunately, this + // code passes the empty string for the URL, but there's a reason for that. + // Before loading we have to set up the opener, openedByDOM, + // and dialogArguments values. Also, to decide whether to use the URL + // we currently do an allowsAccessFrom call using the window we create, + // which can't be done before creating it. We'd have to resolve all those + // issues to pass the URL instead of "". + + bool created; + // We pass in the opener frame here so it can be used for looking up the + // frame name, in case the active frame is different from the opener frame, + // and the name references a frame relative to the opener frame, for example + // "_self" or "_parent". + Frame* newFrame = callingFrame->loader()->createWindow(openerFrame->loader(), frameRequest, windowFeatures, created); + if (!newFrame) + return 0; + + newFrame->loader()->setOpener(openerFrame); + newFrame->page()->setOpenedByDOM(); + + Binding::DOMWindow::storeDialogArgs(state, newFrame, dialogArgs); + + if (!protocolIsJavaScript(url) || BindingSecurity<Binding>::canAccessFrame(state, newFrame, true)) { + KURL completedUrl = + url.isEmpty() ? KURL(ParsedURLString, "") : completeURL(url); + bool userGesture = processingUserGesture(); + + if (created) + newFrame->loader()->changeLocation(completedUrl, referrer, false, false, userGesture); + else if (!url.isEmpty()) + newFrame->redirectScheduler()->scheduleLocationChange(completedUrl.string(), referrer, false, userGesture); + } + + return newFrame; +} + +} // namespace WebCore + +#endif // BindingDOMWindow_h diff --git a/src/3rdparty/webkit/WebCore/bindings/generic/BindingElement.h b/src/3rdparty/webkit/WebCore/bindings/generic/BindingElement.h new file mode 100644 index 0000000..ba7856a --- /dev/null +++ b/src/3rdparty/webkit/WebCore/bindings/generic/BindingElement.h @@ -0,0 +1,102 @@ +/* + * 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: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "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 THE COPYRIGHT + * OWNER 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 BindingElement_h +#define BindingElement_h + +#include "Attr.h" +#include "BindingSecurity.h" +#include "Element.h" +#include "ExceptionCode.h" + +#include <wtf/RefPtr.h> + +namespace WebCore { + +template <class Binding> +class BindingElement { +public: + static void setAttribute(State<Binding>*, Element*, const AtomicString&, const AtomicString&, ExceptionCode&); + static RefPtr<Attr> setAttributeNode(State<Binding>*, Element*, Attr*, ExceptionCode&); + static void setAttributeNS(State<Binding>*, Element*, const AtomicString&, const AtomicString&, const AtomicString&, ExceptionCode&); + static RefPtr<Attr> setAttributeNodeNS(State<Binding>*, Element*, Attr*, ExceptionCode&); +}; + +// Implementations of templated methods must be in this file. + +template <class Binding> +void BindingElement<Binding>::setAttribute(State<Binding>* state, Element* element, const AtomicString& name, const AtomicString& value, ExceptionCode& ec) +{ + ASSERT(element); + + if (!BindingSecurity<Binding>::allowSettingSrcToJavascriptURL(state, element, name, value)) + return; + + element->setAttribute(name, value, ec); +} + +template <class Binding> +RefPtr<Attr> BindingElement<Binding>::setAttributeNode(State<Binding>* state, Element* element, Attr* newAttr, ExceptionCode& ec) +{ + ASSERT(element); + ASSERT(newAttr); + + if (!BindingSecurity<Binding>::allowSettingSrcToJavascriptURL(state, element, newAttr->name(), newAttr->value())) + return 0; + + return element->setAttributeNode(newAttr, ec); +} + +template <class Binding> +void BindingElement<Binding>::setAttributeNS(State<Binding>* state, Element* element, const AtomicString& namespaceURI, const AtomicString& qualifiedName, const AtomicString& value, ExceptionCode& ec) +{ + ASSERT(element); + + if (!BindingSecurity<Binding>::allowSettingSrcToJavascriptURL(state, element, qualifiedName, value)) + return; + + element->setAttributeNS(namespaceURI, qualifiedName, value, ec); +} + +template <class Binding> +RefPtr<Attr> BindingElement<Binding>::setAttributeNodeNS(State<Binding>* state, Element* element, Attr* newAttr, ExceptionCode& ec) +{ + ASSERT(element); + ASSERT(newAttr); + + if (!BindingSecurity<Binding>::allowSettingSrcToJavascriptURL(state, element, newAttr->name(), newAttr->value())) + return 0; + + return element->setAttributeNodeNS(newAttr, ec); +} + +} // namespace WebCore + +#endif // BindingElement_h diff --git a/src/3rdparty/webkit/WebCore/bindings/generic/BindingSecurity.h b/src/3rdparty/webkit/WebCore/bindings/generic/BindingSecurity.h new file mode 100644 index 0000000..929b8f4 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/bindings/generic/BindingSecurity.h @@ -0,0 +1,132 @@ +/* + * Copyright (C) 2009 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: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "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 THE COPYRIGHT + * OWNER 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 BindingSecurity_h +#define BindingSecurity_h + +#include "BindingSecurityBase.h" +#include "CSSHelper.h" +#include "Element.h" +#include "GenericBinding.h" +#include "HTMLFrameElementBase.h" + +namespace WebCore { + +class DOMWindow; +class Frame; +class Node; + +// Security functions shared by various language bindings. +template <class Binding> +class BindingSecurity : public BindingSecurityBase { +public: + // Check if the active execution context can access the target frame. + static bool canAccessFrame(State<Binding>*, Frame*, bool reportError); + + // Check if it is safe to access the given node from the + // current security context. + static bool checkNodeSecurity(State<Binding>*, Node* target); + + static bool allowSettingFrameSrcToJavascriptUrl(State<Binding>*, HTMLFrameElementBase*, String value); + static bool allowSettingSrcToJavascriptURL(State<Binding>*, Element*, String name, String value); + +private: + explicit BindingSecurity() {} + ~BindingSecurity(); + + // Check if the current DOMWindow's security context can access the target + // DOMWindow. This function does not report errors, so most callers should + // use canAccessFrame instead. + static bool canAccessWindow(State<Binding>*, DOMWindow* target); +}; + +// Implementations of templated methods must be in this file. + +template <class Binding> +bool BindingSecurity<Binding>::canAccessWindow(State<Binding>* state, + DOMWindow* targetWindow) +{ + DOMWindow* activeWindow = state->getActiveWindow(); + return canAccess(activeWindow, targetWindow); +} + +template <class Binding> +bool BindingSecurity<Binding>::canAccessFrame(State<Binding>* state, + Frame* target, + bool reportError) +{ + // The subject is detached from a frame, deny accesses. + if (!target) + return false; + + if (!canAccessWindow(state, getDOMWindow(target))) { + if (reportError) + state->immediatelyReportUnsafeAccessTo(target); + return false; + } + return true; +} + +template <class Binding> +bool BindingSecurity<Binding>::checkNodeSecurity(State<Binding>* state, Node* node) +{ + if (!node) + return false; + + Frame* target = getFrame(node); + + if (!target) + return false; + + return canAccessFrame(state, target, true); +} + +template <class Binding> +bool BindingSecurity<Binding>::allowSettingFrameSrcToJavascriptUrl(State<Binding>* state, HTMLFrameElementBase* frame, String value) +{ + if (protocolIsJavaScript(deprecatedParseURL(value))) { + Node* contentDoc = frame->contentDocument(); + if (contentDoc && !checkNodeSecurity(state, contentDoc)) + return false; + } + return true; +} + +template <class Binding> +bool BindingSecurity<Binding>::allowSettingSrcToJavascriptURL(State<Binding>* state, Element* element, String name, String value) +{ + if ((element->hasTagName(HTMLNames::iframeTag) || element->hasTagName(HTMLNames::frameTag)) && equalIgnoringCase(name, "src")) + return allowSettingFrameSrcToJavascriptUrl(state, static_cast<HTMLFrameElementBase*>(element), value); + return true; +} + +} + +#endif // BindingSecurity_h diff --git a/src/3rdparty/webkit/WebCore/bindings/generic/BindingSecurityBase.cpp b/src/3rdparty/webkit/WebCore/bindings/generic/BindingSecurityBase.cpp new file mode 100644 index 0000000..1598781 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/bindings/generic/BindingSecurityBase.cpp @@ -0,0 +1,108 @@ +/* + * Copyright (C) 2009 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: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "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 THE COPYRIGHT + * OWNER 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" +#include "BindingSecurityBase.h" + +#include "DOMWindow.h" +#include "Frame.h" +#include "SecurityOrigin.h" + +namespace WebCore { + +DOMWindow* BindingSecurityBase::getDOMWindow(Frame* frame) +{ + return frame->domWindow(); +} + +Frame* BindingSecurityBase::getFrame(Node* node) +{ + return node->document()->frame(); +} + +// Same origin policy implementation: +// +// Same origin policy prevents JS code from domain A from accessing JS & DOM +// objects in a different domain B. There are exceptions and several objects +// are accessible by cross-domain code. For example, the window.frames object +// is accessible by code from a different domain, but window.document is not. +// +// The JS binding code sets security check callbacks on a function template, +// and accessing instances of the template calls the callback function. +// The callback function enforces the same origin policy. +// +// Callback functions are expensive. Binding code should use a security token +// string to do fast access checks for the common case where source and target +// are in the same domain. A security token is a string object that represents +// the protocol/url/port of a domain. +// +// There are special cases where security token matching is not enough. +// For example, JS can set its domain to a super domain by calling +// document.setDomain(...). In these cases, the binding code can reset +// a context's security token to its global object so that the fast access +// check will always fail. + +// Helper to check if the current execution context can access a target frame. +// First it checks same domain policy using the lexical context. +// +// This is equivalent to KJS::Window::allowsAccessFrom(ExecState*). +bool BindingSecurityBase::canAccess(DOMWindow* activeWindow, + DOMWindow* targetWindow) +{ + ASSERT(targetWindow); + + String message; + + if (activeWindow == targetWindow) + return true; + + if (!activeWindow) + return false; + + const SecurityOrigin* activeSecurityOrigin = activeWindow->securityOrigin(); + const SecurityOrigin* targetSecurityOrigin = targetWindow->securityOrigin(); + + // We have seen crashes were the security origin of the target has not been + // initialized. Defend against that. + if (!targetSecurityOrigin) + return false; + + if (activeSecurityOrigin->canAccess(targetSecurityOrigin)) + return true; + + // Allow access to a "about:blank" page if the dynamic context is a + // detached context of the same frame as the blank page. + if (targetSecurityOrigin->isEmpty() && activeWindow->frame() == targetWindow->frame()) + return true; + + return false; +} + +} // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/bindings/generic/BindingSecurityBase.h b/src/3rdparty/webkit/WebCore/bindings/generic/BindingSecurityBase.h new file mode 100644 index 0000000..cfa2e99 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/bindings/generic/BindingSecurityBase.h @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2009 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: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "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 THE COPYRIGHT + * OWNER 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 BindingSecurityBase_h +#define BindingSecurityBase_h + +namespace WebCore { + +class DOMWindow; +class Frame; +class Node; + +// Helper functions for BindingSecurity that depend on WebCore classes, and +// thus should not be implemented in BindingSecurity.h, which contains template +// method definitions. +class BindingSecurityBase { +protected: + static DOMWindow* getDOMWindow(Frame*); + static Frame* getFrame(Node*); + static bool canAccess(DOMWindow* active, DOMWindow* target); +}; + +} + +#endif // BindingSecurityBase_h diff --git a/src/3rdparty/webkit/WebCore/bindings/js/ScriptObjectQuarantine.h b/src/3rdparty/webkit/WebCore/bindings/generic/GenericBinding.h index df52379..d030b45 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/ScriptObjectQuarantine.h +++ b/src/3rdparty/webkit/WebCore/bindings/generic/GenericBinding.h @@ -1,10 +1,10 @@ /* * Copyright (C) 2009 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: - * + * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above @@ -14,7 +14,7 @@ * * Neither the name of Google Inc. nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. - * + * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR @@ -28,31 +28,25 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef ScriptObjectQuarantine_h -#define ScriptObjectQuarantine_h - -#include "ScriptState.h" +#ifndef GenericBinding_h +#define GenericBinding_h namespace WebCore { - class Database; - class DOMWindow; - class Node; - class ScriptObject; - class ScriptValue; - class Storage; +// Used to instantiate binding templates for any methods shared among all +// language bindings. +class GenericBinding {}; - ScriptValue quarantineValue(ScriptState*, const ScriptValue&); +// Class to represent execution state for each language binding. +template <class T> +class State {}; -#if ENABLE(DATABASE) - bool getQuarantinedScriptObject(Database* database, ScriptObject& quarantinedObject); -#endif -#if ENABLE(DOM_STORAGE) - bool getQuarantinedScriptObject(Storage* storage, ScriptObject& quarantinedObject); -#endif - bool getQuarantinedScriptObject(Node* node, ScriptObject& quarantinedObject); - bool getQuarantinedScriptObject(DOMWindow* domWindow, ScriptObject& quarantinedObject); +// Common notion of execution state for language bindings. +template <> +class State<GenericBinding> { + // Any methods shared across bindings can go here. +}; } -#endif // ScriptObjectQuarantine_h +#endif // GenericBinding_h diff --git a/src/3rdparty/webkit/WebCore/bindings/generic/RuntimeEnabledFeatures.cpp b/src/3rdparty/webkit/WebCore/bindings/generic/RuntimeEnabledFeatures.cpp new file mode 100644 index 0000000..6ba85da --- /dev/null +++ b/src/3rdparty/webkit/WebCore/bindings/generic/RuntimeEnabledFeatures.cpp @@ -0,0 +1,100 @@ +/* + * Copyright (C) 2009 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: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "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 THE COPYRIGHT + * OWNER 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" +#include "RuntimeEnabledFeatures.h" + +#include "Database.h" +#include "MediaPlayer.h" +#include "SharedWorkerRepository.h" +#include "WebSocket.h" + +namespace WebCore { + +bool RuntimeEnabledFeatures::isLocalStorageEnabled = true; +bool RuntimeEnabledFeatures::isSessionStorageEnabled = true; +bool RuntimeEnabledFeatures::isWebkitNotificationsEnabled = false; +bool RuntimeEnabledFeatures::isApplicationCacheEnabled = true; +bool RuntimeEnabledFeatures::isGeolocationEnabled = true; +bool RuntimeEnabledFeatures::isIndexedDBEnabled = false; +bool RuntimeEnabledFeatures::isWebGLEnabled = false; +bool RuntimeEnabledFeatures::isPushStateEnabled = false; + +#if ENABLE(VIDEO) + +bool RuntimeEnabledFeatures::audioEnabled() +{ + return MediaPlayer::isAvailable(); +} + +bool RuntimeEnabledFeatures::htmlMediaElementEnabled() +{ + return MediaPlayer::isAvailable(); +} + +bool RuntimeEnabledFeatures::htmlAudioElementEnabled() +{ + return MediaPlayer::isAvailable(); +} + +bool RuntimeEnabledFeatures::htmlVideoElementEnabled() +{ + return MediaPlayer::isAvailable(); +} + +bool RuntimeEnabledFeatures::mediaErrorEnabled() +{ + return MediaPlayer::isAvailable(); +} + +#endif + +#if ENABLE(SHARED_WORKERS) +bool RuntimeEnabledFeatures::sharedWorkerEnabled() +{ + return SharedWorkerRepository::isAvailable(); +} +#endif + +#if ENABLE(WEB_SOCKETS) +bool RuntimeEnabledFeatures::webSocketEnabled() +{ + return WebSocket::isAvailable(); +} +#endif + +#if ENABLE(DATABASE) +bool RuntimeEnabledFeatures::openDatabaseEnabled() +{ + return Database::isAvailable(); +} +#endif + +} // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/bindings/generic/RuntimeEnabledFeatures.h b/src/3rdparty/webkit/WebCore/bindings/generic/RuntimeEnabledFeatures.h new file mode 100644 index 0000000..37dceff --- /dev/null +++ b/src/3rdparty/webkit/WebCore/bindings/generic/RuntimeEnabledFeatures.h @@ -0,0 +1,113 @@ +/* + * Copyright (C) 2009 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: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "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 THE COPYRIGHT + * OWNER 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 RuntimeEnabledFeatures_h +#define RuntimeEnabledFeatures_h + +namespace WebCore { + +// A class that stores static enablers for all experimental features. Note that +// the method names must line up with the JavaScript method they enable for code +// generation to work properly. + +class RuntimeEnabledFeatures { +public: + static void setLocalStorageEnabled(bool isEnabled) { isLocalStorageEnabled = isEnabled; } + static bool localStorageEnabled() { return isLocalStorageEnabled; } + + static void setSessionStorageEnabled(bool isEnabled) { isSessionStorageEnabled = isEnabled; } + static bool sessionStorageEnabled() { return isSessionStorageEnabled; } + + static void setWebkitNotificationsEnabled(bool isEnabled) { isWebkitNotificationsEnabled = isEnabled; } + static bool webkitNotificationsEnabled() { return isWebkitNotificationsEnabled; } + + static void setApplicationCacheEnabled(bool isEnabled) { isApplicationCacheEnabled = isEnabled; } + static bool applicationCacheEnabled() { return isApplicationCacheEnabled; } + + static void setGeolocationEnabled(bool isEnabled) { isGeolocationEnabled = isEnabled; } + static bool geolocationEnabled() { return isGeolocationEnabled; } + + static void setIndexedDBEnabled(bool isEnabled) { isIndexedDBEnabled = isEnabled; } + static bool indexedDBEnabled() { return isIndexedDBEnabled; } + +#if ENABLE(VIDEO) + static bool audioEnabled(); + static bool htmlMediaElementEnabled(); + static bool htmlAudioElementEnabled(); + static bool htmlVideoElementEnabled(); + static bool mediaErrorEnabled(); +#endif + +#if ENABLE(SHARED_WORKERS) + static bool sharedWorkerEnabled(); +#endif + +#if ENABLE(WEB_SOCKETS) + static bool webSocketEnabled(); +#endif + +#if ENABLE(DATABASE) + static bool openDatabaseEnabled(); +#endif + +#if ENABLE(3D_CANVAS) + static void setWebGLEnabled(bool isEnabled) { isWebGLEnabled = isEnabled; } + static bool webGLRenderingContextEnabled() { return isWebGLEnabled; } + static bool webGLArrayBufferEnabled() { return isWebGLEnabled; } + static bool webGLByteArrayEnabled() { return isWebGLEnabled; } + static bool webGLUnsignedByteArrayEnabled() { return isWebGLEnabled; } + static bool webGLShortArrayEnabled() { return isWebGLEnabled; } + static bool webGLUnsignedShortArrayEnabled() { return isWebGLEnabled; } + static bool webGLIntArrayEnabled() { return isWebGLEnabled; } + static bool webGLUnsignedIntArrayEnabled() { return isWebGLEnabled; } + static bool webGLFloatArrayEnabled() { return isWebGLEnabled; } +#endif + + static void setPushStateEnabled(bool isEnabled) { isPushStateEnabled = isEnabled; } + static bool pushStateEnabled() { return isPushStateEnabled; } + static bool replaceStateEnabled() { return isPushStateEnabled; } + +private: + // Never instantiate. + RuntimeEnabledFeatures() { } + + static bool isLocalStorageEnabled; + static bool isSessionStorageEnabled; + static bool isWebkitNotificationsEnabled; + static bool isApplicationCacheEnabled; + static bool isGeolocationEnabled; + static bool isIndexedDBEnabled; + static bool isWebGLEnabled; + static bool isPushStateEnabled; +}; + +} // namespace WebCore + +#endif // RuntimeEnabledFeatures_h diff --git a/src/3rdparty/webkit/WebCore/bindings/js/DOMObjectHashTableMap.cpp b/src/3rdparty/webkit/WebCore/bindings/js/DOMObjectHashTableMap.cpp new file mode 100644 index 0000000..bfcab0b --- /dev/null +++ b/src/3rdparty/webkit/WebCore/bindings/js/DOMObjectHashTableMap.cpp @@ -0,0 +1,37 @@ +/* + * Copyright (C) 1999-2001 Harri Porten (porten@kde.org) + * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. + * Copyright (C) 2007 Samuel Weinig <sam@webkit.org> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" +#include "DOMObjectHashTableMap.h" + +#include "WebCoreJSClientData.h" + +using namespace JSC; + +namespace WebCore{ + +DOMObjectHashTableMap& DOMObjectHashTableMap::mapFor(JSGlobalData& globalData) +{ + JSGlobalData::ClientData* clientData = globalData.clientData; + ASSERT(clientData); + return static_cast<WebCoreJSClientData*>(clientData)->hashTableMap; +} + +} // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/bindings/js/DOMObjectHashTableMap.h b/src/3rdparty/webkit/WebCore/bindings/js/DOMObjectHashTableMap.h new file mode 100644 index 0000000..4ddacb8 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/bindings/js/DOMObjectHashTableMap.h @@ -0,0 +1,60 @@ +/* + * Copyright (C) 1999-2001 Harri Porten (porten@kde.org) + * Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Apple Inc. All rights reserved. + * Copyright (C) 2007 Samuel Weinig <sam@webkit.org> + * Copyright (C) 2009 Google, Inc. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef DOMObjectHashTableMap_h +#define DOMObjectHashTableMap_h + +#include <runtime/Lookup.h> +#include <wtf/HashMap.h> + +namespace JSC { + class JSGlobalData; +} + +namespace WebCore { + +// Map from static HashTable instances to per-GlobalData ones. +class DOMObjectHashTableMap { +public: + static DOMObjectHashTableMap& mapFor(JSC::JSGlobalData&); + + ~DOMObjectHashTableMap() + { + HashMap<const JSC::HashTable*, JSC::HashTable>::iterator mapEnd = m_map.end(); + for (HashMap<const JSC::HashTable*, JSC::HashTable>::iterator iter = m_map.begin(); iter != m_map.end(); ++iter) + iter->second.deleteTable(); + } + + const JSC::HashTable* get(const JSC::HashTable* staticTable) + { + HashMap<const JSC::HashTable*, JSC::HashTable>::iterator iter = m_map.find(staticTable); + if (iter != m_map.end()) + return &iter->second; + return &m_map.set(staticTable, JSC::HashTable(*staticTable)).first->second; + } + +private: + HashMap<const JSC::HashTable*, JSC::HashTable> m_map; +}; + +} // namespace WebCore + +#endif // DOMObjectHashTableMap_h diff --git a/src/3rdparty/webkit/WebCore/bindings/js/DOMObjectWithSVGContext.h b/src/3rdparty/webkit/WebCore/bindings/js/DOMObjectWithSVGContext.h deleted file mode 100644 index 3d435cb..0000000 --- a/src/3rdparty/webkit/WebCore/bindings/js/DOMObjectWithSVGContext.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (C) 2009 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 THE AUTHOR ``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 THE AUTHOR 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 DOMObjectWithSVGContext_h -#define DOMObjectWithSVGContext_h - -#if ENABLE(SVG) - -#include "JSDOMBinding.h" -#include "SVGElement.h" - -namespace WebCore { - - // FIXME: This class (and file) should be removed once all SVG bindings - // have moved context() onto the various impl() pointers. - class DOMObjectWithSVGContext : public DOMObject { - public: - SVGElement* context() const { return m_context.get(); } - - protected: - DOMObjectWithSVGContext(NonNullPassRefPtr<JSC::Structure> structure, JSDOMGlobalObject*, SVGElement* context) - : DOMObject(structure) - , m_context(context) - { - // No space to store the JSDOMGlobalObject w/o hitting the CELL_SIZE limit. - } - - protected: // FIXME: Many custom bindings use m_context directly. Making this protected to temporariliy reduce code churn. - RefPtr<SVGElement> m_context; - }; - -} // namespace WebCore - -#endif // ENABLE(SVG) -#endif // DOMObjectWithSVGContext_h diff --git a/src/3rdparty/webkit/WebCore/bindings/js/DOMWrapperWorld.cpp b/src/3rdparty/webkit/WebCore/bindings/js/DOMWrapperWorld.cpp new file mode 100644 index 0000000..c696315 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/bindings/js/DOMWrapperWorld.cpp @@ -0,0 +1,68 @@ +/* + * Copyright (C) 1999-2001 Harri Porten (porten@kde.org) + * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. + * Copyright (C) 2007 Samuel Weinig <sam@webkit.org> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" +#include "DOMWrapperWorld.h" + +#include "JSDOMWindow.h" +#include "WebCoreJSClientData.h" + +using namespace JSC; + +namespace WebCore { + +DOMWrapperWorld::DOMWrapperWorld(JSC::JSGlobalData* globalData, bool isNormal) + : m_globalData(globalData) + , m_isNormal(isNormal) +{ +} + +static void forgetWorldOfDOMNodesForDocument(Document* document, DOMWrapperWorld* world) +{ + Document::JSWrapperCache* wrappers = document->wrapperCacheMap().take(world); + ASSERT(wrappers); // 'world' should only know about 'document' if 'document' knows about 'world'! + delete wrappers; +} + +DOMWrapperWorld::~DOMWrapperWorld() +{ + 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); +} + +DOMWrapperWorld* normalWorld(JSC::JSGlobalData& globalData) +{ + JSGlobalData::ClientData* clientData = globalData.clientData; + ASSERT(clientData); + return static_cast<WebCoreJSClientData*>(clientData)->normalWorld(); +} + +DOMWrapperWorld* mainThreadNormalWorld() +{ + ASSERT(isMainThread()); + static DOMWrapperWorld* cachedNormalWorld = normalWorld(*JSDOMWindow::commonJSGlobalData()); + return cachedNormalWorld; +} + +} // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/bindings/js/DOMWrapperWorld.h b/src/3rdparty/webkit/WebCore/bindings/js/DOMWrapperWorld.h new file mode 100644 index 0000000..65cf6a6 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/bindings/js/DOMWrapperWorld.h @@ -0,0 +1,88 @@ +/* + * Copyright (C) 1999-2001 Harri Porten (porten@kde.org) + * Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Apple Inc. All rights reserved. + * Copyright (C) 2007 Samuel Weinig <sam@webkit.org> + * Copyright (C) 2009 Google, Inc. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef DOMWrapperWorld_h +#define DOMWrapperWorld_h + +#include "Document.h" +#include "JSDOMGlobalObject.h" +#include "JSDOMWrapper.h" +#include <runtime/WeakGCMap.h> + +namespace WebCore { + +class StringImpl; + +typedef JSC::WeakGCMap<void*, DOMObject*> DOMObjectWrapperMap; +typedef JSC::WeakGCMap<StringImpl*, JSC::JSString*> JSStringCache; + +class DOMWrapperWorld : public RefCounted<DOMWrapperWorld> { +public: + static PassRefPtr<DOMWrapperWorld> create(JSC::JSGlobalData* globalData, bool isNormal) + { + return adoptRef(new DOMWrapperWorld(globalData, isNormal)); + } + ~DOMWrapperWorld(); + + void rememberDocument(Document* document) { documentsWithWrappers.add(document); } + void forgetDocument(Document* document) { documentsWithWrappers.remove(document); } + + // FIXME: can we make this private? + DOMObjectWrapperMap m_wrappers; + JSStringCache m_stringCache; + + bool isNormal() const { return m_isNormal; } + +protected: + DOMWrapperWorld(JSC::JSGlobalData*, bool isNormal); + +private: + JSC::JSGlobalData* m_globalData; + HashSet<Document*> documentsWithWrappers; + bool m_isNormal; +}; + +DOMWrapperWorld* normalWorld(JSC::JSGlobalData&); +DOMWrapperWorld* mainThreadNormalWorld(); +inline DOMWrapperWorld* debuggerWorld() { return mainThreadNormalWorld(); } +inline DOMWrapperWorld* pluginWorld() { return mainThreadNormalWorld(); } + +inline DOMWrapperWorld* currentWorld(JSC::ExecState* exec) +{ + return static_cast<JSDOMGlobalObject*>(exec->lexicalGlobalObject())->world(); +} + +// From Document.h + +inline Document::JSWrapperCache* Document::getWrapperCache(DOMWrapperWorld* world) +{ + if (world->isNormal()) { + if (Document::JSWrapperCache* wrapperCache = m_normalWorldWrapperCache) + return wrapperCache; + ASSERT(!m_wrapperCacheMap.contains(world)); + } else if (Document::JSWrapperCache* wrapperCache = m_wrapperCacheMap.get(world)) + return wrapperCache; + return createWrapperCache(world); +} + +} // namespace WebCore + +#endif // DOMWrapperWorld_h diff --git a/src/3rdparty/webkit/WebCore/bindings/js/GCController.cpp b/src/3rdparty/webkit/WebCore/bindings/js/GCController.cpp index 59bcfa3..d5a1789 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/GCController.cpp +++ b/src/3rdparty/webkit/WebCore/bindings/js/GCController.cpp @@ -40,17 +40,13 @@ using namespace JSC; namespace WebCore { -#if USE(PTHREADS) - static void* collect(void*) { JSLock lock(SilenceAssertionsOnly); - JSDOMWindow::commonJSGlobalData()->heap.collect(); + JSDOMWindow::commonJSGlobalData()->heap.collectAllGarbage(); return 0; } -#endif - GCController& gcController() { DEFINE_STATIC_LOCAL(GCController, staticGCController, ()); @@ -70,14 +66,14 @@ void GCController::garbageCollectSoon() void GCController::gcTimerFired(Timer<GCController>*) { - JSLock lock(SilenceAssertionsOnly); - JSDOMWindow::commonJSGlobalData()->heap.collect(); + collect(0); } void GCController::garbageCollectNow() { JSLock lock(SilenceAssertionsOnly); - JSDOMWindow::commonJSGlobalData()->heap.collect(); + if (!JSDOMWindow::commonJSGlobalData()->heap.isBusy()) + collect(0); } void GCController::garbageCollectOnAlternateThreadForDebugging(bool waitUntilDone) diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSAbstractWorkerCustom.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSAbstractWorkerCustom.cpp index 6eca7bd..61fcf98 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSAbstractWorkerCustom.cpp +++ b/src/3rdparty/webkit/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/src/3rdparty/webkit/WebCore/bindings/js/JSAttrCustom.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSAttrCustom.cpp index 14457c4..3c01535 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSAttrCustom.cpp +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSAttrCustom.cpp @@ -65,10 +65,8 @@ void JSAttr::markChildren(MarkStack& markStack) // Mark the element so that this will work to access the attribute even if the last // other reference goes away. - if (Element* element = impl()->ownerElement()) { - if (JSNode* wrapper = getCachedDOMNodeWrapper(element->document(), element)) - markStack.append(wrapper); - } + if (Element* element = impl()->ownerElement()) + markDOMNodeWrapper(markStack, element->document(), element); } } // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSAudioConstructor.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSAudioConstructor.cpp index 174cc11..77bb120 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSAudioConstructor.cpp +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSAudioConstructor.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2007, 2008, 2010 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -20,7 +20,7 @@ * 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. + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "config.h" @@ -30,10 +30,7 @@ #include "JSAudioConstructor.h" #include "HTMLAudioElement.h" -#include "HTMLNames.h" #include "JSHTMLAudioElement.h" -#include "ScriptExecutionContext.h" -#include "Text.h" #include <runtime/Error.h> using namespace JSC; @@ -46,24 +43,30 @@ JSAudioConstructor::JSAudioConstructor(ExecState* exec, JSDOMGlobalObject* globa : DOMConstructorWithDocument(JSAudioConstructor::createStructure(globalObject->objectPrototype()), globalObject) { putDirect(exec->propertyNames().prototype, JSHTMLAudioElementPrototype::self(exec, globalObject), None); - putDirect(exec->propertyNames().length, jsNumber(exec, 1), ReadOnly|DontDelete|DontEnum); + putDirect(exec->propertyNames().length, jsNumber(exec, 1), ReadOnly | DontDelete | DontEnum); } static JSObject* constructAudio(ExecState* exec, JSObject* constructor, const ArgList& args) { - JSAudioConstructor* jsAudio = static_cast<JSAudioConstructor*>(constructor); - // FIXME: Why doesn't this need the call toJS on the document like JSImageConstructor? - Document* document = jsAudio->document(); + JSAudioConstructor* jsConstructor = static_cast<JSAudioConstructor*>(constructor); + + Document* document = jsConstructor->document(); if (!document) return throwError(exec, ReferenceError, "Audio constructor associated document is unavailable"); - RefPtr<HTMLAudioElement> audio = new HTMLAudioElement(HTMLNames::audioTag, document); - audio->setAutobuffer(true); - if (args.size() > 0) { - audio->setSrc(args.at(0).toString(exec)); - audio->scheduleLoad(); - } - return asObject(toJS(exec, jsAudio->globalObject(), audio.release())); + // Calling toJS on the document causes the JS document wrapper to be + // added to the window object. This is done to ensure that JSDocument::markChildren + // will be called, which will cause the audio element to be marked if necessary. + toJS(exec, jsConstructor->globalObject(), document); + + // FIXME: This converts an undefined argument to the string "undefined", but possibly we + // should treat it as if no argument was passed instead, by checking the value of args.at + // rather than looking at args.size. + String src; + if (args.size() > 0) + src = args.at(0).toString(exec); + return asObject(toJS(exec, jsConstructor->globalObject(), + HTMLAudioElement::createForJSConstructor(document, src))); } ConstructType JSAudioConstructor::getConstructData(ConstructData& constructData) diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSBindingsAllInOne.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSBindingsAllInOne.cpp index f08303a..5a0820b 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSBindingsAllInOne.cpp +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSBindingsAllInOne.cpp @@ -85,8 +85,8 @@ #include "JSHistoryCustom.cpp" #include "JSImageConstructor.cpp" #include "JSImageDataCustom.cpp" -#include "JSInspectedObjectWrapper.cpp" -#include "JSInspectorBackendCustom.cpp" +#include "JSInjectedScriptHostCustom.cpp" +#include "JSInspectorFrontendHostCustom.cpp" #include "JSJavaScriptCallFrameCustom.cpp" #include "JSLazyEventListener.cpp" #include "JSLocationCustom.cpp" @@ -106,7 +106,6 @@ #include "JSPluginArrayCustom.cpp" #include "JSPluginCustom.cpp" #include "JSPluginElementFunctions.cpp" -#include "JSQuarantinedObjectWrapper.cpp" #include "JSSQLResultSetRowListCustom.cpp" #include "JSSQLTransactionCustom.cpp" #include "JSSVGElementInstanceCustom.cpp" @@ -114,7 +113,6 @@ #include "JSSVGMatrixCustom.cpp" #include "JSSVGPathSegCustom.cpp" #include "JSSVGPathSegListCustom.cpp" -#include "JSSVGPointListCustom.cpp" #include "JSSharedWorkerConstructor.cpp" #include "JSSharedWorkerCustom.cpp" #include "JSStorageCustom.cpp" @@ -142,9 +140,10 @@ #include "ScriptCallStack.cpp" #include "ScriptController.cpp" #include "ScriptControllerWin.cpp" +#include "ScriptDebugServer.cpp" #include "ScriptEventListener.cpp" #include "ScriptFunctionCall.cpp" -#include "ScriptObjectQuarantine.cpp" +#include "ScriptProfiler.cpp" #include "ScriptState.cpp" #include "SerializedScriptValue.cpp" #include "WorkerScriptController.cpp" diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSCSSRuleCustom.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSCSSRuleCustom.cpp index 1b96c06..b0adf15 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSCSSRuleCustom.cpp +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSCSSRuleCustom.cpp @@ -54,7 +54,7 @@ JSValue toJS(ExecState* exec, JSDOMGlobalObject* globalObject, CSSRule* rule) if (!rule) return jsNull(); - DOMObject* wrapper = getCachedDOMObjectWrapper(exec->globalData(), rule); + DOMObject* wrapper = getCachedDOMObjectWrapper(exec, rule); if (wrapper) return wrapper; diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSCSSStyleDeclarationCustom.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSCSSStyleDeclarationCustom.cpp index 4a137d3..fad7aba 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSCSSStyleDeclarationCustom.cpp +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSCSSStyleDeclarationCustom.cpp @@ -142,9 +142,9 @@ bool JSCSSStyleDeclaration::canGetItemsForName(ExecState*, CSSStyleDeclaration*, // FIXME: You can get these properties, and set them (see putDelegate below), // but you should also be able to enumerate them. -JSValue JSCSSStyleDeclaration::nameGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot) +JSValue JSCSSStyleDeclaration::nameGetter(ExecState* exec, JSValue slotBase, const Identifier& propertyName) { - JSCSSStyleDeclaration* thisObj = static_cast<JSCSSStyleDeclaration*>(asObject(slot.slotBase())); + JSCSSStyleDeclaration* thisObj = static_cast<JSCSSStyleDeclaration*>(asObject(slotBase)); // Set up pixelOrPos boolean to handle the fact that // pixelTop returns "CSS Top" as number value in unit pixels diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSCSSValueCustom.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSCSSValueCustom.cpp index 87a5760..83c1d3a 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSCSSValueCustom.cpp +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSCSSValueCustom.cpp @@ -49,7 +49,7 @@ JSValue toJS(ExecState* exec, JSDOMGlobalObject* globalObject, CSSValue* value) if (!value) return jsNull(); - DOMObject* wrapper = getCachedDOMObjectWrapper(exec->globalData(), value); + DOMObject* wrapper = getCachedDOMObjectWrapper(exec, value); if (wrapper) return wrapper; diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSCallbackData.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSCallbackData.cpp index 38292c7..e128f27 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSCallbackData.cpp +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSCallbackData.cpp @@ -47,13 +47,8 @@ JSValue JSCallbackData::invokeCallback(MarkedArgumentBuffer& args, bool* raisedE ASSERT(globalObject()); ExecState* exec = globalObject()->globalExec(); - - JSValue function; - { - // Switch worlds, just in case handleEvent is a getter and causes JS execution! - EnterDOMWrapperWorld worldEntry(exec, m_isolatedWorld.get()); - function = callback()->get(exec, Identifier(exec, "handleEvent")); - } + JSValue function = callback()->get(exec, Identifier(exec, "handleEvent")); + CallData callData; CallType callType = function.getCallData(callData); if (callType == CallTypeNone) { @@ -64,7 +59,7 @@ JSValue JSCallbackData::invokeCallback(MarkedArgumentBuffer& args, bool* raisedE } globalObject()->globalData()->timeoutChecker.start(); - JSValue result = callInWorld(exec, function, callType, callData, callback(), args, m_isolatedWorld.get()); + JSValue result = JSC::call(exec, function, callType, callData, callback(), args); globalObject()->globalData()->timeoutChecker.stop(); Document::updateStyleForAllDocuments(); diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSCallbackData.h b/src/3rdparty/webkit/WebCore/bindings/js/JSCallbackData.h index 5c86701..b939c01 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSCallbackData.h +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSCallbackData.h @@ -48,7 +48,6 @@ public: JSCallbackData(JSC::JSObject* callback, JSDOMGlobalObject* globalObject) : m_callback(callback) , m_globalObject(globalObject) - , m_isolatedWorld(currentWorld(globalObject->globalExec())) { } @@ -65,7 +64,6 @@ public: private: JSC::ProtectedPtr<JSC::JSObject> m_callback; JSC::ProtectedPtr<JSDOMGlobalObject> m_globalObject; - RefPtr<DOMWrapperWorld> m_isolatedWorld; }; } // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSCanvasArrayCustom.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSCanvasArrayCustom.cpp deleted file mode 100644 index 14548d7..0000000 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSCanvasArrayCustom.cpp +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (C) 2009 Apple 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(3D_CANVAS) - -#include "config.h" -#include "JSCanvasArray.h" -#include "JSCanvasByteArray.h" -#include "JSCanvasUnsignedByteArray.h" -#include "JSCanvasShortArray.h" -#include "JSCanvasUnsignedShortArray.h" -#include "JSCanvasIntArray.h" -#include "JSCanvasUnsignedIntArray.h" -#include "JSCanvasFloatArray.h" - -#include "CanvasArray.h" - -using namespace JSC; - -namespace WebCore { - -JSC::JSValue toJS(JSC::ExecState* exec, JSDOMGlobalObject* globalObject, CanvasArray* object) -{ - if (object->isFloatArray()) - return getDOMObjectWrapper<JSCanvasFloatArray>(exec, globalObject, static_cast<CanvasFloatArray*>(object)); - if (object->isUnsignedByteArray()) - return getDOMObjectWrapper<JSCanvasUnsignedByteArray>(exec, globalObject, static_cast<CanvasUnsignedByteArray*>(object)); - if (object->isByteArray()) - return getDOMObjectWrapper<JSCanvasByteArray>(exec, globalObject, static_cast<CanvasByteArray*>(object)); - if (object->isIntArray()) - return getDOMObjectWrapper<JSCanvasIntArray>(exec, globalObject, static_cast<CanvasIntArray*>(object)); - if (object->isUnsignedIntArray()) - return getDOMObjectWrapper<JSCanvasUnsignedIntArray>(exec, globalObject, static_cast<CanvasUnsignedIntArray*>(object)); - if (object->isShortArray()) - return getDOMObjectWrapper<JSCanvasShortArray>(exec, globalObject, static_cast<CanvasShortArray*>(object)); - if (object->isUnsignedShortArray()) - return getDOMObjectWrapper<JSCanvasUnsignedShortArray>(exec, globalObject, static_cast<CanvasUnsignedShortArray*>(object)); - return jsUndefined(); -} - -} // namespace WebCore - -#endif // ENABLE(3D_CANVAS) diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSCanvasRenderingContext2DCustom.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSCanvasRenderingContext2DCustom.cpp index bb3500b..a271923 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSCanvasRenderingContext2DCustom.cpp +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSCanvasRenderingContext2DCustom.cpp @@ -51,10 +51,10 @@ static JSValue toJS(ExecState* exec, CanvasStyle* style) return jsString(exec, style->color()); } -static PassRefPtr<CanvasStyle> toHTMLCanvasStyle(ExecState*, JSValue value) +static PassRefPtr<CanvasStyle> toHTMLCanvasStyle(ExecState* exec, JSValue value) { if (value.isString()) - return CanvasStyle::create(asString(value)->value()); + return CanvasStyle::create(asString(value)->value(exec)); if (!value.isObject()) return 0; JSObject* object = asObject(value); @@ -102,13 +102,13 @@ JSValue JSCanvasRenderingContext2D::setFillColor(ExecState* exec, const ArgList& switch (args.size()) { case 1: if (args.at(0).isString()) - context->setFillColor(asString(args.at(0))->value()); + context->setFillColor(asString(args.at(0))->value(exec)); else context->setFillColor(args.at(0).toFloat(exec)); break; case 2: if (args.at(0).isString()) - context->setFillColor(asString(args.at(0))->value(), args.at(1).toFloat(exec)); + context->setFillColor(asString(args.at(0))->value(exec), args.at(1).toFloat(exec)); else context->setFillColor(args.at(0).toFloat(exec), args.at(1).toFloat(exec)); break; @@ -139,13 +139,13 @@ JSValue JSCanvasRenderingContext2D::setStrokeColor(ExecState* exec, const ArgLis switch (args.size()) { case 1: if (args.at(0).isString()) - context->setStrokeColor(asString(args.at(0))->value()); + context->setStrokeColor(asString(args.at(0))->value(exec)); else context->setStrokeColor(args.at(0).toFloat(exec)); break; case 2: if (args.at(0).isString()) - context->setStrokeColor(asString(args.at(0))->value(), args.at(1).toFloat(exec)); + context->setStrokeColor(asString(args.at(0))->value(exec), args.at(1).toFloat(exec)); else context->setStrokeColor(args.at(0).toFloat(exec), args.at(1).toFloat(exec)); break; @@ -298,7 +298,7 @@ JSValue JSCanvasRenderingContext2D::setShadow(ExecState* exec, const ArgList& ar case 4: if (args.at(3).isString()) context->setShadow(args.at(0).toFloat(exec), args.at(1).toFloat(exec), - args.at(2).toFloat(exec), asString(args.at(3))->value()); + args.at(2).toFloat(exec), asString(args.at(3))->value(exec)); else context->setShadow(args.at(0).toFloat(exec), args.at(1).toFloat(exec), args.at(2).toFloat(exec), args.at(3).toFloat(exec)); @@ -306,7 +306,7 @@ JSValue JSCanvasRenderingContext2D::setShadow(ExecState* exec, const ArgList& ar case 5: if (args.at(3).isString()) context->setShadow(args.at(0).toFloat(exec), args.at(1).toFloat(exec), - args.at(2).toFloat(exec), asString(args.at(3))->value(), + args.at(2).toFloat(exec), asString(args.at(3))->value(exec), args.at(4).toFloat(exec)); else context->setShadow(args.at(0).toFloat(exec), args.at(1).toFloat(exec), diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSCanvasRenderingContext3DCustom.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSCanvasRenderingContext3DCustom.cpp deleted file mode 100644 index 3938ba1..0000000 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSCanvasRenderingContext3DCustom.cpp +++ /dev/null @@ -1,443 +0,0 @@ -/* - * Copyright (C) 2009 Apple 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(3D_CANVAS) - -#include "JSCanvasRenderingContext3D.h" - -#include "CanvasRenderingContext3D.h" -#include "ExceptionCode.h" -#include "HTMLCanvasElement.h" -#include "HTMLImageElement.h" -#include "JSCanvasFloatArray.h" -#include "JSCanvasIntArray.h" -#include "JSHTMLCanvasElement.h" -#include "JSHTMLImageElement.h" -#include "JSWebKitCSSMatrix.h" -#include <runtime/Error.h> -#include <wtf/FastMalloc.h> -#include <wtf/OwnFastMallocPtr.h> - -using namespace JSC; - -namespace WebCore { - -JSValue JSCanvasRenderingContext3D::bufferData(JSC::ExecState* exec, JSC::ArgList const& args) -{ - if (args.size() != 3) - return throwError(exec, SyntaxError); - - unsigned target = args.at(0).toInt32(exec); - unsigned usage = args.at(2).toInt32(exec); - - // If argument 1 is a number, we are initializing this buffer to that size - if (!args.at(1).isObject()) { - unsigned int count = args.at(1).toInt32(exec); - static_cast<CanvasRenderingContext3D*>(impl())->bufferData(target, count, usage); - return jsUndefined(); - } - - CanvasArray* array = toCanvasArray(args.at(1)); - - static_cast<CanvasRenderingContext3D*>(impl())->bufferData(target, array, usage); - return jsUndefined(); -} - -JSValue JSCanvasRenderingContext3D::bufferSubData(JSC::ExecState* exec, JSC::ArgList const& args) -{ - if (args.size() != 3) - return throwError(exec, SyntaxError); - - unsigned target = args.at(0).toInt32(exec); - unsigned offset = args.at(1).toInt32(exec); - - CanvasArray* array = toCanvasArray(args.at(2)); - - static_cast<CanvasRenderingContext3D*>(impl())->bufferSubData(target, offset, array); - return jsUndefined(); -} - -// void texImage2DHTML(in unsigned long target, in unsigned long level, in HTMLImageElement image); -JSValue JSCanvasRenderingContext3D::texImage2D(ExecState* exec, const ArgList& args) -{ - if (args.size() < 3) - return throwError(exec, SyntaxError); - - ExceptionCode ec = 0; - CanvasRenderingContext3D* context = static_cast<CanvasRenderingContext3D*>(impl()); - unsigned target = args.at(0).toInt32(exec); - if (exec->hadException()) - return jsUndefined(); - - unsigned level = args.at(1).toInt32(exec); - if (exec->hadException()) - return jsUndefined(); - - if (args.size() > 5) { - // This must be the bare array case. - if (args.size() != 9) - return throwError(exec, SyntaxError); - - unsigned internalformat = args.at(2).toInt32(exec); - if (exec->hadException()) - return jsUndefined(); - - unsigned width = args.at(3).toInt32(exec); - if (exec->hadException()) - return jsUndefined(); - - unsigned height = args.at(4).toInt32(exec); - if (exec->hadException()) - return jsUndefined(); - - unsigned border = args.at(5).toInt32(exec); - if (exec->hadException()) - return jsUndefined(); - - unsigned format = args.at(6).toInt32(exec); - if (exec->hadException()) - return jsUndefined(); - - unsigned type = args.at(7).toInt32(exec); - if (exec->hadException()) - return jsUndefined(); - - CanvasArray* array = toCanvasArray(args.at(8)); - if (exec->hadException()) - return jsUndefined(); - - if (!array) - return throwError(exec, TypeError); - - // FIXME: Need to check to make sure CanvasArray is a CanvasByteArray or CanvasShortArray, - // depending on the passed type parameter. - - context->texImage2D(target, level, internalformat, width, height, border, format, type, array, ec); - return jsUndefined(); - } - - // The image parameter can be a <img> or <canvas> element. - JSValue value = args.at(2); - if (!value.isObject()) - return throwError(exec, TypeError); - JSObject* o = asObject(value); - - bool flipY = (args.size() > 3) ? args.at(3).toBoolean(exec) : false; - bool premultiplyAlpha = (args.size() > 4) ? args.at(3).toBoolean(exec) : false; - - if (o->inherits(&JSHTMLImageElement::s_info)) { - HTMLImageElement* imgElt = static_cast<HTMLImageElement*>(static_cast<JSHTMLElement*>(o)->impl()); - context->texImage2D(target, level, imgElt, flipY, premultiplyAlpha, ec); - } else if (o->inherits(&JSHTMLCanvasElement::s_info)) { - HTMLCanvasElement* canvas = static_cast<HTMLCanvasElement*>(static_cast<JSHTMLElement*>(o)->impl()); - context->texImage2D(target, level, canvas, flipY, premultiplyAlpha, ec); - } else { - setDOMException(exec, TYPE_MISMATCH_ERR); - } - - return jsUndefined(); -} - -// void texSubImage2DHTML(in unsigned long target, in unsigned long level, in unsigned long xoff, in unsigned long yoff, in unsigned long width, in unsigned long height, in HTMLImageElement image); -JSValue JSCanvasRenderingContext3D::texSubImage2D(ExecState* exec, const ArgList& args) -{ - if (args.size() < 7 || args.size() > 9) - return throwError(exec, SyntaxError); - - CanvasRenderingContext3D* context = static_cast<CanvasRenderingContext3D*>(impl()); - unsigned target = args.at(0).toInt32(exec); - unsigned level = args.at(1).toInt32(exec); - unsigned xoff = args.at(2).toInt32(exec); - unsigned yoff = args.at(3).toInt32(exec); - unsigned width = args.at(4).toInt32(exec); - unsigned height = args.at(5).toInt32(exec); - - // The image parameter can be a <img> or <canvas> element. - JSValue value = args.at(6); - if (!value.isObject()) - return throwError(exec, TypeError); - JSObject* o = asObject(value); - - bool flipY = (args.size() > 3) ? args.at(3).toBoolean(exec) : false; - bool premultiplyAlpha = (args.size() > 4) ? args.at(3).toBoolean(exec) : false; - - ExceptionCode ec = 0; - if (o->inherits(&JSHTMLImageElement::s_info)) { - HTMLImageElement* imgElt = static_cast<HTMLImageElement*>(static_cast<JSHTMLElement*>(o)->impl()); - context->texSubImage2D(target, level, xoff, yoff, width, height, imgElt, flipY, premultiplyAlpha, ec); - } else if (o->inherits(&JSHTMLCanvasElement::s_info)) { - HTMLCanvasElement* canvas = static_cast<HTMLCanvasElement*>(static_cast<JSHTMLElement*>(o)->impl()); - context->texSubImage2D(target, level, xoff, yoff, width, height, canvas, flipY, premultiplyAlpha, ec); - } else { - setDOMException(exec, TYPE_MISMATCH_ERR); - } - - return jsUndefined(); -} - -template<typename T> -void toArray(JSC::ExecState* exec, JSC::JSValue value, T*& array, int& size) -{ - array = 0; - - if (!value.isObject()) - return; - - JSC::JSObject* object = asObject(value); - int length = object->get(exec, JSC::Identifier(exec, "length")).toInt32(exec); - void* tempValues; - if (!tryFastMalloc(length * sizeof(T)).getValue(tempValues)) - return; - - T* values = static_cast<T*>(tempValues); - for (int i = 0; i < length; ++i) { - JSC::JSValue v = object->get(exec, i); - if (exec->hadException()) - return; - values[i] = static_cast<T>(v.toNumber(exec)); - } - - array = values; - size = length; -} - -enum DataFunctionToCall { - f_uniform1v, f_uniform2v, f_uniform3v, f_uniform4v, - f_vertexAttrib1v, f_vertexAttrib2v, f_vertexAttrib3v, f_vertexAttrib4v -}; - -enum DataFunctionMatrixToCall { - f_uniformMatrix2fv, f_uniformMatrix3fv, f_uniformMatrix4fv -}; - -static JSC::JSValue dataFunctionf(DataFunctionToCall f, JSC::ExecState* exec, const JSC::ArgList& args, CanvasRenderingContext3D* context) -{ - if (args.size() != 2) - return throwError(exec, SyntaxError); - - long location = args.at(0).toInt32(exec); - if (exec->hadException()) - return jsUndefined(); - - RefPtr<CanvasFloatArray> canvasArray = toCanvasFloatArray(args.at(1)); - if (exec->hadException()) - return jsUndefined(); - - if (canvasArray) { - switch(f) { - case f_uniform1v: context->uniform1fv(location, canvasArray.get()); break; - case f_uniform2v: context->uniform2fv(location, canvasArray.get()); break; - case f_uniform3v: context->uniform3fv(location, canvasArray.get()); break; - case f_uniform4v: context->uniform4fv(location, canvasArray.get()); break; - case f_vertexAttrib1v: context->vertexAttrib1fv(location, canvasArray.get()); break; - case f_vertexAttrib2v: context->vertexAttrib2fv(location, canvasArray.get()); break; - case f_vertexAttrib3v: context->vertexAttrib3fv(location, canvasArray.get()); break; - case f_vertexAttrib4v: context->vertexAttrib4fv(location, canvasArray.get()); break; - } - return jsUndefined(); - } - - float* array; - int size; - toArray<float>(exec, args.at(1), array, size); - - if (!array) - return throwError(exec, TypeError); - - switch(f) { - case f_uniform1v: context->uniform1fv(location, array, size); break; - case f_uniform2v: context->uniform2fv(location, array, size); break; - case f_uniform3v: context->uniform3fv(location, array, size); break; - case f_uniform4v: context->uniform4fv(location, array, size); break; - case f_vertexAttrib1v: context->vertexAttrib1fv(location, array, size); break; - case f_vertexAttrib2v: context->vertexAttrib2fv(location, array, size); break; - case f_vertexAttrib3v: context->vertexAttrib3fv(location, array, size); break; - case f_vertexAttrib4v: context->vertexAttrib4fv(location, array, size); break; - } - return jsUndefined(); -} - -static JSC::JSValue dataFunctioni(DataFunctionToCall f, JSC::ExecState* exec, const JSC::ArgList& args, CanvasRenderingContext3D* context) -{ - if (args.size() != 2) - return throwError(exec, SyntaxError); - - long location = args.at(0).toInt32(exec); - if (exec->hadException()) - return jsUndefined(); - - RefPtr<CanvasIntArray> canvasArray = toCanvasIntArray(args.at(1)); - if (exec->hadException()) - return jsUndefined(); - - if (canvasArray) { - switch(f) { - case f_uniform1v: context->uniform1iv(location, canvasArray.get()); break; - case f_uniform2v: context->uniform2iv(location, canvasArray.get()); break; - case f_uniform3v: context->uniform3iv(location, canvasArray.get()); break; - case f_uniform4v: context->uniform4iv(location, canvasArray.get()); break; - default: break; - } - return jsUndefined(); - } - - int* array; - int size; - toArray<int>(exec, args.at(1), array, size); - - if (!array) - return throwError(exec, TypeError); - - switch(f) { - case f_uniform1v: context->uniform1iv(location, array, size); break; - case f_uniform2v: context->uniform2iv(location, array, size); break; - case f_uniform3v: context->uniform3iv(location, array, size); break; - case f_uniform4v: context->uniform4iv(location, array, size); break; - default: break; - } - return jsUndefined(); -} - -static JSC::JSValue dataFunctionMatrix(DataFunctionMatrixToCall f, JSC::ExecState* exec, const JSC::ArgList& args, CanvasRenderingContext3D* context) -{ - if (args.size() != 3) - return throwError(exec, SyntaxError); - - long location = args.at(0).toInt32(exec); - if (exec->hadException()) - return jsUndefined(); - - bool transpose = args.at(1).toBoolean(exec); - if (exec->hadException()) - return jsUndefined(); - - RefPtr<CanvasFloatArray> canvasArray = toCanvasFloatArray(args.at(2)); - if (exec->hadException()) - return jsUndefined(); - - if (canvasArray) { - switch(f) { - case f_uniformMatrix2fv: context->uniformMatrix2fv(location, transpose, canvasArray.get()); break; - case f_uniformMatrix3fv: context->uniformMatrix3fv(location, transpose, canvasArray.get()); break; - case f_uniformMatrix4fv: context->uniformMatrix4fv(location, transpose, canvasArray.get()); break; - } - return jsUndefined(); - } - - float* array; - int size; - toArray<float>(exec, args.at(2), array, size); - - if (!array) - return throwError(exec, TypeError); - - switch(f) { - case f_uniformMatrix2fv: context->uniformMatrix2fv(location, transpose, array, size); break; - case f_uniformMatrix3fv: context->uniformMatrix3fv(location, transpose, array, size); break; - case f_uniformMatrix4fv: context->uniformMatrix4fv(location, transpose, array, size); break; - } - return jsUndefined(); -} - -JSC::JSValue JSCanvasRenderingContext3D::uniform1fv(JSC::ExecState* exec, const JSC::ArgList& args) -{ - return dataFunctionf(f_uniform1v, exec, args, static_cast<CanvasRenderingContext3D*>(impl())); -} - -JSC::JSValue JSCanvasRenderingContext3D::uniform1iv(JSC::ExecState* exec, const JSC::ArgList& args) -{ - return dataFunctioni(f_uniform1v, exec, args, static_cast<CanvasRenderingContext3D*>(impl())); -} - -JSC::JSValue JSCanvasRenderingContext3D::uniform2fv(JSC::ExecState* exec, const JSC::ArgList& args) -{ - return dataFunctionf(f_uniform2v, exec, args, static_cast<CanvasRenderingContext3D*>(impl())); -} - -JSC::JSValue JSCanvasRenderingContext3D::uniform2iv(JSC::ExecState* exec, const JSC::ArgList& args) -{ - return dataFunctioni(f_uniform2v, exec, args, static_cast<CanvasRenderingContext3D*>(impl())); -} - -JSC::JSValue JSCanvasRenderingContext3D::uniform3fv(JSC::ExecState* exec, const JSC::ArgList& args) -{ - return dataFunctionf(f_uniform3v, exec, args, static_cast<CanvasRenderingContext3D*>(impl())); -} - -JSC::JSValue JSCanvasRenderingContext3D::uniform3iv(JSC::ExecState* exec, const JSC::ArgList& args) -{ - return dataFunctioni(f_uniform3v, exec, args, static_cast<CanvasRenderingContext3D*>(impl())); -} - -JSC::JSValue JSCanvasRenderingContext3D::uniform4fv(JSC::ExecState* exec, const JSC::ArgList& args) -{ - return dataFunctionf(f_uniform4v, exec, args, static_cast<CanvasRenderingContext3D*>(impl())); -} - -JSC::JSValue JSCanvasRenderingContext3D::uniform4iv(JSC::ExecState* exec, const JSC::ArgList& args) -{ - return dataFunctioni(f_uniform4v, exec, args, static_cast<CanvasRenderingContext3D*>(impl())); -} - -JSC::JSValue JSCanvasRenderingContext3D::uniformMatrix2fv(JSC::ExecState* exec, const JSC::ArgList& args) -{ - return dataFunctionMatrix(f_uniformMatrix2fv, exec, args, static_cast<CanvasRenderingContext3D*>(impl())); -} - -JSC::JSValue JSCanvasRenderingContext3D::uniformMatrix3fv(JSC::ExecState* exec, const JSC::ArgList& args) -{ - return dataFunctionMatrix(f_uniformMatrix3fv, exec, args, static_cast<CanvasRenderingContext3D*>(impl())); -} - -JSC::JSValue JSCanvasRenderingContext3D::uniformMatrix4fv(JSC::ExecState* exec, const JSC::ArgList& args) -{ - return dataFunctionMatrix(f_uniformMatrix4fv, exec, args, static_cast<CanvasRenderingContext3D*>(impl())); -} - -JSC::JSValue JSCanvasRenderingContext3D::vertexAttrib1fv(JSC::ExecState* exec, const JSC::ArgList& args) -{ - return dataFunctionf(f_vertexAttrib1v, exec, args, static_cast<CanvasRenderingContext3D*>(impl())); -} - -JSC::JSValue JSCanvasRenderingContext3D::vertexAttrib2fv(JSC::ExecState* exec, const JSC::ArgList& args) -{ - return dataFunctionf(f_vertexAttrib2v, exec, args, static_cast<CanvasRenderingContext3D*>(impl())); -} - -JSC::JSValue JSCanvasRenderingContext3D::vertexAttrib3fv(JSC::ExecState* exec, const JSC::ArgList& args) -{ - return dataFunctionf(f_vertexAttrib3v, exec, args, static_cast<CanvasRenderingContext3D*>(impl())); -} - -JSC::JSValue JSCanvasRenderingContext3D::vertexAttrib4fv(JSC::ExecState* exec, const JSC::ArgList& args) -{ - return dataFunctionf(f_vertexAttrib4v, exec, args, static_cast<CanvasRenderingContext3D*>(impl())); -} - -} // namespace WebCore - -#endif // ENABLE(3D_CANVAS) diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSCanvasRenderingContextCustom.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSCanvasRenderingContextCustom.cpp index 0cd2aa3..df24eb7 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSCanvasRenderingContextCustom.cpp +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSCanvasRenderingContextCustom.cpp @@ -29,8 +29,8 @@ #include "CanvasRenderingContext2D.h" #include "JSCanvasRenderingContext2D.h" #if ENABLE(3D_CANVAS) -#include "CanvasRenderingContext3D.h" -#include "JSCanvasRenderingContext3D.h" +#include "WebGLRenderingContext.h" +#include "JSWebGLRenderingContext.h" #endif using namespace JSC; @@ -44,7 +44,7 @@ JSC::JSValue toJS(JSC::ExecState* exec, JSDOMGlobalObject* globalObject, CanvasR #if ENABLE(3D_CANVAS) if (object->is3d()) - return getDOMObjectWrapper<JSCanvasRenderingContext3D>(exec, globalObject, static_cast<CanvasRenderingContext3D*>(object)); + return getDOMObjectWrapper<JSWebGLRenderingContext>(exec, globalObject, static_cast<WebGLRenderingContext*>(object)); #endif ASSERT(object->is2d()); return getDOMObjectWrapper<JSCanvasRenderingContext2D>(exec, globalObject, static_cast<CanvasRenderingContext2D*>(object)); diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSCanvasUnsignedShortArrayConstructor.h b/src/3rdparty/webkit/WebCore/bindings/js/JSCanvasUnsignedShortArrayConstructor.h deleted file mode 100644 index 23c197f..0000000 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSCanvasUnsignedShortArrayConstructor.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (C) 2009 Apple 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 JSCanvasUnsignedShortArrayConstructor_h -#define JSCanvasUnsignedShortArrayConstructor_h - -#include "JSDOMBinding.h" -#include "JSDocument.h" - -namespace WebCore { - - class JSCanvasUnsignedShortArrayConstructor : public DOMConstructorObject { - public: - JSCanvasUnsignedShortArrayConstructor(JSC::ExecState*, JSDOMGlobalObject*); - static const JSC::ClassInfo s_info; - - private: - virtual JSC::ConstructType getConstructData(JSC::ConstructData&); - virtual const JSC::ClassInfo* classInfo() const { return &s_info; } - }; - -} - -#endif // JSCanvasUnsignedShortArrayConstructor_h diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSConsoleCustom.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSConsoleCustom.cpp index 9c48467..b631cdd 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSConsoleCustom.cpp +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSConsoleCustom.cpp @@ -24,11 +24,13 @@ */ #include "config.h" + #include "JSConsole.h" -#include "JavaScriptProfile.h" -#include <runtime/JSArray.h> #include "Console.h" +#include "JavaScriptProfile.h" +#include "ScriptCallStack.h" +#include <runtime/JSArray.h> using namespace JSC; diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSCustomPositionCallback.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSCustomPositionCallback.cpp index e5f83aa..cc6d45c 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSCustomPositionCallback.cpp +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSCustomPositionCallback.cpp @@ -26,6 +26,8 @@ #include "config.h" #include "JSCustomPositionCallback.h" +#if ENABLE(GEOLOCATION) + #include "Frame.h" #include "JSGeoposition.h" #include "ScriptController.h" @@ -52,3 +54,5 @@ void JSCustomPositionCallback::handleEvent(Geoposition* geoposition) } } // namespace WebCore + +#endif // ENABLE(GEOLOCATION) diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSCustomPositionErrorCallback.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSCustomPositionErrorCallback.cpp index bd64deb..c94ae9a 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSCustomPositionErrorCallback.cpp +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSCustomPositionErrorCallback.cpp @@ -26,6 +26,8 @@ #include "config.h" #include "JSCustomPositionErrorCallback.h" +#if ENABLE(GEOLOCATION) + #include "Frame.h" #include "JSPositionError.h" #include "ScriptController.h" @@ -53,3 +55,5 @@ void JSCustomPositionErrorCallback::handleEvent(PositionError* positionError) } } // namespace WebCore + +#endif // ENABLE(GEOLOCATION) diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSCustomSQLStatementErrorCallback.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSCustomSQLStatementErrorCallback.cpp index 6178509..4d5de79 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSCustomSQLStatementErrorCallback.cpp +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSCustomSQLStatementErrorCallback.cpp @@ -77,7 +77,7 @@ bool JSCustomSQLStatementErrorCallback::handleEvent(SQLTransaction* transaction, // Therefore an exception and returning true are the same thing - so, return true on an exception return true; } - return result.toBoolean(exec); + return !result.isFalse(); } } diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSCustomXPathNSResolver.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSCustomXPathNSResolver.cpp index c2884d7..07cfc74 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSCustomXPathNSResolver.cpp +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSCustomXPathNSResolver.cpp @@ -90,7 +90,7 @@ String JSCustomXPathNSResolver::lookupNamespaceURI(const String& prefix) args.append(jsString(exec, prefix)); m_globalObject->globalData()->timeoutChecker.start(); - JSValue retval = callInWorld(exec, function, callType, callData, m_customResolver, args, currentWorld(m_globalObject->globalExec())); + JSValue retval = JSC::call(exec, function, callType, callData, m_customResolver, args); m_globalObject->globalData()->timeoutChecker.stop(); String result; diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSDOMApplicationCacheCustom.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSDOMApplicationCacheCustom.cpp index 91ee51a..5637087 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSDOMApplicationCacheCustom.cpp +++ b/src/3rdparty/webkit/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/src/3rdparty/webkit/WebCore/bindings/js/JSDOMBinding.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSDOMBinding.cpp index ef69c7b..f294dad 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSDOMBinding.cpp +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSDOMBinding.cpp @@ -25,6 +25,7 @@ #include "ActiveDOMObject.h" #include "DOMCoreException.h" +#include "DOMObjectHashTableMap.h" #include "Document.h" #include "EventException.h" #include "ExceptionBase.h" @@ -33,10 +34,11 @@ #include "HTMLAudioElement.h" #include "HTMLCanvasElement.h" #include "HTMLImageElement.h" -#include "HTMLScriptElement.h" #include "HTMLNames.h" +#include "HTMLScriptElement.h" #include "JSDOMCoreException.h" #include "JSDOMWindowCustom.h" +#include "JSDebugWrapperSet.h" #include "JSEventException.h" #include "JSExceptionBase.h" #include "JSNode.h" @@ -45,12 +47,16 @@ #include "KURL.h" #include "MessagePort.h" #include "RangeException.h" +#include "ScriptCachedFrameData.h" #include "ScriptController.h" #include "Settings.h" +#include "WebCoreJSClientData.h" #include "XMLHttpRequestException.h" +#include <runtime/DateInstance.h> #include <runtime/Error.h> #include <runtime/JSFunction.h> #include <runtime/PrototypeFunction.h> +#include <wtf/MathExtras.h> #include <wtf/StdLibExtras.h> #if ENABLE(SVG) @@ -63,11 +69,6 @@ #include "XPathException.h" #endif -#if ENABLE(WORKERS) -#include <wtf/ThreadSpecific.h> -using namespace WTF; -#endif - using namespace JSC; namespace WebCore { @@ -77,121 +78,6 @@ using namespace HTMLNames; typedef Document::JSWrapperCache JSWrapperCache; typedef Document::JSWrapperCacheMap JSWrapperCacheMap; -// For debugging, keep a set of wrappers currently registered, and check that -// all are unregistered before they are destroyed. This has helped us fix at -// least one bug. - -static void addWrapper(DOMObject* wrapper); -static void removeWrapper(DOMObject* wrapper); -static void removeWrappers(const JSWrapperCache& wrappers); -static void removeWrappers(const DOMObjectWrapperMap& wrappers); - -#ifdef NDEBUG - -static inline void addWrapper(DOMObject*) -{ -} - -static inline void removeWrapper(DOMObject*) -{ -} - -static inline void removeWrappers(const JSWrapperCache&) -{ -} - -static inline void removeWrappers(const DOMObjectWrapperMap&) -{ -} - -#else - -static HashSet<DOMObject*>& wrapperSet() -{ -#if ENABLE(WORKERS) - DEFINE_STATIC_LOCAL(ThreadSpecific<HashSet<DOMObject*> >, staticWrapperSet, ()); - return *staticWrapperSet; -#else - DEFINE_STATIC_LOCAL(HashSet<DOMObject*>, staticWrapperSet, ()); - return staticWrapperSet; -#endif -} - -static void addWrapper(DOMObject* wrapper) -{ - ASSERT(!wrapperSet().contains(wrapper)); - wrapperSet().add(wrapper); -} - -static void removeWrapper(DOMObject* wrapper) -{ - if (!wrapper) - return; - ASSERT(wrapperSet().contains(wrapper)); - wrapperSet().remove(wrapper); -} - -static void removeWrappers(const JSWrapperCache& wrappers) -{ - JSWrapperCache::const_iterator wrappersEnd = wrappers.end(); - for (JSWrapperCache::const_iterator it = wrappers.begin(); it != wrappersEnd; ++it) - removeWrapper(it->second); -} - -static inline void removeWrappers(const DOMObjectWrapperMap& wrappers) -{ - DOMObjectWrapperMap::const_iterator wrappersEnd = wrappers.end(); - for (DOMObjectWrapperMap::const_iterator it = wrappers.begin(); it != wrappersEnd; ++it) - removeWrapper(it->second); -} - -DOMObject::~DOMObject() -{ - ASSERT(!wrapperSet().contains(this)); -} - -#endif - -DOMWrapperWorld::DOMWrapperWorld(JSC::JSGlobalData* globalData) - : m_globalData(globalData) -{ -} - -DOMWrapperWorld::~DOMWrapperWorld() -{ - JSGlobalData::ClientData* clientData = m_globalData->clientData; - ASSERT(clientData); - static_cast<WebCoreJSClientData*>(clientData)->forgetWorld(this); - - removeWrappers(m_wrappers); - - for (HashSet<Document*>::iterator iter = documentsWithWrappers.begin(); iter != documentsWithWrappers.end(); ++iter) - forgetWorldOfDOMNodesForDocument(*iter, this); - for (HashSet<ScriptController*>::iterator iter = scriptControllersWithShells.begin(); iter != scriptControllersWithShells.end(); ++iter) - (*iter)->forgetWorld(this); -} - -EnterDOMWrapperWorld::EnterDOMWrapperWorld(JSC::JSGlobalData& globalData, DOMWrapperWorld* isolatedWorld) -{ - JSGlobalData::ClientData* clientData = globalData.clientData; - ASSERT(clientData); - m_clientData = static_cast<WebCoreJSClientData*>(clientData); - m_clientData->m_worldStack.append(isolatedWorld); -} - -EnterDOMWrapperWorld::EnterDOMWrapperWorld(JSC::ExecState* exec, DOMWrapperWorld* isolatedWorld) -{ - JSGlobalData::ClientData* clientData = exec->globalData().clientData; - ASSERT(clientData); - m_clientData = static_cast<WebCoreJSClientData*>(clientData); - m_clientData->m_worldStack.append(isolatedWorld); -} - -EnterDOMWrapperWorld::~EnterDOMWrapperWorld() -{ - m_clientData->m_worldStack.removeLast(); -} - class JSGlobalDataWorldIterator { public: JSGlobalDataWorldIterator(JSGlobalData* globalData) @@ -228,124 +114,105 @@ private: HashSet<DOMWrapperWorld*>::iterator m_end; }; -static inline DOMWrapperWorld* currentWorld(JSC::JSGlobalData& globalData) -{ - JSGlobalData::ClientData* clientData = globalData.clientData; - ASSERT(clientData); - return static_cast<WebCoreJSClientData*>(clientData)->currentWorld(); -} - -DOMWrapperWorld* currentWorld(JSC::ExecState* exec) -{ - return currentWorld(exec->globalData()); -} - -DOMWrapperWorld* normalWorld(JSC::JSGlobalData& globalData) -{ - JSGlobalData::ClientData* clientData = globalData.clientData; - ASSERT(clientData); - return static_cast<WebCoreJSClientData*>(clientData)->normalWorld(); -} - -DOMWrapperWorld* mainThreadNormalWorld() -{ - ASSERT(isMainThread()); - return normalWorld(*JSDOMWindow::commonJSGlobalData()); -} - -DOMWrapperWorld* mainThreadCurrentWorld() +const JSC::HashTable* getHashTableForGlobalData(JSGlobalData& globalData, const JSC::HashTable* staticTable) { - ASSERT(isMainThread()); - - JSGlobalData::ClientData* clientData = JSDOMWindowBase::commonJSGlobalData()->clientData; - ASSERT(clientData); - return static_cast<WebCoreJSClientData*>(clientData)->currentWorld(); + return DOMObjectHashTableMap::mapFor(globalData).get(staticTable); } -DOMObjectHashTableMap& DOMObjectHashTableMap::mapFor(JSGlobalData& globalData) +bool hasCachedDOMObjectWrapperUnchecked(JSGlobalData* globalData, void* objectHandle) { - JSGlobalData::ClientData* clientData = globalData.clientData; - ASSERT(clientData); - return static_cast<WebCoreJSClientData*>(clientData)->hashTableMap; + for (JSGlobalDataWorldIterator worldIter(globalData); worldIter; ++worldIter) { + if (worldIter->m_wrappers.uncheckedGet(objectHandle)) + return true; + } + return false; } -const JSC::HashTable* getHashTableForGlobalData(JSGlobalData& globalData, const JSC::HashTable* staticTable) +bool hasCachedDOMObjectWrapper(JSGlobalData* globalData, void* objectHandle) { - return DOMObjectHashTableMap::mapFor(globalData).get(staticTable); + for (JSGlobalDataWorldIterator worldIter(globalData); worldIter; ++worldIter) { + if (worldIter->m_wrappers.get(objectHandle)) + return true; + } + return false; } -//inline DOMObjectWrapperMap& DOMObjectWrapperMap::mapFor(JSGlobalData& globalData) -inline DOMObjectWrapperMap& DOMObjectWrapperMapFor(JSGlobalData& globalData) +DOMObject* getCachedDOMObjectWrapper(JSC::ExecState* exec, void* objectHandle) { - return currentWorld(globalData)->m_wrappers; + return domObjectWrapperMapFor(exec).get(objectHandle); } -DOMObject* getCachedDOMObjectWrapper(JSGlobalData& globalData, void* objectHandle) +void cacheDOMObjectWrapper(JSC::ExecState* exec, void* objectHandle, DOMObject* wrapper) { - return DOMObjectWrapperMapFor(globalData).get(objectHandle); + JSDebugWrapperSet::willCacheWrapper(wrapper); + domObjectWrapperMapFor(exec).set(objectHandle, wrapper); } -void cacheDOMObjectWrapper(JSGlobalData& globalData, void* objectHandle, DOMObject* wrapper) +bool hasCachedDOMNodeWrapperUnchecked(Document* document, Node* node) { - addWrapper(wrapper); - DOMObjectWrapperMapFor(globalData).set(objectHandle, wrapper); -} + if (!document) + return hasCachedDOMObjectWrapperUnchecked(JSDOMWindow::commonJSGlobalData(), node); -JSNode* getCachedDOMNodeWrapper(Document* document, Node* node) -{ - if (document) - return document->getWrapperCache(mainThreadCurrentWorld())->get(node); - return static_cast<JSNode*>(DOMObjectWrapperMapFor(*JSDOMWindow::commonJSGlobalData()).get(node)); + JSWrapperCacheMap& wrapperCacheMap = document->wrapperCacheMap(); + for (JSWrapperCacheMap::iterator iter = wrapperCacheMap.begin(); iter != wrapperCacheMap.end(); ++iter) { + if (iter->second->uncheckedGet(node)) + return true; + } + return false; } void forgetDOMObject(DOMObject* wrapper, void* objectHandle) { JSC::JSGlobalData* globalData = Heap::heap(wrapper)->globalData(); - for (JSGlobalDataWorldIterator worldIter(globalData); worldIter; ++worldIter) { - DOMObjectWrapperMap& wrappers = worldIter->m_wrappers; - DOMObjectWrapperMap::iterator iter = wrappers.find(objectHandle); - if ((iter != wrappers.end()) && (iter->second == wrapper)) { - removeWrapper(wrapper); - wrappers.remove(iter); - return; - } + + // Check the normal world first! + JSGlobalData::ClientData* clientData = globalData->clientData; + ASSERT(clientData); + DOMObjectWrapperMap& wrappers = static_cast<WebCoreJSClientData*>(clientData)->normalWorld()->m_wrappers; + if (wrappers.uncheckedRemove(objectHandle, wrapper)) { + JSDebugWrapperSet::didUncacheWrapper(wrapper); + return; } - // If the world went away, it should have removed this wrapper from the set. - ASSERT(!wrapperSet().contains(wrapper)); + // We can't guarantee that a wrapper is in the cache when it uncaches itself, + // since a new wrapper may be cached before the old wrapper's destructor runs. + for (JSGlobalDataWorldIterator worldIter(globalData); worldIter; ++worldIter) { + if (worldIter->m_wrappers.uncheckedRemove(objectHandle, wrapper)) + break; + } + JSDebugWrapperSet::didUncacheWrapper(wrapper); } -void forgetDOMNode(DOMObject* wrapper, Node* node, Document* document) +void forgetDOMNode(JSNode* wrapper, Node* node, Document* document) { + node->clearWrapper(wrapper); + if (!document) { forgetDOMObject(wrapper, node); return; } + // We can't guarantee that a wrapper is in the cache when it uncaches itself, + // since a new wrapper may be cached before the old wrapper's destructor runs. JSWrapperCacheMap& wrapperCacheMap = document->wrapperCacheMap(); for (JSWrapperCacheMap::iterator wrappersIter = wrapperCacheMap.begin(); wrappersIter != wrapperCacheMap.end(); ++wrappersIter) { - JSWrapperCache* wrappers = wrappersIter->second; - JSWrapperCache::iterator iter = wrappers->find(node); - if ((iter != wrappers->end()) && (iter->second == wrapper)) { - wrappers->remove(iter); - removeWrapper(wrapper); - return; - } + if (wrappersIter->second->uncheckedRemove(node, wrapper)) + break; } - - // If the world went away, it should have removed this wrapper from the set. - ASSERT(!wrapperSet().contains(wrapper)); + JSDebugWrapperSet::didUncacheWrapper(wrapper); } -void cacheDOMNodeWrapper(Document* document, Node* node, JSNode* wrapper) +void cacheDOMNodeWrapper(JSC::ExecState* exec, Document* document, Node* node, JSNode* wrapper) { - if (!document) { - addWrapper(wrapper); - DOMObjectWrapperMapFor(*JSDOMWindow::commonJSGlobalData()).set(node, wrapper); - return; - } - addWrapper(wrapper); - document->getWrapperCache(mainThreadCurrentWorld())->set(node, wrapper); + JSDebugWrapperSet::willCacheWrapper(wrapper); + + if (!document) + domObjectWrapperMapFor(exec).set(node, wrapper); + else + document->getWrapperCache(currentWorld(exec))->set(node, wrapper); + + if (currentWorld(exec)->isNormal()) + node->setWrapper(wrapper); } void forgetAllDOMNodesForDocument(Document* document) @@ -354,21 +221,11 @@ void forgetAllDOMNodesForDocument(Document* document) JSWrapperCacheMap& wrapperCacheMap = document->wrapperCacheMap(); JSWrapperCacheMap::const_iterator wrappersMapEnd = wrapperCacheMap.end(); for (JSWrapperCacheMap::const_iterator wrappersMapIter = wrapperCacheMap.begin(); wrappersMapIter != wrappersMapEnd; ++wrappersMapIter) { - JSWrapperCache* wrappers = wrappersMapIter->second; - removeWrappers(*wrappers); - delete wrappers; + delete wrappersMapIter->second; wrappersMapIter->first->forgetDocument(document); } } -void forgetWorldOfDOMNodesForDocument(Document* document, DOMWrapperWorld* world) -{ - JSWrapperCache* wrappers = document->wrapperCacheMap().take(world); - ASSERT(wrappers); // 'world' should only know about 'document' if 'document' knows about 'world'! - removeWrappers(*wrappers); - delete wrappers; -} - static inline bool isObservableThroughDOM(JSNode* jsNode, DOMWrapperWorld* world) { // Certain conditions implicitly make a JS DOM node wrapper observable @@ -395,14 +252,14 @@ static inline bool isObservableThroughDOM(JSNode* jsNode, DOMWrapperWorld* world // the custom markChildren functions rather than here. if (node->isElementNode()) { if (NamedNodeMap* attributes = static_cast<Element*>(node)->attributeMap()) { - if (DOMObject* wrapper = world->m_wrappers.get(attributes)) { + if (DOMObject* wrapper = world->m_wrappers.uncheckedGet(attributes)) { if (wrapper->hasCustomProperties()) return true; } } if (node->isStyledElement()) { if (CSSMutableStyleDeclaration* style = static_cast<StyledElement*>(node)->inlineStyleDecl()) { - if (DOMObject* wrapper = world->m_wrappers.get(style)) { + if (DOMObject* wrapper = world->m_wrappers.uncheckedGet(style)) { if (wrapper->hasCustomProperties()) return true; } @@ -410,7 +267,7 @@ static inline bool isObservableThroughDOM(JSNode* jsNode, DOMWrapperWorld* world } if (static_cast<Element*>(node)->hasTagName(canvasTag)) { if (CanvasRenderingContext* context = static_cast<HTMLCanvasElement*>(node)->renderingContext()) { - if (DOMObject* wrapper = world->m_wrappers.get(context)) { + if (DOMObject* wrapper = world->m_wrappers.uncheckedGet(context)) { if (wrapper->hasCustomProperties()) return true; } @@ -448,8 +305,8 @@ void markDOMNodesForDocument(MarkStack& markStack, Document* document) DOMWrapperWorld* world = wrappersIter->first; JSWrapperCache* nodeDict = wrappersIter->second; - JSWrapperCache::iterator nodeEnd = nodeDict->end(); - for (JSWrapperCache::iterator nodeIt = nodeDict->begin(); nodeIt != nodeEnd; ++nodeIt) { + JSWrapperCache::iterator nodeEnd = nodeDict->uncheckedEnd(); + for (JSWrapperCache::iterator nodeIt = nodeDict->uncheckedBegin(); nodeIt != nodeEnd; ++nodeIt) { JSNode* jsNode = nodeIt->second; if (isObservableThroughDOM(jsNode, world)) markStack.append(jsNode); @@ -467,8 +324,7 @@ void markActiveObjectsForContext(MarkStack& markStack, JSGlobalData& globalData, for (HashMap<ActiveDOMObject*, void*>::const_iterator iter = activeObjects.begin(); iter != activeObjectsEnd; ++iter) { if (iter->first->hasPendingActivity()) { // Generally, an active object with pending activity must have a wrapper to mark its listeners. - // However, some ActiveDOMObjects don't have JS wrappers (timers created by setTimeout is one example). - // FIXME: perhaps need to make sure even timers have a markable 'wrapper'. + // However, some ActiveDOMObjects don't have JS wrappers. markDOMObjectWrapper(markStack, globalData, iter->second); } } @@ -491,7 +347,7 @@ static inline void takeWrappers(Node* node, Document* document, WrapperSet& wrap JSWrapperCacheMap& wrapperCacheMap = document->wrapperCacheMap(); for (JSWrapperCacheMap::iterator iter = wrapperCacheMap.begin(); iter != wrapperCacheMap.end(); ++iter) { if (JSNode* wrapper = iter->second->take(node)) { - removeWrapper(wrapper); + JSDebugWrapperSet::didUncacheWrapper(wrapper); wrapperSet.append(WrapperAndWorld(wrapper, iter->first)); } } @@ -499,7 +355,7 @@ static inline void takeWrappers(Node* node, Document* document, WrapperSet& wrap for (JSGlobalDataWorldIterator worldIter(JSDOMWindow::commonJSGlobalData()); worldIter; ++worldIter) { DOMWrapperWorld* world = *worldIter; if (JSNode* wrapper = static_cast<JSNode*>(world->m_wrappers.take(node))) { - removeWrapper(wrapper); + JSDebugWrapperSet::didUncacheWrapper(wrapper); wrapperSet.append(WrapperAndWorld(wrapper, world)); } } @@ -515,11 +371,11 @@ void updateDOMNodeDocument(Node* node, Document* oldDocument, Document* newDocum for (unsigned i = 0; i < wrapperSet.size(); ++i) { JSNode* wrapper = wrapperSet[i].first; + JSDebugWrapperSet::willCacheWrapper(wrapper); if (newDocument) newDocument->getWrapperCache(wrapperSet[i].second)->set(node, wrapper); else wrapperSet[i].second->m_wrappers.set(node, wrapper); - addWrapper(wrapper); } } @@ -532,11 +388,65 @@ void markDOMObjectWrapper(MarkStack& markStack, JSGlobalData& globalData, void* return; for (JSGlobalDataWorldIterator worldIter(&globalData); worldIter; ++worldIter) { - if (DOMObject* wrapper = worldIter->m_wrappers.get(object)) + if (DOMObject* wrapper = worldIter->m_wrappers.uncheckedGet(object)) + markStack.append(wrapper); + } +} + +void markDOMNodeWrapper(MarkStack& markStack, Document* document, Node* node) +{ + if (document) { + JSWrapperCacheMap& wrapperCacheMap = document->wrapperCacheMap(); + for (JSWrapperCacheMap::iterator iter = wrapperCacheMap.begin(); iter != wrapperCacheMap.end(); ++iter) { + if (JSNode* wrapper = iter->second->uncheckedGet(node)) + markStack.append(wrapper); + } + return; + } + + for (JSGlobalDataWorldIterator worldIter(JSDOMWindow::commonJSGlobalData()); worldIter; ++worldIter) { + if (DOMObject* wrapper = worldIter->m_wrappers.uncheckedGet(node)) markStack.append(wrapper); } } +static void stringWrapperDestroyed(JSString* str, void* context) +{ + StringImpl* cacheKey = static_cast<StringImpl*>(context); + JSC::JSGlobalData* globalData = Heap::heap(str)->globalData(); + + // Check the normal world first! + JSGlobalData::ClientData* clientData = globalData->clientData; + ASSERT(clientData); + JSStringCache& cache = static_cast<WebCoreJSClientData*>(clientData)->normalWorld()->m_stringCache; + if (cache.uncheckedRemove(cacheKey, str)) { + cacheKey->deref(); + return; + } + + for (JSGlobalDataWorldIterator worldIter(globalData); worldIter; ++worldIter) { + if (worldIter->m_stringCache.uncheckedRemove(cacheKey, str)) + break; + } + + cacheKey->deref(); +} + +JSValue jsStringSlowCase(ExecState* exec, JSStringCache& stringCache, StringImpl* stringImpl) +{ + // If there is a stale entry, we have to explicitly remove it to avoid + // problems down the line. + if (JSString* wrapper = stringCache.uncheckedGet(stringImpl)) + stringCache.uncheckedRemove(stringImpl, wrapper); + + JSString* wrapper = jsStringWithFinalizer(exec, stringImpl->ustring(), stringWrapperDestroyed, stringImpl); + stringCache.set(stringImpl, wrapper); + // ref explicitly instead of using a RefPtr-keyed hashtable because the wrapper can + // outlive the cache, so the stringImpl has to match the wrapper's lifetime. + stringImpl->ref(); + return wrapper; +} + JSValue jsStringOrNull(ExecState* exec, const String& s) { if (s.isNull()) @@ -565,6 +475,11 @@ JSValue jsStringOrFalse(ExecState* exec, const String& s) return jsString(exec, s); } +JSValue jsString(ExecState* exec, const KURL& url) +{ + return jsString(exec, url.string()); +} + JSValue jsStringOrNull(ExecState* exec, const KURL& url) { if (url.isNull()) @@ -600,6 +515,22 @@ UString valueToStringWithUndefinedOrNullCheck(ExecState* exec, JSValue value) return value.toString(exec); } +JSValue jsDateOrNull(ExecState* exec, double value) +{ + if (!isfinite(value)) + return jsNull(); + return new (exec) DateInstance(exec, value); +} + +double valueToDate(ExecState* exec, JSValue value) +{ + if (value.isNumber()) + return value.uncheckedGetNumber(); + if (!value.inherits(&DateInstance::info)) + return std::numeric_limits<double>::quiet_NaN(); + return static_cast<DateInstance*>(value.toObject(exec))->internalNumber(); +} + void reportException(ExecState* exec, JSValue exception) { UString errorMessage = exception.toString(exec); @@ -658,7 +589,7 @@ void setDOMException(ExecState* exec, ExceptionCode ec) break; #if ENABLE(SVG) case SVGExceptionType: - errorObject = toJS(exec, globalObject, SVGException::create(description).get(), 0); + errorObject = toJS(exec, globalObject, SVGException::create(description).get(), 0 /* no context on purpose */); break; #endif #if ENABLE(XPATH) @@ -728,19 +659,19 @@ Frame* toDynamicFrame(ExecState* exec) bool processingUserGesture(ExecState* exec) { Frame* frame = toDynamicFrame(exec); - return frame && frame->script()->processingUserGesture(); + return frame && frame->script()->processingUserGesture(currentWorld(exec)); } KURL completeURL(ExecState* exec, const String& relativeURL) { - // For histoical reasons, we need to complete the URL using the dynamic frame. + // For historical reasons, we need to complete the URL using the dynamic frame. Frame* frame = toDynamicFrame(exec); if (!frame) return KURL(); return frame->loader()->completeURL(relativeURL); } -JSValue objectToStringFunctionGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot&) +JSValue objectToStringFunctionGetter(ExecState* exec, JSValue, const Identifier& propertyName) { return new (exec) NativeFunctionWrapper(exec, exec->lexicalGlobalObject()->prototypeFunctionStructure(), 0, propertyName, objectProtoFuncToString); } @@ -804,34 +735,4 @@ JSC::JSObject* toJSSequence(ExecState* exec, JSValue value, unsigned& length) return object; } -bool DOMObject::defineOwnProperty(ExecState* exec, const Identifier&, PropertyDescriptor&, bool) -{ - throwError(exec, TypeError, "defineProperty is not supported on DOM Objects"); - return false; -} - -JSValue DebuggerCallFrame_evaluateInWorld(const JSC::DebuggerCallFrame& debuggerCallFrame, const UString& script, JSValue& exception) -{ - EnterDOMWrapperWorld worldEntry(debuggerCallFrame.dynamicGlobalObject()->globalExec(), debuggerWorld()); - return debuggerCallFrame.evaluate(script, exception); -} - -JSValue callInWorld(ExecState* exec, JSValue function, CallType callType, const CallData& callData, JSValue thisValue, const ArgList& args, DOMWrapperWorld* isolatedWorld) -{ - EnterDOMWrapperWorld worldEntry(exec, isolatedWorld); - return JSC::call(exec, function, callType, callData, thisValue, args); -} - -JSObject* constructInWorld(ExecState* exec, JSValue object, ConstructType constructType, const ConstructData& constructData, const ArgList& args, DOMWrapperWorld* isolatedWorld) -{ - EnterDOMWrapperWorld worldEntry(exec, isolatedWorld); - return JSC::construct(exec, object, constructType, constructData, args); -} - -Completion evaluateInWorld(ExecState* exec, ScopeChain& scopeChain, const SourceCode& sourceCode, JSValue thisValue, DOMWrapperWorld* isolatedWorld) -{ - EnterDOMWrapperWorld worldEntry(exec, isolatedWorld); - return JSC::evaluate(exec, scopeChain, sourceCode, thisValue); -} - } // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSDOMBinding.h b/src/3rdparty/webkit/WebCore/bindings/js/JSDOMBinding.h index ba41d85..219472b 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSDOMBinding.h +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSDOMBinding.h @@ -23,9 +23,13 @@ #define JSDOMBinding_h #include "JSDOMGlobalObject.h" -#include "Document.h" // For DOMConstructorWithDocument +#include "JSDOMWrapper.h" +#include "DOMWrapperWorld.h" +#include "JSSVGContextCache.h" +#include "Document.h" #include <runtime/Completion.h> #include <runtime/Lookup.h> +#include <runtime/WeakGCMap.h> #include <wtf/Noncopyable.h> namespace JSC { @@ -42,6 +46,7 @@ namespace WebCore { class Node; class String; class ScriptController; + class ScriptCachedFrameData; typedef int ExceptionCode; @@ -49,60 +54,37 @@ namespace WebCore { class SVGElement; #endif - // Base class for all objects in this binding except Window. - class DOMObject : public JSC::JSObject { - protected: - explicit DOMObject(NonNullPassRefPtr<JSC::Structure> structure) - : JSObject(structure) - { - } - - virtual bool defineOwnProperty(JSC::ExecState*, const JSC::Identifier&, JSC::PropertyDescriptor&, bool); - -#ifndef NDEBUG - virtual ~DOMObject(); -#endif - }; - // FIXME: This class should collapse into DOMObject once all DOMObjects are // updated to store a globalObject pointer. class DOMObjectWithGlobalPointer : public DOMObject { public: - JSDOMGlobalObject* globalObject() const { return m_globalObject; } + JSDOMGlobalObject* globalObject() const { return static_cast<JSDOMGlobalObject*>(getAnonymousValue(GlobalObjectSlot).asCell()); } ScriptExecutionContext* scriptExecutionContext() const { // FIXME: Should never be 0, but can be due to bug 27640. - return m_globalObject->scriptExecutionContext(); + return globalObject()->scriptExecutionContext(); } static PassRefPtr<JSC::Structure> createStructure(JSC::JSValue prototype) { - return JSC::Structure::create(prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags)); + return JSC::Structure::create(prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), AnonymousSlotCount); } protected: - static const unsigned StructureFlags = JSC::OverridesMarkChildren | DOMObject::StructureFlags; + static const unsigned AnonymousSlotCount = 1 + DOMObject::AnonymousSlotCount; + static const unsigned GlobalObjectSlot = AnonymousSlotCount - 1; DOMObjectWithGlobalPointer(NonNullPassRefPtr<JSC::Structure> structure, JSDOMGlobalObject* globalObject) : DOMObject(structure) - , m_globalObject(globalObject) { // FIXME: This ASSERT is valid, but fires in fast/dom/gc-6.html when trying to create // new JavaScript objects on detached windows due to DOMWindow::document() // needing to reach through the frame to get to the Document*. See bug 27640. // ASSERT(globalObject->scriptExecutionContext()); + putAnonymousValue(GlobalObjectSlot, globalObject); } virtual ~DOMObjectWithGlobalPointer() { } - - void markChildren(JSC::MarkStack& markStack) - { - DOMObject::markChildren(markStack); - markStack.append(m_globalObject); - } - - private: - JSDOMGlobalObject* m_globalObject; }; // Base class for all constructor objects in the JSC bindings. @@ -110,7 +92,7 @@ namespace WebCore { public: static PassRefPtr<JSC::Structure> createStructure(JSC::JSValue prototype) { - return JSC::Structure::create(prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags)); + return JSC::Structure::create(prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), AnonymousSlotCount); } protected: @@ -138,121 +120,29 @@ namespace WebCore { } }; - typedef HashMap<void*, DOMObject*> DOMObjectWrapperMap; - - class DOMWrapperWorld : public RefCounted<DOMWrapperWorld> { - public: - DOMWrapperWorld(JSC::JSGlobalData*); - ~DOMWrapperWorld(); - - void rememberDocument(Document* document) { documentsWithWrappers.add(document); } - void forgetDocument(Document* document) { documentsWithWrappers.remove(document); } - void rememberScriptController(ScriptController* scriptController) { scriptControllersWithShells.add(scriptController); } - void forgetScriptController(ScriptController* scriptController) { scriptControllersWithShells.remove(scriptController); } - - // FIXME: can we make this private? - DOMObjectWrapperMap m_wrappers; - - private: - JSC::JSGlobalData* m_globalData; - HashSet<Document*> documentsWithWrappers; - HashSet<ScriptController*> scriptControllersWithShells; - }; - - // Map from static HashTable instances to per-GlobalData ones. - class DOMObjectHashTableMap { - public: - static DOMObjectHashTableMap& mapFor(JSC::JSGlobalData&); - - ~DOMObjectHashTableMap() - { - HashMap<const JSC::HashTable*, JSC::HashTable>::iterator mapEnd = m_map.end(); - for (HashMap<const JSC::HashTable*, JSC::HashTable>::iterator iter = m_map.begin(); iter != m_map.end(); ++iter) - iter->second.deleteTable(); - } - - const JSC::HashTable* get(const JSC::HashTable* staticTable) - { - HashMap<const JSC::HashTable*, JSC::HashTable>::iterator iter = m_map.find(staticTable); - if (iter != m_map.end()) - return &iter->second; - return &m_map.set(staticTable, JSC::HashTable(*staticTable)).first->second; - } - - private: - HashMap<const JSC::HashTable*, JSC::HashTable> m_map; - }; - - class WebCoreJSClientData : public JSC::JSGlobalData::ClientData { - friend class EnterDOMWrapperWorld; - friend class JSGlobalDataWorldIterator; - - public: - WebCoreJSClientData(JSC::JSGlobalData* globalData) - : m_normalWorld(globalData) - { - m_worldStack.append(&m_normalWorld); - m_worldSet.add(&m_normalWorld); - } - // FIXME: add a destructor to assert m_worldSet only contains m_normalWorld? - - DOMWrapperWorld* currentWorld() { return m_worldStack.last(); } - DOMWrapperWorld* normalWorld() { return &m_normalWorld; } - - void rememberWorld(DOMWrapperWorld* world) - { - ASSERT(!m_worldSet.contains(world)); - m_worldSet.add(world); - } - void forgetWorld(DOMWrapperWorld* world) - { - ASSERT(m_worldSet.contains(world)); - m_worldSet.remove(world); - } - - DOMObjectHashTableMap hashTableMap; - private: - Vector<DOMWrapperWorld*> m_worldStack; - HashSet<DOMWrapperWorld*> m_worldSet; - DOMWrapperWorld m_normalWorld; - }; - - class EnterDOMWrapperWorld { - public: - EnterDOMWrapperWorld(JSC::JSGlobalData&, DOMWrapperWorld*); - EnterDOMWrapperWorld(JSC::ExecState*, DOMWrapperWorld*); - ~EnterDOMWrapperWorld(); - - private: - WebCoreJSClientData* m_clientData; - }; - - DOMObject* getCachedDOMObjectWrapper(JSC::JSGlobalData&, void* objectHandle); - void cacheDOMObjectWrapper(JSC::JSGlobalData&, void* objectHandle, DOMObject* wrapper); - void forgetDOMNode(DOMObject* wrapper, Node* node, Document* document); + DOMObject* getCachedDOMObjectWrapper(JSC::ExecState*, void* objectHandle); + bool hasCachedDOMObjectWrapper(JSC::JSGlobalData*, void* objectHandle); + void cacheDOMObjectWrapper(JSC::ExecState*, void* objectHandle, DOMObject* wrapper); + void forgetDOMNode(JSNode* wrapper, Node* node, Document* document); void forgetDOMObject(DOMObject* wrapper, void* objectHandle); - JSNode* getCachedDOMNodeWrapper(Document*, Node*); - void cacheDOMNodeWrapper(Document*, Node*, JSNode* wrapper); + JSNode* getCachedDOMNodeWrapper(JSC::ExecState*, Document*, Node*); + void cacheDOMNodeWrapper(JSC::ExecState*, Document*, Node*, JSNode* wrapper); void forgetAllDOMNodesForDocument(Document*); - void forgetWorldOfDOMNodesForDocument(Document*, DOMWrapperWorld*); void updateDOMNodeDocument(Node*, Document* oldDocument, Document* newDocument); + void markDOMNodesForDocument(JSC::MarkStack&, Document*); void markActiveObjectsForContext(JSC::MarkStack&, JSC::JSGlobalData&, ScriptExecutionContext*); void markDOMObjectWrapper(JSC::MarkStack&, JSC::JSGlobalData& globalData, void* object); + void markDOMNodeWrapper(JSC::MarkStack& markStack, Document* document, Node* node); + bool hasCachedDOMObjectWrapperUnchecked(JSC::JSGlobalData*, void* objectHandle); + bool hasCachedDOMNodeWrapperUnchecked(Document*, Node*); JSC::Structure* getCachedDOMStructure(JSDOMGlobalObject*, const JSC::ClassInfo*); JSC::Structure* cacheDOMStructure(JSDOMGlobalObject*, NonNullPassRefPtr<JSC::Structure>, const JSC::ClassInfo*); JSC::Structure* getCachedDOMStructure(JSC::ExecState*, const JSC::ClassInfo*); JSC::Structure* cacheDOMStructure(JSC::ExecState*, NonNullPassRefPtr<JSC::Structure>, const JSC::ClassInfo*); - DOMWrapperWorld* currentWorld(JSC::ExecState*); - DOMWrapperWorld* normalWorld(JSC::JSGlobalData&); - DOMWrapperWorld* mainThreadCurrentWorld(); - DOMWrapperWorld* mainThreadNormalWorld(); - inline DOMWrapperWorld* debuggerWorld() { return mainThreadNormalWorld(); } - inline DOMWrapperWorld* pluginWorld() { return mainThreadNormalWorld(); } - JSC::JSObject* getCachedDOMConstructor(JSC::ExecState*, const JSC::ClassInfo*); void cacheDOMConstructor(JSC::ExecState*, const JSC::ClassInfo*, JSC::JSObject* constructor); @@ -283,17 +173,17 @@ namespace WebCore { template<class WrapperClass, class DOMClass> inline DOMObject* createDOMObjectWrapper(JSC::ExecState* exec, JSDOMGlobalObject* globalObject, DOMClass* object) { ASSERT(object); - ASSERT(!getCachedDOMObjectWrapper(exec->globalData(), object)); + ASSERT(!getCachedDOMObjectWrapper(exec, object)); // FIXME: new (exec) could use a different globalData than the globalData this wrapper is cached on. WrapperClass* wrapper = new (exec) WrapperClass(getDOMStructure<WrapperClass>(exec, globalObject), globalObject, object); - cacheDOMObjectWrapper(exec->globalData(), object, wrapper); + cacheDOMObjectWrapper(exec, object, wrapper); return wrapper; } template<class WrapperClass, class DOMClass> inline JSC::JSValue getDOMObjectWrapper(JSC::ExecState* exec, JSDOMGlobalObject* globalObject, DOMClass* object) { if (!object) return JSC::jsNull(); - if (DOMObject* wrapper = getCachedDOMObjectWrapper(exec->globalData(), object)) + if (DOMObject* wrapper = getCachedDOMObjectWrapper(exec, object)) return wrapper; return createDOMObjectWrapper<WrapperClass>(exec, globalObject, object); } @@ -302,19 +192,21 @@ namespace WebCore { #define CREATE_SVG_OBJECT_WRAPPER(exec, globalObject, className, object, context) createDOMObjectWrapper<JS##className>(exec, globalObject, static_cast<className*>(object), context) template<class WrapperClass, class DOMClass> inline DOMObject* createDOMObjectWrapper(JSC::ExecState* exec, JSDOMGlobalObject* globalObject, DOMClass* object, SVGElement* context) { - ASSERT(object); - ASSERT(!getCachedDOMObjectWrapper(exec->globalData(), object)); - WrapperClass* wrapper = new (exec) WrapperClass(getDOMStructure<WrapperClass>(exec, globalObject), globalObject, object, context); - cacheDOMObjectWrapper(exec->globalData(), object, wrapper); + DOMObject* wrapper = createDOMObjectWrapper<WrapperClass, DOMClass>(exec, globalObject, object); + ASSERT(wrapper); + if (context) + JSSVGContextCache::addWrapper(wrapper, context); return wrapper; } template<class WrapperClass, class DOMClass> inline JSC::JSValue getDOMObjectWrapper(JSC::ExecState* exec, JSDOMGlobalObject* globalObject, DOMClass* object, SVGElement* context) { if (!object) return JSC::jsNull(); - if (DOMObject* wrapper = getCachedDOMObjectWrapper(exec->globalData(), object)) + if (DOMObject* wrapper = getCachedDOMObjectWrapper(exec, object)) { + ASSERT(JSSVGContextCache::svgContextForDOMObject(wrapper) == context); return wrapper; - return createDOMObjectWrapper<WrapperClass>(exec, globalObject, object, context); + } + return createDOMObjectWrapper<WrapperClass, DOMClass>(exec, globalObject, object, context); } #endif @@ -322,18 +214,18 @@ namespace WebCore { template<class WrapperClass, class DOMClass> inline JSNode* createDOMNodeWrapper(JSC::ExecState* exec, JSDOMGlobalObject* globalObject, DOMClass* node) { ASSERT(node); - ASSERT(!getCachedDOMNodeWrapper(node->document(), node)); + ASSERT(!getCachedDOMNodeWrapper(exec, node->document(), node)); WrapperClass* wrapper = new (exec) WrapperClass(getDOMStructure<WrapperClass>(exec, globalObject), globalObject, node); // FIXME: The entire function can be removed, once we fix caching. // This function is a one-off hack to make Nodes cache in the right global object. - cacheDOMNodeWrapper(node->document(), node, wrapper); + cacheDOMNodeWrapper(exec, node->document(), node, wrapper); return wrapper; } template<class WrapperClass, class DOMClass> inline JSC::JSValue getDOMNodeWrapper(JSC::ExecState* exec, JSDOMGlobalObject* globalObject, DOMClass* node) { if (!node) return JSC::jsNull(); - if (JSNode* wrapper = getCachedDOMNodeWrapper(node->document(), node)) + if (JSNode* wrapper = getCachedDOMNodeWrapper(exec, node->document(), node)) return wrapper; return createDOMNodeWrapper<WrapperClass>(exec, globalObject, node); } @@ -346,6 +238,14 @@ namespace WebCore { // Convert a DOM implementation exception code into a JavaScript exception in the execution state. void setDOMException(JSC::ExecState*, ExceptionCode); + JSC::JSValue jsString(JSC::ExecState*, const String&); // empty if the string is null + JSC::JSValue jsStringSlowCase(JSC::ExecState*, JSStringCache&, StringImpl*); + JSC::JSValue jsString(JSC::ExecState*, const KURL&); // empty if the URL is null + inline JSC::JSValue jsString(JSC::ExecState* exec, const AtomicString& s) + { + return jsString(exec, s.string()); + } + JSC::JSValue jsStringOrNull(JSC::ExecState*, const String&); // null if the string is null JSC::JSValue jsStringOrNull(JSC::ExecState*, const KURL&); // null if the URL is null @@ -362,6 +262,11 @@ namespace WebCore { JSC::UString valueToStringWithNullCheck(JSC::ExecState*, JSC::JSValue); // null if the value is null JSC::UString valueToStringWithUndefinedOrNullCheck(JSC::ExecState*, JSC::JSValue); // null if the value is null or undefined + // Returns a Date instance for the specified value, or null if the value is NaN or infinity. + JSC::JSValue jsDateOrNull(JSC::ExecState*, double); + // NaN if the value can't be converted to a date. + double valueToDate(JSC::ExecState*, JSC::JSValue); + // FIXME: These are a stop-gap until all toJS calls can be converted to pass a globalObject template <typename T> inline JSC::JSValue toJS(JSC::ExecState* exec, T* ptr) @@ -397,17 +302,33 @@ namespace WebCore { bool allowsAccessFromFrame(JSC::ExecState*, Frame*, String& message); bool shouldAllowNavigation(JSC::ExecState*, Frame*); void printErrorMessageForFrame(Frame*, const String& message); - JSC::JSValue objectToStringFunctionGetter(JSC::ExecState*, const JSC::Identifier& propertyName, const JSC::PropertySlot&); + JSC::JSValue objectToStringFunctionGetter(JSC::ExecState*, JSC::JSValue, const JSC::Identifier& propertyName); Frame* toLexicalFrame(JSC::ExecState*); Frame* toDynamicFrame(JSC::ExecState*); bool processingUserGesture(JSC::ExecState*); KURL completeURL(JSC::ExecState*, const String& relativeURL); + + inline JSC::JSValue jsString(JSC::ExecState* exec, const String& s) + { + StringImpl* stringImpl = s.impl(); + if (!stringImpl || !stringImpl->length()) + return jsEmptyString(exec); - JSC::JSValue DebuggerCallFrame_evaluateInWorld(const JSC::DebuggerCallFrame& debuggerCallFrame, const JSC::UString& script, JSC::JSValue& exception); - JSC::JSValue callInWorld(JSC::ExecState*, JSC::JSValue function, JSC::CallType, const JSC::CallData&, JSC::JSValue thisValue, const JSC::ArgList&, DOMWrapperWorld*); - JSC::JSObject* constructInWorld(JSC::ExecState* exec, JSC::JSValue object, JSC::ConstructType constructType, const JSC::ConstructData& constructData, const JSC::ArgList& args, DOMWrapperWorld*); - JSC::Completion evaluateInWorld(JSC::ExecState*, JSC::ScopeChain&, const JSC::SourceCode&, JSC::JSValue thisValue, DOMWrapperWorld*); + if (stringImpl->length() == 1 && stringImpl->characters()[0] <= 0xFF) + return jsString(exec, stringImpl->ustring()); + + JSStringCache& stringCache = currentWorld(exec)->m_stringCache; + if (JSC::JSString* wrapper = stringCache.get(stringImpl)) + return wrapper; + + return jsStringSlowCase(exec, stringCache, stringImpl); + } + + inline DOMObjectWrapperMap& domObjectWrapperMapFor(JSC::ExecState* exec) + { + return currentWorld(exec)->m_wrappers; + } } // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSDOMFormDataCustom.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSDOMFormDataCustom.cpp new file mode 100644 index 0000000..222cbcc --- /dev/null +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSDOMFormDataCustom.cpp @@ -0,0 +1,56 @@ +/* + * 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: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "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 THE COPYRIGHT + * OWNER 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" +#include "JSDOMFormData.h" + +#include "DOMFormData.h" +#include "JSBlob.h" +#include <runtime/Error.h> + +using namespace JSC; + +namespace WebCore { + +JSValue JSDOMFormData::append(ExecState* exec, const ArgList& args) +{ + if (args.size() >= 2) { + String name = args.at(0).toString(exec); + JSValue value = args.at(1); + if (value.inherits(&JSBlob::s_info)) + impl()->append(name, toBlob(value)); + else + impl()->append(name, value.toString(exec)); + } + + return jsUndefined(); +} + +} // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSDOMGlobalObject.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSDOMGlobalObject.cpp index 011a4e4..e0b5b89 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSDOMGlobalObject.cpp +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSDOMGlobalObject.cpp @@ -40,6 +40,8 @@ using namespace JSC; namespace WebCore { +const ClassInfo JSDOMGlobalObject::s_info = { "DOMGlobalObject", 0, 0, 0 }; + JSDOMGlobalObject::JSDOMGlobalObject(NonNullPassRefPtr<Structure> structure, JSDOMGlobalObject::JSDOMGlobalObjectData* data, JSObject* thisValue) : JSGlobalObject(structure, data, thisValue) { @@ -56,14 +58,9 @@ void JSDOMGlobalObject::markChildren(MarkStack& markStack) JSDOMConstructorMap::iterator end2 = constructors().end(); for (JSDOMConstructorMap::iterator it2 = constructors().begin(); it2 != end2; ++it2) markStack.append(it2->second); -} -PassRefPtr<JSEventListener> JSDOMGlobalObject::createJSAttributeEventListener(JSValue val) -{ - if (!val.isObject()) - return 0; - - return JSEventListener::create(asObject(val), true, currentWorld(globalExec())).get(); + if (d()->m_injectedScript) + markStack.append(d()->m_injectedScript); } void JSDOMGlobalObject::setCurrentEvent(Event* evt) @@ -76,6 +73,16 @@ Event* JSDOMGlobalObject::currentEvent() const return d()->evt; } +void JSDOMGlobalObject::setInjectedScript(JSObject* injectedScript) +{ + d()->m_injectedScript = injectedScript; +} + +JSObject* JSDOMGlobalObject::injectedScript() const +{ + return d()->m_injectedScript; +} + void JSDOMGlobalObject::destroyJSDOMGlobalObjectData(void* jsDOMGlobalObjectData) { delete static_cast<JSDOMGlobalObjectData*>(jsDOMGlobalObjectData); diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSDOMGlobalObject.h b/src/3rdparty/webkit/WebCore/bindings/js/JSDOMGlobalObject.h index 6b75a6f..8eb55c1 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSDOMGlobalObject.h +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSDOMGlobalObject.h @@ -54,29 +54,29 @@ namespace WebCore { virtual ScriptExecutionContext* scriptExecutionContext() const = 0; - // Creates a JS EventListener for an "onXXX" event attribute. These - // listeners cannot be removed through the removeEventListener API. - PassRefPtr<JSEventListener> createJSAttributeEventListener(JSC::JSValue); - // Make binding code generation easier. JSDOMGlobalObject* globalObject() { return this; } void setCurrentEvent(Event*); Event* currentEvent() const; + void setInjectedScript(JSObject*); + JSObject* injectedScript() const; + virtual void markChildren(JSC::MarkStack&); + DOMWrapperWorld* world() { return d()->m_world.get(); } + + virtual const JSC::ClassInfo* classInfo() const { return &s_info; } + static const JSC::ClassInfo s_info; + protected: struct JSDOMGlobalObjectData : public JSC::JSGlobalObject::JSGlobalObjectData { - JSDOMGlobalObjectData() - : JSGlobalObjectData(destroyJSDOMGlobalObjectData) - , evt(0) - { - } - - JSDOMGlobalObjectData(Destructor destructor) + JSDOMGlobalObjectData(DOMWrapperWorld* world, Destructor destructor = destroyJSDOMGlobalObjectData) : JSGlobalObjectData(destructor) , evt(0) + , m_world(world) + , m_injectedScript(0) { } @@ -84,6 +84,8 @@ namespace WebCore { JSDOMConstructorMap constructors; Event* evt; + RefPtr<DOMWrapperWorld> m_world; + JSObject* m_injectedScript; }; private: diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSDOMWindowBase.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSDOMWindowBase.cpp index 86ff149..c25a70a 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSDOMWindowBase.cpp +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSDOMWindowBase.cpp @@ -24,6 +24,7 @@ #include "JSDOMWindowBase.h" #include "CString.h" +#include "Chrome.h" #include "Console.h" #include "DOMWindow.h" #include "Frame.h" @@ -35,12 +36,20 @@ #include "ScriptController.h" #include "SecurityOrigin.h" #include "Settings.h" +#include "WebCoreJSClientData.h" using namespace JSC; namespace WebCore { -const ClassInfo JSDOMWindowBase::s_info = { "Window", 0, 0, 0 }; +const ClassInfo JSDOMWindowBase::s_info = { "Window", &JSDOMGlobalObject::s_info, 0, 0 }; + +JSDOMWindowBase::JSDOMWindowBaseData::JSDOMWindowBaseData(PassRefPtr<DOMWindow> window, JSDOMWindowShell* shell) + : JSDOMGlobalObjectData(shell->world(), destroyJSDOMWindowBaseData) + , impl(window) + , shell(shell) +{ +} JSDOMWindowBase::JSDOMWindowBase(NonNullPassRefPtr<Structure> structure, PassRefPtr<DOMWindow> window, JSDOMWindowShell* shell) : JSDOMGlobalObject(structure, new JSDOMWindowBaseData(window, shell), shell) @@ -53,11 +62,10 @@ JSDOMWindowBase::JSDOMWindowBase(NonNullPassRefPtr<Structure> structure, PassRef addStaticGlobals(staticGlobals, sizeof(staticGlobals) / sizeof(GlobalPropertyInfo)); } -void JSDOMWindowBase::updateDocument(DOMWrapperWorld* world) +void JSDOMWindowBase::updateDocument() { ASSERT(d()->impl->document()); ExecState* exec = globalExec(); - EnterDOMWrapperWorld worldEntry(exec, world); symbolTablePutWithAttributes(Identifier(exec, "document"), toJS(exec, this, d()->impl->document()), DontDelete | ReadOnly); } @@ -69,7 +77,7 @@ ScriptExecutionContext* JSDOMWindowBase::scriptExecutionContext() const String JSDOMWindowBase::crossDomainAccessErrorMessage(const JSGlobalObject* other) const { KURL originURL = asJSDOMWindow(other)->impl()->url(); - KURL targetURL = impl()->frame()->document()->url(); + KURL targetURL = d()->shell->window()->impl()->url(); if (originURL.isNull() || targetURL.isNull()) return String(); @@ -164,7 +172,7 @@ void JSDOMWindowBase::destroyJSDOMWindowBaseData(void* jsDOMWindowBaseData) delete static_cast<JSDOMWindowBaseData*>(jsDOMWindowBaseData); } -// JSDOMGlobalObject* is ignored, accesing a window in any context will +// JSDOMGlobalObject* is ignored, accessing a window in any context will // use that DOMWindow's prototype chain. JSValue toJS(ExecState* exec, JSDOMGlobalObject*, DOMWindow* domWindow) { diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSDOMWindowBase.h b/src/3rdparty/webkit/WebCore/bindings/js/JSDOMWindowBase.h index 31e2486..2726996 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSDOMWindowBase.h +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSDOMWindowBase.h @@ -47,7 +47,7 @@ namespace WebCore { JSDOMWindowBase(NonNullPassRefPtr<JSC::Structure>, PassRefPtr<DOMWindow>, JSDOMWindowShell*); public: - void updateDocument(DOMWrapperWorld*); + void updateDocument(); DOMWindow* impl() const { return d()->impl.get(); } virtual ScriptExecutionContext* scriptExecutionContext() const; @@ -77,12 +77,7 @@ namespace WebCore { private: struct JSDOMWindowBaseData : public JSDOMGlobalObjectData { - JSDOMWindowBaseData(PassRefPtr<DOMWindow> window, JSDOMWindowShell* shell) - : JSDOMGlobalObjectData(destroyJSDOMWindowBaseData) - , impl(window) - , shell(shell) - { - } + JSDOMWindowBaseData(PassRefPtr<DOMWindow> window, JSDOMWindowShell* shell); RefPtr<DOMWindow> impl; JSDOMWindowShell* shell; @@ -97,7 +92,7 @@ namespace WebCore { }; // Returns a JSDOMWindow or jsNull() - // JSDOMGlobalObject* is ignored, accesing a window in any context will + // JSDOMGlobalObject* is ignored, accessing a window in any context will // use that DOMWindow's prototype chain. JSC::JSValue toJS(JSC::ExecState*, JSDOMGlobalObject*, DOMWindow*); JSC::JSValue toJS(JSC::ExecState*, DOMWindow*); diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSDOMWindowCustom.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSDOMWindowCustom.cpp index 2804b3c..e8c2781 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSDOMWindowCustom.cpp +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSDOMWindowCustom.cpp @@ -21,7 +21,8 @@ #include "JSDOMWindowCustom.h" #include "AtomicString.h" -#include "Base64.h" +#include "Chrome.h" +#include "Database.h" #include "DOMWindow.h" #include "Document.h" #include "ExceptionCode.h" @@ -35,6 +36,8 @@ #include "HTMLDocument.h" #include "History.h" #include "JSAudioConstructor.h" +#include "JSDatabase.h" +#include "JSDatabaseCallback.h" #include "JSDOMWindowShell.h" #include "JSEvent.h" #include "JSEventListener.h" @@ -53,14 +56,14 @@ #endif #if ENABLE(3D_CANVAS) -#include "JSCanvasArrayBufferConstructor.h" -#include "JSCanvasByteArrayConstructor.h" -#include "JSCanvasUnsignedByteArrayConstructor.h" -#include "JSCanvasIntArrayConstructor.h" -#include "JSCanvasUnsignedIntArrayConstructor.h" -#include "JSCanvasShortArrayConstructor.h" -#include "JSCanvasUnsignedShortArrayConstructor.h" -#include "JSCanvasFloatArrayConstructor.h" +#include "JSWebGLArrayBufferConstructor.h" +#include "JSWebGLByteArrayConstructor.h" +#include "JSWebGLUnsignedByteArrayConstructor.h" +#include "JSWebGLIntArrayConstructor.h" +#include "JSWebGLUnsignedIntArrayConstructor.h" +#include "JSWebGLShortArrayConstructor.h" +#include "JSWebGLUnsignedShortArrayConstructor.h" +#include "JSWebGLFloatArrayConstructor.h" #endif #include "JSWebKitCSSMatrixConstructor.h" #include "JSWebKitPointConstructor.h" @@ -96,7 +99,7 @@ void JSDOMWindow::markChildren(MarkStack& markStack) { Base::markChildren(markStack); - impl()->markEventListeners(markStack); + impl()->markJSEventListeners(markStack); JSGlobalData& globalData = *Heap::heap(this)->globalData(); @@ -112,6 +115,7 @@ void JSDOMWindow::markChildren(MarkStack& markStack) markDOMObjectWrapper(markStack, globalData, impl()->optionalStatusbar()); markDOMObjectWrapper(markStack, globalData, impl()->optionalToolbar()); markDOMObjectWrapper(markStack, globalData, impl()->optionalLocation()); + markDOMObjectWrapper(markStack, globalData, impl()->optionalMedia()); #if ENABLE(DOM_STORAGE) markDOMObjectWrapper(markStack, globalData, impl()->optionalSessionStorage()); markDOMObjectWrapper(markStack, globalData, impl()->optionalLocalStorage()); @@ -122,24 +126,24 @@ void JSDOMWindow::markChildren(MarkStack& markStack) } template<NativeFunction nativeFunction, int length> -JSValue nonCachingStaticFunctionGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot&) +JSValue nonCachingStaticFunctionGetter(ExecState* exec, JSValue, const Identifier& propertyName) { return new (exec) NativeFunctionWrapper(exec, exec->lexicalGlobalObject()->prototypeFunctionStructure(), length, propertyName, nativeFunction); } -static JSValue childFrameGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot) +static JSValue childFrameGetter(ExecState* exec, JSValue slotBase, const Identifier& propertyName) { - return toJS(exec, static_cast<JSDOMWindow*>(asObject(slot.slotBase()))->impl()->frame()->tree()->child(AtomicString(propertyName))->domWindow()); + return toJS(exec, static_cast<JSDOMWindow*>(asObject(slotBase))->impl()->frame()->tree()->child(AtomicString(propertyName))->domWindow()); } -static JSValue indexGetter(ExecState* exec, const Identifier&, const PropertySlot& slot) +static JSValue indexGetter(ExecState* exec, JSValue slotBase, unsigned index) { - return toJS(exec, static_cast<JSDOMWindow*>(asObject(slot.slotBase()))->impl()->frame()->tree()->child(slot.index())->domWindow()); + return toJS(exec, static_cast<JSDOMWindow*>(asObject(slotBase))->impl()->frame()->tree()->child(index)->domWindow()); } -static JSValue namedItemGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot) +static JSValue namedItemGetter(ExecState* exec, JSValue slotBase, const Identifier& propertyName) { - JSDOMWindowBase* thisObj = static_cast<JSDOMWindow*>(asObject(slot.slotBase())); + JSDOMWindowBase* thisObj = static_cast<JSDOMWindow*>(asObject(slotBase)); Document* document = thisObj->impl()->frame()->document(); ASSERT(thisObj->allowsAccessFrom(exec)); @@ -265,7 +269,7 @@ bool JSDOMWindow::getOwnPropertySlot(ExecState* exec, const Identifier& property } } - // FIXME: Search the whole frame hierachy somewhere around here. + // FIXME: Search the whole frame hierarchy somewhere around here. // We need to test the correct priority order. // allow window[1] or parent[1] etc. (#56983) @@ -297,10 +301,10 @@ bool JSDOMWindow::getOwnPropertySlot(ExecState* exec, const Identifier& property bool JSDOMWindow::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor) { - // When accessing a Window cross-domain, functions are always the native built-in ones, and they - // are not affected by properties changed on the Window or anything in its prototype chain. - // This is consistent with the behavior of Firefox. - + // Never allow cross-domain getOwnPropertyDescriptor + if (!allowsAccessFrom(exec)) + return false; + const HashEntry* entry; // We don't want any properties other than "close" and "closed" on a closed window. @@ -323,65 +327,6 @@ bool JSDOMWindow::getOwnPropertyDescriptor(ExecState* exec, const Identifier& pr return true; } - String errorMessage; - bool allowsAccess = allowsAccessFrom(exec, errorMessage); - if (allowsAccess && JSGlobalObject::getOwnPropertyDescriptor(exec, propertyName, descriptor)) - return true; - - // We need this code here because otherwise JSDOMWindowBase will stop the search before we even get to the - // prototype due to the blanket same origin (allowsAccessFrom) check at the end of getOwnPropertySlot. - // Also, it's important to get the implementation straight out of the DOMWindow prototype regardless of - // what prototype is actually set on this object. - entry = JSDOMWindowPrototype::s_info.propHashTable(exec)->entry(exec, propertyName); - if (entry) { - if (entry->attributes() & Function) { - if (entry->function() == jsDOMWindowPrototypeFunctionBlur) { - if (!allowsAccess) { - PropertySlot slot; - slot.setCustom(this, nonCachingStaticFunctionGetter<jsDOMWindowPrototypeFunctionBlur, 0>); - descriptor.setDescriptor(slot.getValue(exec, propertyName), ReadOnly | DontDelete | DontEnum); - return true; - } - } else if (entry->function() == jsDOMWindowPrototypeFunctionClose) { - if (!allowsAccess) { - PropertySlot slot; - slot.setCustom(this, nonCachingStaticFunctionGetter<jsDOMWindowPrototypeFunctionClose, 0>); - descriptor.setDescriptor(slot.getValue(exec, propertyName), ReadOnly | DontDelete | DontEnum); - return true; - } - } else if (entry->function() == jsDOMWindowPrototypeFunctionFocus) { - if (!allowsAccess) { - PropertySlot slot; - slot.setCustom(this, nonCachingStaticFunctionGetter<jsDOMWindowPrototypeFunctionFocus, 0>); - descriptor.setDescriptor(slot.getValue(exec, propertyName), ReadOnly | DontDelete | DontEnum); - return true; - } - } else if (entry->function() == jsDOMWindowPrototypeFunctionPostMessage) { - if (!allowsAccess) { - PropertySlot slot; - slot.setCustom(this, nonCachingStaticFunctionGetter<jsDOMWindowPrototypeFunctionPostMessage, 2>); - descriptor.setDescriptor(slot.getValue(exec, propertyName), ReadOnly | DontDelete | DontEnum); - return true; - } - } else if (entry->function() == jsDOMWindowPrototypeFunctionShowModalDialog) { - if (!DOMWindow::canShowModalDialog(impl()->frame())) { - descriptor.setUndefined(); - return true; - } - } - } - } else { - // Allow access to toString() cross-domain, but always Object.prototype.toString. - if (propertyName == exec->propertyNames().toString) { - if (!allowsAccess) { - PropertySlot slot; - slot.setCustom(this, objectToStringFunctionGetter); - descriptor.setDescriptor(slot.getValue(exec, propertyName), ReadOnly | DontDelete | DontEnum); - return true; - } - } - } - entry = JSDOMWindow::s_info.propHashTable(exec)->entry(exec, propertyName); if (entry) { PropertySlot slot; @@ -402,19 +347,6 @@ bool JSDOMWindow::getOwnPropertyDescriptor(ExecState* exec, const Identifier& pr return true; } - // Do prototype lookup early so that functions and attributes in the prototype can have - // precedence over the index and name getters. - JSValue proto = prototype(); - if (proto.isObject()) { - if (asObject(proto)->getPropertyDescriptor(exec, propertyName, descriptor)) { - if (!allowsAccess) { - printErrorMessage(errorMessage); - descriptor.setUndefined(); - } - return true; - } - } - bool ok; unsigned i = propertyName.toArrayIndex(&ok); if (ok && i < impl()->frame()->tree()->childCount()) { @@ -466,28 +398,20 @@ bool JSDOMWindow::deleteProperty(ExecState* exec, const Identifier& propertyName return Base::deleteProperty(exec, propertyName); } -void JSDOMWindow::getPropertyNames(ExecState* exec, PropertyNameArray& propertyNames) +void JSDOMWindow::getPropertyNames(ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode) { // Only allow the window to enumerated by frames in the same origin. if (!allowsAccessFrom(exec)) return; - Base::getPropertyNames(exec, propertyNames); + Base::getPropertyNames(exec, propertyNames, mode); } -void JSDOMWindow::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames) +void JSDOMWindow::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode) { // Only allow the window to enumerated by frames in the same origin. if (!allowsAccessFrom(exec)) return; - Base::getOwnPropertyNames(exec, propertyNames); -} - -bool JSDOMWindow::getPropertyAttributes(ExecState* exec, const Identifier& propertyName, unsigned& attributes) const -{ - // Only allow getting property attributes properties by frames in the same origin. - if (!allowsAccessFrom(exec)) - return false; - return Base::getPropertyAttributes(exec, propertyName, attributes); + Base::getOwnPropertyNames(exec, propertyNames, mode); } void JSDOMWindow::defineGetter(ExecState* exec, const Identifier& propertyName, JSObject* getterFunction, unsigned attributes) @@ -540,24 +464,24 @@ JSValue JSDOMWindow::lookupSetter(ExecState* exec, const Identifier& propertyNam JSValue JSDOMWindow::history(ExecState* exec) const { History* history = impl()->history(); - if (DOMObject* wrapper = getCachedDOMObjectWrapper(exec->globalData(), history)) + if (DOMObject* wrapper = getCachedDOMObjectWrapper(exec, history)) return wrapper; JSDOMWindow* window = const_cast<JSDOMWindow*>(this); JSHistory* jsHistory = new (exec) JSHistory(getDOMStructure<JSHistory>(exec, window), window, history); - cacheDOMObjectWrapper(exec->globalData(), history, jsHistory); + cacheDOMObjectWrapper(exec, history, jsHistory); return jsHistory; } JSValue JSDOMWindow::location(ExecState* exec) const { Location* location = impl()->location(); - if (DOMObject* wrapper = getCachedDOMObjectWrapper(exec->globalData(), location)) + if (DOMObject* wrapper = getCachedDOMObjectWrapper(exec, location)) return wrapper; JSDOMWindow* window = const_cast<JSDOMWindow*>(this); JSLocation* jsLocation = new (exec) JSLocation(getDOMStructure<JSLocation>(exec, window), window, location); - cacheDOMObjectWrapper(exec->globalData(), location, jsLocation); + cacheDOMObjectWrapper(exec, location, jsLocation); return jsLocation; } @@ -645,44 +569,44 @@ JSValue JSDOMWindow::webKitCSSMatrix(ExecState* exec) const } #if ENABLE(3D_CANVAS) -JSValue JSDOMWindow::canvasArrayBuffer(ExecState* exec) const +JSValue JSDOMWindow::webGLArrayBuffer(ExecState* exec) const { - return getDOMConstructor<JSCanvasArrayBufferConstructor>(exec, this); + return getDOMConstructor<JSWebGLArrayBufferConstructor>(exec, this); } -JSValue JSDOMWindow::canvasByteArray(ExecState* exec) const +JSValue JSDOMWindow::webGLByteArray(ExecState* exec) const { - return getDOMConstructor<JSCanvasByteArrayConstructor>(exec, this); + return getDOMConstructor<JSWebGLByteArrayConstructor>(exec, this); } -JSValue JSDOMWindow::canvasUnsignedByteArray(ExecState* exec) const +JSValue JSDOMWindow::webGLUnsignedByteArray(ExecState* exec) const { - return getDOMConstructor<JSCanvasUnsignedByteArrayConstructor>(exec, this); + return getDOMConstructor<JSWebGLUnsignedByteArrayConstructor>(exec, this); } -JSValue JSDOMWindow::canvasIntArray(ExecState* exec) const +JSValue JSDOMWindow::webGLIntArray(ExecState* exec) const { - return getDOMConstructor<JSCanvasIntArrayConstructor>(exec, this); + return getDOMConstructor<JSWebGLIntArrayConstructor>(exec, this); } -JSValue JSDOMWindow::canvasUnsignedIntArray(ExecState* exec) const +JSValue JSDOMWindow::webGLUnsignedIntArray(ExecState* exec) const { - return getDOMConstructor<JSCanvasUnsignedIntArrayConstructor>(exec, this); + return getDOMConstructor<JSWebGLUnsignedIntArrayConstructor>(exec, this); } -JSValue JSDOMWindow::canvasShortArray(ExecState* exec) const +JSValue JSDOMWindow::webGLShortArray(ExecState* exec) const { - return getDOMConstructor<JSCanvasShortArrayConstructor>(exec, this); + return getDOMConstructor<JSWebGLShortArrayConstructor>(exec, this); } -JSValue JSDOMWindow::canvasUnsignedShortArray(ExecState* exec) const +JSValue JSDOMWindow::webGLUnsignedShortArray(ExecState* exec) const { - return getDOMConstructor<JSCanvasUnsignedShortArrayConstructor>(exec, this); + return getDOMConstructor<JSWebGLUnsignedShortArrayConstructor>(exec, this); } -JSValue JSDOMWindow::canvasFloatArray(ExecState* exec) const +JSValue JSDOMWindow::webGLFloatArray(ExecState* exec) const { - return getDOMConstructor<JSCanvasFloatArrayConstructor>(exec, this); + return getDOMConstructor<JSWebGLFloatArrayConstructor>(exec, this); } #endif @@ -744,6 +668,12 @@ static Frame* createWindow(ExecState* exec, Frame* lexicalFrame, Frame* dynamicF ASSERT(lexicalFrame); ASSERT(dynamicFrame); + if (Document* lexicalDocument = lexicalFrame->document()) { + // Sandboxed iframes cannot open new auxiliary browsing contexts. + if (lexicalDocument->securityOrigin()->isSandboxed(SandboxNavigation)) + return 0; + } + ResourceRequest request; // For whatever reason, Firefox uses the dynamicGlobalObject to determine @@ -790,6 +720,14 @@ static Frame* createWindow(ExecState* exec, Frame* lexicalFrame, Frame* dynamicF return newFrame; } +static bool domWindowAllowPopUp(Frame* activeFrame, ExecState* exec) +{ + ASSERT(activeFrame); + if (activeFrame->script()->processingUserGesture(currentWorld(exec))) + return true; + return DOMWindow::allowPopUp(activeFrame); +} + JSValue JSDOMWindow::open(ExecState* exec, const ArgList& args) { String urlString = valueToStringWithUndefinedOrNullCheck(exec, args.at(0)); @@ -810,7 +748,7 @@ JSValue JSDOMWindow::open(ExecState* exec, const ArgList& args) // Because FrameTree::find() returns true for empty strings, we must check for empty framenames. // Otherwise, illegitimate window.open() calls with no name will pass right through the popup blocker. - if (!DOMWindow::allowPopUp(dynamicFrame) && (frameName.isEmpty() || !frame->tree()->find(frameName))) + if (!domWindowAllowPopUp(dynamicFrame, exec) && (frameName.isEmpty() || !frame->tree()->find(frameName))) return jsUndefined(); // Get the target frame for the special cases of _top and _parent. In those @@ -880,7 +818,7 @@ JSValue JSDOMWindow::showModalDialog(ExecState* exec, const ArgList& args) if (!dynamicFrame) return jsUndefined(); - if (!DOMWindow::canShowModalDialogNow(frame) || !DOMWindow::allowPopUp(dynamicFrame)) + if (!DOMWindow::canShowModalDialogNow(frame) || !domWindowAllowPopUp(dynamicFrame, exec)) return jsUndefined(); HashMap<String, String> features; @@ -976,71 +914,30 @@ JSValue JSDOMWindow::postMessage(ExecState* exec, const ArgList& args) JSValue JSDOMWindow::setTimeout(ExecState* exec, const ArgList& args) { - ScheduledAction* action = ScheduledAction::create(exec, args, currentWorld(exec)); + OwnPtr<ScheduledAction> action = ScheduledAction::create(exec, args, currentWorld(exec)); if (exec->hadException()) return jsUndefined(); int delay = args.at(1).toInt32(exec); - return jsNumber(exec, impl()->setTimeout(action, delay)); + + ExceptionCode ec = 0; + int result = impl()->setTimeout(action.release(), delay, ec); + setDOMException(exec, ec); + + return jsNumber(exec, result); } JSValue JSDOMWindow::setInterval(ExecState* exec, const ArgList& args) { - ScheduledAction* action = ScheduledAction::create(exec, args, currentWorld(exec)); + OwnPtr<ScheduledAction> action = ScheduledAction::create(exec, args, currentWorld(exec)); if (exec->hadException()) return jsUndefined(); int delay = args.at(1).toInt32(exec); - return jsNumber(exec, impl()->setInterval(action, delay)); -} -JSValue JSDOMWindow::atob(ExecState* exec, const ArgList& args) -{ - if (args.size() < 1) - return throwError(exec, SyntaxError, "Not enough arguments"); - - JSValue v = args.at(0); - if (v.isNull()) - return jsEmptyString(exec); - - UString s = v.toString(exec); - if (!s.is8Bit()) { - setDOMException(exec, INVALID_CHARACTER_ERR); - return jsUndefined(); - } - - Vector<char> in(s.size()); - for (int i = 0; i < s.size(); ++i) - in[i] = static_cast<char>(s.data()[i]); - Vector<char> out; - - if (!base64Decode(in, out)) - return throwError(exec, GeneralError, "Cannot decode base64"); - - return jsString(exec, String(out.data(), out.size())); -} - -JSValue JSDOMWindow::btoa(ExecState* exec, const ArgList& args) -{ - if (args.size() < 1) - return throwError(exec, SyntaxError, "Not enough arguments"); - - JSValue v = args.at(0); - if (v.isNull()) - return jsEmptyString(exec); - - UString s = v.toString(exec); - if (!s.is8Bit()) { - setDOMException(exec, INVALID_CHARACTER_ERR); - return jsUndefined(); - } - - Vector<char> in(s.size()); - for (int i = 0; i < s.size(); ++i) - in[i] = static_cast<char>(s.data()[i]); - Vector<char> out; - - base64Encode(in, out); + ExceptionCode ec = 0; + int result = impl()->setInterval(action.release(), delay, ec); + setDOMException(exec, ec); - return jsString(exec, String(out.data(), out.size())); + return jsNumber(exec, result); } JSValue JSDOMWindow::addEventListener(ExecState* exec, const ArgList& args) @@ -1053,7 +950,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(); } @@ -1067,10 +964,30 @@ 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(); } +#if ENABLE(DATABASE) +JSValue JSDOMWindow::openDatabase(ExecState* exec, const ArgList& args) +{ + if (!allowsAccessFrom(exec) || (args.size() < 4)) + return jsUndefined(); + ExceptionCode ec = 0; + const UString& name = args.at(0).toString(exec); + const UString& version = args.at(1).toString(exec); + const UString& displayName = args.at(2).toString(exec); + unsigned long estimatedSize = args.at(3).toInt32(exec); + RefPtr<DatabaseCallback> creationCallback; + if ((args.size() >= 5) && args.at(4).isObject()) + creationCallback = JSDatabaseCallback::create(asObject(args.at(4)), globalObject()); + + JSValue result = toJS(exec, globalObject(), WTF::getPtr(impl()->openDatabase(name, version, displayName, estimatedSize, creationCallback.release(), ec))); + setDOMException(exec, ec); + return result; +} +#endif + DOMWindow* toDOMWindow(JSValue value) { if (!value.isObject()) diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSDOMWindowShell.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSDOMWindowShell.cpp index 9072f91..1e82a49 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSDOMWindowShell.cpp +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSDOMWindowShell.cpp @@ -43,9 +43,10 @@ ASSERT_CLASS_FITS_IN_CELL(JSDOMWindowShell); const ClassInfo JSDOMWindowShell::s_info = { "JSDOMWindowShell", 0, 0, 0 }; -JSDOMWindowShell::JSDOMWindowShell(PassRefPtr<DOMWindow> window) +JSDOMWindowShell::JSDOMWindowShell(PassRefPtr<DOMWindow> window, DOMWrapperWorld* world) : Base(JSDOMWindowShell::createStructure(jsNull())) , m_window(0) + , m_world(world) { setWindow(window); } @@ -113,19 +114,14 @@ bool JSDOMWindowShell::deleteProperty(ExecState* exec, const Identifier& propert return m_window->deleteProperty(exec, propertyName); } -void JSDOMWindowShell::getPropertyNames(ExecState* exec, PropertyNameArray& propertyNames) +void JSDOMWindowShell::getPropertyNames(ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode) { - m_window->getPropertyNames(exec, propertyNames); + m_window->getPropertyNames(exec, propertyNames, mode); } -void JSDOMWindowShell::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames) +void JSDOMWindowShell::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode) { - m_window->getOwnPropertyNames(exec, propertyNames); -} - -bool JSDOMWindowShell::getPropertyAttributes(JSC::ExecState* exec, const Identifier& propertyName, unsigned& attributes) const -{ - return m_window->getPropertyAttributes(exec, propertyName, attributes); + m_window->getOwnPropertyNames(exec, propertyNames, mode); } void JSDOMWindowShell::defineGetter(ExecState* exec, const Identifier& propertyName, JSObject* getterFunction, unsigned attributes) diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSDOMWindowShell.h b/src/3rdparty/webkit/WebCore/bindings/js/JSDOMWindowShell.h index 36cb8d6..1b986b8 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSDOMWindowShell.h +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSDOMWindowShell.h @@ -40,7 +40,7 @@ namespace WebCore { class JSDOMWindowShell : public DOMObject { typedef DOMObject Base; public: - JSDOMWindowShell(PassRefPtr<DOMWindow>); + JSDOMWindowShell(PassRefPtr<DOMWindow>, DOMWrapperWorld* world); virtual ~JSDOMWindowShell(); JSDOMWindow* window() const { return m_window; } @@ -60,9 +60,11 @@ namespace WebCore { static PassRefPtr<JSC::Structure> createStructure(JSC::JSValue prototype) { - return JSC::Structure::create(prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags)); + return JSC::Structure::create(prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), AnonymousSlotCount); } + DOMWrapperWorld* world() { return m_world.get(); } + private: static const unsigned StructureFlags = JSC::OverridesGetOwnPropertySlot | JSC::OverridesMarkChildren | JSC::OverridesGetPropertyNames | DOMObject::StructureFlags; @@ -73,9 +75,8 @@ namespace WebCore { virtual void put(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::JSValue, JSC::PutPropertySlot&); virtual void putWithAttributes(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::JSValue, unsigned attributes); virtual bool deleteProperty(JSC::ExecState*, const JSC::Identifier& propertyName); - virtual void getPropertyNames(JSC::ExecState*, JSC::PropertyNameArray&); - virtual void getOwnPropertyNames(JSC::ExecState*, JSC::PropertyNameArray&); - virtual bool getPropertyAttributes(JSC::ExecState*, const JSC::Identifier& propertyName, unsigned& attributes) const; + virtual void getPropertyNames(JSC::ExecState*, JSC::PropertyNameArray&, JSC::EnumerationMode mode = JSC::ExcludeDontEnumProperties); + virtual void getOwnPropertyNames(JSC::ExecState*, JSC::PropertyNameArray&, JSC::EnumerationMode mode = JSC::ExcludeDontEnumProperties); virtual void defineGetter(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::JSObject* getterFunction, unsigned attributes); virtual void defineSetter(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::JSObject* setterFunction, unsigned attributes); virtual bool defineOwnProperty(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::PropertyDescriptor&, bool shouldThrow); @@ -85,6 +86,7 @@ namespace WebCore { virtual const JSC::ClassInfo* classInfo() const { return &s_info; } JSDOMWindow* m_window; + RefPtr<DOMWrapperWorld> m_world; }; JSC::JSValue toJS(JSC::ExecState*, Frame*); diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSDOMWrapper.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSDOMWrapper.cpp new file mode 100644 index 0000000..3fcdcc1 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSDOMWrapper.cpp @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2010 Apple 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 INC. AND ITS CONTRIBUTORS ``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 INC. OR ITS 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" +#include "JSDOMWrapper.h" + +#include "JSDebugWrapperSet.h" +#include <runtime/Error.h> + +using namespace JSC; + +namespace WebCore { + +#ifndef NDEBUG + +DOMObject::~DOMObject() +{ + ASSERT(!JSDebugWrapperSet::shared().contains(this)); +} + +#endif + +bool DOMObject::defineOwnProperty(ExecState* exec, const Identifier&, PropertyDescriptor&, bool) +{ + throwError(exec, TypeError, "defineProperty is not supported on DOM Objects"); + return false; +} + +} // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSDOMWrapper.h b/src/3rdparty/webkit/WebCore/bindings/js/JSDOMWrapper.h new file mode 100644 index 0000000..00594cf --- /dev/null +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSDOMWrapper.h @@ -0,0 +1,46 @@ +/* + * Copyright (C) 1999-2001 Harri Porten (porten@kde.org) + * Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009, 2010 Apple Inc. All rights reserved. + * Copyright (C) 2007 Samuel Weinig <sam@webkit.org> + * Copyright (C) 2009 Google, Inc. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef JSDOMWrapper_h +#define JSDOMWrapper_h + +#include <runtime/JSObject.h> + +namespace WebCore { + +// Base class for all objects in this binding except Window. +class DOMObject : public JSC::JSObject { +protected: + explicit DOMObject(NonNullPassRefPtr<JSC::Structure> structure) + : JSObject(structure) + { + } + + virtual bool defineOwnProperty(JSC::ExecState*, const JSC::Identifier&, JSC::PropertyDescriptor&, bool); + +#ifndef NDEBUG + virtual ~DOMObject(); +#endif +}; + +} // namespace WebCore + +#endif // JSDOMWrapper_h diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSDataGridColumnListCustom.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSDataGridColumnListCustom.cpp index 91b3d15..9a6982a 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSDataGridColumnListCustom.cpp +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSDataGridColumnListCustom.cpp @@ -43,9 +43,9 @@ bool JSDataGridColumnList::canGetItemsForName(ExecState*, DataGridColumnList* im return impl->itemWithName(propertyName); } -JSValue JSDataGridColumnList::nameGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot) +JSValue JSDataGridColumnList::nameGetter(ExecState* exec, JSValue slotBase, const Identifier& propertyName) { - JSDataGridColumnList* thisObj = static_cast<JSDataGridColumnList*>(asObject(slot.slotBase())); + JSDataGridColumnList* thisObj = static_cast<JSDataGridColumnList*>(asObject(slotBase)); return toJS(exec, thisObj->globalObject(), thisObj->impl()->itemWithName(propertyName)); } diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSDatabaseCallback.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSDatabaseCallback.cpp new file mode 100644 index 0000000..c75a6e5 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSDatabaseCallback.cpp @@ -0,0 +1,84 @@ +/* + * 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: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "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 THE COPYRIGHT + * OWNER 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" +#include "JSDatabaseCallback.h" + +#if ENABLE(DATABASE) + +#include "Frame.h" +#include "JSDatabase.h" +#include "ScriptController.h" +#include "ScriptExecutionContext.h" +#include <runtime/JSLock.h> +#include <wtf/MainThread.h> + +namespace WebCore { + +using namespace JSC; + +JSDatabaseCallback::JSDatabaseCallback(JSObject* callback, JSDOMGlobalObject* globalObject) + : m_data(new JSCallbackData(callback, globalObject)) + , m_isolatedWorld(DOMWrapperWorld::create(globalObject->globalData(), true)) +{ +} + +JSDatabaseCallback::~JSDatabaseCallback() +{ + callOnMainThread(JSCallbackData::deleteData, m_data); +#ifndef NDEBUG + m_data = 0; +#endif +} + +void JSDatabaseCallback::handleEvent(ScriptExecutionContext* context, Database* database) +{ + ASSERT(m_data); + ASSERT(context); + + RefPtr<JSDatabaseCallback> protect(this); + + JSC::JSLock lock(SilenceAssertionsOnly); + + JSDOMGlobalObject* globalObject = toJSDOMGlobalObject(context, m_isolatedWorld.get()); + if (!globalObject) + return; + + ExecState* exec = globalObject->globalExec(); + MarkedArgumentBuffer args; + args.append(toJS(exec, database)); + + bool ignored; + m_data->invokeCallback(args, &ignored); +} + +} + +#endif // ENABLE(DATABASE) diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSDatabaseCallback.h b/src/3rdparty/webkit/WebCore/bindings/js/JSDatabaseCallback.h new file mode 100644 index 0000000..2f9234e --- /dev/null +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSDatabaseCallback.h @@ -0,0 +1,65 @@ +/* + * 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: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "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 THE COPYRIGHT + * OWNER 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 JSDatabaseCallback_h +#define JSDatabaseCallback_h + +#if ENABLE(DATABASE) + +#include "DatabaseCallback.h" +#include "JSCallbackData.h" + +namespace WebCore { + +class ScriptExecutionContext; + +class JSDatabaseCallback : public DatabaseCallback { +public: + static PassRefPtr<JSDatabaseCallback> create(JSC::JSObject* callback, JSDOMGlobalObject* globalObject) + { + return adoptRef(new JSDatabaseCallback(callback, globalObject)); + } + + virtual ~JSDatabaseCallback(); + + virtual void handleEvent(ScriptExecutionContext*, Database*); + +private: + JSDatabaseCallback(JSC::JSObject* callback, JSDOMGlobalObject*); + + JSCallbackData* m_data; + RefPtr<DOMWrapperWorld> m_isolatedWorld; +}; + +} + +#endif // ENABLE(DATABASE) + +#endif // JSDatabaseCallback_h diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSDebugWrapperSet.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSDebugWrapperSet.cpp new file mode 100644 index 0000000..b0d6ca9 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSDebugWrapperSet.cpp @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2010 Apple 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 INC. AND ITS CONTRIBUTORS ``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 INC. OR ITS 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" +#include "JSDebugWrapperSet.h" + +#include <wtf/StdLibExtras.h> + +#if ENABLE(WORKERS) +#include <wtf/ThreadSpecific.h> +#endif + +namespace WebCore { + +JSDebugWrapperSet& JSDebugWrapperSet::shared() +{ +#if ENABLE(WORKERS) + DEFINE_STATIC_LOCAL(WTF::ThreadSpecific<JSDebugWrapperSet>, staticWrapperSet, ()); + return *staticWrapperSet; +#else + DEFINE_STATIC_LOCAL(JSDebugWrapperSet, staticWrapperSet, ()); + return staticWrapperSet; +#endif +} + +JSDebugWrapperSet::JSDebugWrapperSet() +{ +} + +} // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSDebugWrapperSet.h b/src/3rdparty/webkit/WebCore/bindings/js/JSDebugWrapperSet.h new file mode 100644 index 0000000..94b6f78 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSDebugWrapperSet.h @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2010 Apple 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 INC. AND ITS CONTRIBUTORS ``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 INC. OR ITS 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 JSDebugWrapperSet_h +#define JSDebugWrapperSet_h + +#include "JSDOMWrapper.h" +#include <wtf/HashSet.h> +#include <wtf/Noncopyable.h> + +namespace WebCore { + +// For debugging, keep a set of wrappers currently cached, and check that +// all are uncached before they are destroyed. This helps us catch bugs like: +// - wrappers being deleted without being removed from the cache +// - wrappers being cached twice + +class JSDebugWrapperSet : public Noncopyable { + friend class WTF::ThreadSpecific<JSDebugWrapperSet>; +public: + static JSDebugWrapperSet& shared(); + + void add(DOMObject* object) { m_wrapperSet.add(object); } + void remove(DOMObject* object) { m_wrapperSet.remove(object); } + bool contains(DOMObject* object) const { return m_wrapperSet.contains(object); } + + static void willCacheWrapper(DOMObject*); + static void didUncacheWrapper(DOMObject*); + +private: + JSDebugWrapperSet(); + + HashSet<DOMObject*> m_wrapperSet; +}; + +#ifdef NDEBUG + +inline void JSDebugWrapperSet::willCacheWrapper(DOMObject*) +{ +} + +inline void JSDebugWrapperSet::didUncacheWrapper(DOMObject*) +{ +} + +#else + +inline void JSDebugWrapperSet::willCacheWrapper(DOMObject* wrapper) +{ + ASSERT(!JSDebugWrapperSet::shared().contains(wrapper)); + JSDebugWrapperSet::shared().add(wrapper); +} + +inline void JSDebugWrapperSet::didUncacheWrapper(DOMObject* wrapper) +{ + if (!wrapper) + return; + ASSERT(JSDebugWrapperSet::shared().contains(wrapper)); + JSDebugWrapperSet::shared().remove(wrapper); +} + +#endif + +} // namespace WebCore + +#endif // JSDebugWrapperSet_h diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSDocumentCustom.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSDocumentCustom.cpp index d7f8725..eda153e 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSDocumentCustom.cpp +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSDocumentCustom.cpp @@ -26,7 +26,7 @@ #include "HTMLDocument.h" #include "JSCanvasRenderingContext2D.h" #if ENABLE(3D_CANVAS) -#include "JSCanvasRenderingContext3D.h" +#include "JSWebGLRenderingContext.h" #endif #include "JSDOMWindowCustom.h" #include "JSHTMLDocument.h" @@ -65,11 +65,11 @@ JSValue JSDocument::location(ExecState* exec) const return jsNull(); Location* location = frame->domWindow()->location(); - if (DOMObject* wrapper = getCachedDOMObjectWrapper(exec->globalData(), location)) + if (DOMObject* wrapper = getCachedDOMObjectWrapper(exec, location)) return wrapper; JSLocation* jsLocation = new (exec) JSLocation(getDOMStructure<JSLocation>(exec, globalObject()), globalObject(), location); - cacheDOMObjectWrapper(exec->globalData(), location, jsLocation); + cacheDOMObjectWrapper(exec, location, jsLocation); return jsLocation; } @@ -87,7 +87,7 @@ void JSDocument::setLocation(ExecState* exec, JSValue value) if (activeFrame) str = activeFrame->document()->completeURL(str).string(); - bool userGesture = activeFrame->script()->processingUserGesture(); + bool userGesture = activeFrame->script()->processingUserGesture(currentWorld(exec)); frame->redirectScheduler()->scheduleLocationChange(str, activeFrame->loader()->outgoingReferrer(), !activeFrame->script()->anyPageIsProcessingUserGesture(), false, userGesture); } @@ -96,18 +96,18 @@ JSValue toJS(ExecState* exec, JSDOMGlobalObject* globalObject, Document* documen if (!document) return jsNull(); - DOMObject* wrapper = getCachedDOMObjectWrapper(exec->globalData(), document); + DOMObject* wrapper = getCachedDOMNodeWrapper(exec, document, document); if (wrapper) return wrapper; if (document->isHTMLDocument()) - wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, globalObject, HTMLDocument, document); + wrapper = CREATE_DOM_NODE_WRAPPER(exec, globalObject, HTMLDocument, document); #if ENABLE(SVG) else if (document->isSVGDocument()) - wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, globalObject, SVGDocument, document); + wrapper = CREATE_DOM_NODE_WRAPPER(exec, globalObject, SVGDocument, document); #endif else - wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, globalObject, Document, document); + wrapper = CREATE_DOM_NODE_WRAPPER(exec, globalObject, Document, document); // Make sure the document is kept around by the window object, and works right with the // back/forward cache. diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSElementCustom.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSElementCustom.cpp index fb64ff2..c725290 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSElementCustom.cpp +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSElementCustom.cpp @@ -145,7 +145,7 @@ JSValue toJSNewlyCreated(ExecState* exec, JSDOMGlobalObject* globalObject, Eleme if (!element) return jsNull(); - ASSERT(!getCachedDOMNodeWrapper(element->document(), element)); + ASSERT(!getCachedDOMNodeWrapper(exec, element->document(), element)); JSNode* wrapper; if (element->isHTMLElement()) diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSEventCustom.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSEventCustom.cpp index edf9151..6686d7a 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSEventCustom.cpp +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSEventCustom.cpp @@ -30,9 +30,13 @@ #include "JSEvent.h" #include "Clipboard.h" +#include "CompositionEvent.h" +#include "CustomEvent.h" #include "Event.h" #include "JSBeforeLoadEvent.h" #include "JSClipboard.h" +#include "JSCustomEvent.h" +#include "JSCompositionEvent.h" #include "JSErrorEvent.h" #include "JSKeyboardEvent.h" #include "JSMessageEvent.h" @@ -40,6 +44,7 @@ #include "JSMutationEvent.h" #include "JSOverflowEvent.h" #include "JSPageTransitionEvent.h" +#include "JSPopStateEvent.h" #include "JSProgressEvent.h" #include "JSTextEvent.h" #include "JSUIEvent.h" @@ -55,6 +60,7 @@ #include "MutationEvent.h" #include "OverflowEvent.h" #include "PageTransitionEvent.h" +#include "PopStateEvent.h" #include "ProgressEvent.h" #include "TextEvent.h" #include "UIEvent.h" @@ -74,6 +80,11 @@ #include "SVGZoomEvent.h" #endif +#if ENABLE(TOUCH_EVENTS) +#include "JSTouchEvent.h" +#include "TouchEvent.h" +#endif + using namespace JSC; namespace WebCore { @@ -90,7 +101,7 @@ JSValue toJS(ExecState* exec, JSDOMGlobalObject* globalObject, Event* event) if (!event) return jsNull(); - DOMObject* wrapper = getCachedDOMObjectWrapper(exec->globalData(), event); + DOMObject* wrapper = getCachedDOMObjectWrapper(exec, event); if (wrapper) return wrapper; @@ -107,6 +118,12 @@ JSValue toJS(ExecState* exec, JSDOMGlobalObject* globalObject, Event* event) else if (event->isSVGZoomEvent()) wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, globalObject, SVGZoomEvent, event); #endif + else if (event->isCompositionEvent()) + wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, globalObject, CompositionEvent, event); +#if ENABLE(TOUCH_EVENTS) + else if (event->isTouchEvent()) + wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, globalObject, TouchEvent, event); +#endif else wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, globalObject, UIEvent, event); } else if (event->isMutationEvent()) @@ -136,6 +153,10 @@ JSValue toJS(ExecState* exec, JSDOMGlobalObject* globalObject, Event* event) else if (event->isErrorEvent()) wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, globalObject, ErrorEvent, event); #endif + else if (event->isPopStateEvent()) + wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, globalObject, PopStateEvent, event); + else if (event->isCustomEvent()) + wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, globalObject, CustomEvent, event); else wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, globalObject, Event, event); diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSEventListener.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSEventListener.cpp index 1a999a8..be049db 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSEventListener.cpp +++ b/src/3rdparty/webkit/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) @@ -81,18 +83,13 @@ void JSEventListener::handleEvent(ScriptExecutionContext* scriptExecutionContext return; // FIXME: Is this check needed for other contexts? ScriptController* script = frame->script(); - if (!script->isEnabled() || script->isPaused()) + if (!script->canExecuteScripts(AboutToExecuteScript) || script->isPaused()) return; } ExecState* exec = globalObject->globalExec(); + JSValue handleEventFunction = jsFunction->get(exec, Identifier(exec, "handleEvent")); - JSValue handleEventFunction; - { - // Switch worlds, just in case handleEvent is a getter and causes JS execution! - EnterDOMWrapperWorld worldEntry(exec, m_isolatedWorld.get()); - handleEventFunction = jsFunction->get(exec, Identifier(exec, "handleEvent")); - } CallData callData; CallType callType = handleEventFunction.getCallData(callData); if (callType == CallTypeNone) { @@ -114,8 +111,8 @@ void JSEventListener::handleEvent(ScriptExecutionContext* scriptExecutionContext globalData->timeoutChecker.start(); JSValue retval = handleEventFunction - ? callInWorld(exec, handleEventFunction, callType, callData, jsFunction, args, m_isolatedWorld.get()) - : callInWorld(exec, jsFunction, callType, callData, toJS(exec, globalObject, event->currentTarget()), args, m_isolatedWorld.get()); + ? JSC::call(exec, handleEventFunction, callType, callData, jsFunction, args) + : JSC::call(exec, jsFunction, callType, callData, toJS(exec, globalObject, event->currentTarget()), args); globalData->timeoutChecker.stop(); globalObject->setCurrentEvent(savedEvent); @@ -132,8 +129,6 @@ void JSEventListener::handleEvent(ScriptExecutionContext* scriptExecutionContext } } - if (scriptExecutionContext->isDocument()) - Document::updateStyleForAllDocuments(); deref(); } } @@ -166,7 +161,7 @@ bool JSEventListener::reportError(ScriptExecutionContext* context, const String& JSValue thisValue = globalObject->toThisObject(exec); globalData->timeoutChecker.start(); - JSValue returnValue = callInWorld(exec, jsFunction, callType, callData, thisValue, args, m_isolatedWorld.get()); + JSValue returnValue = JSC::call(exec, jsFunction, callType, callData, thisValue, args); globalData->timeoutChecker.stop(); // If an error occurs while handling the script error, it should be bubbled up. diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSEventListener.h b/src/3rdparty/webkit/WebCore/bindings/js/JSEventListener.h index bf3af48..569c192 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSEventListener.h +++ b/src/3rdparty/webkit/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,23 +49,64 @@ 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, JSC::JSObject* wrapper) + { + if (!listener.isObject()) + return 0; + + return JSEventListener::create(asObject(listener), wrapper, true, currentWorld(exec)); + } + + } // namespace WebCore #endif // JSEventListener_h diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSEventSourceCustom.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSEventSourceCustom.cpp index 8f0dfb1..dab3285 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSEventSourceCustom.cpp +++ b/src/3rdparty/webkit/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/src/3rdparty/webkit/WebCore/bindings/js/JSGeolocationCustom.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSGeolocationCustom.cpp index 530b89b..8bc348c 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSGeolocationCustom.cpp +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSGeolocationCustom.cpp @@ -26,6 +26,8 @@ #include "config.h" #include "JSGeolocation.h" +#if ENABLE(GEOLOCATION) + #include "DOMWindow.h" #include "ExceptionCode.h" #include "Geolocation.h" @@ -178,3 +180,5 @@ JSValue JSGeolocation::watchPosition(ExecState* exec, const ArgList& args) } } // namespace WebCore + +#endif // ENABLE(GEOLOCATION) diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSHTMLAllCollectionCustom.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSHTMLAllCollectionCustom.cpp index fd1dd11..06b3ce4 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSHTMLAllCollectionCustom.cpp +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSHTMLAllCollectionCustom.cpp @@ -112,9 +112,9 @@ bool JSHTMLAllCollection::canGetItemsForName(ExecState*, HTMLAllCollection* coll return !namedItems.isEmpty(); } -JSValue JSHTMLAllCollection::nameGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot) +JSValue JSHTMLAllCollection::nameGetter(ExecState* exec, JSValue slotBase, const Identifier& propertyName) { - JSHTMLAllCollection* thisObj = static_cast<JSHTMLAllCollection*>(asObject(slot.slotBase())); + JSHTMLAllCollection* thisObj = static_cast<JSHTMLAllCollection*>(asObject(slotBase)); return getNamedItems(exec, thisObj, propertyName); } diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSHTMLAppletElementCustom.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSHTMLAppletElementCustom.cpp index 30892e0..40d20cf 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSHTMLAppletElementCustom.cpp +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSHTMLAppletElementCustom.cpp @@ -53,14 +53,4 @@ CallType JSHTMLAppletElement::getCallData(CallData& callData) return runtimeObjectGetCallData(impl(), callData); } -bool JSHTMLAppletElement::canGetItemsForName(ExecState*, HTMLAppletElement*, const Identifier& propertyName) -{ - return propertyName == "__apple_runtime_object"; -} - -JSValue JSHTMLAppletElement::nameGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot) -{ - return runtimeObjectGetter(exec, propertyName, slot); -} - } // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSHTMLCanvasElementCustom.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSHTMLCanvasElementCustom.cpp index 8ecd287..80634f7 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSHTMLCanvasElementCustom.cpp +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSHTMLCanvasElementCustom.cpp @@ -26,10 +26,12 @@ #include "config.h" #include "JSHTMLCanvasElement.h" +#include "CanvasContextAttributes.h" #include "HTMLCanvasElement.h" #include "JSCanvasRenderingContext2D.h" #if ENABLE(3D_CANVAS) -#include "JSCanvasRenderingContext3D.h" +#include "JSWebGLRenderingContext.h" +#include "WebGLContextAttributes.h" #endif #include <wtf/GetPtr.h> @@ -47,4 +49,36 @@ void JSHTMLCanvasElement::markChildren(MarkStack& markStack) markDOMObjectWrapper(markStack, globalData, canvas->renderingContext()); } +JSValue JSHTMLCanvasElement::getContext(ExecState* exec, const ArgList& args) +{ + HTMLCanvasElement* canvas = static_cast<HTMLCanvasElement*>(impl()); + const UString& contextId = args.at(0).toString(exec); + RefPtr<CanvasContextAttributes> attrs; +#if ENABLE(3D_CANVAS) + if (contextId == "experimental-webgl" || contextId == "webkit-3d") { + attrs = WebGLContextAttributes::create(); + WebGLContextAttributes* webGLAttrs = static_cast<WebGLContextAttributes*>(attrs.get()); + if (args.size() > 1 && args.at(1).isObject()) { + JSObject* jsAttrs = args.at(1).getObject(); + Identifier alpha(exec, "alpha"); + if (jsAttrs->hasProperty(exec, alpha)) + webGLAttrs->setAlpha(jsAttrs->get(exec, alpha).toBoolean(exec)); + Identifier depth(exec, "depth"); + if (jsAttrs->hasProperty(exec, depth)) + webGLAttrs->setDepth(jsAttrs->get(exec, depth).toBoolean(exec)); + Identifier stencil(exec, "stencil"); + if (jsAttrs->hasProperty(exec, stencil)) + webGLAttrs->setStencil(jsAttrs->get(exec, stencil).toBoolean(exec)); + Identifier antialias(exec, "antialias"); + if (jsAttrs->hasProperty(exec, antialias)) + webGLAttrs->setAntialias(jsAttrs->get(exec, antialias).toBoolean(exec)); + Identifier premultipliedAlpha(exec, "premultipliedAlpha"); + if (jsAttrs->hasProperty(exec, premultipliedAlpha)) + webGLAttrs->setPremultipliedAlpha(jsAttrs->get(exec, premultipliedAlpha).toBoolean(exec)); + } + } +#endif + return toJS(exec, globalObject(), WTF::getPtr(canvas->getContext(contextId, attrs.get()))); +} + } // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSHTMLCollectionCustom.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSHTMLCollectionCustom.cpp index dd4ceaa..73728ed 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSHTMLCollectionCustom.cpp +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSHTMLCollectionCustom.cpp @@ -109,9 +109,9 @@ bool JSHTMLCollection::canGetItemsForName(ExecState*, HTMLCollection* collection return !namedItems.isEmpty(); } -JSValue JSHTMLCollection::nameGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot) +JSValue JSHTMLCollection::nameGetter(ExecState* exec, JSValue slotBase, const Identifier& propertyName) { - JSHTMLCollection* thisObj = static_cast<JSHTMLCollection*>(asObject(slot.slotBase())); + JSHTMLCollection* thisObj = static_cast<JSHTMLCollection*>(asObject(slotBase)); return getNamedItems(exec, thisObj, propertyName); } @@ -134,7 +134,7 @@ JSValue toJS(ExecState* exec, JSDOMGlobalObject* globalObject, HTMLCollection* c if (!collection) return jsNull(); - DOMObject* wrapper = getCachedDOMObjectWrapper(exec->globalData(), collection); + DOMObject* wrapper = getCachedDOMObjectWrapper(exec, collection); if (wrapper) return wrapper; diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSHTMLDocumentCustom.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSHTMLDocumentCustom.cpp index a65ca7c..410c553 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSHTMLDocumentCustom.cpp +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSHTMLDocumentCustom.cpp @@ -55,9 +55,9 @@ bool JSHTMLDocument::canGetItemsForName(ExecState*, HTMLDocument* document, cons return atomicPropertyName && (document->hasNamedItem(atomicPropertyName) || document->hasExtraNamedItem(atomicPropertyName)); } -JSValue JSHTMLDocument::nameGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot) +JSValue JSHTMLDocument::nameGetter(ExecState* exec, JSValue slotBase, const Identifier& propertyName) { - JSHTMLDocument* thisObj = static_cast<JSHTMLDocument*>(asObject(slot.slotBase())); + JSHTMLDocument* thisObj = static_cast<JSHTMLDocument*>(asObject(slotBase)); HTMLDocument* document = static_cast<HTMLDocument*>(thisObj->impl()); String name = propertyName; @@ -113,7 +113,7 @@ JSValue JSHTMLDocument::open(ExecState* exec, const ArgList& args) CallType callType = function.getCallData(callData); if (callType == CallTypeNone) return throwError(exec, TypeError); - return callInWorld(exec, function, callType, callData, wrapper, args, currentWorld(exec)); + return JSC::call(exec, function, callType, callData, wrapper, args); } } return jsUndefined(); diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSHTMLEmbedElementCustom.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSHTMLEmbedElementCustom.cpp index bce3ffb..b9f8c12 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSHTMLEmbedElementCustom.cpp +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSHTMLEmbedElementCustom.cpp @@ -53,14 +53,4 @@ CallType JSHTMLEmbedElement::getCallData(CallData& callData) return runtimeObjectGetCallData(impl(), callData); } -bool JSHTMLEmbedElement::canGetItemsForName(ExecState*, HTMLEmbedElement*, const Identifier& propertyName) -{ - return propertyName == "__apple_runtime_object"; -} - -JSValue JSHTMLEmbedElement::nameGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot) -{ - return runtimeObjectGetter(exec, propertyName, slot); -} - } // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSHTMLFormElementCustom.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSHTMLFormElementCustom.cpp index de9ec4a..36ddfb1 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSHTMLFormElementCustom.cpp +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSHTMLFormElementCustom.cpp @@ -44,9 +44,9 @@ bool JSHTMLFormElement::canGetItemsForName(ExecState*, HTMLFormElement* form, co return namedItems.size(); } -JSValue JSHTMLFormElement::nameGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot) +JSValue JSHTMLFormElement::nameGetter(ExecState* exec, JSValue slotBase, const Identifier& propertyName) { - JSHTMLElement* jsForm = static_cast<JSHTMLFormElement*>(asObject(slot.slotBase())); + JSHTMLElement* jsForm = static_cast<JSHTMLFormElement*>(asObject(slotBase)); HTMLFormElement* form = static_cast<HTMLFormElement*>(jsForm->impl()); Vector<RefPtr<Node> > namedItems; @@ -66,7 +66,7 @@ JSValue JSHTMLFormElement::submit(ExecState* exec, const ArgList&) Frame* activeFrame = asJSDOMWindow(exec->dynamicGlobalObject())->impl()->frame(); if (!activeFrame) return jsUndefined(); - static_cast<HTMLFormElement*>(impl())->submit(0, false, !activeFrame->script()->anyPageIsProcessingUserGesture()); + static_cast<HTMLFormElement*>(impl())->submit(activeFrame); return jsUndefined(); } diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSHTMLFrameSetElementCustom.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSHTMLFrameSetElementCustom.cpp index 68769d6..484c357 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSHTMLFrameSetElementCustom.cpp +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSHTMLFrameSetElementCustom.cpp @@ -47,9 +47,9 @@ bool JSHTMLFrameSetElement::canGetItemsForName(ExecState*, HTMLFrameSetElement* return frame && frame->hasTagName(frameTag); } -JSValue JSHTMLFrameSetElement::nameGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot) +JSValue JSHTMLFrameSetElement::nameGetter(ExecState* exec, JSValue slotBase, const Identifier& propertyName) { - JSHTMLElement* thisObj = static_cast<JSHTMLElement*>(asObject(slot.slotBase())); + JSHTMLElement* thisObj = static_cast<JSHTMLElement*>(asObject(slotBase)); HTMLElement* element = static_cast<HTMLElement*>(thisObj->impl()); Node* frame = element->children()->namedItem(propertyName); diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSHTMLObjectElementCustom.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSHTMLObjectElementCustom.cpp index 1bfb51f..68c9e59 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSHTMLObjectElementCustom.cpp +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSHTMLObjectElementCustom.cpp @@ -53,14 +53,4 @@ CallType JSHTMLObjectElement::getCallData(CallData& callData) return runtimeObjectGetCallData(impl(), callData); } -bool JSHTMLObjectElement::canGetItemsForName(ExecState*, HTMLObjectElement*, const Identifier& propertyName) -{ - return propertyName == "__apple_runtime_object"; -} - -JSValue JSHTMLObjectElement::nameGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot) -{ - return runtimeObjectGetter(exec, propertyName, slot); -} - } // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSHistoryCustom.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSHistoryCustom.cpp index b24b1ff..c031b30 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSHistoryCustom.cpp +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSHistoryCustom.cpp @@ -38,17 +38,17 @@ using namespace JSC; namespace WebCore { -static JSValue nonCachingStaticBackFunctionGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot&) +static JSValue nonCachingStaticBackFunctionGetter(ExecState* exec, JSValue, const Identifier& propertyName) { return new (exec) NativeFunctionWrapper(exec, exec->lexicalGlobalObject()->prototypeFunctionStructure(), 0, propertyName, jsHistoryPrototypeFunctionBack); } -static JSValue nonCachingStaticForwardFunctionGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot&) +static JSValue nonCachingStaticForwardFunctionGetter(ExecState* exec, JSValue, const Identifier& propertyName) { return new (exec) NativeFunctionWrapper(exec, exec->lexicalGlobalObject()->prototypeFunctionStructure(), 0, propertyName, jsHistoryPrototypeFunctionForward); } -static JSValue nonCachingStaticGoFunctionGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot&) +static JSValue nonCachingStaticGoFunctionGetter(ExecState* exec, JSValue, const Identifier& propertyName) { return new (exec) NativeFunctionWrapper(exec, exec->lexicalGlobalObject()->prototypeFunctionStructure(), 1, propertyName, jsHistoryPrototypeFunctionGo); } @@ -95,15 +95,15 @@ bool JSHistory::getOwnPropertySlotDelegate(ExecState* exec, const Identifier& pr bool JSHistory::getOwnPropertyDescriptorDelegate(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor) { - // When accessing History cross-domain, functions are always the native built-in ones. - // See JSDOMWindow::getOwnPropertySlotDelegate for additional details. - - // Our custom code is only needed to implement the Window cross-domain scheme, so if access is - // allowed, return false so the normal lookup will take place. - String message; - if (allowsAccessFromFrame(exec, impl()->frame(), message)) - return false; - + if (!impl()->frame()) { + descriptor.setUndefined(); + return true; + } + + // Throw out all cross domain access + if (!allowsAccessFromFrame(exec, impl()->frame())) + return true; + // Check for the few functions that we allow, even when called cross-domain. const HashEntry* entry = JSHistoryPrototype::s_info.propHashTable(exec)->entry(exec, propertyName); if (entry) { @@ -133,8 +133,7 @@ bool JSHistory::getOwnPropertyDescriptorDelegate(ExecState* exec, const Identifi return true; } } - - printErrorMessageForFrame(impl()->frame(), message); + descriptor.setUndefined(); return true; } @@ -155,12 +154,60 @@ bool JSHistory::deleteProperty(ExecState* exec, const Identifier& propertyName) return Base::deleteProperty(exec, propertyName); } -void JSHistory::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames) +void JSHistory::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode) { // Only allow the history object to enumerated by frames in the same origin. if (!allowsAccessFromFrame(exec, impl()->frame())) return; - Base::getOwnPropertyNames(exec, propertyNames); + Base::getOwnPropertyNames(exec, propertyNames, mode); +} + +JSValue JSHistory::pushState(ExecState* exec, const ArgList& args) +{ + RefPtr<SerializedScriptValue> historyState = SerializedScriptValue::create(exec, args.at(0)); + if (exec->hadException()) + return jsUndefined(); + + String title = valueToStringWithUndefinedOrNullCheck(exec, args.at(1)); + if (exec->hadException()) + return jsUndefined(); + + String url; + if (args.size() > 2) { + url = valueToStringWithUndefinedOrNullCheck(exec, args.at(2)); + if (exec->hadException()) + return jsUndefined(); + } + + ExceptionCode ec = 0; + impl()->stateObjectAdded(historyState.release(), title, url, History::StateObjectPush, ec); + setDOMException(exec, ec); + + return jsUndefined(); +} + +JSValue JSHistory::replaceState(ExecState* exec, const ArgList& args) +{ + RefPtr<SerializedScriptValue> historyState = SerializedScriptValue::create(exec, args.at(0)); + if (exec->hadException()) + return jsUndefined(); + + String title = valueToStringWithUndefinedOrNullCheck(exec, args.at(1)); + if (exec->hadException()) + return jsUndefined(); + + String url; + if (args.size() > 2) { + url = valueToStringWithUndefinedOrNullCheck(exec, args.at(2)); + if (exec->hadException()) + return jsUndefined(); + } + + ExceptionCode ec = 0; + impl()->stateObjectAdded(historyState.release(), title, url, History::StateObjectReplace, ec); + setDOMException(exec, ec); + + return jsUndefined(); } } // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSImageConstructor.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSImageConstructor.cpp index 0f4a991..a574326 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSImageConstructor.cpp +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSImageConstructor.cpp @@ -1,6 +1,6 @@ /* * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) - * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2010 Apple Inc. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -24,7 +24,6 @@ #include "HTMLNames.h" #include "JSHTMLImageElement.h" #include "JSNode.h" -#include "ScriptExecutionContext.h" #include <runtime/Error.h> using namespace JSC; @@ -43,35 +42,30 @@ JSImageConstructor::JSImageConstructor(ExecState* exec, JSDOMGlobalObject* globa static JSObject* constructImage(ExecState* exec, JSObject* constructor, const ArgList& args) { - bool widthSet = false; - bool heightSet = false; - int width = 0; - int height = 0; - if (args.size() > 0) { - widthSet = true; - width = args.at(0).toInt32(exec); - } - if (args.size() > 1) { - heightSet = true; - height = args.at(1).toInt32(exec); - } - JSImageConstructor* jsConstructor = static_cast<JSImageConstructor*>(constructor); Document* document = jsConstructor->document(); if (!document) return throwError(exec, ReferenceError, "Image constructor associated document is unavailable"); // Calling toJS on the document causes the JS document wrapper to be - // added to the window object. This is done to ensure that JSDocument::mark - // will be called (which will cause the image element to be marked if necessary). + // added to the window object. This is done to ensure that JSDocument::markChildren + // will be called, which will cause the image element to be marked if necessary. toJS(exec, jsConstructor->globalObject(), document); + int width; + int height; + int* optionalWidth = 0; + int* optionalHeight = 0; + if (args.size() > 0) { + width = args.at(0).toInt32(exec); + optionalWidth = &width; + } + if (args.size() > 1) { + height = args.at(1).toInt32(exec); + optionalHeight = &height; + } - RefPtr<HTMLImageElement> image = new HTMLImageElement(HTMLNames::imgTag, document); - if (widthSet) - image->setWidth(width); - if (heightSet) - image->setHeight(height); - return asObject(toJS(exec, jsConstructor->globalObject(), image.release())); + return asObject(toJS(exec, jsConstructor->globalObject(), + HTMLImageElement::createForJSConstructor(document, optionalWidth, optionalHeight))); } ConstructType JSImageConstructor::getConstructData(ConstructData& constructData) diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSImageDataCustom.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSImageDataCustom.cpp index fa3b1d5..61c5112 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSImageDataCustom.cpp +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSImageDataCustom.cpp @@ -41,7 +41,7 @@ JSValue toJS(ExecState* exec, JSDOMGlobalObject* globalObject, ImageData* imageD if (!imageData) return jsNull(); - DOMObject* wrapper = getCachedDOMObjectWrapper(exec->globalData(), imageData); + DOMObject* wrapper = getCachedDOMObjectWrapper(exec, imageData); if (wrapper) return wrapper; diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSInjectedScriptHostCustom.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSInjectedScriptHostCustom.cpp new file mode 100644 index 0000000..75597fb --- /dev/null +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSInjectedScriptHostCustom.cpp @@ -0,0 +1,234 @@ +/* + * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2008 Matt Lilek <webkit@mattlilek.com> + * 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: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "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 THE COPYRIGHT + * OWNER 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" +#include "JSInjectedScriptHost.h" + +#if ENABLE(INSPECTOR) + +#include "Console.h" +#if ENABLE(DATABASE) +#include "Database.h" +#include "JSDatabase.h" +#endif +#include "ExceptionCode.h" +#include "Frame.h" +#include "FrameLoader.h" +#include "InjectedScript.h" +#include "InjectedScriptHost.h" +#include "InspectorController.h" +#include "InspectorResource.h" +#include "JSDOMWindow.h" +#include "JSNode.h" +#include "JSRange.h" +#include "Node.h" +#include "Page.h" +#if ENABLE(DOM_STORAGE) +#include "SerializedScriptValue.h" +#include "Storage.h" +#include "JSStorage.h" +#endif +#include "TextIterator.h" +#include "VisiblePosition.h" +#include <parser/SourceCode.h> +#include <runtime/JSArray.h> +#include <runtime/JSLock.h> +#include <wtf/RefPtr.h> +#include <wtf/Vector.h> + +#if ENABLE(JAVASCRIPT_DEBUGGER) +#include "JavaScriptCallFrame.h" +#include "JSJavaScriptCallFrame.h" +#include "ScriptDebugServer.h" +#endif + +using namespace JSC; + +namespace WebCore { + +ScriptObject InjectedScriptHost::createInjectedScript(const String& source, ScriptState* scriptState, long id) +{ + SourceCode sourceCode = makeSource(source); + JSLock lock(SilenceAssertionsOnly); + JSDOMGlobalObject* globalObject = static_cast<JSDOMGlobalObject*>(scriptState->lexicalGlobalObject()); + JSValue globalThisValue = scriptState->globalThisValue(); + Completion comp = JSC::evaluate(scriptState, globalObject->globalScopeChain(), sourceCode, globalThisValue); + if (comp.complType() != JSC::Normal && comp.complType() != JSC::ReturnValue) + return ScriptObject(); + JSValue functionValue = comp.value(); + CallData callData; + CallType callType = functionValue.getCallData(callData); + if (callType == CallTypeNone) + return ScriptObject(); + + MarkedArgumentBuffer args; + args.append(toJS(scriptState, globalObject, this)); + args.append(globalThisValue); + args.append(jsNumber(scriptState, id)); + JSValue result = JSC::call(scriptState, functionValue, callType, callData, globalThisValue, args); + if (result.isObject()) + return ScriptObject(scriptState, result.getObject()); + return ScriptObject(); +} + +#if ENABLE(DATABASE) +JSValue JSInjectedScriptHost::databaseForId(ExecState* exec, const ArgList& args) +{ + if (args.size() < 1) + return jsUndefined(); + + InspectorController* ic = impl()->inspectorController(); + if (!ic) + return jsUndefined(); + + Database* database = impl()->databaseForId(args.at(0).toInt32(exec)); + if (!database) + return jsUndefined(); + return toJS(exec, database); +} +#endif + +#if ENABLE(JAVASCRIPT_DEBUGGER) +JSValue JSInjectedScriptHost::currentCallFrame(ExecState* exec, const ArgList&) +{ + JavaScriptCallFrame* callFrame = ScriptDebugServer::shared().currentCallFrame(); + if (!callFrame || !callFrame->isValid()) + return jsUndefined(); + + JSLock lock(SilenceAssertionsOnly); + return toJS(exec, callFrame); +} + +JSValue JSInjectedScriptHost::isActivation(ExecState*, const ArgList& args) +{ + JSObject* object = args.at(0).getObject(); + return jsBoolean(object && object->isActivationObject()); +} +#endif + +JSValue JSInjectedScriptHost::nodeForId(ExecState* exec, const ArgList& args) +{ + if (args.size() < 1) + return jsUndefined(); + + Node* node = impl()->nodeForId(args.at(0).toInt32(exec)); + if (!node) + return jsUndefined(); + + InspectorController* ic = impl()->inspectorController(); + if (!ic) + return jsUndefined(); + + JSLock lock(SilenceAssertionsOnly); + return toJS(exec, node); +} + +JSValue JSInjectedScriptHost::pushNodePathToFrontend(ExecState* exec, const ArgList& args) +{ + if (args.size() < 3) + return jsUndefined(); + + Node* node = toNode(args.at(0)); + if (!node) + return jsUndefined(); + + bool withChildren = args.at(1).toBoolean(exec); + bool selectInUI = args.at(2).toBoolean(exec); + return jsNumber(exec, impl()->pushNodePathToFrontend(node, withChildren, selectInUI)); +} + +#if ENABLE(DATABASE) +JSValue JSInjectedScriptHost::selectDatabase(ExecState*, const ArgList& args) +{ + if (args.size() < 1) + return jsUndefined(); + + Database* database = toDatabase(args.at(0)); + if (database) + impl()->selectDatabase(database); + return jsUndefined(); +} +#endif + +#if ENABLE(DOM_STORAGE) +JSValue JSInjectedScriptHost::selectDOMStorage(ExecState*, const ArgList& args) +{ + if (args.size() < 1) + return jsUndefined(); + InspectorController* ic = impl()->inspectorController(); + if (!ic) + return jsUndefined(); + + Storage* storage = toStorage(args.at(0)); + if (storage) + impl()->selectDOMStorage(storage); + return jsUndefined(); +} +#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); + JSDOMGlobalObject* globalObject = static_cast<JSDOMGlobalObject*>(scriptState->lexicalGlobalObject()); + JSObject* injectedScript = globalObject->injectedScript(); + if (injectedScript) + return InjectedScript(ScriptObject(scriptState, injectedScript)); + + ASSERT(!m_injectedScriptSource.isEmpty()); + pair<long, ScriptObject> injectedScriptObject = injectScript(m_injectedScriptSource, scriptState); + globalObject->setInjectedScript(injectedScriptObject.second.jsObject()); + InjectedScript result(injectedScriptObject.second); + m_idToInjectedScript.set(injectedScriptObject.first, result); + return result; +} + +} // namespace WebCore + +#endif // ENABLE(INSPECTOR) diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSInspectedObjectWrapper.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSInspectedObjectWrapper.cpp deleted file mode 100644 index ed79427..0000000 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSInspectedObjectWrapper.cpp +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Copyright (C) 2008 Apple 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 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 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" -#include "JSInspectedObjectWrapper.h" - -#if ENABLE(INSPECTOR) - -#include "JSInspectorCallbackWrapper.h" -#include <runtime/JSGlobalObject.h> -#include <wtf/StdLibExtras.h> - -using namespace JSC; - -namespace WebCore { - -ASSERT_CLASS_FITS_IN_CELL(JSInspectedObjectWrapper); - -typedef HashMap<JSObject*, JSInspectedObjectWrapper*> WrapperMap; -typedef HashMap<JSGlobalObject*, WrapperMap*> GlobalObjectWrapperMap; - -static GlobalObjectWrapperMap& wrappers() -{ - DEFINE_STATIC_LOCAL(GlobalObjectWrapperMap, map, ()); - return map; -} - -const ClassInfo JSInspectedObjectWrapper::s_info = { "JSInspectedObjectWrapper", &JSQuarantinedObjectWrapper::s_info, 0, 0 }; - -JSValue JSInspectedObjectWrapper::wrap(ExecState* unwrappedExec, JSValue unwrappedValue) -{ - if (!unwrappedValue.isObject()) - return unwrappedValue; - - JSObject* unwrappedObject = asObject(unwrappedValue); - - if (unwrappedObject->inherits(&JSInspectedObjectWrapper::s_info)) - return unwrappedObject; - - if (WrapperMap* wrapperMap = wrappers().get(unwrappedExec->lexicalGlobalObject())) - if (JSInspectedObjectWrapper* wrapper = wrapperMap->get(unwrappedObject)) - return wrapper; - - JSValue prototype = unwrappedObject->prototype(); - ASSERT(prototype.isNull() || prototype.isObject()); - - if (prototype.isNull()) - return new (unwrappedExec) JSInspectedObjectWrapper(unwrappedExec, unwrappedObject, JSQuarantinedObjectWrapper::createStructure(jsNull())); - return new (unwrappedExec) JSInspectedObjectWrapper(unwrappedExec, unwrappedObject, JSQuarantinedObjectWrapper::createStructure(asObject(wrap(unwrappedExec, prototype)))); -} - -JSInspectedObjectWrapper::JSInspectedObjectWrapper(ExecState* unwrappedExec, JSObject* unwrappedObject, NonNullPassRefPtr<Structure> structure) - : JSQuarantinedObjectWrapper(unwrappedExec, unwrappedObject, structure) -{ - WrapperMap* wrapperMap = wrappers().get(unwrappedGlobalObject()); - if (!wrapperMap) { - wrapperMap = new WrapperMap; - wrappers().set(unwrappedGlobalObject(), wrapperMap); - } - - ASSERT(!wrapperMap->contains(unwrappedObject)); - wrapperMap->set(unwrappedObject, this); -} - -JSInspectedObjectWrapper::~JSInspectedObjectWrapper() -{ - ASSERT(wrappers().contains(unwrappedGlobalObject())); - WrapperMap* wrapperMap = wrappers().get(unwrappedGlobalObject()); - - ASSERT(wrapperMap->contains(unwrappedObject())); - wrapperMap->remove(unwrappedObject()); - - if (wrapperMap->isEmpty()) { - wrappers().remove(unwrappedGlobalObject()); - delete wrapperMap; - } -} - -JSValue JSInspectedObjectWrapper::prepareIncomingValue(ExecState*, JSValue value) const -{ - // The Inspector is only allowed to pass primitive values and wrapped objects to objects from the inspected page. - - if (!value.isObject()) - return value; - - JSQuarantinedObjectWrapper* wrapper = asWrapper(value); - ASSERT_WITH_MESSAGE(wrapper, "Objects passed to JSInspectedObjectWrapper must be wrapped"); - if (!wrapper) - return jsUndefined(); - - if (wrapper->allowsUnwrappedAccessFrom(unwrappedExecState())) { - ASSERT_WITH_MESSAGE(wrapper->inherits(&s_info), "A wrapper contains an object from the inspected page but is not a JSInspectedObjectWrapper"); - if (!wrapper->inherits(&s_info)) - return jsUndefined(); - - // Return the unwrapped object so the inspected page never sees one of its own objects in wrapped form. - return wrapper->unwrappedObject(); - } - - ASSERT_WITH_MESSAGE(wrapper->inherits(&JSInspectorCallbackWrapper::s_info), "A wrapper that was not from the inspected page and is not an Inspector callback was passed to a JSInspectedObjectWrapper"); - if (!wrapper->inherits(&JSInspectorCallbackWrapper::s_info)) - return jsUndefined(); - - return wrapper; -} - -} // namespace WebCore - -#endif // ENABLE(INSPECTOR) diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSInspectedObjectWrapper.h b/src/3rdparty/webkit/WebCore/bindings/js/JSInspectedObjectWrapper.h deleted file mode 100644 index ad97035..0000000 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSInspectedObjectWrapper.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (C) 2008 Apple 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 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 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 JSInspectedObjectWrapper_h -#define JSInspectedObjectWrapper_h - -#include "JSQuarantinedObjectWrapper.h" - -namespace WebCore { - - class JSInspectedObjectWrapper : public JSQuarantinedObjectWrapper { - public: - static JSC::JSValue wrap(JSC::ExecState* unwrappedExec, JSC::JSValue unwrappedValue); - virtual ~JSInspectedObjectWrapper(); - - static const JSC::ClassInfo s_info; - - private: - JSInspectedObjectWrapper(JSC::ExecState* unwrappedExec, JSC::JSObject* unwrappedObject, NonNullPassRefPtr<JSC::Structure>); - - virtual bool allowsGetProperty() const { return true; } - virtual bool allowsSetProperty() const { return true; } - virtual bool allowsDeleteProperty() const { return true; } - virtual bool allowsConstruct() const { return true; } - virtual bool allowsHasInstance() const { return true; } - virtual bool allowsCallAsFunction() const { return true; } - virtual bool allowsGetPropertyNames() const { return true; } - - virtual JSC::JSValue prepareIncomingValue(JSC::ExecState* unwrappedExec, JSC::JSValue unwrappedValue) const; - virtual JSC::JSValue wrapOutgoingValue(JSC::ExecState* unwrappedExec, JSC::JSValue unwrappedValue) const { return wrap(unwrappedExec, unwrappedValue); } - - virtual const JSC::ClassInfo* classInfo() const { return &s_info; } - }; - -} // namespace WebCore - -#endif // JSInspectedObjectWrapper_h diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSInspectorBackendCustom.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSInspectorBackendCustom.cpp deleted file mode 100644 index 439f532..0000000 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSInspectorBackendCustom.cpp +++ /dev/null @@ -1,346 +0,0 @@ -/* - * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. - * Copyright (C) 2008 Matt Lilek <webkit@mattlilek.com> - * Copyright (C) 2009 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: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * 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. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "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 THE COPYRIGHT - * OWNER 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" -#include "JSInspectorBackend.h" - -#if ENABLE(INSPECTOR) - -#include "Console.h" -#if ENABLE(DATABASE) -#include "Database.h" -#include "JSDatabase.h" -#endif -#include "ExceptionCode.h" -#include "Frame.h" -#include "FrameLoader.h" -#include "InspectorBackend.h" -#include "InspectorController.h" -#include "InspectorResource.h" -#include "JSDOMWindow.h" -#include "JSInspectedObjectWrapper.h" -#include "JSInspectorCallbackWrapper.h" -#include "JSNode.h" -#include "JSRange.h" -#include "Node.h" -#include "Page.h" -#if ENABLE(DOM_STORAGE) -#include "Storage.h" -#include "JSStorage.h" -#endif -#include "TextIterator.h" -#include "VisiblePosition.h" -#include <runtime/JSArray.h> -#include <runtime/JSLock.h> -#include <wtf/Vector.h> - -#if ENABLE(JAVASCRIPT_DEBUGGER) -#include "JavaScriptCallFrame.h" -#include "JavaScriptDebugServer.h" -#include "JSJavaScriptCallFrame.h" -#endif - -using namespace JSC; - -namespace WebCore { - -JSValue JSInspectorBackend::highlightDOMNode(JSC::ExecState* exec, const JSC::ArgList& args) -{ - if (args.size() < 1) - return jsUndefined(); - - impl()->highlight(args.at(0).toInt32(exec)); - return jsUndefined(); -} - -JSValue JSInspectorBackend::search(ExecState* exec, const ArgList& args) -{ - if (args.size() < 2) - return jsUndefined(); - - Node* node = toNode(args.at(0)); - if (!node) - return jsUndefined(); - - String target = args.at(1).toString(exec); - if (exec->hadException()) - return jsUndefined(); - - MarkedArgumentBuffer result; - RefPtr<Range> searchRange(rangeOfContents(node)); - - ExceptionCode ec = 0; - do { - RefPtr<Range> resultRange(findPlainText(searchRange.get(), target, true, false)); - if (resultRange->collapsed(ec)) - break; - - // A non-collapsed result range can in some funky whitespace cases still not - // advance the range's start position (4509328). Break to avoid infinite loop. - VisiblePosition newStart = endVisiblePosition(resultRange.get(), DOWNSTREAM); - if (newStart == startVisiblePosition(searchRange.get(), DOWNSTREAM)) - break; - - result.append(toJS(exec, resultRange.get())); - - setStart(searchRange.get(), newStart); - } while (true); - - return constructArray(exec, result); -} - -#if ENABLE(DATABASE) -JSValue JSInspectorBackend::databaseForId(ExecState* exec, const ArgList& args) -{ - if (args.size() < 1) - return jsUndefined(); - - InspectorController* ic = impl()->inspectorController(); - if (!ic) - return jsUndefined(); - - Database* database = impl()->databaseForId(args.at(0).toInt32(exec)); - if (!database) - return jsUndefined(); - // Could use currentWorld(exec) ... but which exec! The following mixed use of exec & inspectedWindow->globalExec() scares me! - JSDOMWindow* inspectedWindow = toJSDOMWindow(ic->inspectedPage()->mainFrame(), debuggerWorld()); - return JSInspectedObjectWrapper::wrap(inspectedWindow->globalExec(), toJS(exec, database)); -} -#endif - -JSValue JSInspectorBackend::inspectedWindow(ExecState*, const ArgList&) -{ - InspectorController* ic = impl()->inspectorController(); - if (!ic) - return jsUndefined(); - JSDOMWindow* inspectedWindow = toJSDOMWindow(ic->inspectedPage()->mainFrame(), debuggerWorld()); - return JSInspectedObjectWrapper::wrap(inspectedWindow->globalExec(), inspectedWindow); -} - -JSValue JSInspectorBackend::setting(ExecState* exec, const ArgList& args) -{ - if (args.size() < 1) - return jsUndefined(); - - String key = args.at(0).toString(exec); - if (exec->hadException()) - return jsUndefined(); - - InspectorController* ic = impl()->inspectorController(); - if (!ic) - return jsUndefined(); - const InspectorController::Setting& setting = ic->setting(key); - - switch (setting.type()) { - default: - case InspectorController::Setting::NoType: - return jsUndefined(); - case InspectorController::Setting::StringType: - return jsString(exec, setting.string()); - case InspectorController::Setting::DoubleType: - return jsNumber(exec, setting.doubleValue()); - case InspectorController::Setting::IntegerType: - return jsNumber(exec, setting.integerValue()); - case InspectorController::Setting::BooleanType: - return jsBoolean(setting.booleanValue()); - case InspectorController::Setting::StringVectorType: { - MarkedArgumentBuffer stringsArray; - const Vector<String>& strings = setting.stringVector(); - const unsigned length = strings.size(); - for (unsigned i = 0; i < length; ++i) - stringsArray.append(jsString(exec, strings[i])); - return constructArray(exec, stringsArray); - } - } -} - -JSValue JSInspectorBackend::setSetting(ExecState* exec, const ArgList& args) -{ - if (args.size() < 2) - return jsUndefined(); - - String key = args.at(0).toString(exec); - if (exec->hadException()) - return jsUndefined(); - - InspectorController::Setting setting; - - JSValue value = args.at(1); - if (value.isUndefined() || value.isNull()) { - // Do nothing. The setting is already NoType. - ASSERT(setting.type() == InspectorController::Setting::NoType); - } else if (value.isString()) - setting.set(value.toString(exec)); - else if (value.isNumber()) - setting.set(value.toNumber(exec)); - else if (value.isBoolean()) - setting.set(value.toBoolean(exec)); - else { - JSArray* jsArray = asArray(value); - if (!jsArray) - return jsUndefined(); - Vector<String> strings; - for (unsigned i = 0; i < jsArray->length(); ++i) { - String item = jsArray->get(exec, i).toString(exec); - if (exec->hadException()) - return jsUndefined(); - strings.append(item); - } - setting.set(strings); - } - - if (exec->hadException()) - return jsUndefined(); - - InspectorController* ic = impl()->inspectorController(); - if (ic) - ic->setSetting(key, setting); - - return jsUndefined(); -} - -JSValue JSInspectorBackend::wrapCallback(ExecState* exec, const ArgList& args) -{ - if (args.size() < 1) - return jsUndefined(); - - return JSInspectorCallbackWrapper::wrap(exec, args.at(0)); -} - -#if ENABLE(JAVASCRIPT_DEBUGGER) - -JSValue JSInspectorBackend::currentCallFrame(ExecState* exec, const ArgList&) -{ - JavaScriptCallFrame* callFrame = impl()->currentCallFrame(); - if (!callFrame || !callFrame->isValid()) - return jsUndefined(); - - // FIXME: I am not sure if this is actually needed. Can we just use exec? - ExecState* globalExec = callFrame->scopeChain()->globalObject->globalExec(); - - JSLock lock(SilenceAssertionsOnly); - return JSInspectedObjectWrapper::wrap(globalExec, toJS(exec, callFrame)); -} - -#endif - -JSValue JSInspectorBackend::nodeForId(ExecState* exec, const ArgList& args) -{ - if (args.size() < 1) - return jsUndefined(); - - Node* node = impl()->nodeForId(args.at(0).toInt32(exec)); - if (!node) - return jsUndefined(); - - InspectorController* ic = impl()->inspectorController(); - if (!ic) - return jsUndefined(); - - JSLock lock(SilenceAssertionsOnly); - JSDOMWindow* inspectedWindow = toJSDOMWindow(ic->inspectedPage()->mainFrame(), debuggerWorld()); - return JSInspectedObjectWrapper::wrap(inspectedWindow->globalExec(), toJS(exec, deprecatedGlobalObjectForPrototype(inspectedWindow->globalExec()), node)); -} - -JSValue JSInspectorBackend::wrapObject(ExecState* exec, const ArgList& args) -{ - if (args.size() < 2) - return jsUndefined(); - - return impl()->wrapObject(ScriptValue(args.at(0)), args.at(1).toString(exec)).jsValue(); -} - -JSValue JSInspectorBackend::unwrapObject(ExecState* exec, const ArgList& args) -{ - if (args.size() < 1) - return jsUndefined(); - - return impl()->unwrapObject(args.at(0).toString(exec)).jsValue(); -} - -JSValue JSInspectorBackend::pushNodePathToFrontend(ExecState* exec, const ArgList& args) -{ - if (args.size() < 2) - return jsUndefined(); - - JSQuarantinedObjectWrapper* wrapper = JSQuarantinedObjectWrapper::asWrapper(args.at(0)); - if (!wrapper) - return jsUndefined(); - - Node* node = toNode(wrapper->unwrappedObject()); - if (!node) - return jsUndefined(); - - bool selectInUI = args.at(1).toBoolean(exec); - return jsNumber(exec, impl()->pushNodePathToFrontend(node, selectInUI)); -} - -#if ENABLE(DATABASE) -JSValue JSInspectorBackend::selectDatabase(ExecState*, const ArgList& args) -{ - if (args.size() < 1) - return jsUndefined(); - - JSQuarantinedObjectWrapper* wrapper = JSQuarantinedObjectWrapper::asWrapper(args.at(0)); - if (!wrapper) - return jsUndefined(); - - Database* database = toDatabase(wrapper->unwrappedObject()); - if (database) - impl()->selectDatabase(database); - return jsUndefined(); -} -#endif - -#if ENABLE(DOM_STORAGE) -JSValue JSInspectorBackend::selectDOMStorage(ExecState*, const ArgList& args) -{ - if (args.size() < 1) - return jsUndefined(); - InspectorController* ic = impl()->inspectorController(); - if (!ic) - return jsUndefined(); - - JSQuarantinedObjectWrapper* wrapper = JSQuarantinedObjectWrapper::asWrapper(args.at(0)); - if (!wrapper) - return jsUndefined(); - - Storage* storage = toStorage(wrapper->unwrappedObject()); - if (storage) - impl()->selectDOMStorage(storage); - return jsUndefined(); -} -#endif - -} // namespace WebCore - -#endif // ENABLE(INSPECTOR) diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSInspectorCallbackWrapper.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSInspectorCallbackWrapper.cpp deleted file mode 100644 index 9c4330d..0000000 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSInspectorCallbackWrapper.cpp +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright (C) 2008 Apple 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 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 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" -#include "JSInspectorCallbackWrapper.h" - -#if ENABLE(INSPECTOR) - -#include "JSInspectedObjectWrapper.h" -#include <wtf/StdLibExtras.h> - -using namespace JSC; - -namespace WebCore { - -ASSERT_CLASS_FITS_IN_CELL(JSInspectorCallbackWrapper); - -typedef HashMap<JSObject*, JSInspectorCallbackWrapper*> WrapperMap; - -static WrapperMap& wrappers() -{ - DEFINE_STATIC_LOCAL(WrapperMap, map, ()); - return map; -} - -const ClassInfo JSInspectorCallbackWrapper::s_info = { "JSInspectorCallbackWrapper", &JSQuarantinedObjectWrapper::s_info, 0, 0 }; - -static Structure* leakInspectorCallbackWrapperStructure() -{ - Structure::startIgnoringLeaks(); - Structure* structure = JSInspectorCallbackWrapper::createStructure(jsNull()).releaseRef(); - Structure::stopIgnoringLeaks(); - return structure; -} - -JSValue JSInspectorCallbackWrapper::wrap(ExecState* unwrappedExec, JSValue unwrappedValue) -{ - if (!unwrappedValue.isObject()) - return unwrappedValue; - - JSObject* unwrappedObject = asObject(unwrappedValue); - - if (unwrappedObject->inherits(&JSInspectorCallbackWrapper::s_info)) - return unwrappedObject; - - if (JSInspectorCallbackWrapper* wrapper = wrappers().get(unwrappedObject)) - return wrapper; - - JSValue prototype = unwrappedObject->prototype(); - ASSERT(prototype.isNull() || prototype.isObject()); - - if (prototype.isNull()) { - static Structure* structure = leakInspectorCallbackWrapperStructure(); - return new (unwrappedExec) JSInspectorCallbackWrapper(unwrappedExec, unwrappedObject, structure); - } - return new (unwrappedExec) JSInspectorCallbackWrapper(unwrappedExec, unwrappedObject, createStructure(wrap(unwrappedExec, prototype))); -} - -JSInspectorCallbackWrapper::JSInspectorCallbackWrapper(ExecState* unwrappedExec, JSObject* unwrappedObject, NonNullPassRefPtr<Structure> structure) - : JSQuarantinedObjectWrapper(unwrappedExec, unwrappedObject, structure) -{ - ASSERT(!wrappers().contains(unwrappedObject)); - wrappers().set(unwrappedObject, this); -} - -JSInspectorCallbackWrapper::~JSInspectorCallbackWrapper() -{ - wrappers().remove(unwrappedObject()); -} - -JSValue JSInspectorCallbackWrapper::prepareIncomingValue(ExecState* unwrappedExec, JSValue unwrappedValue) const -{ - if (JSQuarantinedObjectWrapper* wrapper = asWrapper(unwrappedValue)) { - // The only time a wrapper should be passed into a JSInspectorCallbackWrapper is when a client-side storage callback - // is called. (The client-side storage API calls the callback with the `this` object set to the callback itself.) - ASSERT_WITH_MESSAGE(wrapper == this, "A different wrapper was passed into a JSInspectorCallbackWrapper"); - if (wrapper != this) - return jsUndefined(); - - return wrapper->unwrappedObject(); - } - - // Any value being passed to the Inspector from the inspected page should be wrapped in a JSInspectedObjectWrapper. - return JSInspectedObjectWrapper::wrap(unwrappedExec, unwrappedValue); -} - -} // namespace WebCore - -#endif // ENABLE(INSPECTOR) diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSInspectorCallbackWrapper.h b/src/3rdparty/webkit/WebCore/bindings/js/JSInspectorCallbackWrapper.h deleted file mode 100644 index be28063..0000000 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSInspectorCallbackWrapper.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (C) 2008 Apple 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 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 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 JSInspectorCallbackWrapper_h -#define JSInspectorCallbackWrapper_h - -#include "JSQuarantinedObjectWrapper.h" - -namespace WebCore { - - class JSInspectorCallbackWrapper : public JSQuarantinedObjectWrapper { - public: - static JSC::JSValue wrap(JSC::ExecState* unwrappedExec, JSC::JSValue unwrappedValue); - - virtual ~JSInspectorCallbackWrapper(); - - virtual const JSC::ClassInfo* classInfo() const { return &s_info; } - static const JSC::ClassInfo s_info; - - protected: - JSInspectorCallbackWrapper(JSC::ExecState* unwrappedExec, JSC::JSObject* unwrappedObject, NonNullPassRefPtr<JSC::Structure>); - - virtual bool allowsCallAsFunction() const { return true; } - - virtual JSC::JSValue prepareIncomingValue(JSC::ExecState* unwrappedExec, JSC::JSValue unwrappedValue) const; - virtual JSC::JSValue wrapOutgoingValue(JSC::ExecState* unwrappedExec, JSC::JSValue unwrappedValue) const { return wrap(unwrappedExec, unwrappedValue); } - }; - -} // namespace WebCore - -#endif // JSInspectorCallbackWrapper_h diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSInspectorFrontendHostCustom.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSInspectorFrontendHostCustom.cpp new file mode 100644 index 0000000..7b06bac --- /dev/null +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSInspectorFrontendHostCustom.cpp @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2008 Matt Lilek <webkit@mattlilek.com> + * Copyright (C) 2009 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: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "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 THE COPYRIGHT + * OWNER 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" +#include "JSInspectorFrontendHost.h" + +#if ENABLE(INSPECTOR) + +#include "ContextMenuItem.h" +#include "InspectorController.h" +#include "InspectorFrontendHost.h" +#include "JSEvent.h" +#include "MouseEvent.h" +#include <runtime/JSArray.h> +#include <runtime/JSLock.h> +#include <runtime/JSObject.h> +#include <wtf/Vector.h> + +using namespace JSC; + +namespace WebCore { + +JSValue JSInspectorFrontendHost::showContextMenu(ExecState* execState, const ArgList& args) +{ + if (args.size() < 2) + return jsUndefined(); + + Event* event = toEvent(args.at(0)); + + JSArray* array = asArray(args.at(1)); + Vector<ContextMenuItem*> items; + + for (size_t i = 0; i < array->length(); ++i) { + JSObject* item = asObject(array->getIndex(i)); + JSValue label = item->get(execState, Identifier(execState, "label")); + JSValue id = item->get(execState, Identifier(execState, "id")); + if (label.isUndefined() || id.isUndefined()) + items.append(new ContextMenuItem(SeparatorType, ContextMenuItemTagNoAction, String())); + else { + ContextMenuAction typedId = static_cast<ContextMenuAction>(ContextMenuItemBaseCustomTag + id.toInt32(execState)); + items.append(new ContextMenuItem(ActionType, typedId, label.toString(execState))); + } + } + + impl()->showContextMenu(event, items); + return jsUndefined(); +} + +} // namespace WebCore + +#endif // ENABLE(INSPECTOR) diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSJavaScriptCallFrameCustom.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSJavaScriptCallFrameCustom.cpp index 08ecf2b..afbdf5d 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSJavaScriptCallFrameCustom.cpp +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSJavaScriptCallFrameCustom.cpp @@ -55,9 +55,9 @@ JSValue JSJavaScriptCallFrame::type(ExecState* exec) const { switch (impl()->type()) { case DebuggerCallFrame::FunctionType: - return jsString(exec, "function"); + return jsString(exec, UString("function")); case DebuggerCallFrame::ProgramType: - return jsString(exec, "program"); + return jsString(exec, UString("program")); } ASSERT_NOT_REACHED(); diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSLazyEventListener.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSLazyEventListener.cpp index 6d75f4f..cd1d267 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSLazyEventListener.cpp +++ b/src/3rdparty/webkit/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->isEnabled()) - return; + if (!scriptController->canExecuteScripts(AboutToExecuteScript)) + 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->isEnabled() || script->isPaused()) - return; + if (!script->canExecuteScripts(AboutToExecuteScript) || script->isPaused()) + 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/src/3rdparty/webkit/WebCore/bindings/js/JSLazyEventListener.h b/src/3rdparty/webkit/WebCore/bindings/js/JSLazyEventListener.h index ba26ef6..1b00b75 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSLazyEventListener.h +++ b/src/3rdparty/webkit/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/src/3rdparty/webkit/WebCore/bindings/js/JSLocationCustom.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSLocationCustom.cpp index c76a2b1..a3e2bae 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSLocationCustom.cpp +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSLocationCustom.cpp @@ -24,6 +24,7 @@ #include "JSLocationCustom.h" #include "DOMWindow.h" +#include "ExceptionCode.h" #include "Frame.h" #include "FrameLoader.h" #include "JSDOMBinding.h" @@ -38,17 +39,17 @@ using namespace JSC; namespace WebCore { -static JSValue nonCachingStaticReplaceFunctionGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot&) +static JSValue nonCachingStaticReplaceFunctionGetter(ExecState* exec, JSValue, const Identifier& propertyName) { return new (exec) NativeFunctionWrapper(exec, exec->lexicalGlobalObject()->prototypeFunctionStructure(), 1, propertyName, jsLocationPrototypeFunctionReplace); } -static JSValue nonCachingStaticReloadFunctionGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot&) +static JSValue nonCachingStaticReloadFunctionGetter(ExecState* exec, JSValue, const Identifier& propertyName) { return new (exec) NativeFunctionWrapper(exec, exec->lexicalGlobalObject()->prototypeFunctionStructure(), 0, propertyName, jsLocationPrototypeFunctionReload); } -static JSValue nonCachingStaticAssignFunctionGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot&) +static JSValue nonCachingStaticAssignFunctionGetter(ExecState* exec, JSValue, const Identifier& propertyName) { return new (exec) NativeFunctionWrapper(exec, exec->lexicalGlobalObject()->prototypeFunctionStructure(), 1, propertyName, jsLocationPrototypeFunctionAssign); } @@ -102,14 +103,9 @@ bool JSLocation::getOwnPropertyDescriptorDelegate(ExecState* exec, const Identif return true; } - // When accessing Location cross-domain, functions are always the native built-in ones. - // See JSDOMWindow::getOwnPropertySlotDelegate for additional details. - - // Our custom code is only needed to implement the Window cross-domain scheme, so if access is - // allowed, return false so the normal lookup will take place. - String message; - if (allowsAccessFromFrame(exec, frame, message)) - return false; + // throw out all cross domain access + if (!allowsAccessFromFrame(exec, frame)) + return true; // Check for the few functions that we allow, even when called cross-domain. const HashEntry* entry = JSLocationPrototype::s_info.propHashTable(exec)->entry(exec, propertyName); @@ -133,8 +129,7 @@ bool JSLocation::getOwnPropertyDescriptorDelegate(ExecState* exec, const Identif // FIXME: Other implementers of the Window cross-domain scheme (Window, History) allow toString, // but for now we have decided not to, partly because it seems silly to return "[Object Location]" in // such cases when normally the string form of Location would be the URL. - - printErrorMessageForFrame(frame, message); + descriptor.setUndefined(); return true; } @@ -174,12 +169,12 @@ bool JSLocation::deleteProperty(ExecState* exec, const Identifier& propertyName) return Base::deleteProperty(exec, propertyName); } -void JSLocation::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames) +void JSLocation::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode) { // Only allow the location object to enumerated by frames in the same origin. if (!allowsAccessFromFrame(exec, impl()->frame())) return; - Base::getOwnPropertyNames(exec, propertyNames); + Base::getOwnPropertyNames(exec, propertyNames, mode); } void JSLocation::defineGetter(ExecState* exec, const Identifier& propertyName, JSObject* getterFunction, unsigned attributes) @@ -220,7 +215,10 @@ void JSLocation::setProtocol(ExecState* exec, JSValue value) ASSERT(frame); KURL url = frame->loader()->url(); - url.setProtocol(value.toString(exec)); + if (!url.setProtocol(value.toString(exec))) { + setDOMException(exec, SYNTAX_ERR); + return; + } navigateIfAllowed(exec, frame, url, !frame->script()->anyPageIsProcessingUserGesture(), false); } @@ -257,8 +255,9 @@ void JSLocation::setPort(ExecState* exec, JSValue value) const UString& portString = value.toString(exec); int port = charactersToInt(portString.data(), portString.size()); if (port < 0 || port > 0xFFFF) - port = 0; - url.setPort(port); + url.removePort(); + else + url.setPort(port); navigateIfAllowed(exec, frame, url, !frame->script()->anyPageIsProcessingUserGesture(), false); } diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSMessagePortCustom.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSMessagePortCustom.cpp index 2c09620..2ee8125 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSMessagePortCustom.cpp +++ b/src/3rdparty/webkit/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/src/3rdparty/webkit/WebCore/bindings/js/JSMimeTypeArrayCustom.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSMimeTypeArrayCustom.cpp index c90dadd..c4b3189 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSMimeTypeArrayCustom.cpp +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSMimeTypeArrayCustom.cpp @@ -33,9 +33,9 @@ bool JSMimeTypeArray::canGetItemsForName(ExecState*, MimeTypeArray* mimeTypeArra return mimeTypeArray->canGetItemsForName(propertyName); } -JSValue JSMimeTypeArray::nameGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot) +JSValue JSMimeTypeArray::nameGetter(ExecState* exec, JSValue slotBase, const Identifier& propertyName) { - JSMimeTypeArray* thisObj = static_cast<JSMimeTypeArray*>(asObject(slot.slotBase())); + JSMimeTypeArray* thisObj = static_cast<JSMimeTypeArray*>(asObject(slotBase)); return toJS(exec, thisObj->impl()->namedItem(propertyName)); } diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSNamedNodeMapCustom.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSNamedNodeMapCustom.cpp index 1974ab0..13f3628 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSNamedNodeMapCustom.cpp +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSNamedNodeMapCustom.cpp @@ -40,9 +40,9 @@ bool JSNamedNodeMap::canGetItemsForName(ExecState*, NamedNodeMap* impl, const Id return impl->getNamedItem(propertyName); } -JSValue JSNamedNodeMap::nameGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot) +JSValue JSNamedNodeMap::nameGetter(ExecState* exec, JSValue slotBase, const Identifier& propertyName) { - JSNamedNodeMap* thisObj = static_cast<JSNamedNodeMap*>(asObject(slot.slotBase())); + JSNamedNodeMap* thisObj = static_cast<JSNamedNodeMap*>(asObject(slotBase)); return toJS(exec, thisObj->impl()->getNamedItem(propertyName)); } @@ -52,10 +52,8 @@ void JSNamedNodeMap::markChildren(MarkStack& markStack) // Mark the element so that this will work to access the attribute even if the last // other reference goes away. - if (Element* element = impl()->element()) { - if (JSNode* wrapper = getCachedDOMNodeWrapper(element->document(), element)) - markStack.append(wrapper); - } + if (Element* element = impl()->element()) + markDOMNodeWrapper(markStack, element->document(), element); } } // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSNodeCustom.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSNodeCustom.cpp index 2a4aa80..134c581 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSNodeCustom.cpp +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSNodeCustom.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007, 2009 Apple Inc. All rights reserved. + * Copyright (C) 2007, 2009, 2010 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -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,42 +137,45 @@ 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 // mark any other nodes. if (node->inDocument()) { if (Document* doc = node->ownerDocument()) - markDOMObjectWrapper(markStack, *Heap::heap(this)->globalData(), doc); + markDOMNodeWrapper(markStack, doc, doc); return; } - // This is a node outside the document, so find the root of the tree it is in, - // and start marking from there. + // This is a node outside the document. + // Find the the root, and the highest ancestor with a wrapper. Node* root = node; - for (Node* current = m_impl.get(); current; current = current->parentNode()) + Node* outermostNodeWithWrapper = node; + for (Node* current = m_impl.get(); current; current = current->parentNode()) { root = current; + if (hasCachedDOMNodeWrapperUnchecked(current->document(), current)) + outermostNodeWithWrapper = current; + } - // Nodes in a subtree are marked by the tree's root, so, if the root is already - // marking the tree, we don't need to explicitly mark any other nodes. - if (root->inSubtreeMark()) + // Only nodes that have no ancestors with wrappers mark the subtree. In the common + // case, the root of the detached subtree has a wrapper, so the tree will only + // get marked once. Nodes that aren't outermost need to mark the outermost + // in case it is otherwise unreachable. + if (node != outermostNodeWithWrapper) { + markDOMNodeWrapper(markStack, m_impl->document(), outermostNodeWithWrapper); return; + } // Mark the whole tree subtree. - root->setInSubtreeMark(true); - for (Node* nodeToMark = root; nodeToMark; nodeToMark = nodeToMark->traverseNextNode()) { - JSNode* wrapper = getCachedDOMNodeWrapper(m_impl->document(), nodeToMark); - if (wrapper) - markStack.append(wrapper); - } - root->setInSubtreeMark(false); + for (Node* nodeToMark = root; nodeToMark; nodeToMark = nodeToMark->traverseNextNode()) + markDOMNodeWrapper(markStack, m_impl->document(), nodeToMark); } -static ALWAYS_INLINE JSValue createWrapper(ExecState* exec, JSDOMGlobalObject* globalObject, Node* node) +static ALWAYS_INLINE JSValue createWrapperInline(ExecState* exec, JSDOMGlobalObject* globalObject, Node* node) { ASSERT(node); - ASSERT(!getCachedDOMNodeWrapper(node->document(), node)); + ASSERT(!getCachedDOMNodeWrapper(exec, node->document(), node)); JSNode* wrapper; switch (node->nodeType()) { @@ -225,25 +228,18 @@ static ALWAYS_INLINE JSValue createWrapper(ExecState* exec, JSDOMGlobalObject* g return wrapper; } - -JSValue toJSNewlyCreated(ExecState* exec, JSDOMGlobalObject* globalObject, Node* node) + +JSValue createWrapper(ExecState* exec, JSDOMGlobalObject* globalObject, Node* node) { - if (!node) - return jsNull(); - - return createWrapper(exec, globalObject, node); + return createWrapperInline(exec, globalObject, node); } -JSValue toJS(ExecState* exec, JSDOMGlobalObject* globalObject, Node* node) +JSValue toJSNewlyCreated(ExecState* exec, JSDOMGlobalObject* globalObject, Node* node) { if (!node) return jsNull(); - - JSNode* wrapper = getCachedDOMNodeWrapper(node->document(), node); - if (wrapper) - return wrapper; - - return createWrapper(exec, globalObject, node); + + return createWrapperInline(exec, globalObject, node); } } // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSNodeCustom.h b/src/3rdparty/webkit/WebCore/bindings/js/JSNodeCustom.h new file mode 100644 index 0000000..9d06ae6 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSNodeCustom.h @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2007, 2009, 2010 Apple 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 JSNodeCustom_h +#define JSNodeCustom_h + +#include "JSDOMBinding.h" +#include <wtf/AlwaysInline.h> + +namespace WebCore { + +inline JSNode* getCachedDOMNodeWrapper(JSC::ExecState* exec, Document* document, Node* node) +{ + if (currentWorld(exec)->isNormal()) { + ASSERT(node->wrapper() == (document ? document->getWrapperCache(currentWorld(exec))->get(node) : domObjectWrapperMapFor(exec).get(node))); + return static_cast<JSNode*>(node->wrapper()); + } + + if (document) + return document->getWrapperCache(currentWorld(exec))->get(node); + return static_cast<JSNode*>(domObjectWrapperMapFor(exec).get(node)); +} + +JSC::JSValue createWrapper(JSC::ExecState*, JSDOMGlobalObject*, Node*); + +inline JSC::JSValue toJS(JSC::ExecState* exec, JSDOMGlobalObject* globalObject, Node* node) +{ + if (!node) + return JSC::jsNull(); + + JSNode* wrapper = getCachedDOMNodeWrapper(exec, node->document(), node); + if (wrapper) + return wrapper; + + return createWrapper(exec, globalObject, node); +} + +} + +#endif // JSDOMNodeCustom_h diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSNodeFilterCondition.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSNodeFilterCondition.cpp index 54dc020..d34f5c1 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSNodeFilterCondition.cpp +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSNodeFilterCondition.cpp @@ -66,7 +66,7 @@ short JSNodeFilterCondition::acceptNode(JSC::ExecState* exec, Node* filterNode) if (exec->hadException()) return NodeFilter::FILTER_REJECT; - JSValue result = callInWorld(exec, m_filter, callType, callData, m_filter, args, currentWorld(exec)); + JSValue result = JSC::call(exec, m_filter, callType, callData, m_filter, args); if (exec->hadException()) return NodeFilter::FILTER_REJECT; diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSNodeListCustom.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSNodeListCustom.cpp index 2821d01..3f7d08b 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSNodeListCustom.cpp +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSNodeListCustom.cpp @@ -56,9 +56,9 @@ bool JSNodeList::canGetItemsForName(ExecState*, NodeList* impl, const Identifier return impl->itemWithName(propertyName); } -JSValue JSNodeList::nameGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot) +JSValue JSNodeList::nameGetter(ExecState* exec, JSValue slotBase, const Identifier& propertyName) { - JSNodeList* thisObj = static_cast<JSNodeList*>(asObject(slot.slotBase())); + JSNodeList* thisObj = static_cast<JSNodeList*>(asObject(slotBase)); return toJS(exec, thisObj->impl()->itemWithName(propertyName)); } diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSOptionConstructor.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSOptionConstructor.cpp index 7da0666..995903e 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSOptionConstructor.cpp +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSOptionConstructor.cpp @@ -49,21 +49,18 @@ static JSObject* constructHTMLOptionElement(ExecState* exec, JSObject* construct if (!document) return throwError(exec, ReferenceError, "Option constructor associated document is unavailable"); - RefPtr<HTMLOptionElement> element = static_pointer_cast<HTMLOptionElement>(document->createElement(HTMLNames::optionTag, false)); - - ExceptionCode ec = 0; - RefPtr<Text> text = document->createTextNode(""); + String data; if (!args.at(0).isUndefined()) - text->setData(args.at(0).toString(exec), ec); - if (ec == 0) - element->appendChild(text.release(), ec); - if (ec == 0 && !args.at(1).isUndefined()) - element->setValue(args.at(1).toString(exec)); - if (ec == 0) - element->setDefaultSelected(args.at(2).toBoolean(exec)); - if (ec == 0) - element->setSelected(args.at(3).toBoolean(exec)); + data = args.at(0).toString(exec); + String value; + if (!args.at(1).isUndefined()) + value = args.at(1).toString(exec); + bool defaultSelected = args.at(2).toBoolean(exec); + bool selected = args.at(3).toBoolean(exec); + + ExceptionCode ec = 0; + RefPtr<HTMLOptionElement> element = HTMLOptionElement::createForJSConstructor(document, data, value, defaultSelected, selected, ec); if (ec) { setDOMException(exec, ec); return 0; diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSPluginArrayCustom.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSPluginArrayCustom.cpp index 81d4295..9e0c3f5 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSPluginArrayCustom.cpp +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSPluginArrayCustom.cpp @@ -33,9 +33,9 @@ bool JSPluginArray::canGetItemsForName(ExecState*, PluginArray* pluginArray, con return pluginArray->canGetItemsForName(propertyName); } -JSValue JSPluginArray::nameGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot) +JSValue JSPluginArray::nameGetter(ExecState* exec, JSValue slotBase, const Identifier& propertyName) { - JSPluginArray* thisObj = static_cast<JSPluginArray*>(asObject(slot.slotBase())); + JSPluginArray* thisObj = static_cast<JSPluginArray*>(asObject(slotBase)); return toJS(exec, thisObj->impl()->namedItem(propertyName)); } diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSPluginCustom.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSPluginCustom.cpp index 555dd9e..b29e583 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSPluginCustom.cpp +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSPluginCustom.cpp @@ -32,9 +32,9 @@ bool JSPlugin::canGetItemsForName(ExecState*, Plugin* plugin, const Identifier& return plugin->canGetItemsForName(propertyName); } -JSValue JSPlugin::nameGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot) +JSValue JSPlugin::nameGetter(ExecState* exec, JSValue slotBase, const Identifier& propertyName) { - JSPlugin* thisObj = static_cast<JSPlugin*>(asObject(slot.slotBase())); + JSPlugin* thisObj = static_cast<JSPlugin*>(asObject(slotBase)); return toJS(exec, thisObj->impl()->namedItem(propertyName)); } diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSPluginElementFunctions.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSPluginElementFunctions.cpp index ada2a77..b20b9a7 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSPluginElementFunctions.cpp +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSPluginElementFunctions.cpp @@ -20,10 +20,10 @@ #include "config.h" #include "JSPluginElementFunctions.h" +#include "Bridge.h" #include "HTMLNames.h" #include "HTMLPlugInElement.h" #include "JSHTMLElement.h" -#include "runtime.h" #include "runtime_object.h" using namespace JSC; @@ -35,7 +35,7 @@ using namespace HTMLNames; // Runtime object support code for JSHTMLAppletElement, JSHTMLEmbedElement and JSHTMLObjectElement. -static Instance* pluginInstance(Node* node) +Instance* pluginInstance(Node* node) { if (!node) return 0; @@ -49,7 +49,7 @@ static Instance* pluginInstance(Node* node) return instance; } -static RuntimeObjectImp* getRuntimeObject(ExecState* exec, Node* node) +static RuntimeObject* getRuntimeObject(ExecState* exec, Node* node) { Instance* instance = pluginInstance(node); if (!instance) @@ -57,19 +57,11 @@ static RuntimeObjectImp* getRuntimeObject(ExecState* exec, Node* node) return instance->createRuntimeObject(exec); } -JSValue runtimeObjectGetter(ExecState* exec, const Identifier&, const PropertySlot& slot) +JSValue runtimeObjectPropertyGetter(ExecState* exec, JSValue slotBase, const Identifier& propertyName) { - JSHTMLElement* thisObj = static_cast<JSHTMLElement*>(asObject(slot.slotBase())); + JSHTMLElement* thisObj = static_cast<JSHTMLElement*>(asObject(slotBase)); HTMLElement* element = static_cast<HTMLElement*>(thisObj->impl()); - RuntimeObjectImp* runtimeObject = getRuntimeObject(exec, element); - return runtimeObject ? runtimeObject : jsUndefined(); -} - -JSValue runtimeObjectPropertyGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot) -{ - JSHTMLElement* thisObj = static_cast<JSHTMLElement*>(asObject(slot.slotBase())); - HTMLElement* element = static_cast<HTMLElement*>(thisObj->impl()); - RuntimeObjectImp* runtimeObject = getRuntimeObject(exec, element); + RuntimeObject* runtimeObject = getRuntimeObject(exec, element); if (!runtimeObject) return jsUndefined(); return runtimeObject->get(exec, propertyName); @@ -77,7 +69,7 @@ JSValue runtimeObjectPropertyGetter(ExecState* exec, const Identifier& propertyN bool runtimeObjectCustomGetOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot, JSHTMLElement* element) { - RuntimeObjectImp* runtimeObject = getRuntimeObject(exec, element->impl()); + RuntimeObject* runtimeObject = getRuntimeObject(exec, element->impl()); if (!runtimeObject) return false; if (!runtimeObject->hasProperty(exec, propertyName)) @@ -88,7 +80,7 @@ bool runtimeObjectCustomGetOwnPropertySlot(ExecState* exec, const Identifier& pr bool runtimeObjectCustomGetOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor, JSHTMLElement* element) { - RuntimeObjectImp* runtimeObject = getRuntimeObject(exec, element->impl()); + RuntimeObject* runtimeObject = getRuntimeObject(exec, element->impl()); if (!runtimeObject) return false; if (!runtimeObject->hasProperty(exec, propertyName)) @@ -104,7 +96,7 @@ bool runtimeObjectCustomGetOwnPropertyDescriptor(ExecState* exec, const Identifi bool runtimeObjectCustomPut(ExecState* exec, const Identifier& propertyName, JSValue value, HTMLElement* element, PutPropertySlot& slot) { - RuntimeObjectImp* runtimeObject = getRuntimeObject(exec, element); + RuntimeObject* runtimeObject = getRuntimeObject(exec, element); if (!runtimeObject) return 0; if (!runtimeObject->hasProperty(exec, propertyName)) diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSPluginElementFunctions.h b/src/3rdparty/webkit/WebCore/bindings/js/JSPluginElementFunctions.h index a5a323a..736ace9 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSPluginElementFunctions.h +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSPluginElementFunctions.h @@ -22,6 +22,12 @@ #include "JSDOMBinding.h" +namespace JSC { +namespace Bindings { +class Instance; +} +} + namespace WebCore { class HTMLElement; @@ -29,9 +35,9 @@ namespace WebCore { class Node; // Runtime object support code for JSHTMLAppletElement, JSHTMLEmbedElement and JSHTMLObjectElement. + JSC::Bindings::Instance* pluginInstance(Node*); - JSC::JSValue runtimeObjectGetter(JSC::ExecState*, const JSC::Identifier&, const JSC::PropertySlot&); - JSC::JSValue runtimeObjectPropertyGetter(JSC::ExecState*, const JSC::Identifier&, const JSC::PropertySlot&); + JSC::JSValue runtimeObjectPropertyGetter(JSC::ExecState*, JSC::JSValue, const JSC::Identifier&); bool runtimeObjectCustomGetOwnPropertySlot(JSC::ExecState*, const JSC::Identifier&, JSC::PropertySlot&, JSHTMLElement*); bool runtimeObjectCustomGetOwnPropertyDescriptor(JSC::ExecState*, const JSC::Identifier&, JSC::PropertyDescriptor&, JSHTMLElement*); bool runtimeObjectCustomPut(JSC::ExecState*, const JSC::Identifier&, JSC::JSValue, HTMLElement*, JSC::PutPropertySlot&); diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSPopStateEventCustom.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSPopStateEventCustom.cpp new file mode 100644 index 0000000..3f5fd7e --- /dev/null +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSPopStateEventCustom.cpp @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2009 Apple 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, 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" +#include "JSPopStateEvent.h" + +#include "PopStateEvent.h" + +using namespace JSC; + +namespace WebCore { + +JSValue JSPopStateEvent::initPopStateEvent(ExecState* exec, const ArgList& args) +{ + const UString& typeArg = args.at(0).toString(exec); + bool canBubbleArg = args.at(1).toBoolean(exec); + bool cancelableArg = args.at(2).toBoolean(exec); + RefPtr<SerializedScriptValue> stateObjectArg = SerializedScriptValue::create(exec, args.at(3)); + + PopStateEvent* event = static_cast<PopStateEvent*>(impl()); + event->initPopStateEvent(typeArg, canBubbleArg, cancelableArg, stateObjectArg.release()); + return jsUndefined(); +} + +} // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSQuarantinedObjectWrapper.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSQuarantinedObjectWrapper.cpp deleted file mode 100644 index 2ab2c00..0000000 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSQuarantinedObjectWrapper.cpp +++ /dev/null @@ -1,336 +0,0 @@ -/* - * Copyright (C) 2008, 2009 Apple 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 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 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" -#include "JSQuarantinedObjectWrapper.h" - -#include "JSDOMBinding.h" - -#include <runtime/JSGlobalObject.h> - -using namespace JSC; - -namespace WebCore { - -ASSERT_CLASS_FITS_IN_CELL(JSQuarantinedObjectWrapper); - -const ClassInfo JSQuarantinedObjectWrapper::s_info = { "JSQuarantinedObjectWrapper", 0, 0, 0 }; - -JSQuarantinedObjectWrapper* JSQuarantinedObjectWrapper::asWrapper(JSValue value) -{ - if (!value.isObject()) - return 0; - - JSObject* object = asObject(value); - - if (!object->inherits(&JSQuarantinedObjectWrapper::s_info)) - return 0; - - return static_cast<JSQuarantinedObjectWrapper*>(object); -} - -JSValue JSQuarantinedObjectWrapper::cachedValueGetter(ExecState*, const Identifier&, const PropertySlot& slot) -{ - JSValue v = slot.slotBase(); - ASSERT(v); - return v; -} - -JSQuarantinedObjectWrapper::JSQuarantinedObjectWrapper(ExecState* unwrappedExec, JSObject* unwrappedObject, NonNullPassRefPtr<Structure> structure) - : JSObject(structure) - , m_unwrappedGlobalObject(unwrappedExec->lexicalGlobalObject()) - , m_unwrappedObject(unwrappedObject) -{ - ASSERT_ARG(unwrappedExec, unwrappedExec); - ASSERT_ARG(unwrappedObject, unwrappedObject); - ASSERT(this->structure()); -} - -JSQuarantinedObjectWrapper::~JSQuarantinedObjectWrapper() -{ -} - -bool JSQuarantinedObjectWrapper::allowsUnwrappedAccessFrom(ExecState* exec) const -{ - return m_unwrappedGlobalObject->profileGroup() == exec->lexicalGlobalObject()->profileGroup(); -} - -ExecState* JSQuarantinedObjectWrapper::unwrappedExecState() const -{ - return m_unwrappedGlobalObject->globalExec(); -} - -void JSQuarantinedObjectWrapper::transferExceptionToExecState(ExecState* exec) const -{ - ASSERT(exec != unwrappedExecState()); - - if (!unwrappedExecState()->hadException()) - return; - - JSValue exception = unwrappedExecState()->exception(); - unwrappedExecState()->clearException(); - exec->setException(wrapOutgoingValue(unwrappedExecState(), exception)); -} - -void JSQuarantinedObjectWrapper::markChildren(MarkStack& markStack) -{ - JSObject::markChildren(markStack); - - markStack.append(m_unwrappedObject); - markStack.append(m_unwrappedGlobalObject); -} - -bool JSQuarantinedObjectWrapper::getOwnPropertySlot(ExecState* exec, const Identifier& identifier, PropertySlot& slot) -{ - if (!allowsGetProperty()) { - slot.setUndefined(); - return true; - } - - PropertySlot unwrappedSlot(m_unwrappedObject); - bool result = m_unwrappedObject->getOwnPropertySlot(unwrappedExecState(), identifier, unwrappedSlot); - if (result) { - JSValue unwrappedValue = unwrappedSlot.getValue(unwrappedExecState(), identifier); - slot.setCustom(wrapOutgoingValue(unwrappedExecState(), unwrappedValue), cachedValueGetter); - } - - transferExceptionToExecState(exec); - - return result; -} - -bool JSQuarantinedObjectWrapper::getOwnPropertySlot(ExecState* exec, unsigned identifier, PropertySlot& slot) -{ - if (!allowsGetProperty()) { - slot.setUndefined(); - return true; - } - - PropertySlot unwrappedSlot(m_unwrappedObject); - bool result = m_unwrappedObject->getOwnPropertySlot(unwrappedExecState(), identifier, unwrappedSlot); - if (result) { - JSValue unwrappedValue = unwrappedSlot.getValue(unwrappedExecState(), identifier); - slot.setCustom(wrapOutgoingValue(unwrappedExecState(), unwrappedValue), cachedValueGetter); - } - - transferExceptionToExecState(exec); - - return result; -} - -bool JSQuarantinedObjectWrapper::getOwnPropertyDescriptor(ExecState* exec, const Identifier& identifier, PropertyDescriptor& descriptor) -{ - if (!allowsGetProperty()) { - descriptor.setUndefined(); - return true; - } - - PropertyDescriptor unwrappedDescriptor; - bool result = m_unwrappedObject->getOwnPropertyDescriptor(unwrappedExecState(), identifier, unwrappedDescriptor); - - if (unwrappedDescriptor.isAccessorDescriptor()) { - descriptor.setAccessorDescriptor(wrapOutgoingValue(unwrappedExecState(), unwrappedDescriptor.getter()), - wrapOutgoingValue(unwrappedExecState(), unwrappedDescriptor.setter()), - unwrappedDescriptor.attributes()); - } else - descriptor.setDescriptor(wrapOutgoingValue(unwrappedExecState(), unwrappedDescriptor.value()), unwrappedDescriptor.attributes()); - transferExceptionToExecState(exec); - return result; -} - -void JSQuarantinedObjectWrapper::put(ExecState* exec, const Identifier& identifier, JSValue value, PutPropertySlot& slot) -{ - if (!allowsSetProperty()) - return; - - m_unwrappedObject->put(unwrappedExecState(), identifier, prepareIncomingValue(exec, value), slot); - - transferExceptionToExecState(exec); -} - -void JSQuarantinedObjectWrapper::put(ExecState* exec, unsigned identifier, JSValue value) -{ - if (!allowsSetProperty()) - return; - - m_unwrappedObject->put(unwrappedExecState(), identifier, prepareIncomingValue(exec, value)); - - transferExceptionToExecState(exec); -} - -bool JSQuarantinedObjectWrapper::defineOwnProperty(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor, bool shouldThrow) -{ - if (!allowsSetProperty()) - return false; - - PropertyDescriptor wrappedDescriptor; - if (descriptor.isDataDescriptor()) { - wrappedDescriptor.setValue(prepareIncomingValue(exec, descriptor.value())); - if (wrappedDescriptor.writablePresent()) - wrappedDescriptor.setWritable(descriptor.writable()); - } else if (descriptor.isAccessorDescriptor()) { - if (descriptor.getter()) - wrappedDescriptor.setGetter(prepareIncomingValue(exec, descriptor.getter())); - if (descriptor.setter()) - wrappedDescriptor.setSetter(prepareIncomingValue(exec, descriptor.setter())); - } - if (wrappedDescriptor.enumerablePresent()) - wrappedDescriptor.setEnumerable(descriptor.enumerable()); - if (wrappedDescriptor.configurablePresent()) - wrappedDescriptor.setConfigurable(descriptor.configurable()); - - bool result = m_unwrappedObject->defineOwnProperty(unwrappedExecState(), propertyName, wrappedDescriptor, shouldThrow); - - transferExceptionToExecState(exec); - return result; -} - -bool JSQuarantinedObjectWrapper::deleteProperty(ExecState* exec, const Identifier& identifier) -{ - if (!allowsDeleteProperty()) - return false; - - bool result = m_unwrappedObject->deleteProperty(unwrappedExecState(), identifier); - - transferExceptionToExecState(exec); - - return result; -} - -bool JSQuarantinedObjectWrapper::deleteProperty(ExecState* exec, unsigned identifier) -{ - if (!allowsDeleteProperty()) - return false; - - bool result = m_unwrappedObject->deleteProperty(unwrappedExecState(), identifier); - - transferExceptionToExecState(exec); - - return result; -} - -JSObject* JSQuarantinedObjectWrapper::construct(ExecState* exec, JSObject* constructor, const ArgList& args) -{ - JSQuarantinedObjectWrapper* wrapper = static_cast<JSQuarantinedObjectWrapper*>(constructor); - - MarkedArgumentBuffer preparedArgs; - for (size_t i = 0; i < args.size(); ++i) - preparedArgs.append(wrapper->prepareIncomingValue(exec, args.at(i))); - - // FIXME: Would be nice to find a way to reuse the result of m_unwrappedObject->getConstructData - // from when we called it in JSQuarantinedObjectWrapper::getConstructData. - ConstructData unwrappedConstructData; - ConstructType unwrappedConstructType = wrapper->m_unwrappedObject->getConstructData(unwrappedConstructData); - ASSERT(unwrappedConstructType != ConstructTypeNone); - - // FIXME: Quarantined objects are all in the debuggerWorld(), for now. Instead, we should remove the quarantined objects, & replace them with an isolated world? - JSValue unwrappedResult = constructInWorld(wrapper->unwrappedExecState(), wrapper->m_unwrappedObject, unwrappedConstructType, unwrappedConstructData, preparedArgs, debuggerWorld()); - - JSValue resultValue = wrapper->wrapOutgoingValue(wrapper->unwrappedExecState(), unwrappedResult); - ASSERT(resultValue.isObject()); - JSObject* result = asObject(resultValue); - - wrapper->transferExceptionToExecState(exec); - - return result; -} - -ConstructType JSQuarantinedObjectWrapper::getConstructData(ConstructData& constructData) -{ - if (!allowsConstruct()) - return ConstructTypeNone; - ConstructData unwrappedConstructData; - if (m_unwrappedObject->getConstructData(unwrappedConstructData) == ConstructTypeNone) - return ConstructTypeNone; - constructData.native.function = construct; - return ConstructTypeHost; -} - -bool JSQuarantinedObjectWrapper::hasInstance(ExecState* exec, JSValue value, JSValue proto) -{ - if (!allowsHasInstance()) - return false; - - bool result = m_unwrappedObject->hasInstance(unwrappedExecState(), prepareIncomingValue(exec, value), prepareIncomingValue(exec, proto)); - - transferExceptionToExecState(exec); - - return result; -} - -JSValue JSQuarantinedObjectWrapper::call(ExecState* exec, JSObject* function, JSValue thisValue, const ArgList& args) -{ - JSQuarantinedObjectWrapper* wrapper = static_cast<JSQuarantinedObjectWrapper*>(function); - - JSValue preparedThisValue = wrapper->prepareIncomingValue(exec, thisValue); - - MarkedArgumentBuffer preparedArgs; - for (size_t i = 0; i < args.size(); ++i) - preparedArgs.append(wrapper->prepareIncomingValue(exec, args.at(i))); - - // FIXME: Would be nice to find a way to reuse the result of m_unwrappedObject->getCallData - // from when we called it in JSQuarantinedObjectWrapper::getCallData. - CallData unwrappedCallData; - CallType unwrappedCallType = wrapper->m_unwrappedObject->getCallData(unwrappedCallData); - ASSERT(unwrappedCallType != CallTypeNone); - - // FIXME: Quarantined objects are all in the debuggerWorld(), for now. Instead, we should remove the quarantined objects, & replace them with an isolated world? - JSValue unwrappedResult = callInWorld(wrapper->unwrappedExecState(), wrapper->m_unwrappedObject, unwrappedCallType, unwrappedCallData, preparedThisValue, preparedArgs, debuggerWorld()); - - JSValue result = wrapper->wrapOutgoingValue(wrapper->unwrappedExecState(), unwrappedResult); - - wrapper->transferExceptionToExecState(exec); - - return result; -} - -CallType JSQuarantinedObjectWrapper::getCallData(CallData& callData) -{ - if (!allowsCallAsFunction()) - return CallTypeNone; - CallData unwrappedCallData; - if (m_unwrappedObject->getCallData(unwrappedCallData) == CallTypeNone) - return CallTypeNone; - callData.native.function = call; - return CallTypeHost; -} - -void JSQuarantinedObjectWrapper::getPropertyNames(ExecState*, PropertyNameArray& array) -{ - if (!allowsGetPropertyNames()) - return; - - m_unwrappedObject->getPropertyNames(unwrappedExecState(), array); -} - -void JSQuarantinedObjectWrapper::getOwnPropertyNames(ExecState*, PropertyNameArray& array) -{ - if (!allowsGetPropertyNames()) - return; - - m_unwrappedObject->getOwnPropertyNames(unwrappedExecState(), array); -} - -} // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSQuarantinedObjectWrapper.h b/src/3rdparty/webkit/WebCore/bindings/js/JSQuarantinedObjectWrapper.h deleted file mode 100644 index 9f62495..0000000 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSQuarantinedObjectWrapper.h +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright (C) 2008, 2009 Apple 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 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 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 JSQuarantinedObjectWrapper_h -#define JSQuarantinedObjectWrapper_h - -#include <runtime/JSObject.h> - -namespace WebCore { - - class JSQuarantinedObjectWrapper : public JSC::JSObject { - public: - static JSQuarantinedObjectWrapper* asWrapper(JSC::JSValue); - - virtual ~JSQuarantinedObjectWrapper(); - - virtual JSC::JSObject* unwrappedObject() { return m_unwrappedObject; } - - JSC::JSGlobalObject* unwrappedGlobalObject() const { return m_unwrappedGlobalObject; }; - JSC::ExecState* unwrappedExecState() const; - - bool allowsUnwrappedAccessFrom(JSC::ExecState*) const; - - static const JSC::ClassInfo s_info; - - static PassRefPtr<JSC::Structure> createStructure(JSC::JSValue proto) - { - return JSC::Structure::create(proto, JSC::TypeInfo(JSC::ObjectType, StructureFlags)); - } - - protected: - static const unsigned StructureFlags = JSC::OverridesGetOwnPropertySlot | JSC::ImplementsHasInstance | JSC::OverridesHasInstance | JSC::OverridesMarkChildren | JSC::OverridesGetPropertyNames | JSC::JSObject::StructureFlags; - - JSQuarantinedObjectWrapper(JSC::ExecState* unwrappedExec, JSC::JSObject* unwrappedObject, NonNullPassRefPtr<JSC::Structure>); - - virtual void markChildren(JSC::MarkStack&); - - private: - virtual bool getOwnPropertySlot(JSC::ExecState*, const JSC::Identifier&, JSC::PropertySlot&); - virtual bool getOwnPropertySlot(JSC::ExecState*, unsigned, JSC::PropertySlot&); - virtual bool getOwnPropertyDescriptor(JSC::ExecState*, const JSC::Identifier&, JSC::PropertyDescriptor&); - - virtual void put(JSC::ExecState*, const JSC::Identifier&, JSC::JSValue, JSC::PutPropertySlot&); - virtual void put(JSC::ExecState*, unsigned, JSC::JSValue); - virtual bool defineOwnProperty(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::PropertyDescriptor&, bool shouldThrow); - - virtual bool deleteProperty(JSC::ExecState*, const JSC::Identifier&); - virtual bool deleteProperty(JSC::ExecState*, unsigned); - - virtual JSC::CallType getCallData(JSC::CallData&); - virtual JSC::ConstructType getConstructData(JSC::ConstructData&); - - virtual bool hasInstance(JSC::ExecState*, JSC::JSValue, JSC::JSValue proto); - - virtual void getPropertyNames(JSC::ExecState*, JSC::PropertyNameArray&); - virtual void getOwnPropertyNames(JSC::ExecState*, JSC::PropertyNameArray&); - - virtual JSC::UString className() const { return m_unwrappedObject->className(); } - - virtual bool allowsGetProperty() const { return false; } - virtual bool allowsSetProperty() const { return false; } - virtual bool allowsDeleteProperty() const { return false; } - virtual bool allowsConstruct() const { return false; } - virtual bool allowsHasInstance() const { return false; } - virtual bool allowsCallAsFunction() const { return false; } - virtual bool allowsGetPropertyNames() const { return false; } - - virtual JSC::JSValue prepareIncomingValue(JSC::ExecState* unwrappedExec, JSC::JSValue unwrappedValue) const = 0; - virtual JSC::JSValue wrapOutgoingValue(JSC::ExecState* unwrappedExec, JSC::JSValue unwrappedValue) const = 0; - - static JSC::JSValue cachedValueGetter(JSC::ExecState*, const JSC::Identifier&, const JSC::PropertySlot&); - - void transferExceptionToExecState(JSC::ExecState*) const; - - static JSC::JSValue JSC_HOST_CALL call(JSC::ExecState*, JSC::JSObject* function, JSC::JSValue thisValue, const JSC::ArgList&); - static JSC::JSObject* construct(JSC::ExecState*, JSC::JSObject*, const JSC::ArgList&); - - JSC::JSGlobalObject* m_unwrappedGlobalObject; - JSC::JSObject* m_unwrappedObject; - }; - -} // namespace WebCore - -#endif // JSQuarantinedObjectWrapper_h diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSSVGContextCache.h b/src/3rdparty/webkit/WebCore/bindings/js/JSSVGContextCache.h new file mode 100644 index 0000000..75ed324 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSSVGContextCache.h @@ -0,0 +1,97 @@ +/* + Copyright (C) Research In Motion Limited 2009-2010. All rights reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef JSSVGContextCache_h +#define JSSVGContextCache_h + +#if ENABLE(SVG) +#include "SVGElement.h" +#include <wtf/StdLibExtras.h> + +namespace WebCore { + +class DOMObject; + +class JSSVGContextCache : public Noncopyable { +public: + typedef HashMap<DOMObject*, SVGElement*> WrapperMap; + + static WrapperMap& wrapperMap() + { + DEFINE_STATIC_LOCAL(WrapperMap, s_wrapperMap, ()); + return s_wrapperMap; + } + + static void addWrapper(DOMObject* wrapper, SVGElement* context) + { + ASSERT(wrapper); + ASSERT(context); + + pair<WrapperMap::iterator, bool> result = wrapperMap().add(wrapper, context); + if (result.second) { + WrapperMap::iterator& it = result.first; + ASSERT_UNUSED(it, it->second == context); + } + } + + static void forgetWrapper(DOMObject* wrapper) + { + ASSERT(wrapper); + + WrapperMap& map = wrapperMap(); + WrapperMap::iterator it = map.find(wrapper); + if (it == map.end()) + return; + + map.remove(it); + } + + static void propagateSVGDOMChange(DOMObject* wrapper, const QualifiedName& attributeName) + { + WrapperMap& map = wrapperMap(); + WrapperMap::iterator it = map.find(wrapper); + if (it == map.end()) + return; + + SVGElement* context = it->second; + ASSERT(context); + + context->svgAttributeChanged(attributeName); + } + + static SVGElement* svgContextForDOMObject(DOMObject* wrapper) + { + ASSERT(wrapper); + + WrapperMap& map = wrapperMap(); + WrapperMap::iterator it = map.find(wrapper); + if (it == map.end()) + return 0; + + SVGElement* context = it->second; + ASSERT(context); + return context; + } + +}; + +} + +#endif +#endif diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSSVGElementInstanceCustom.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSSVGElementInstanceCustom.cpp index ba1cf22..b3bded5 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSSVGElementInstanceCustom.cpp +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSSVGElementInstanceCustom.cpp @@ -43,9 +43,7 @@ void JSSVGElementInstance::markChildren(MarkStack& markStack) Base::markChildren(markStack); // Mark the wrapper for our corresponding element, so it can mark its event handlers. - JSNode* correspondingWrapper = getCachedDOMNodeWrapper(impl()->correspondingElement()->document(), impl()->correspondingElement()); - if (correspondingWrapper) - markStack.append(correspondingWrapper); + markDOMNodeWrapper(markStack, impl()->correspondingElement()->document(), impl()->correspondingElement()); } JSValue JSSVGElementInstance::addEventListener(ExecState* exec, const ArgList& args) @@ -54,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(); } @@ -64,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/src/3rdparty/webkit/WebCore/bindings/js/JSSVGLengthCustom.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSSVGLengthCustom.cpp index bad52ae..33bbf30 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSSVGLengthCustom.cpp +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSSVGLengthCustom.cpp @@ -28,18 +28,22 @@ namespace WebCore { JSValue JSSVGLength::value(ExecState* exec) const { - SVGLength imp(*impl()); - return jsNumber(exec, imp.value(context())); + JSSVGPODTypeWrapper<SVGLength>* imp = impl(); + SVGElement* context = JSSVGContextCache::svgContextForDOMObject(const_cast<JSSVGLength*>(this)); + + SVGLength podImp(*imp); + return jsNumber(exec, podImp.value(context)); } JSValue JSSVGLength::convertToSpecifiedUnits(ExecState* exec, const ArgList& args) { - JSSVGPODTypeWrapper<SVGLength>* wrapper = impl(); + JSSVGPODTypeWrapper<SVGLength>* imp = impl(); + SVGElement* context = JSSVGContextCache::svgContextForDOMObject(this); - SVGLength imp(*wrapper); - imp.convertToSpecifiedUnits(args.at(0).toInt32(exec), context()); + SVGLength podImp(*imp); + podImp.convertToSpecifiedUnits(args.at(0).toInt32(exec), context); - wrapper->commitChange(imp, context()); + imp->commitChange(podImp, this); return jsUndefined(); } diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSSVGMatrixCustom.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSSVGMatrixCustom.cpp index 35390b2..59e3f03 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSSVGMatrixCustom.cpp +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSSVGMatrixCustom.cpp @@ -1,5 +1,6 @@ /* * Copyright (C) 2006, 2007, 2008 Nikolas Zimmermann <zimmermann@kde.org> + * Copyright (C) 2009 Jeff Schiller <codedread@gmail.com> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -22,17 +23,37 @@ #if ENABLE(SVG) #include "JSSVGMatrix.h" -#include "TransformationMatrix.h" +#include "AffineTransform.h" #include "SVGException.h" +#include <runtime/Error.h> using namespace JSC; namespace WebCore { +JSValue JSSVGMatrix::multiply(ExecState* exec, const ArgList& args) +{ + if (args.size() < 1) + return throwError(exec, SyntaxError, "Not enough arguments"); + + if (!args.at(0).inherits(&JSSVGMatrix::s_info)) + return throwError(exec, TypeError, "secondMatrix argument was not a SVGMatrix"); + + JSSVGMatrix* matrixObj = static_cast<JSSVGMatrix*>(asObject(args.at(0))); + + AffineTransform m1(*impl()); + AffineTransform m2(*(matrixObj->impl())); + + SVGElement* context = JSSVGContextCache::svgContextForDOMObject(this); + return toJS(exec, globalObject(), JSSVGStaticPODTypeWrapper<AffineTransform>::create(m1.multLeft(m2)).get(), context); +} + JSValue JSSVGMatrix::inverse(ExecState* exec, const ArgList&) { - TransformationMatrix imp(*impl()); - JSC::JSValue result = toJS(exec, deprecatedGlobalObjectForPrototype(exec), JSSVGStaticPODTypeWrapper<TransformationMatrix>::create(imp.inverse()).get(), m_context.get()); + AffineTransform imp(*impl()); + + SVGElement* context = JSSVGContextCache::svgContextForDOMObject(this); + JSValue result = toJS(exec, globalObject(), JSSVGStaticPODTypeWrapper<AffineTransform>::create(imp.inverse()).get(), context); if (!imp.isInvertible()) setDOMException(exec, SVGException::SVG_MATRIX_NOT_INVERTABLE); @@ -42,12 +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); - JSC::JSValue result = toJS(exec, deprecatedGlobalObjectForPrototype(exec), JSSVGStaticPODTypeWrapper<TransformationMatrix>::create(imp.rotateFromVector(x, y)).get(), m_context.get()); + SVGElement* context = JSSVGContextCache::svgContextForDOMObject(this); + 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/src/3rdparty/webkit/WebCore/bindings/js/JSSVGPODListCustom.h b/src/3rdparty/webkit/WebCore/bindings/js/JSSVGPODListCustom.h new file mode 100644 index 0000000..8a0654c --- /dev/null +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSSVGPODListCustom.h @@ -0,0 +1,199 @@ +/* + * Copyright (C) Research In Motion Limited 2010. All rights reserved. + * Copyright (C) 2007, 2008 Nikolas Zimmermann <zimmermann@kde.org> + * Copyright (C) 2008 Apple Inc. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef JSSVGPODListCustom_h +#define JSSVGPODListCustom_h + +#include "JSSVGContextCache.h" +#include "JSSVGPODTypeWrapper.h" +#include "SVGList.h" + +namespace WebCore { + +namespace JSSVGPODListCustom { + +// Helper structure only containing public typedefs, as C++ does not allow templatized typedefs +template<typename PODType> +struct JSSVGPODListTraits { + typedef SVGPODListItem<PODType> PODListItem; + typedef SVGList<RefPtr<PODListItem> > PODList; + typedef PODType (*ConversionCallback)(JSC::JSValue); +}; + +template<typename JSPODListType, typename PODType> +static JSC::JSValue finishGetter(JSC::ExecState* exec, ExceptionCode& ec, JSPODListType* wrapper, + PassRefPtr<typename JSSVGPODListTraits<PODType>::PODListItem> item) +{ + if (ec) { + setDOMException(exec, ec); + return JSC::jsUndefined(); + } + + typename JSSVGPODListTraits<PODType>::PODList* listImp = wrapper->impl(); + + SVGElement* context = JSSVGContextCache::svgContextForDOMObject(wrapper); + return toJS(exec, wrapper->globalObject(), + JSSVGPODTypeWrapperCreatorForList<PODType>::create(item.get(), listImp->associatedAttributeName()).get(), context); +} + +template<typename JSPODListType, typename PODType> +static JSC::JSValue finishSetter(JSC::ExecState* exec, ExceptionCode& ec, JSPODListType* wrapper, + PassRefPtr<typename JSSVGPODListTraits<PODType>::PODListItem> item) +{ + if (ec) { + setDOMException(exec, ec); + return JSC::jsUndefined(); + } + + typename JSSVGPODListTraits<PODType>::PODList* listImp = wrapper->impl(); + + const QualifiedName& attributeName = listImp->associatedAttributeName(); + JSSVGContextCache::propagateSVGDOMChange(wrapper, attributeName); + + SVGElement* context = JSSVGContextCache::svgContextForDOMObject(wrapper); + return toJS(exec, wrapper->globalObject(), + JSSVGPODTypeWrapperCreatorForList<PODType>::create(item.get(), attributeName).get(), context); +} + +template<typename JSPODListType, typename PODType> +static JSC::JSValue finishSetterReadOnlyResult(JSC::ExecState* exec, ExceptionCode& ec, JSPODListType* wrapper, + PassRefPtr<typename JSSVGPODListTraits<PODType>::PODListItem> item) +{ + if (ec) { + setDOMException(exec, ec); + return JSC::jsUndefined(); + } + + typename JSSVGPODListTraits<PODType>::PODList* listImp = wrapper->impl(); + JSSVGContextCache::propagateSVGDOMChange(wrapper, listImp->associatedAttributeName()); + return toJS(exec, wrapper->globalObject(), + JSSVGStaticPODTypeWrapper<PODType>::create(*item).get(), 0 /* no context on purpose */); +} + +template<typename JSPODListType, typename PODType> +static JSC::JSValue clear(JSPODListType* wrapper, JSC::ExecState* exec, const JSC::ArgList&, + typename JSSVGPODListTraits<PODType>::ConversionCallback) +{ + ExceptionCode ec = 0; + typename JSSVGPODListTraits<PODType>::PODList* listImp = wrapper->impl(); + listImp->clear(ec); + + if (ec) + setDOMException(exec, ec); + else + JSSVGContextCache::propagateSVGDOMChange(wrapper, listImp->associatedAttributeName()); + + return JSC::jsUndefined(); +} + +template<typename JSPODListType, typename PODType> +static JSC::JSValue initialize(JSPODListType* wrapper, JSC::ExecState* exec, const JSC::ArgList& args, + typename JSSVGPODListTraits<PODType>::ConversionCallback conversion) +{ + ExceptionCode ec = 0; + typename JSSVGPODListTraits<PODType>::PODList* listImp = wrapper->impl(); + return finishSetter<JSPODListType, PODType>(exec, ec, wrapper, + listImp->initialize(JSSVGPODListTraits<PODType>::PODListItem::copy(conversion(args.at(0))), ec)); +} + +template<typename JSPODListType, typename PODType> +static JSC::JSValue getItem(JSPODListType* wrapper, JSC::ExecState* exec, const JSC::ArgList& args, + typename JSSVGPODListTraits<PODType>::ConversionCallback) +{ + bool indexOk = false; + unsigned index = args.at(0).toUInt32(exec, indexOk); + if (!indexOk) { + setDOMException(exec, TYPE_MISMATCH_ERR); + return JSC::jsUndefined(); + } + + ExceptionCode ec = 0; + typename JSSVGPODListTraits<PODType>::PODList* listImp = wrapper->impl(); + return finishGetter<JSPODListType, PODType>(exec, ec, wrapper, + listImp->getItem(index, ec)); +} + +template<typename JSPODListType, typename PODType> +static JSC::JSValue insertItemBefore(JSPODListType* wrapper, JSC::ExecState* exec, const JSC::ArgList& args, + typename JSSVGPODListTraits<PODType>::ConversionCallback conversion) +{ + bool indexOk = false; + unsigned index = args.at(1).toUInt32(exec, indexOk); + if (!indexOk) { + setDOMException(exec, TYPE_MISMATCH_ERR); + return JSC::jsUndefined(); + } + + ExceptionCode ec = 0; + typename JSSVGPODListTraits<PODType>::PODList* listImp = wrapper->impl(); + return finishSetter<JSPODListType, PODType>(exec, ec, wrapper, + listImp->insertItemBefore(JSSVGPODListTraits<PODType>::PODListItem::copy(conversion(args.at(0))), index, ec)); +} + +template<typename JSPODListType, typename PODType> +static JSC::JSValue replaceItem(JSPODListType* wrapper, JSC::ExecState* exec, const JSC::ArgList& args, + typename JSSVGPODListTraits<PODType>::ConversionCallback conversion) +{ + bool indexOk = false; + unsigned index = args.at(1).toUInt32(exec, indexOk); + if (!indexOk) { + setDOMException(exec, TYPE_MISMATCH_ERR); + return JSC::jsUndefined(); + } + + ExceptionCode ec = 0; + typename JSSVGPODListTraits<PODType>::PODList* listImp = wrapper->impl(); + return finishSetter<JSPODListType, PODType>(exec, ec, wrapper, + listImp->replaceItem(JSSVGPODListTraits<PODType>::PODListItem::copy(conversion(args.at(0))), index, ec)); +} + +template<typename JSPODListType, typename PODType> +static JSC::JSValue removeItem(JSPODListType* wrapper, JSC::ExecState* exec, const JSC::ArgList& args, + typename JSSVGPODListTraits<PODType>::ConversionCallback) +{ + bool indexOk = false; + unsigned index = args.at(0).toUInt32(exec, indexOk); + if (!indexOk) { + setDOMException(exec, TYPE_MISMATCH_ERR); + return JSC::jsUndefined(); + } + + ExceptionCode ec = 0; + typename JSSVGPODListTraits<PODType>::PODList* listImp = wrapper->impl(); + return finishSetterReadOnlyResult<JSPODListType, PODType>(exec, ec, wrapper, + listImp->removeItem(index, ec)); +} + +template<typename JSPODListType, typename PODType> +static JSC::JSValue appendItem(JSPODListType* wrapper, JSC::ExecState* exec, const JSC::ArgList& args, + typename JSSVGPODListTraits<PODType>::ConversionCallback conversion) +{ + ExceptionCode ec = 0; + typename JSSVGPODListTraits<PODType>::PODList* listImp = wrapper->impl(); + return finishSetter<JSPODListType, PODType>(exec, ec, wrapper, + listImp->appendItem(JSSVGPODListTraits<PODType>::PODListItem::copy(conversion(args.at(0))), ec)); +} + +} + +} + +#endif diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSSVGPODTypeWrapper.h b/src/3rdparty/webkit/WebCore/bindings/js/JSSVGPODTypeWrapper.h index 51e4e9e..2efc60e 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSSVGPODTypeWrapper.h +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSSVGPODTypeWrapper.h @@ -28,28 +28,31 @@ #define JSSVGPODTypeWrapper_h #if ENABLE(SVG) +#include "JSSVGContextCache.h" #include "SVGElement.h" #include <wtf/StdLibExtras.h> namespace WebCore { +class DOMObject; + template<typename PODType> class JSSVGPODTypeWrapper : public RefCounted<JSSVGPODTypeWrapper<PODType> > { public: virtual ~JSSVGPODTypeWrapper() { } virtual operator PODType() = 0; - virtual void commitChange(PODType, SVGElement*) = 0; + virtual void commitChange(PODType, DOMObject*) = 0; }; // 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 (ie. '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 +// SVGMatrix object (i.e. 'someElement.transform.matrix.a = 50.0', in that case 'SVGTransform'). +// 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, ...). @@ -68,13 +71,13 @@ public: // GetterMethod and SetterMethod are each 12 bytes. We have to pack to a size // greater than or equal to that to avoid an alignment warning (C4121). 16 is // the next-largest size allowed for packing, so we use that. -#pragma pack(16) +#pragma pack(push, 16) #endif template<typename PODType, typename PODTypeCreator> class JSSVGDynamicPODTypeWrapper : public JSSVGPODTypeWrapper<PODType> { public: typedef PODType (PODTypeCreator::*GetterMethod)() const; - typedef void (PODTypeCreator::*SetterMethod)(PODType); + typedef void (PODTypeCreator::*SetterMethod)(const PODType&); static PassRefPtr<JSSVGDynamicPODTypeWrapper> create(PassRefPtr<PODTypeCreator> creator, GetterMethod getter, SetterMethod setter) { @@ -86,12 +89,10 @@ public: return (m_creator.get()->*m_getter)(); } - virtual void commitChange(PODType type, SVGElement* context) + virtual void commitChange(PODType type, DOMObject* wrapper) { (m_creator.get()->*m_setter)(type); - - if (context) - context->svgAttributeChanged(m_creator->associatedAttributeName()); + JSSVGContextCache::propagateSVGDOMChange(wrapper, m_creator->associatedAttributeName()); } private: @@ -105,15 +106,20 @@ private: ASSERT(m_setter); } + virtual ~JSSVGDynamicPODTypeWrapper(); + // Update callbacks RefPtr<PODTypeCreator> m_creator; GetterMethod m_getter; SetterMethod m_setter; }; +#if COMPILER(MSVC) +#pragma pack(pop) +#endif -// Represents a JS wrapper object for SVG POD types (not for SVGAnimated* clases). Any modification to the SVG POD +// Represents a JS wrapper object for SVG POD types (not for SVGAnimated* classes). Any modification to the SVG POD // types don't cause any updates unlike JSSVGDynamicPODTypeWrapper. This class is used for return values (ie. getBBox()) -// and for properties where SVG specification explicitely states, that the contents of the POD type are immutable. +// and for properties where SVG specification explicitly states, that the contents of the POD type are immutable. template<typename PODType> class JSSVGStaticPODTypeWrapper : public JSSVGPODTypeWrapper<PODType> { @@ -128,7 +134,7 @@ public: return m_podType; } - virtual void commitChange(PODType type, SVGElement*) + virtual void commitChange(PODType type, DOMObject*) { m_podType = type; } @@ -152,10 +158,10 @@ public: return adoptRef(new JSSVGStaticPODTypeWrapperWithPODTypeParent(type, parent)); } - virtual void commitChange(PODType type, SVGElement* context) + virtual void commitChange(PODType type, DOMObject* wrapper) { - JSSVGStaticPODTypeWrapper<PODType>::commitChange(type, context); - m_parentType->commitChange(ParentTypeArg(type), context); + JSSVGStaticPODTypeWrapper<PODType>::commitChange(type, wrapper); + m_parentType->commitChange(ParentTypeArg(type), wrapper); } private: @@ -172,7 +178,7 @@ private: // GetterMethod and SetterMethod are each 12 bytes. We have to pack to a size // greater than or equal to that to avoid an alignment warning (C4121). 16 is // the next-largest size allowed for packing, so we use that. -#pragma pack(16) +#pragma pack(push, 16) #endif template<typename PODType, typename ParentType> class JSSVGStaticPODTypeWrapperWithParent : public JSSVGPODTypeWrapper<PODType> { @@ -190,7 +196,7 @@ public: return (m_parent.get()->*m_getter)(); } - virtual void commitChange(PODType type, SVGElement*) + virtual void commitChange(PODType type, DOMObject*) { (m_parent.get()->*m_setter)(type); } @@ -223,7 +229,7 @@ public: typedef SVGPODListItem<PODType> PODListItemPtrType; typedef PODType (SVGPODListItem<PODType>::*GetterMethod)() const; - typedef void (SVGPODListItem<PODType>::*SetterMethod)(PODType); + typedef void (SVGPODListItem<PODType>::*SetterMethod)(const PODType&); static PassRefPtr<JSSVGPODTypeWrapperCreatorForList> create(PassRefPtr<PODListItemPtrType> creator, const QualifiedName& attributeName) { @@ -235,15 +241,13 @@ public: return (m_creator.get()->*m_getter)(); } - virtual void commitChange(PODType type, SVGElement* context) + virtual void commitChange(PODType type, DOMObject* wrapper) { if (!m_setter) return; (m_creator.get()->*m_setter)(type); - - if (context) - context->svgAttributeChanged(m_associatedAttributeName); + JSSVGContextCache::propagateSVGDOMChange(wrapper, m_associatedAttributeName); } private: @@ -269,7 +273,7 @@ private: template<typename PODType, typename PODTypeCreator> struct PODTypeWrapperCacheInfo { typedef PODType (PODTypeCreator::*GetterMethod)() const; - typedef void (PODTypeCreator::*SetterMethod)(PODType); + typedef void (PODTypeCreator::*SetterMethod)(const PODType&); // Empty value PODTypeWrapperCacheInfo() @@ -309,6 +313,9 @@ struct PODTypeWrapperCacheInfo { GetterMethod getter; SetterMethod setter; }; +#if COMPILER(MSVC) +#pragma pack(pop) +#endif template<typename PODType, typename PODTypeCreator> struct PODTypeWrapperCacheInfoHash { @@ -351,60 +358,53 @@ struct PODTypeWrapperCacheInfoTraits : WTF::GenericHashTraits<PODTypeWrapperCach } }; +// Used for dynamic read-write attributes template<typename PODType, typename PODTypeCreator> class JSSVGDynamicPODTypeWrapperCache { public: typedef PODType (PODTypeCreator::*GetterMethod)() const; - typedef void (PODTypeCreator::*SetterMethod)(PODType); + typedef void (PODTypeCreator::*SetterMethod)(const PODType&); typedef PODTypeWrapperCacheInfo<PODType, PODTypeCreator> CacheInfo; typedef PODTypeWrapperCacheInfoHash<PODType, PODTypeCreator> CacheInfoHash; typedef PODTypeWrapperCacheInfoTraits<PODType, PODTypeCreator> CacheInfoTraits; typedef JSSVGPODTypeWrapper<PODType> WrapperBase; - typedef JSSVGDynamicPODTypeWrapper<PODType, PODTypeCreator> DynamicWrapper; - typedef HashMap<CacheInfo, DynamicWrapper*, CacheInfoHash, CacheInfoTraits> DynamicWrapperHashMap; - typedef typename DynamicWrapperHashMap::const_iterator DynamicWrapperHashMapIterator; + typedef JSSVGDynamicPODTypeWrapper<PODType, PODTypeCreator> Wrapper; + typedef HashMap<CacheInfo, Wrapper*, CacheInfoHash, CacheInfoTraits> WrapperMap; - static DynamicWrapperHashMap& dynamicWrapperHashMap() + static WrapperMap& wrapperMap() { - DEFINE_STATIC_LOCAL(DynamicWrapperHashMap, s_dynamicWrapperHashMap, ()); - return s_dynamicWrapperHashMap; + DEFINE_STATIC_LOCAL(WrapperMap, s_wrapperMap, ()); + return s_wrapperMap; } - // Used for readwrite attributes only static PassRefPtr<WrapperBase> lookupOrCreateWrapper(PODTypeCreator* creator, GetterMethod getter, SetterMethod setter) { - DynamicWrapperHashMap& map(dynamicWrapperHashMap()); CacheInfo info(creator, getter, setter); + pair<typename WrapperMap::iterator, bool> result = wrapperMap().add(info, 0); + if (!result.second) // pre-existing entry + return result.first->second; - if (map.contains(info)) - return map.get(info); - - RefPtr<DynamicWrapper> wrapper = DynamicWrapper::create(creator, getter, setter); - map.set(info, wrapper.get()); + RefPtr<Wrapper> wrapper = Wrapper::create(creator, getter, setter); + result.first->second = wrapper.get(); return wrapper.release(); } - static void forgetWrapper(WrapperBase* wrapper) + static void forgetWrapper(PODTypeCreator* creator, GetterMethod getter, SetterMethod setter) { - DynamicWrapperHashMap& map(dynamicWrapperHashMap()); - - DynamicWrapperHashMapIterator it = map.begin(); - DynamicWrapperHashMapIterator end = map.end(); - - for (; it != end; ++it) { - if (it->second != wrapper) - continue; - - // It's guaranteed that there's just one object we need to take care of. - map.remove(it->first); - break; - } + CacheInfo info(creator, getter, setter); + wrapperMap().remove(info); } }; -}; +template<typename PODType, typename PODTypeCreator> +JSSVGDynamicPODTypeWrapper<PODType, PODTypeCreator>::~JSSVGDynamicPODTypeWrapper() +{ + JSSVGDynamicPODTypeWrapperCache<PODType, PODTypeCreator>::forgetWrapper(m_creator.get(), m_getter, m_setter); +} + +} // namespace WebCore #endif // ENABLE(SVG) #endif // JSSVGPODTypeWrapper_h diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSSVGPathSegCustom.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSSVGPathSegCustom.cpp index 42fa878..eac2c4b 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSSVGPathSegCustom.cpp +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSSVGPathSegCustom.cpp @@ -21,6 +21,8 @@ #if ENABLE(SVG) #include "JSSVGPathSeg.h" + +#include "JSDOMBinding.h" #include "JSSVGPathSegArcAbs.h" #include "JSSVGPathSegArcRel.h" #include "JSSVGPathSegClosePath.h" @@ -40,9 +42,6 @@ #include "JSSVGPathSegLinetoVerticalRel.h" #include "JSSVGPathSegMovetoAbs.h" #include "JSSVGPathSegMovetoRel.h" - -#include "JSDOMBinding.h" - #include "SVGPathSeg.h" #include "SVGPathSegArc.h" #include "SVGPathSegClosePath.h" @@ -64,8 +63,10 @@ JSValue toJS(ExecState* exec, JSDOMGlobalObject* globalObject, SVGPathSeg* objec if (!object) return jsNull(); - if (DOMObject* wrapper = getCachedDOMObjectWrapper(exec->globalData(), object)) + if (DOMObject* wrapper = getCachedDOMObjectWrapper(exec, object)) { + ASSERT(JSSVGContextCache::svgContextForDOMObject(wrapper) == context); return wrapper; + } switch (object->pathSegType()) { case SVGPathSeg::PATHSEG_CLOSEPATH: @@ -115,5 +116,3 @@ JSValue toJS(ExecState* exec, JSDOMGlobalObject* globalObject, SVGPathSeg* objec } #endif // ENABLE(SVG) - -// vim:ts=4:noet diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSSVGPathSegListCustom.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSSVGPathSegListCustom.cpp index b71f3a6..4831727 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSSVGPathSegListCustom.cpp +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSSVGPathSegListCustom.cpp @@ -24,6 +24,7 @@ #include "Document.h" #include "Frame.h" +#include "JSSVGContextCache.h" #include "JSSVGPathSeg.h" #include "SVGDocumentExtensions.h" #include "SVGElement.h" @@ -39,12 +40,12 @@ JSValue JSSVGPathSegList::clear(ExecState* exec, const ArgList&) { ExceptionCode ec = 0; - SVGPathSegList* imp = static_cast<SVGPathSegList*>(impl()); - imp->clear(ec); + SVGPathSegList* list = impl(); + list->clear(ec); setDOMException(exec, ec); - m_context->svgAttributeChanged(imp->associatedAttributeName()); + JSSVGContextCache::propagateSVGDOMChange(this, list->associatedAttributeName()); return jsUndefined(); } @@ -53,14 +54,15 @@ JSValue JSSVGPathSegList::initialize(ExecState* exec, const ArgList& args) ExceptionCode ec = 0; SVGPathSeg* newItem = toSVGPathSeg(args.at(0)); - SVGPathSegList* imp = static_cast<SVGPathSegList*>(impl()); + SVGPathSegList* list = impl(); - SVGPathSeg* obj = WTF::getPtr(imp->initialize(newItem, ec)); + SVGPathSeg* obj = WTF::getPtr(list->initialize(newItem, ec)); + SVGElement* context = JSSVGContextCache::svgContextForDOMObject(this); - JSC::JSValue result = toJS(exec, deprecatedGlobalObjectForPrototype(exec), obj, m_context.get()); + JSValue result = toJS(exec, globalObject(), obj, context); setDOMException(exec, ec); - m_context->svgAttributeChanged(imp->associatedAttributeName()); + JSSVGContextCache::propagateSVGDOMChange(this, list->associatedAttributeName()); return result; } @@ -75,10 +77,11 @@ JSValue JSSVGPathSegList::getItem(ExecState* exec, const ArgList& args) return jsUndefined(); } - SVGPathSegList* imp = static_cast<SVGPathSegList*>(impl()); - SVGPathSeg* obj = WTF::getPtr(imp->getItem(index, ec)); + SVGPathSegList* list = impl(); + SVGPathSeg* obj = WTF::getPtr(list->getItem(index, ec)); + SVGElement* context = JSSVGContextCache::svgContextForDOMObject(this); - JSC::JSValue result = toJS(exec, deprecatedGlobalObjectForPrototype(exec), obj, m_context.get()); + JSValue result = toJS(exec, globalObject(), obj, context); setDOMException(exec, ec); return result; } @@ -95,12 +98,13 @@ JSValue JSSVGPathSegList::insertItemBefore(ExecState* exec, const ArgList& args) return jsUndefined(); } - SVGPathSegList* imp = static_cast<SVGPathSegList*>(impl()); + SVGPathSegList* list = impl(); + SVGElement* context = JSSVGContextCache::svgContextForDOMObject(this); - JSC::JSValue result = toJS(exec, deprecatedGlobalObjectForPrototype(exec), WTF::getPtr(imp->insertItemBefore(newItem, index, ec)), m_context.get()); + JSValue result = toJS(exec, globalObject(), WTF::getPtr(list->insertItemBefore(newItem, index, ec)), context); setDOMException(exec, ec); - m_context->svgAttributeChanged(imp->associatedAttributeName()); + JSSVGContextCache::propagateSVGDOMChange(this, list->associatedAttributeName()); return result; } @@ -116,12 +120,13 @@ JSValue JSSVGPathSegList::replaceItem(ExecState* exec, const ArgList& args) return jsUndefined(); } - SVGPathSegList* imp = static_cast<SVGPathSegList*>(impl()); + SVGPathSegList* list = impl(); + SVGElement* context = JSSVGContextCache::svgContextForDOMObject(this); - JSC::JSValue result = toJS(exec, deprecatedGlobalObjectForPrototype(exec), WTF::getPtr(imp->replaceItem(newItem, index, ec)), m_context.get()); + JSValue result = toJS(exec, globalObject(), WTF::getPtr(list->replaceItem(newItem, index, ec)), context); setDOMException(exec, ec); - m_context->svgAttributeChanged(imp->associatedAttributeName()); + JSSVGContextCache::propagateSVGDOMChange(this, list->associatedAttributeName()); return result; } @@ -136,14 +141,15 @@ JSValue JSSVGPathSegList::removeItem(ExecState* exec, const ArgList& args) return jsUndefined(); } - SVGPathSegList* imp = static_cast<SVGPathSegList*>(impl()); + SVGPathSegList* list = impl(); - RefPtr<SVGPathSeg> obj(imp->removeItem(index, ec)); + RefPtr<SVGPathSeg> obj(list->removeItem(index, ec)); + SVGElement* context = JSSVGContextCache::svgContextForDOMObject(this); - JSC::JSValue result = toJS(exec, deprecatedGlobalObjectForPrototype(exec), obj.get(), m_context.get()); + JSValue result = toJS(exec, globalObject(), obj.get(), context); setDOMException(exec, ec); - m_context->svgAttributeChanged(imp->associatedAttributeName()); + JSSVGContextCache::propagateSVGDOMChange(this, list->associatedAttributeName()); return result; } @@ -152,12 +158,13 @@ JSValue JSSVGPathSegList::appendItem(ExecState* exec, const ArgList& args) ExceptionCode ec = 0; SVGPathSeg* newItem = toSVGPathSeg(args.at(0)); - SVGPathSegList* imp = static_cast<SVGPathSegList*>(impl()); + SVGPathSegList* list = impl(); + SVGElement* context = JSSVGContextCache::svgContextForDOMObject(this); - JSC::JSValue result = toJS(exec, deprecatedGlobalObjectForPrototype(exec), WTF::getPtr(imp->appendItem(newItem, ec)), m_context.get()); + JSValue result = toJS(exec, globalObject(), WTF::getPtr(list->appendItem(newItem, ec)), context); setDOMException(exec, ec); - m_context->svgAttributeChanged(imp->associatedAttributeName()); + JSSVGContextCache::propagateSVGDOMChange(this, list->associatedAttributeName()); return result; } diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSSVGPointListCustom.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSSVGPointListCustom.cpp deleted file mode 100644 index 1969fe2..0000000 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSSVGPointListCustom.cpp +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Copyright (C) 2006, 2007, 2008 Nikolas Zimmermann <zimmermann@kde.org> - * Copyright (C) 2008 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#include "config.h" - -#if ENABLE(SVG) -#include "JSSVGPointList.h" - -#include "JSSVGPoint.h" -#include "SVGPointList.h" - -using namespace JSC; - -namespace WebCore { - -typedef SVGPODListItem<FloatPoint> PODListItem; -typedef SVGList<RefPtr<PODListItem> > SVGPointListBase; - -static JSValue finishGetter(ExecState* exec, ExceptionCode& ec, SVGElement* context, SVGPointList* list, PassRefPtr<PODListItem > item) -{ - if (ec) { - setDOMException(exec, ec); - return jsUndefined(); - } - return toJS(exec, deprecatedGlobalObjectForPrototype(exec), JSSVGPODTypeWrapperCreatorForList<FloatPoint>::create(item.get(), list->associatedAttributeName()).get(), context); -} - -static JSValue finishSetter(ExecState* exec, ExceptionCode& ec, SVGElement* context, SVGPointList* list, PassRefPtr<PODListItem > item) -{ - if (ec) { - setDOMException(exec, ec); - return jsUndefined(); - } - const QualifiedName& attributeName = list->associatedAttributeName(); - context->svgAttributeChanged(attributeName); - return toJS(exec, deprecatedGlobalObjectForPrototype(exec), JSSVGPODTypeWrapperCreatorForList<FloatPoint>::create(item.get(), attributeName).get(), context); -} - -static JSValue finishSetterReadOnlyResult(ExecState* exec, ExceptionCode& ec, SVGElement* context, SVGPointList* list, PassRefPtr<PODListItem> item) -{ - if (ec) { - setDOMException(exec, ec); - return jsUndefined(); - } - context->svgAttributeChanged(list->associatedAttributeName()); - return toJS(exec, deprecatedGlobalObjectForPrototype(exec), JSSVGStaticPODTypeWrapper<FloatPoint>::create(*item).get(), context); -} - -JSValue JSSVGPointList::clear(ExecState* exec, const ArgList&) -{ - ExceptionCode ec = 0; - impl()->clear(ec); - setDOMException(exec, ec); - m_context->svgAttributeChanged(impl()->associatedAttributeName()); - return jsUndefined(); -} - -JSValue JSSVGPointList::initialize(ExecState* exec, const ArgList& args) -{ - ExceptionCode ec = 0; - SVGPointListBase* listImp = impl(); - return finishSetter(exec, ec, context(), impl(), - listImp->initialize(PODListItem::copy(toSVGPoint(args.at(0))), ec)); -} - -JSValue JSSVGPointList::getItem(ExecState* exec, const ArgList& args) -{ - bool indexOk; - unsigned index = args.at(0).toUInt32(exec, indexOk); - if (!indexOk) { - setDOMException(exec, TYPE_MISMATCH_ERR); - return jsUndefined(); - } - - ExceptionCode ec = 0; - SVGPointListBase* listImp = impl(); - return finishGetter(exec, ec, context(), impl(), - listImp->getItem(index, ec)); -} - -JSValue JSSVGPointList::insertItemBefore(ExecState* exec, const ArgList& args) -{ - bool indexOk; - unsigned index = args.at(1).toUInt32(exec, indexOk); - if (!indexOk) { - setDOMException(exec, TYPE_MISMATCH_ERR); - return jsUndefined(); - } - - ExceptionCode ec = 0; - SVGPointListBase* listImp = impl(); - return finishSetter(exec, ec, context(), impl(), - listImp->insertItemBefore(PODListItem::copy(toSVGPoint(args.at(0))), index, ec)); -} - -JSValue JSSVGPointList::replaceItem(ExecState* exec, const ArgList& args) -{ - bool indexOk; - unsigned index = args.at(1).toInt32(exec, indexOk); - if (!indexOk) { - setDOMException(exec, TYPE_MISMATCH_ERR); - return jsUndefined(); - } - - ExceptionCode ec = 0; - SVGPointListBase* listImp = impl(); - return finishSetter(exec, ec, context(), impl(), - listImp->replaceItem(PODListItem::copy(toSVGPoint(args.at(0))), index, ec)); -} - -JSValue JSSVGPointList::removeItem(ExecState* exec, const ArgList& args) -{ - bool indexOk; - unsigned index = args.at(0).toInt32(exec, indexOk); - if (!indexOk) { - setDOMException(exec, TYPE_MISMATCH_ERR); - return jsUndefined(); - } - - ExceptionCode ec = 0; - SVGPointListBase* listImp = impl(); - return finishSetterReadOnlyResult(exec, ec, context(), impl(), - listImp->removeItem(index, ec)); -} - -JSValue JSSVGPointList::appendItem(ExecState* exec, const ArgList& args) -{ - ExceptionCode ec = 0; - SVGPointListBase* listImp = impl(); - return finishSetter(exec, ec, context(), impl(), - listImp->appendItem(PODListItem::copy(toSVGPoint(args.at(0))), ec)); -} - -} - -#endif // ENABLE(SVG) diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSSVGTransformListCustom.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSSVGTransformListCustom.cpp deleted file mode 100644 index 1a9110a..0000000 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSSVGTransformListCustom.cpp +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Copyright (C) 2007, 2008 Nikolas Zimmermann <zimmermann@kde.org> - * Copyright (C) 2008 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#include "config.h" - -#if ENABLE(SVG) -#include "JSSVGTransformList.h" - -#include "JSSVGTransform.h" -#include "SVGTransformList.h" - -using namespace JSC; - -namespace WebCore { - -typedef SVGPODListItem<SVGTransform> PODListItem; -typedef SVGList<RefPtr<PODListItem> > SVGTransformListBase; - -static JSValue finishGetter(ExecState* exec, ExceptionCode& ec, SVGElement* context, SVGTransformList* list, PassRefPtr<PODListItem> item) -{ - if (ec) { - setDOMException(exec, ec); - return jsUndefined(); - } - return toJS(exec, deprecatedGlobalObjectForPrototype(exec), JSSVGPODTypeWrapperCreatorForList<SVGTransform>::create(item.get(), list->associatedAttributeName()).get(), context); -} - -static JSValue finishSetter(ExecState* exec, ExceptionCode& ec, SVGElement* context, SVGTransformList* list, PassRefPtr<PODListItem> item) -{ - if (ec) { - setDOMException(exec, ec); - return jsUndefined(); - } - const QualifiedName& attributeName = list->associatedAttributeName(); - context->svgAttributeChanged(attributeName); - return toJS(exec, deprecatedGlobalObjectForPrototype(exec), JSSVGPODTypeWrapperCreatorForList<SVGTransform>::create(item.get(), attributeName).get(), context); -} - -static JSValue finishSetterReadOnlyResult(ExecState* exec, ExceptionCode& ec, SVGElement* context, SVGTransformList* list, PassRefPtr<PODListItem> item) -{ - if (ec) { - setDOMException(exec, ec); - return jsUndefined(); - } - context->svgAttributeChanged(list->associatedAttributeName()); - return toJS(exec, deprecatedGlobalObjectForPrototype(exec), JSSVGStaticPODTypeWrapper<SVGTransform>::create(*item).get(), context); -} - -JSValue JSSVGTransformList::clear(ExecState* exec, const ArgList&) -{ - ExceptionCode ec = 0; - impl()->clear(ec); - setDOMException(exec, ec); - m_context->svgAttributeChanged(impl()->associatedAttributeName()); - return jsUndefined(); -} - -JSValue JSSVGTransformList::initialize(ExecState* exec, const ArgList& args) -{ - ExceptionCode ec = 0; - SVGTransformListBase* listImp = impl(); - return finishSetter(exec, ec, context(), impl(), - listImp->initialize(PODListItem::copy(toSVGTransform(args.at(0))), ec)); -} - -JSValue JSSVGTransformList::getItem(ExecState* exec, const ArgList& args) -{ - bool indexOk; - unsigned index = args.at(0).toUInt32(exec, indexOk); - if (!indexOk) { - setDOMException(exec, TYPE_MISMATCH_ERR); - return jsUndefined(); - } - - ExceptionCode ec = 0; - SVGTransformListBase* listImp = impl(); - return finishGetter(exec, ec, context(), impl(), - listImp->getItem(index, ec)); -} - -JSValue JSSVGTransformList::insertItemBefore(ExecState* exec, const ArgList& args) -{ - bool indexOk; - unsigned index = args.at(1).toUInt32(exec, indexOk); - if (!indexOk) { - setDOMException(exec, TYPE_MISMATCH_ERR); - return jsUndefined(); - } - - ExceptionCode ec = 0; - SVGTransformListBase* listImp = impl(); - return finishSetter(exec, ec, context(), impl(), - listImp->insertItemBefore(PODListItem::copy(toSVGTransform(args.at(0))), index, ec)); -} - -JSValue JSSVGTransformList::replaceItem(ExecState* exec, const ArgList& args) -{ - bool indexOk; - unsigned index = args.at(1).toUInt32(exec, indexOk); - if (!indexOk) { - setDOMException(exec, TYPE_MISMATCH_ERR); - return jsUndefined(); - } - - ExceptionCode ec = 0; - SVGTransformListBase* listImp = impl(); - return finishSetter(exec, ec, context(), impl(), - listImp->replaceItem(PODListItem::copy(toSVGTransform(args.at(0))), index, ec)); -} - -JSValue JSSVGTransformList::removeItem(ExecState* exec, const ArgList& args) -{ - bool indexOk; - unsigned index = args.at(0).toUInt32(exec, indexOk); - if (!indexOk) { - setDOMException(exec, TYPE_MISMATCH_ERR); - return jsUndefined(); - } - - ExceptionCode ec = 0; - SVGTransformListBase* listImp = impl(); - return finishSetterReadOnlyResult(exec, ec, context(), impl(), - listImp->removeItem(index, ec)); -} - -JSValue JSSVGTransformList::appendItem(ExecState* exec, const ArgList& args) -{ - ExceptionCode ec = 0; - SVGTransformListBase* listImp = impl(); - return finishSetter(exec, ec, context(), impl(), - listImp->appendItem(PODListItem::copy(toSVGTransform(args.at(0))), ec)); -} - -} - -#endif // ENABLE(SVG) diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSStorageCustom.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSStorageCustom.cpp index e416d35..63a38d6 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSStorageCustom.cpp +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSStorageCustom.cpp @@ -41,9 +41,9 @@ bool JSStorage::canGetItemsForName(ExecState*, Storage* impl, const Identifier& return impl->contains(propertyName); } -JSValue JSStorage::nameGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot) +JSValue JSStorage::nameGetter(ExecState* exec, JSValue slotBase, const Identifier& propertyName) { - JSStorage* thisObj = static_cast<JSStorage*>(asObject(slot.slotBase())); + JSStorage* thisObj = static_cast<JSStorage*>(asObject(slotBase)); return jsStringOrNull(exec, thisObj->impl()->getItem(propertyName)); } @@ -64,13 +64,13 @@ bool JSStorage::deleteProperty(ExecState* exec, const Identifier& propertyName) return true; } -void JSStorage::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames) +void JSStorage::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode) { unsigned length = m_impl->length(); for (unsigned i = 0; i < length; ++i) propertyNames.add(Identifier(exec, m_impl->key(i))); - Base::getOwnPropertyNames(exec, propertyNames); + Base::getOwnPropertyNames(exec, propertyNames, mode); } bool JSStorage::putDelegate(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot&) diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSStyleSheetCustom.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSStyleSheetCustom.cpp index d711b6f..ecfc6a6 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSStyleSheetCustom.cpp +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSStyleSheetCustom.cpp @@ -40,7 +40,7 @@ JSValue toJS(ExecState* exec, JSDOMGlobalObject* globalObject, StyleSheet* style if (!styleSheet) return jsNull(); - DOMObject* wrapper = getCachedDOMObjectWrapper(exec->globalData(), styleSheet); + DOMObject* wrapper = getCachedDOMObjectWrapper(exec, styleSheet); if (wrapper) return wrapper; @@ -68,10 +68,8 @@ void JSStyleSheet::markChildren(MarkStack& markStack) // is kept around, then we want the node to stay around too. One possibility would // be to make ref/deref on the style sheet ref/deref the node instead, but there's // a lot of disentangling of the CSS DOM objects that would need to happen first. - if (Node* ownerNode = sheet->ownerNode()) { - if (JSNode* ownerNodeWrapper = getCachedDOMNodeWrapper(ownerNode->document(), ownerNode)) - markStack.append(ownerNodeWrapper); - } + if (Node* ownerNode = sheet->ownerNode()) + markDOMNodeWrapper(markStack, ownerNode->document(), ownerNode); } } // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSStyleSheetListCustom.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSStyleSheetListCustom.cpp index 7bf9389..873f211 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSStyleSheetListCustom.cpp +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSStyleSheetListCustom.cpp @@ -52,9 +52,9 @@ bool JSStyleSheetList::canGetItemsForName(ExecState*, StyleSheetList* styleSheet return styleSheetList->getNamedItem(propertyName); } -JSValue JSStyleSheetList::nameGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot) +JSValue JSStyleSheetList::nameGetter(ExecState* exec, JSValue slotBase, const Identifier& propertyName) { - JSStyleSheetList* thisObj = static_cast<JSStyleSheetList*>(asObject(slot.slotBase())); + JSStyleSheetList* thisObj = static_cast<JSStyleSheetList*>(asObject(slotBase)); HTMLStyleElement* element = thisObj->impl()->getNamedItem(propertyName); ASSERT(element); return toJS(exec, element->sheet()); diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSCanvasArrayBufferConstructor.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSWebGLArrayBufferConstructor.cpp index 93d53ca..8671908 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSCanvasArrayBufferConstructor.cpp +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSWebGLArrayBufferConstructor.cpp @@ -27,28 +27,27 @@ #if ENABLE(3D_CANVAS) -#include "JSCanvasArrayBufferConstructor.h" +#include "JSWebGLArrayBufferConstructor.h" #include "Document.h" -#include "CanvasArrayBuffer.h" -#include "JSCanvasArrayBuffer.h" +#include "JSWebGLArrayBuffer.h" namespace WebCore { using namespace JSC; -const ClassInfo JSCanvasArrayBufferConstructor::s_info = { "CanvasArrayBufferConstructor", 0, 0, 0 }; +const ClassInfo JSWebGLArrayBufferConstructor::s_info = { "WebGLArrayBufferConstructor", 0, 0, 0 }; -JSCanvasArrayBufferConstructor::JSCanvasArrayBufferConstructor(ExecState* exec, JSDOMGlobalObject* globalObject) - : DOMConstructorObject(JSCanvasArrayBufferConstructor::createStructure(globalObject->objectPrototype()), globalObject) +JSWebGLArrayBufferConstructor::JSWebGLArrayBufferConstructor(ExecState* exec, JSDOMGlobalObject* globalObject) + : DOMConstructorObject(JSWebGLArrayBufferConstructor::createStructure(globalObject->objectPrototype()), globalObject) { - putDirect(exec->propertyNames().prototype, JSCanvasArrayBufferPrototype::self(exec, globalObject), None); + putDirect(exec->propertyNames().prototype, JSWebGLArrayBufferPrototype::self(exec, globalObject), None); putDirect(exec->propertyNames().length, jsNumber(exec, 2), ReadOnly|DontDelete|DontEnum); } static JSObject* constructCanvasArrayBuffer(ExecState* exec, JSObject* constructor, const ArgList& args) { - JSCanvasArrayBufferConstructor* jsConstructor = static_cast<JSCanvasArrayBufferConstructor*>(constructor); + JSWebGLArrayBufferConstructor* jsConstructor = static_cast<JSWebGLArrayBufferConstructor*>(constructor); unsigned int size = 0; if (args.size() == 1) { @@ -56,10 +55,15 @@ static JSObject* constructCanvasArrayBuffer(ExecState* exec, JSObject* construct if (isnan(size)) size = 0; } - return asObject(toJS(exec, jsConstructor->globalObject(), CanvasArrayBuffer::create(size))); + RefPtr<WebGLArrayBuffer> buffer = WebGLArrayBuffer::create(size, 1); + if (!buffer.get()){ + setDOMException(exec, INDEX_SIZE_ERR); + return 0; + } + return asObject(toJS(exec, jsConstructor->globalObject(), buffer.get())); } -JSC::ConstructType JSCanvasArrayBufferConstructor::getConstructData(JSC::ConstructData& constructData) +JSC::ConstructType JSWebGLArrayBufferConstructor::getConstructData(JSC::ConstructData& constructData) { constructData.native.function = constructCanvasArrayBuffer; return ConstructTypeHost; diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSCanvasArrayBufferConstructor.h b/src/3rdparty/webkit/WebCore/bindings/js/JSWebGLArrayBufferConstructor.h index 5f1254e..c7a927e 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSCanvasArrayBufferConstructor.h +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSWebGLArrayBufferConstructor.h @@ -23,26 +23,27 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef JSCanvasArrayBufferConstructor_h -#define JSCanvasArrayBufferConstructor_h +#ifndef JSWebGLArrayBufferConstructor_h +#define JSWebGLArrayBufferConstructor_h #include "JSDOMBinding.h" #include "JSDocument.h" -#include "JSCanvasArrayBuffer.h" +#include "JSWebGLArrayBuffer.h" #include <runtime/Error.h> +#include "WebGLArrayBuffer.h" namespace WebCore { - class CanvasArray; + class WebGLArray; // Template function used by CanvasXXXArrayConstructors template<class C, typename T> - PassRefPtr<CanvasArray> construct(JSC::ExecState* exec, const JSC::ArgList& args) + PassRefPtr<WebGLArray> construct(JSC::ExecState* exec, const JSC::ArgList& args) { // There are 3 constructors: // // 1) (in int size) - // 2) (in CanvasArrayBuffer buffer, [Optional] in int offset, [Optional] in unsigned int length) + // 2) (in WebGLArrayBuffer buffer, [Optional] in int offset, [Optional] in unsigned int length) // 3) (in sequence<T>) - This ends up being a JS "array-like" object // RefPtr<C> arrayObject; @@ -51,24 +52,30 @@ namespace WebCore { if (args.size() < 1) return C::create(0, 0, 0); + if (args.size() > 1 && !args.at(0).isObject()) + // Invalid first argument + return 0; + if (args.at(0).isObject()) { - RefPtr<CanvasArrayBuffer> buffer = toCanvasArrayBuffer(args.at(0)); + RefPtr<WebGLArrayBuffer> buffer = toWebGLArrayBuffer(args.at(0)); if (buffer) { - int offset = (args.size() > 1) ? args.at(1).toInt32(exec) : 0; - unsigned int length = (args.size() > 2) ? static_cast<unsigned int>(args.at(2).toInt32(exec)) : 0; + unsigned offset = (args.size() > 1) ? args.at(1).toUInt32(exec) : 0; + unsigned int length = (buffer->byteLength() - offset) / sizeof(T); + if (args.size() > 2) + length = args.at(2).toUInt32(exec); return C::create(buffer, offset, length); } JSC::JSObject* array = asObject(args.at(0)); - int length = array->get(exec, JSC::Identifier(exec, "length")).toInt32(exec); + unsigned length = array->get(exec, JSC::Identifier(exec, "length")).toUInt32(exec); void* tempValues; - if (!tryFastMalloc(length * sizeof(T)).getValue(tempValues)) { + if (!tryFastCalloc(length, sizeof(T)).getValue(tempValues)) { throwError(exec, JSC::GeneralError); return 0; } OwnFastMallocPtr<T> values(static_cast<T*>(tempValues)); - for (int i = 0; i < length; ++i) { + for (unsigned i = 0; i < length; ++i) { JSC::JSValue v = array->get(exec, i); if (exec->hadException()) return 0; @@ -78,13 +85,13 @@ namespace WebCore { return C::create(values.get(), length); } - unsigned size = static_cast<unsigned>(args.at(0).toInt32(exec)); + unsigned size = args.at(0).toUInt32(exec); return C::create(size); } - class JSCanvasArrayBufferConstructor : public DOMConstructorObject { + class JSWebGLArrayBufferConstructor : public DOMConstructorObject { public: - JSCanvasArrayBufferConstructor(JSC::ExecState*, JSDOMGlobalObject*); + JSWebGLArrayBufferConstructor(JSC::ExecState*, JSDOMGlobalObject*); static const JSC::ClassInfo s_info; private: @@ -94,4 +101,4 @@ namespace WebCore { } -#endif // JSCanvasArrayBufferConstructor_h +#endif // JSWebGLArrayBufferConstructor_h diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSWebGLArrayCustom.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSWebGLArrayCustom.cpp new file mode 100644 index 0000000..d111d4e --- /dev/null +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSWebGLArrayCustom.cpp @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2009 Apple 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(3D_CANVAS) + +#include "config.h" +#include "JSWebGLArray.h" +#include "JSWebGLByteArray.h" +#include "JSWebGLUnsignedByteArray.h" +#include "JSWebGLShortArray.h" +#include "JSWebGLUnsignedShortArray.h" +#include "JSWebGLIntArray.h" +#include "JSWebGLUnsignedIntArray.h" +#include "JSWebGLFloatArray.h" + +#include "WebGLArray.h" + +using namespace JSC; + +namespace WebCore { + +JSC::JSValue toJS(JSC::ExecState* exec, JSDOMGlobalObject* globalObject, WebGLArray* object) +{ + if (!object) + return jsUndefined(); + + if (object) { + if (object->isFloatArray()) + return getDOMObjectWrapper<JSWebGLFloatArray>(exec, globalObject, static_cast<WebGLFloatArray*>(object)); + if (object->isUnsignedByteArray()) + return getDOMObjectWrapper<JSWebGLUnsignedByteArray>(exec, globalObject, static_cast<WebGLUnsignedByteArray*>(object)); + if (object->isByteArray()) + return getDOMObjectWrapper<JSWebGLByteArray>(exec, globalObject, static_cast<WebGLByteArray*>(object)); + if (object->isIntArray()) + return getDOMObjectWrapper<JSWebGLIntArray>(exec, globalObject, static_cast<WebGLIntArray*>(object)); + if (object->isUnsignedIntArray()) + return getDOMObjectWrapper<JSWebGLUnsignedIntArray>(exec, globalObject, static_cast<WebGLUnsignedIntArray*>(object)); + if (object->isShortArray()) + return getDOMObjectWrapper<JSWebGLShortArray>(exec, globalObject, static_cast<WebGLShortArray*>(object)); + if (object->isUnsignedShortArray()) + return getDOMObjectWrapper<JSWebGLUnsignedShortArray>(exec, globalObject, static_cast<WebGLUnsignedShortArray*>(object)); + } + return jsUndefined(); +} + +JSValue JSWebGLArray::slice(ExecState* exec, const ArgList& args) +{ + WebGLArray* array = reinterpret_cast<WebGLArray*>(impl()); + + int start, end; + switch (args.size()) { + case 0: + start = 0; + end = array->length(); + break; + case 1: + start = args.at(0).toInt32(exec); + end = array->length(); + break; + default: + start = args.at(0).toInt32(exec); + end = args.at(1).toInt32(exec); + } + return toJS(exec, globalObject(), array->slice(start, end)); +} + +} // namespace WebCore + +#endif // ENABLE(3D_CANVAS) diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSWebGLArrayHelper.h b/src/3rdparty/webkit/WebCore/bindings/js/JSWebGLArrayHelper.h new file mode 100644 index 0000000..481c68f --- /dev/null +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSWebGLArrayHelper.h @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2009 Apple Inc. All rights reserved. + * Copyright (C) 2009 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 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 JSWebGLArrayHelper_h +#define JSWebGLArrayHelper_h + +#include "ExceptionCode.h" +#include "JSDOMBinding.h" +#include <interpreter/CallFrame.h> +#include <runtime/ArgList.h> +#include <runtime/Error.h> +#include <runtime/JSObject.h> +#include <runtime/JSValue.h> + +namespace WebCore { + +template <class T> +JSC::JSValue setWebGLArrayFromArray(JSC::ExecState* exec, T* webGLArray, JSC::ArgList const& args) +{ + if (args.at(0).isObject()) { + // void set(in sequence<long> array, [Optional] in unsigned long offset); + JSC::JSObject* array = JSC::asObject(args.at(0)); + uint32_t offset = 0; + if (args.size() == 2) + offset = args.at(1).toInt32(exec); + uint32_t length = array->get(exec, JSC::Identifier(exec, "length")).toInt32(exec); + if (offset > webGLArray->length() || + offset + length > webGLArray->length() || + offset + length < offset) + setDOMException(exec, INDEX_SIZE_ERR); + else { + for (uint32_t i = 0; i < length; i++) { + JSC::JSValue v = array->get(exec, i); + if (exec->hadException()) + return JSC::jsUndefined(); + webGLArray->set(i + offset, v.toNumber(exec)); + } + } + + return JSC::jsUndefined(); + } + + return JSC::throwError(exec, JSC::SyntaxError); +} + +} + +#endif // JSWebGLArrayHelper_h diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSCanvasFloatArrayConstructor.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSWebGLByteArrayConstructor.cpp index 15e39c2..f76fb1d 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSCanvasFloatArrayConstructor.cpp +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSWebGLByteArrayConstructor.cpp @@ -27,38 +27,42 @@ #if ENABLE(3D_CANVAS) -#include "JSCanvasFloatArrayConstructor.h" +#include "JSWebGLByteArrayConstructor.h" #include "Document.h" -#include "CanvasFloatArray.h" -#include "JSCanvasArrayBuffer.h" -#include "JSCanvasArrayBufferConstructor.h" -#include "JSCanvasFloatArray.h" +#include "WebGLByteArray.h" +#include "JSWebGLArrayBuffer.h" +#include "JSWebGLArrayBufferConstructor.h" +#include "JSWebGLByteArray.h" #include <runtime/Error.h> namespace WebCore { using namespace JSC; -const ClassInfo JSCanvasFloatArrayConstructor::s_info = { "CanvasFloatArrayConstructor", &JSCanvasArray::s_info, 0, 0 }; +const ClassInfo JSWebGLByteArrayConstructor::s_info = { "WebGLByteArrayConstructor", &JSWebGLArray::s_info, 0, 0 }; -JSCanvasFloatArrayConstructor::JSCanvasFloatArrayConstructor(ExecState* exec, JSDOMGlobalObject* globalObject) - : DOMConstructorObject(JSCanvasFloatArrayConstructor::createStructure(globalObject->objectPrototype()), globalObject) +JSWebGLByteArrayConstructor::JSWebGLByteArrayConstructor(ExecState* exec, JSDOMGlobalObject* globalObject) + : DOMConstructorObject(JSWebGLByteArrayConstructor::createStructure(globalObject->objectPrototype()), globalObject) { - putDirect(exec->propertyNames().prototype, JSCanvasFloatArrayPrototype::self(exec, globalObject), None); + putDirect(exec->propertyNames().prototype, JSWebGLByteArrayPrototype::self(exec, globalObject), None); putDirect(exec->propertyNames().length, jsNumber(exec, 2), ReadOnly|DontDelete|DontEnum); } -static JSObject* constructCanvasFloatArray(ExecState* exec, JSObject* constructor, const ArgList& args) +static JSObject* constructCanvasByteArray(ExecState* exec, JSObject* constructor, const ArgList& args) { - JSCanvasFloatArrayConstructor* jsConstructor = static_cast<JSCanvasFloatArrayConstructor*>(constructor); - RefPtr<CanvasFloatArray> array = static_cast<CanvasFloatArray*>(construct<CanvasFloatArray, float>(exec, args).get()); + JSWebGLByteArrayConstructor* jsConstructor = static_cast<JSWebGLByteArrayConstructor*>(constructor); + RefPtr<WebGLByteArray> array = static_cast<WebGLByteArray*>(construct<WebGLByteArray, signed char>(exec, args).get()); + if (!array.get()) { + setDOMException(exec, INDEX_SIZE_ERR); + return 0; + } return asObject(toJS(exec, jsConstructor->globalObject(), array.get())); } -JSC::ConstructType JSCanvasFloatArrayConstructor::getConstructData(JSC::ConstructData& constructData) +JSC::ConstructType JSWebGLByteArrayConstructor::getConstructData(JSC::ConstructData& constructData) { - constructData.native.function = constructCanvasFloatArray; + constructData.native.function = constructCanvasByteArray; return ConstructTypeHost; } diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSCanvasIntArrayConstructor.h b/src/3rdparty/webkit/WebCore/bindings/js/JSWebGLByteArrayConstructor.h index 5e19652..a201567 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSCanvasIntArrayConstructor.h +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSWebGLByteArrayConstructor.h @@ -23,17 +23,17 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef JSCanvasIntArrayConstructor_h -#define JSCanvasIntArrayConstructor_h +#ifndef JSWebGLByteArrayConstructor_h +#define JSWebGLByteArrayConstructor_h #include "JSDOMBinding.h" #include "JSDocument.h" namespace WebCore { - class JSCanvasIntArrayConstructor : public DOMConstructorObject { + class JSWebGLByteArrayConstructor : public DOMConstructorObject { public: - JSCanvasIntArrayConstructor(JSC::ExecState*, JSDOMGlobalObject*); + JSWebGLByteArrayConstructor(JSC::ExecState*, JSDOMGlobalObject*); static const JSC::ClassInfo s_info; private: @@ -43,4 +43,4 @@ namespace WebCore { } -#endif // JSCanvasIntArrayConstructor_h +#endif // JSWebGLByteArrayConstructor_h diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSWebGLByteArrayCustom.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSWebGLByteArrayCustom.cpp new file mode 100644 index 0000000..f7872a8 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSWebGLByteArrayCustom.cpp @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2009 Apple 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(3D_CANVAS) + +#include "JSWebGLArrayHelper.h" +#include "JSWebGLByteArray.h" + +#include "WebGLByteArray.h" + +#include <runtime/Error.h> + +using namespace JSC; + +namespace WebCore { + +void JSWebGLByteArray::indexSetter(JSC::ExecState* exec, unsigned index, JSC::JSValue value) +{ + impl()->set(index, static_cast<signed char>(value.toInt32(exec))); +} + +JSC::JSValue toJS(JSC::ExecState* exec, JSDOMGlobalObject* globalObject, WebGLByteArray* object) +{ + return getDOMObjectWrapper<JSWebGLByteArray>(exec, globalObject, object); +} + +JSC::JSValue JSWebGLByteArray::set(JSC::ExecState* exec, JSC::ArgList const& args) +{ + if (args.size() < 1 || args.size() > 2) + return throwError(exec, SyntaxError); + + if (args.size() == 2 && args.at(0).isInt32()) { + // void set(in unsigned long index, in long value); + unsigned index = args.at(0).toUInt32(exec); + impl()->set(index, static_cast<signed char>(args.at(1).toInt32(exec))); + return jsUndefined(); + } + + WebGLByteArray* array = toWebGLByteArray(args.at(0)); + if (array) { + // void set(in WebGLByteArray array, [Optional] in unsigned long offset); + unsigned offset = 0; + if (args.size() == 2) + offset = args.at(1).toInt32(exec); + ExceptionCode ec = 0; + impl()->set(array, offset, ec); + setDOMException(exec, ec); + return jsUndefined(); + } + + return setWebGLArrayFromArray(exec, impl(), args); +} + +} // namespace WebCore + +#endif // ENABLE(3D_CANVAS) diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSCanvasByteArrayConstructor.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSWebGLFloatArrayConstructor.cpp index ec1d66d..e6375ac 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSCanvasByteArrayConstructor.cpp +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSWebGLFloatArrayConstructor.cpp @@ -27,38 +27,42 @@ #if ENABLE(3D_CANVAS) -#include "JSCanvasByteArrayConstructor.h" +#include "JSWebGLFloatArrayConstructor.h" #include "Document.h" -#include "CanvasByteArray.h" -#include "JSCanvasArrayBuffer.h" -#include "JSCanvasArrayBufferConstructor.h" -#include "JSCanvasByteArray.h" +#include "WebGLFloatArray.h" +#include "JSWebGLArrayBuffer.h" +#include "JSWebGLArrayBufferConstructor.h" +#include "JSWebGLFloatArray.h" #include <runtime/Error.h> namespace WebCore { using namespace JSC; -const ClassInfo JSCanvasByteArrayConstructor::s_info = { "CanvasByteArrayConstructor", &JSCanvasArray::s_info, 0, 0 }; +const ClassInfo JSWebGLFloatArrayConstructor::s_info = { "WebGLFloatArrayConstructor", &JSWebGLArray::s_info, 0, 0 }; -JSCanvasByteArrayConstructor::JSCanvasByteArrayConstructor(ExecState* exec, JSDOMGlobalObject* globalObject) - : DOMConstructorObject(JSCanvasByteArrayConstructor::createStructure(globalObject->objectPrototype()), globalObject) +JSWebGLFloatArrayConstructor::JSWebGLFloatArrayConstructor(ExecState* exec, JSDOMGlobalObject* globalObject) + : DOMConstructorObject(JSWebGLFloatArrayConstructor::createStructure(globalObject->objectPrototype()), globalObject) { - putDirect(exec->propertyNames().prototype, JSCanvasByteArrayPrototype::self(exec, globalObject), None); + putDirect(exec->propertyNames().prototype, JSWebGLFloatArrayPrototype::self(exec, globalObject), None); putDirect(exec->propertyNames().length, jsNumber(exec, 2), ReadOnly|DontDelete|DontEnum); } -static JSObject* constructCanvasByteArray(ExecState* exec, JSObject* constructor, const ArgList& args) +static JSObject* constructCanvasFloatArray(ExecState* exec, JSObject* constructor, const ArgList& args) { - JSCanvasByteArrayConstructor* jsConstructor = static_cast<JSCanvasByteArrayConstructor*>(constructor); - RefPtr<CanvasByteArray> array = static_cast<CanvasByteArray*>(construct<CanvasByteArray, signed char>(exec, args).get()); + JSWebGLFloatArrayConstructor* jsConstructor = static_cast<JSWebGLFloatArrayConstructor*>(constructor); + RefPtr<WebGLFloatArray> array = static_cast<WebGLFloatArray*>(construct<WebGLFloatArray, float>(exec, args).get()); + if (!array.get()) { + setDOMException(exec, INDEX_SIZE_ERR); + return 0; + } return asObject(toJS(exec, jsConstructor->globalObject(), array.get())); } -JSC::ConstructType JSCanvasByteArrayConstructor::getConstructData(JSC::ConstructData& constructData) +JSC::ConstructType JSWebGLFloatArrayConstructor::getConstructData(JSC::ConstructData& constructData) { - constructData.native.function = constructCanvasByteArray; + constructData.native.function = constructCanvasFloatArray; return ConstructTypeHost; } diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSCanvasByteArrayConstructor.h b/src/3rdparty/webkit/WebCore/bindings/js/JSWebGLFloatArrayConstructor.h index 4d5dc11..faf90ff 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSCanvasByteArrayConstructor.h +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSWebGLFloatArrayConstructor.h @@ -23,17 +23,17 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef JSCanvasByteArrayConstructor_h -#define JSCanvasByteArrayConstructor_h +#ifndef JSWebGLFloatArrayConstructor_h +#define JSWebGLFloatArrayConstructor_h #include "JSDOMBinding.h" #include "JSDocument.h" namespace WebCore { - class JSCanvasByteArrayConstructor : public DOMConstructorObject { + class JSWebGLFloatArrayConstructor : public DOMConstructorObject { public: - JSCanvasByteArrayConstructor(JSC::ExecState*, JSDOMGlobalObject*); + JSWebGLFloatArrayConstructor(JSC::ExecState*, JSDOMGlobalObject*); static const JSC::ClassInfo s_info; private: @@ -43,4 +43,4 @@ namespace WebCore { } -#endif // JSCanvasByteArrayConstructor_h +#endif // JSWebGLFloatArrayConstructor_h diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSWebGLFloatArrayCustom.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSWebGLFloatArrayCustom.cpp new file mode 100644 index 0000000..f4acbcf --- /dev/null +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSWebGLFloatArrayCustom.cpp @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2009 Apple 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(3D_CANVAS) + +#include "JSWebGLArrayHelper.h" +#include "JSWebGLFloatArray.h" + +#include "WebGLFloatArray.h" + +using namespace JSC; + +namespace WebCore { + +void JSWebGLFloatArray::indexSetter(JSC::ExecState* exec, unsigned index, JSC::JSValue value) +{ + impl()->set(index, static_cast<float>(value.toNumber(exec))); +} + +JSC::JSValue toJS(JSC::ExecState* exec, JSDOMGlobalObject* globalObject, WebGLFloatArray* object) +{ + return getDOMObjectWrapper<JSWebGLFloatArray>(exec, globalObject, object); +} + +JSC::JSValue JSWebGLFloatArray::set(JSC::ExecState* exec, JSC::ArgList const& args) +{ + if (args.size() > 2) + return throwError(exec, SyntaxError); + + if (args.size() == 2 && args.at(0).isInt32()) { + // void set(in unsigned long index, in float value); + unsigned index = args.at(0).toUInt32(exec); + impl()->set(index, static_cast<float>(args.at(1).toNumber(exec))); + return jsUndefined(); + } + + WebGLFloatArray* array = toWebGLFloatArray(args.at(0)); + if (array) { + // void set(in WebGLFloatArray array, [Optional] in unsigned long offset); + unsigned offset = 0; + if (args.size() == 2) + offset = args.at(1).toInt32(exec); + ExceptionCode ec = 0; + impl()->set(array, offset, ec); + setDOMException(exec, ec); + return jsUndefined(); + } + + return setWebGLArrayFromArray(exec, impl(), args); +} + +} // namespace WebCore + +#endif // ENABLE(3D_CANVAS) diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSCanvasIntArrayConstructor.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSWebGLIntArrayConstructor.cpp index 6d57912..5b14803 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSCanvasIntArrayConstructor.cpp +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSWebGLIntArrayConstructor.cpp @@ -27,36 +27,40 @@ #if ENABLE(3D_CANVAS) -#include "JSCanvasIntArrayConstructor.h" +#include "JSWebGLIntArrayConstructor.h" #include "Document.h" -#include "CanvasIntArray.h" -#include "JSCanvasArrayBuffer.h" -#include "JSCanvasArrayBufferConstructor.h" -#include "JSCanvasIntArray.h" +#include "WebGLIntArray.h" +#include "JSWebGLArrayBuffer.h" +#include "JSWebGLArrayBufferConstructor.h" +#include "JSWebGLIntArray.h" #include <runtime/Error.h> namespace WebCore { using namespace JSC; -const ClassInfo JSCanvasIntArrayConstructor::s_info = { "CanvasIntArrayConstructor", &JSCanvasArray::s_info, 0, 0 }; +const ClassInfo JSWebGLIntArrayConstructor::s_info = { "WebGLIntArrayConstructor", &JSWebGLArray::s_info, 0, 0 }; -JSCanvasIntArrayConstructor::JSCanvasIntArrayConstructor(ExecState* exec, JSDOMGlobalObject* globalObject) - : DOMConstructorObject(JSCanvasIntArrayConstructor::createStructure(globalObject->objectPrototype()), globalObject) +JSWebGLIntArrayConstructor::JSWebGLIntArrayConstructor(ExecState* exec, JSDOMGlobalObject* globalObject) + : DOMConstructorObject(JSWebGLIntArrayConstructor::createStructure(globalObject->objectPrototype()), globalObject) { - putDirect(exec->propertyNames().prototype, JSCanvasIntArrayPrototype::self(exec, globalObject), None); + putDirect(exec->propertyNames().prototype, JSWebGLIntArrayPrototype::self(exec, globalObject), None); putDirect(exec->propertyNames().length, jsNumber(exec, 2), ReadOnly|DontDelete|DontEnum); } static JSObject* constructCanvasIntArray(ExecState* exec, JSObject* constructor, const ArgList& args) { - JSCanvasIntArrayConstructor* jsConstructor = static_cast<JSCanvasIntArrayConstructor*>(constructor); - RefPtr<CanvasIntArray> array = static_cast<CanvasIntArray*>(construct<CanvasIntArray, int>(exec, args).get()); + JSWebGLIntArrayConstructor* jsConstructor = static_cast<JSWebGLIntArrayConstructor*>(constructor); + RefPtr<WebGLIntArray> array = static_cast<WebGLIntArray*>(construct<WebGLIntArray, int>(exec, args).get()); + if (!array.get()) { + setDOMException(exec, INDEX_SIZE_ERR); + return 0; + } return asObject(toJS(exec, jsConstructor->globalObject(), array.get())); } -JSC::ConstructType JSCanvasIntArrayConstructor::getConstructData(JSC::ConstructData& constructData) +JSC::ConstructType JSWebGLIntArrayConstructor::getConstructData(JSC::ConstructData& constructData) { constructData.native.function = constructCanvasIntArray; return ConstructTypeHost; diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSCanvasFloatArrayConstructor.h b/src/3rdparty/webkit/WebCore/bindings/js/JSWebGLIntArrayConstructor.h index efea250..d42c046 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSCanvasFloatArrayConstructor.h +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSWebGLIntArrayConstructor.h @@ -23,17 +23,17 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef JSCanvasFloatArrayConstructor_h -#define JSCanvasFloatArrayConstructor_h +#ifndef JSWebGLIntArrayConstructor_h +#define JSWebGLIntArrayConstructor_h #include "JSDOMBinding.h" #include "JSDocument.h" namespace WebCore { - class JSCanvasFloatArrayConstructor : public DOMConstructorObject { + class JSWebGLIntArrayConstructor : public DOMConstructorObject { public: - JSCanvasFloatArrayConstructor(JSC::ExecState*, JSDOMGlobalObject*); + JSWebGLIntArrayConstructor(JSC::ExecState*, JSDOMGlobalObject*); static const JSC::ClassInfo s_info; private: @@ -43,4 +43,4 @@ namespace WebCore { } -#endif // JSCanvasFloatArrayConstructor_h +#endif // JSWebGLIntArrayConstructor_h diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSWebGLIntArrayCustom.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSWebGLIntArrayCustom.cpp new file mode 100644 index 0000000..de08256 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSWebGLIntArrayCustom.cpp @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2009 Apple 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(3D_CANVAS) + +#include "JSWebGLArrayHelper.h" +#include "JSWebGLIntArray.h" + +#include "WebGLIntArray.h" + +using namespace JSC; + +namespace WebCore { + +void JSWebGLIntArray::indexSetter(JSC::ExecState* exec, unsigned index, JSC::JSValue value) +{ + impl()->set(index, static_cast<signed int>(value.toInt32(exec))); +} + +JSC::JSValue toJS(JSC::ExecState* exec, JSDOMGlobalObject* globalObject, WebGLIntArray* object) +{ + return getDOMObjectWrapper<JSWebGLIntArray>(exec, globalObject, object); +} + +JSC::JSValue JSWebGLIntArray::set(JSC::ExecState* exec, JSC::ArgList const& args) +{ + if (args.size() > 2) + return throwError(exec, SyntaxError); + + if (args.size() == 2 && args.at(0).isInt32()) { + // void set(in unsigned long index, in long value); + unsigned index = args.at(0).toUInt32(exec); + impl()->set(index, static_cast<signed int>(args.at(1).toInt32(exec))); + return jsUndefined(); + } + + WebGLIntArray* array = toWebGLIntArray(args.at(0)); + if (array) { + // void set(in WebGLIntArray array, [Optional] in unsigned long offset); + unsigned offset = 0; + if (args.size() == 2) + offset = args.at(1).toInt32(exec); + ExceptionCode ec = 0; + impl()->set(array, offset, ec); + setDOMException(exec, ec); + return jsUndefined(); + } + + return setWebGLArrayFromArray(exec, impl(), args); +} + +} // namespace WebCore + +#endif // ENABLE(3D_CANVAS) diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSWebGLRenderingContextCustom.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSWebGLRenderingContextCustom.cpp new file mode 100644 index 0000000..e336027 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSWebGLRenderingContextCustom.cpp @@ -0,0 +1,835 @@ +/* + * Copyright (C) 2009 Apple 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(3D_CANVAS) + +#include "JSWebGLRenderingContext.h" + +#include "ExceptionCode.h" +#include "HTMLCanvasElement.h" +#include "HTMLImageElement.h" +#include "HTMLVideoElement.h" +#include "JSHTMLCanvasElement.h" +#include "JSHTMLImageElement.h" +#include "JSHTMLVideoElement.h" +#include "JSImageData.h" +#include "JSWebGLBuffer.h" +#include "JSWebGLFloatArray.h" +#include "JSWebGLFramebuffer.h" +#include "JSWebGLIntArray.h" +#include "JSWebGLProgram.h" +#include "JSWebGLRenderbuffer.h" +#include "JSWebGLShader.h" +#include "JSWebGLTexture.h" +#include "JSWebGLUniformLocation.h" +#include "JSWebGLUnsignedByteArray.h" +#include "JSWebKitCSSMatrix.h" +#include "NotImplemented.h" +#include "WebGLBuffer.h" +#include "WebGLFloatArray.h" +#include "WebGLFramebuffer.h" +#include "WebGLGetInfo.h" +#include "WebGLIntArray.h" +#include "WebGLProgram.h" +#include "WebGLRenderingContext.h" +#include <runtime/Error.h> +#include <wtf/FastMalloc.h> +#include <wtf/OwnFastMallocPtr.h> + +using namespace JSC; + +namespace WebCore { + +JSValue JSWebGLRenderingContext::bufferData(JSC::ExecState* exec, JSC::ArgList const& args) +{ + if (args.size() != 3) + return throwError(exec, SyntaxError); + + unsigned target = args.at(0).toInt32(exec); + unsigned usage = args.at(2).toInt32(exec); + ExceptionCode ec = 0; + + // If argument 1 is a number, we are initializing this buffer to that size + if (!args.at(1).isObject()) { + unsigned int count = args.at(1).toInt32(exec); + static_cast<WebGLRenderingContext*>(impl())->bufferData(target, count, usage, ec); + } else { + WebGLArray* array = toWebGLArray(args.at(1)); + static_cast<WebGLRenderingContext*>(impl())->bufferData(target, array, usage, ec); + } + + setDOMException(exec, ec); + return jsUndefined(); +} + +JSValue JSWebGLRenderingContext::bufferSubData(JSC::ExecState* exec, JSC::ArgList const& args) +{ + if (args.size() != 3) + return throwError(exec, SyntaxError); + + unsigned target = args.at(0).toInt32(exec); + unsigned offset = args.at(1).toInt32(exec); + ExceptionCode ec = 0; + + WebGLArray* array = toWebGLArray(args.at(2)); + + static_cast<WebGLRenderingContext*>(impl())->bufferSubData(target, offset, array, ec); + + setDOMException(exec, ec); + return jsUndefined(); +} + +static JSValue toJS(ExecState* exec, JSDOMGlobalObject* globalObject, const WebGLGetInfo& info) +{ + switch (info.getType()) { + case WebGLGetInfo::kTypeBool: + return jsBoolean(info.getBool()); + case WebGLGetInfo::kTypeFloat: + return jsNumber(exec, info.getFloat()); + case WebGLGetInfo::kTypeLong: + return jsNumber(exec, info.getLong()); + case WebGLGetInfo::kTypeNull: + return jsNull(); + case WebGLGetInfo::kTypeString: + return jsString(exec, info.getString()); + case WebGLGetInfo::kTypeUnsignedLong: + return jsNumber(exec, info.getUnsignedLong()); + case WebGLGetInfo::kTypeWebGLBuffer: + return toJS(exec, globalObject, info.getWebGLBuffer()); + case WebGLGetInfo::kTypeWebGLFloatArray: + return toJS(exec, globalObject, info.getWebGLFloatArray()); + case WebGLGetInfo::kTypeWebGLFramebuffer: + return toJS(exec, globalObject, info.getWebGLFramebuffer()); + case WebGLGetInfo::kTypeWebGLIntArray: + return toJS(exec, globalObject, info.getWebGLIntArray()); + // FIXME: implement WebGLObjectArray + // case WebGLGetInfo::kTypeWebGLObjectArray: + case WebGLGetInfo::kTypeWebGLProgram: + return toJS(exec, globalObject, info.getWebGLProgram()); + case WebGLGetInfo::kTypeWebGLRenderbuffer: + return toJS(exec, globalObject, info.getWebGLRenderbuffer()); + case WebGLGetInfo::kTypeWebGLTexture: + return toJS(exec, globalObject, info.getWebGLTexture()); + case WebGLGetInfo::kTypeWebGLUnsignedByteArray: + return toJS(exec, globalObject, info.getWebGLUnsignedByteArray()); + default: + notImplemented(); + return jsUndefined(); + } +} + +enum ObjectType { + kBuffer, kRenderbuffer, kTexture, kVertexAttrib +}; + +static JSValue getObjectParameter(JSWebGLRenderingContext* obj, ExecState* exec, const ArgList& args, ObjectType objectType) +{ + if (args.size() != 2) + return throwError(exec, SyntaxError); + + ExceptionCode ec = 0; + WebGLRenderingContext* context = static_cast<WebGLRenderingContext*>(obj->impl()); + unsigned target = args.at(0).toInt32(exec); + if (exec->hadException()) + return jsUndefined(); + unsigned pname = args.at(1).toInt32(exec); + if (exec->hadException()) + return jsUndefined(); + WebGLGetInfo info; + switch (objectType) { + case kBuffer: + info = context->getBufferParameter(target, pname, ec); + break; + case kRenderbuffer: + info = context->getRenderbufferParameter(target, pname, ec); + break; + case kTexture: + info = context->getTexParameter(target, pname, ec); + break; + case kVertexAttrib: + // target => index + info = context->getVertexAttrib(target, pname, ec); + break; + default: + notImplemented(); + break; + } + if (ec) { + setDOMException(exec, ec); + return jsUndefined(); + } + return toJS(exec, obj->globalObject(), info); +} + +enum WhichProgramCall { + kProgramParameter, kUniform +}; + +JSValue JSWebGLRenderingContext::getBufferParameter(ExecState* exec, const ArgList& args) +{ + return getObjectParameter(this, exec, args, kBuffer); +} + +JSValue JSWebGLRenderingContext::getFramebufferAttachmentParameter(ExecState* exec, const ArgList& args) +{ + if (args.size() != 3) + return throwError(exec, SyntaxError); + + ExceptionCode ec = 0; + WebGLRenderingContext* context = static_cast<WebGLRenderingContext*>(impl()); + unsigned target = args.at(0).toInt32(exec); + if (exec->hadException()) + return jsUndefined(); + unsigned attachment = args.at(1).toInt32(exec); + if (exec->hadException()) + return jsUndefined(); + unsigned pname = args.at(2).toInt32(exec); + if (exec->hadException()) + return jsUndefined(); + WebGLGetInfo info = context->getFramebufferAttachmentParameter(target, attachment, pname, ec); + if (ec) { + setDOMException(exec, ec); + return jsUndefined(); + } + return toJS(exec, globalObject(), info); +} + +JSValue JSWebGLRenderingContext::getParameter(ExecState* exec, const ArgList& args) +{ + if (args.size() != 1) + return throwError(exec, SyntaxError); + + ExceptionCode ec = 0; + WebGLRenderingContext* context = static_cast<WebGLRenderingContext*>(impl()); + unsigned pname = args.at(0).toInt32(exec); + if (exec->hadException()) + return jsUndefined(); + WebGLGetInfo info = context->getParameter(pname, ec); + if (ec) { + setDOMException(exec, ec); + return jsUndefined(); + } + return toJS(exec, globalObject(), info); +} + +JSValue JSWebGLRenderingContext::getProgramParameter(ExecState* exec, const ArgList& args) +{ + if (args.size() != 2) + return throwError(exec, SyntaxError); + + ExceptionCode ec = 0; + WebGLRenderingContext* context = static_cast<WebGLRenderingContext*>(impl()); + WebGLProgram* program = toWebGLProgram(args.at(0)); + unsigned pname = args.at(1).toInt32(exec); + if (exec->hadException()) + return jsUndefined(); + WebGLGetInfo info = context->getProgramParameter(program, pname, ec); + if (ec) { + setDOMException(exec, ec); + return jsUndefined(); + } + return toJS(exec, globalObject(), info); +} + +JSValue JSWebGLRenderingContext::getRenderbufferParameter(ExecState* exec, const ArgList& args) +{ + return getObjectParameter(this, exec, args, kRenderbuffer); +} + +JSValue JSWebGLRenderingContext::getShaderParameter(ExecState* exec, const ArgList& args) +{ + if (args.size() != 2) + return throwError(exec, SyntaxError); + + ExceptionCode ec = 0; + WebGLRenderingContext* context = static_cast<WebGLRenderingContext*>(impl()); + WebGLShader* shader = toWebGLShader(args.at(0)); + unsigned pname = args.at(1).toInt32(exec); + if (exec->hadException()) + return jsUndefined(); + WebGLGetInfo info = context->getShaderParameter(shader, pname, ec); + if (ec) { + setDOMException(exec, ec); + return jsUndefined(); + } + return toJS(exec, globalObject(), info); +} + +JSValue JSWebGLRenderingContext::getTexParameter(ExecState* exec, const ArgList& args) +{ + return getObjectParameter(this, exec, args, kTexture); +} + +JSValue JSWebGLRenderingContext::getUniform(ExecState* exec, const ArgList& args) +{ + if (args.size() != 2) + return throwError(exec, SyntaxError); + + ExceptionCode ec = 0; + WebGLRenderingContext* context = static_cast<WebGLRenderingContext*>(impl()); + WebGLProgram* program = toWebGLProgram(args.at(0)); + WebGLUniformLocation* loc = toWebGLUniformLocation(args.at(1)); + if (exec->hadException()) + return jsUndefined(); + WebGLGetInfo info = context->getUniform(program, loc, ec); + if (ec) { + setDOMException(exec, ec); + return jsUndefined(); + } + return toJS(exec, globalObject(), info); +} + +JSValue JSWebGLRenderingContext::getVertexAttrib(ExecState* exec, const ArgList& args) +{ + return getObjectParameter(this, exec, args, kVertexAttrib); +} + +// void texImage2D(in GLenum target, in GLint level, in GLenum internalformat, in GLsizei width, in GLsizei height, in GLint border, in GLenum format, in GLenum type, in WebGLArray pixels); +// void texImage2D(in GLenum target, in GLint level, in ImageData pixels, [Optional] GLboolean flipY, [Optional] in premultiplyAlpha); +// void texImage2D(in GLenum target, in GLint level, in HTMLImageElement image, [Optional] in GLboolean flipY, [Optional] in premultiplyAlpha); +// void texImage2D(in GLenum target, in GLint level, in HTMLCanvasElement canvas, [Optional] in GLboolean flipY, [Optional] in premultiplyAlpha); +// void texImage2D(in GLenum target, in GLint level, in HTMLVideoElement video, [Optional] in GLboolean flipY, [Optional] in premultiplyAlpha); +JSValue JSWebGLRenderingContext::texImage2D(ExecState* exec, const ArgList& args) +{ + if (args.size() < 3 || args.size() > 9) + return throwError(exec, SyntaxError); + + ExceptionCode ec = 0; + + WebGLRenderingContext* context = static_cast<WebGLRenderingContext*>(impl()); + unsigned target = args.at(0).toInt32(exec); + if (exec->hadException()) + return jsUndefined(); + + unsigned level = args.at(1).toInt32(exec); + if (exec->hadException()) + return jsUndefined(); + + JSObject* o = 0; + + if (args.size() <= 5) { + // This is one of the last 4 forms. Param 2 can be ImageData or <img>, <canvas> or <video> element. + JSValue value = args.at(2); + + if (!value.isObject()) + return throwError(exec, TypeError); + + o = asObject(value); + + bool flipY = args.at(3).toBoolean(exec); + bool premultiplyAlpha = args.at(4).toBoolean(exec); + + if (o->inherits(&JSImageData::s_info)) { + ImageData* data = static_cast<ImageData*>(static_cast<JSImageData*>(o)->impl()); + context->texImage2D(target, level, data, flipY, premultiplyAlpha, ec); + } else if (o->inherits(&JSHTMLImageElement::s_info)) { + HTMLImageElement* element = static_cast<HTMLImageElement*>(static_cast<JSHTMLImageElement*>(o)->impl()); + context->texImage2D(target, level, element, flipY, premultiplyAlpha, ec); + } else if (o->inherits(&JSHTMLCanvasElement::s_info)) { + HTMLCanvasElement* element = static_cast<HTMLCanvasElement*>(static_cast<JSHTMLCanvasElement*>(o)->impl()); + context->texImage2D(target, level, element, flipY, premultiplyAlpha, ec); + } else if (o->inherits(&JSHTMLVideoElement::s_info)) { + HTMLVideoElement* element = static_cast<HTMLVideoElement*>(static_cast<JSHTMLVideoElement*>(o)->impl()); + context->texImage2D(target, level, element, flipY, premultiplyAlpha, ec); + } else + ec = TYPE_MISMATCH_ERR; + } else { + if (args.size() != 9) + return throwError(exec, SyntaxError); + + // This must be the WebGLArray case + unsigned internalformat = args.at(2).toInt32(exec); + if (exec->hadException()) + return jsUndefined(); + + unsigned width = args.at(3).toInt32(exec); + if (exec->hadException()) + return jsUndefined(); + + unsigned height = args.at(4).toInt32(exec); + if (exec->hadException()) + return jsUndefined(); + + unsigned border = args.at(5).toInt32(exec); + if (exec->hadException()) + return jsUndefined(); + + unsigned format = args.at(6).toInt32(exec); + if (exec->hadException()) + return jsUndefined(); + + unsigned type = args.at(7).toInt32(exec); + if (exec->hadException()) + return jsUndefined(); + + JSValue value = args.at(8); + + // For this case passing 0 (for a null array) is allowed + if (value.isNull()) + context->texImage2D(target, level, internalformat, width, height, border, format, type, 0, ec); + else if (value.isObject()) { + o = asObject(value); + + if (o->inherits(&JSWebGLArray::s_info)) { + // FIXME: Need to check to make sure WebGLArray is a WebGLByteArray or WebGLShortArray, + // depending on the passed type parameter. + WebGLArray* obj = static_cast<WebGLArray*>(static_cast<JSWebGLArray*>(o)->impl()); + context->texImage2D(target, level, internalformat, width, height, border, format, type, obj, ec); + } else + return throwError(exec, TypeError); + } else + return throwError(exec, TypeError); + } + + setDOMException(exec, ec); + return jsUndefined(); +} + +// void texSubImage2D(in GLenum target, in GLint level, in GLint xoffset, in GLint yoffset, in GLsizei width, in GLsizei height, in GLenum format, in GLenum type, in WebGLArray pixels); +// void texSubImage2D(in GLenum target, in GLint level, in GLint xoffset, in GLint yoffset, in ImageData pixels, [Optional] GLboolean flipY, [Optional] in premultiplyAlpha); +// void texSubImage2D(in GLenum target, in GLint level, in GLint xoffset, in GLint yoffset, in HTMLImageElement image, [Optional] GLboolean flipY, [Optional] in premultiplyAlpha); +// void texSubImage2D(in GLenum target, in GLint level, in GLint xoffset, in GLint yoffset, in HTMLCanvasElement canvas, [Optional] GLboolean flipY, [Optional] in premultiplyAlpha); +// void texSubImage2D(in GLenum target, in GLint level, in GLint xoffset, in GLint yoffset, in HTMLVideoElement video, [Optional] GLboolean flipY, [Optional] in premultiplyAlpha); +JSValue JSWebGLRenderingContext::texSubImage2D(ExecState* exec, const ArgList& args) +{ + if (args.size() < 5 || args.size() > 9) + return throwError(exec, SyntaxError); + + ExceptionCode ec = 0; + + WebGLRenderingContext* context = static_cast<WebGLRenderingContext*>(impl()); + unsigned target = args.at(0).toInt32(exec); + if (exec->hadException()) + return jsUndefined(); + + unsigned level = args.at(1).toInt32(exec); + if (exec->hadException()) + return jsUndefined(); + + unsigned xoff = args.at(2).toInt32(exec); + if (exec->hadException()) + return jsUndefined(); + + unsigned yoff = args.at(3).toInt32(exec); + if (exec->hadException()) + return jsUndefined(); + + JSObject* o = 0; + + if (args.size() <= 7) { + // This is one of the last 4 forms. Param 4 can be <img>, <canvas> or <video> element, of the format param. + JSValue value = args.at(4); + + if (!value.isObject()) + return throwError(exec, SyntaxError); + + o = asObject(value); + + bool flipY = args.at(5).toBoolean(exec); + bool premultiplyAlpha = args.at(6).toBoolean(exec); + + if (o->inherits(&JSImageData::s_info)) { + ImageData* data = static_cast<ImageData*>(static_cast<JSImageData*>(o)->impl()); + context->texSubImage2D(target, level, xoff, yoff, data, flipY, premultiplyAlpha, ec); + } else if (o->inherits(&JSHTMLImageElement::s_info)) { + HTMLImageElement* element = static_cast<HTMLImageElement*>(static_cast<JSHTMLImageElement*>(o)->impl()); + context->texSubImage2D(target, level, xoff, yoff, element, flipY, premultiplyAlpha, ec); + } else if (o->inherits(&JSHTMLCanvasElement::s_info)) { + HTMLCanvasElement* element = static_cast<HTMLCanvasElement*>(static_cast<JSHTMLCanvasElement*>(o)->impl()); + context->texSubImage2D(target, level, xoff, yoff, element, flipY, premultiplyAlpha, ec); + } else if (o->inherits(&JSHTMLVideoElement::s_info)) { + HTMLVideoElement* element = static_cast<HTMLVideoElement*>(static_cast<JSHTMLVideoElement*>(o)->impl()); + context->texSubImage2D(target, level, xoff, yoff, element, flipY, premultiplyAlpha, ec); + } else + ec = TYPE_MISMATCH_ERR; + } else { + // This must be the WebGLArray form + if (args.size() != 9) + return throwError(exec, SyntaxError); + + unsigned width = args.at(4).toInt32(exec); + if (exec->hadException()) + return jsUndefined(); + + unsigned height = args.at(5).toInt32(exec); + if (exec->hadException()) + return jsUndefined(); + + unsigned format = args.at(6).toInt32(exec); + if (exec->hadException()) + return jsUndefined(); + + unsigned type = args.at(7).toInt32(exec); + if (exec->hadException()) + return jsUndefined(); + + JSValue value = args.at(8); + if (!value.isObject()) + context->texSubImage2D(target, level, xoff, yoff, width, height, format, type, 0, ec); + else { + o = asObject(value); + + if (o->inherits(&JSWebGLArray::s_info)) { + WebGLArray* obj = static_cast<WebGLArray*>(static_cast<JSWebGLArray*>(o)->impl()); + context->texSubImage2D(target, level, xoff, yoff, width, height, format, type, obj, ec); + } else + return throwError(exec, TypeError); + } + } + + setDOMException(exec, ec); + return jsUndefined(); +} + +template<typename T, size_t inlineCapacity> +bool toVector(JSC::ExecState* exec, JSC::JSValue value, Vector<T, inlineCapacity>& vector) +{ + if (!value.isObject()) + return false; + + JSC::JSObject* object = asObject(value); + int32_t length = object->get(exec, JSC::Identifier(exec, "length")).toInt32(exec); + vector.resize(length); + + for (int32_t i = 0; i < length; ++i) { + JSC::JSValue v = object->get(exec, i); + if (exec->hadException()) + return false; + vector[i] = static_cast<T>(v.toNumber(exec)); + } + + return true; +} + +enum DataFunctionToCall { + f_uniform1v, f_uniform2v, f_uniform3v, f_uniform4v, + f_vertexAttrib1v, f_vertexAttrib2v, f_vertexAttrib3v, f_vertexAttrib4v +}; + +enum DataFunctionMatrixToCall { + f_uniformMatrix2fv, f_uniformMatrix3fv, f_uniformMatrix4fv +}; + +static bool functionForUniform(DataFunctionToCall f) +{ + switch (f) { + case f_uniform1v: + case f_uniform2v: + case f_uniform3v: + case f_uniform4v: + return true; + break; + default: break; + } + return false; +} + +static JSC::JSValue dataFunctionf(DataFunctionToCall f, JSC::ExecState* exec, const JSC::ArgList& args, WebGLRenderingContext* context) +{ + if (args.size() != 2) + return throwError(exec, SyntaxError); + + WebGLUniformLocation* location = 0; + long index = -1; + + if (functionForUniform(f)) + location = toWebGLUniformLocation(args.at(0)); + else + index = args.at(0).toInt32(exec); + + if (exec->hadException()) + return jsUndefined(); + + RefPtr<WebGLFloatArray> webGLArray = toWebGLFloatArray(args.at(1)); + if (exec->hadException()) + return jsUndefined(); + + ExceptionCode ec = 0; + if (webGLArray) { + switch (f) { + case f_uniform1v: + context->uniform1fv(location, webGLArray.get(), ec); + break; + case f_uniform2v: + context->uniform2fv(location, webGLArray.get(), ec); + break; + case f_uniform3v: + context->uniform3fv(location, webGLArray.get(), ec); + break; + case f_uniform4v: + context->uniform4fv(location, webGLArray.get(), ec); + break; + case f_vertexAttrib1v: + context->vertexAttrib1fv(index, webGLArray.get()); + break; + case f_vertexAttrib2v: + context->vertexAttrib2fv(index, webGLArray.get()); + break; + case f_vertexAttrib3v: + context->vertexAttrib3fv(index, webGLArray.get()); + break; + case f_vertexAttrib4v: + context->vertexAttrib4fv(index, webGLArray.get()); + break; + } + + setDOMException(exec, ec); + return jsUndefined(); + } + + Vector<float, 64> array; + if (!toVector(exec, args.at(1), array)) + return throwError(exec, TypeError); + + switch (f) { + case f_uniform1v: + context->uniform1fv(location, array.data(), array.size(), ec); + break; + case f_uniform2v: + context->uniform2fv(location, array.data(), array.size(), ec); + break; + case f_uniform3v: + context->uniform3fv(location, array.data(), array.size(), ec); + break; + case f_uniform4v: + context->uniform4fv(location, array.data(), array.size(), ec); + break; + case f_vertexAttrib1v: + context->vertexAttrib1fv(index, array.data(), array.size()); + break; + case f_vertexAttrib2v: + context->vertexAttrib2fv(index, array.data(), array.size()); + break; + case f_vertexAttrib3v: + context->vertexAttrib3fv(index, array.data(), array.size()); + break; + case f_vertexAttrib4v: + context->vertexAttrib4fv(index, array.data(), array.size()); + break; + } + + setDOMException(exec, ec); + return jsUndefined(); +} + +static JSC::JSValue dataFunctioni(DataFunctionToCall f, JSC::ExecState* exec, const JSC::ArgList& args, WebGLRenderingContext* context) +{ + if (args.size() != 2) + return throwError(exec, SyntaxError); + + WebGLUniformLocation* location = toWebGLUniformLocation(args.at(0)); + + if (exec->hadException()) + return jsUndefined(); + + RefPtr<WebGLIntArray> webGLArray = toWebGLIntArray(args.at(1)); + if (exec->hadException()) + return jsUndefined(); + + ExceptionCode ec = 0; + if (webGLArray) { + switch (f) { + case f_uniform1v: + context->uniform1iv(location, webGLArray.get(), ec); + break; + case f_uniform2v: + context->uniform2iv(location, webGLArray.get(), ec); + break; + case f_uniform3v: + context->uniform3iv(location, webGLArray.get(), ec); + break; + case f_uniform4v: + context->uniform4iv(location, webGLArray.get(), ec); + break; + default: + break; + } + + setDOMException(exec, ec); + return jsUndefined(); + } + + + Vector<int, 64> array; + if (!toVector(exec, args.at(1), array)) + return throwError(exec, TypeError); + + switch (f) { + case f_uniform1v: + context->uniform1iv(location, array.data(), array.size(), ec); + break; + case f_uniform2v: + context->uniform2iv(location, array.data(), array.size(), ec); + break; + case f_uniform3v: + context->uniform3iv(location, array.data(), array.size(), ec); + break; + case f_uniform4v: + context->uniform4iv(location, array.data(), array.size(), ec); + break; + default: + break; + } + + setDOMException(exec, ec); + return jsUndefined(); +} + +static JSC::JSValue dataFunctionMatrix(DataFunctionMatrixToCall f, JSC::ExecState* exec, const JSC::ArgList& args, WebGLRenderingContext* context) +{ + if (args.size() != 3) + return throwError(exec, SyntaxError); + + WebGLUniformLocation* location = toWebGLUniformLocation(args.at(0)); + + if (exec->hadException()) + return jsUndefined(); + + bool transpose = args.at(1).toBoolean(exec); + if (exec->hadException()) + return jsUndefined(); + + RefPtr<WebGLFloatArray> webGLArray = toWebGLFloatArray(args.at(2)); + if (exec->hadException()) + return jsUndefined(); + + ExceptionCode ec = 0; + if (webGLArray) { + switch (f) { + case f_uniformMatrix2fv: + context->uniformMatrix2fv(location, transpose, webGLArray.get(), ec); + break; + case f_uniformMatrix3fv: + context->uniformMatrix3fv(location, transpose, webGLArray.get(), ec); + break; + case f_uniformMatrix4fv: + context->uniformMatrix4fv(location, transpose, webGLArray.get(), ec); + break; + } + + setDOMException(exec, ec); + return jsUndefined(); + } + + Vector<float, 64> array; + if (!toVector(exec, args.at(2), array)) + return throwError(exec, TypeError); + + switch (f) { + case f_uniformMatrix2fv: + context->uniformMatrix2fv(location, transpose, array.data(), array.size(), ec); + break; + case f_uniformMatrix3fv: + context->uniformMatrix3fv(location, transpose, array.data(), array.size(), ec); + break; + case f_uniformMatrix4fv: + context->uniformMatrix4fv(location, transpose, array.data(), array.size(), ec); + break; + } + + setDOMException(exec, ec); + return jsUndefined(); +} + +JSC::JSValue JSWebGLRenderingContext::uniform1fv(JSC::ExecState* exec, const JSC::ArgList& args) +{ + return dataFunctionf(f_uniform1v, exec, args, static_cast<WebGLRenderingContext*>(impl())); +} + +JSC::JSValue JSWebGLRenderingContext::uniform1iv(JSC::ExecState* exec, const JSC::ArgList& args) +{ + return dataFunctioni(f_uniform1v, exec, args, static_cast<WebGLRenderingContext*>(impl())); +} + +JSC::JSValue JSWebGLRenderingContext::uniform2fv(JSC::ExecState* exec, const JSC::ArgList& args) +{ + return dataFunctionf(f_uniform2v, exec, args, static_cast<WebGLRenderingContext*>(impl())); +} + +JSC::JSValue JSWebGLRenderingContext::uniform2iv(JSC::ExecState* exec, const JSC::ArgList& args) +{ + return dataFunctioni(f_uniform2v, exec, args, static_cast<WebGLRenderingContext*>(impl())); +} + +JSC::JSValue JSWebGLRenderingContext::uniform3fv(JSC::ExecState* exec, const JSC::ArgList& args) +{ + return dataFunctionf(f_uniform3v, exec, args, static_cast<WebGLRenderingContext*>(impl())); +} + +JSC::JSValue JSWebGLRenderingContext::uniform3iv(JSC::ExecState* exec, const JSC::ArgList& args) +{ + return dataFunctioni(f_uniform3v, exec, args, static_cast<WebGLRenderingContext*>(impl())); +} + +JSC::JSValue JSWebGLRenderingContext::uniform4fv(JSC::ExecState* exec, const JSC::ArgList& args) +{ + return dataFunctionf(f_uniform4v, exec, args, static_cast<WebGLRenderingContext*>(impl())); +} + +JSC::JSValue JSWebGLRenderingContext::uniform4iv(JSC::ExecState* exec, const JSC::ArgList& args) +{ + return dataFunctioni(f_uniform4v, exec, args, static_cast<WebGLRenderingContext*>(impl())); +} + +JSC::JSValue JSWebGLRenderingContext::uniformMatrix2fv(JSC::ExecState* exec, const JSC::ArgList& args) +{ + return dataFunctionMatrix(f_uniformMatrix2fv, exec, args, static_cast<WebGLRenderingContext*>(impl())); +} + +JSC::JSValue JSWebGLRenderingContext::uniformMatrix3fv(JSC::ExecState* exec, const JSC::ArgList& args) +{ + return dataFunctionMatrix(f_uniformMatrix3fv, exec, args, static_cast<WebGLRenderingContext*>(impl())); +} + +JSC::JSValue JSWebGLRenderingContext::uniformMatrix4fv(JSC::ExecState* exec, const JSC::ArgList& args) +{ + return dataFunctionMatrix(f_uniformMatrix4fv, exec, args, static_cast<WebGLRenderingContext*>(impl())); +} + +JSC::JSValue JSWebGLRenderingContext::vertexAttrib1fv(JSC::ExecState* exec, const JSC::ArgList& args) +{ + return dataFunctionf(f_vertexAttrib1v, exec, args, static_cast<WebGLRenderingContext*>(impl())); +} + +JSC::JSValue JSWebGLRenderingContext::vertexAttrib2fv(JSC::ExecState* exec, const JSC::ArgList& args) +{ + return dataFunctionf(f_vertexAttrib2v, exec, args, static_cast<WebGLRenderingContext*>(impl())); +} + +JSC::JSValue JSWebGLRenderingContext::vertexAttrib3fv(JSC::ExecState* exec, const JSC::ArgList& args) +{ + return dataFunctionf(f_vertexAttrib3v, exec, args, static_cast<WebGLRenderingContext*>(impl())); +} + +JSC::JSValue JSWebGLRenderingContext::vertexAttrib4fv(JSC::ExecState* exec, const JSC::ArgList& args) +{ + return dataFunctionf(f_vertexAttrib4v, exec, args, static_cast<WebGLRenderingContext*>(impl())); +} + +} // namespace WebCore + +#endif // ENABLE(3D_CANVAS) diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSCanvasShortArrayConstructor.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSWebGLShortArrayConstructor.cpp index a885b7b..a33779b 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSCanvasShortArrayConstructor.cpp +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSWebGLShortArrayConstructor.cpp @@ -27,37 +27,41 @@ #if ENABLE(3D_CANVAS) -#include "JSCanvasShortArrayConstructor.h" +#include "JSWebGLShortArrayConstructor.h" #include "Document.h" -#include "CanvasShortArray.h" -#include "JSCanvasArray.h" -#include "JSCanvasArrayBuffer.h" -#include "JSCanvasArrayBufferConstructor.h" -#include "JSCanvasShortArray.h" +#include "WebGLShortArray.h" +#include "JSWebGLArray.h" +#include "JSWebGLArrayBuffer.h" +#include "JSWebGLArrayBufferConstructor.h" +#include "JSWebGLShortArray.h" #include <runtime/Error.h> namespace WebCore { using namespace JSC; -const ClassInfo JSCanvasShortArrayConstructor::s_info = { "CanvasShortArrayConstructor", &JSCanvasArray::s_info, 0, 0 }; +const ClassInfo JSWebGLShortArrayConstructor::s_info = { "WebGLShortArrayConstructor", &JSWebGLArray::s_info, 0, 0 }; -JSCanvasShortArrayConstructor::JSCanvasShortArrayConstructor(ExecState* exec, JSDOMGlobalObject* globalObject) - : DOMConstructorObject(JSCanvasShortArrayConstructor::createStructure(globalObject->objectPrototype()), globalObject) +JSWebGLShortArrayConstructor::JSWebGLShortArrayConstructor(ExecState* exec, JSDOMGlobalObject* globalObject) + : DOMConstructorObject(JSWebGLShortArrayConstructor::createStructure(globalObject->objectPrototype()), globalObject) { - putDirect(exec->propertyNames().prototype, JSCanvasShortArrayPrototype::self(exec, globalObject), None); + putDirect(exec->propertyNames().prototype, JSWebGLShortArrayPrototype::self(exec, globalObject), None); putDirect(exec->propertyNames().length, jsNumber(exec, 2), ReadOnly|DontDelete|DontEnum); } static JSObject* constructCanvasShortArray(ExecState* exec, JSObject* constructor, const ArgList& args) { - JSCanvasShortArrayConstructor* jsConstructor = static_cast<JSCanvasShortArrayConstructor*>(constructor); - RefPtr<CanvasShortArray> array = static_cast<CanvasShortArray*>(construct<CanvasShortArray, short>(exec, args).get()); + JSWebGLShortArrayConstructor* jsConstructor = static_cast<JSWebGLShortArrayConstructor*>(constructor); + RefPtr<WebGLShortArray> array = static_cast<WebGLShortArray*>(construct<WebGLShortArray, short>(exec, args).get()); + if (!array.get()) { + setDOMException(exec, INDEX_SIZE_ERR); + return 0; + } return asObject(toJS(exec, jsConstructor->globalObject(), array.get())); } -JSC::ConstructType JSCanvasShortArrayConstructor::getConstructData(JSC::ConstructData& constructData) +JSC::ConstructType JSWebGLShortArrayConstructor::getConstructData(JSC::ConstructData& constructData) { constructData.native.function = constructCanvasShortArray; return ConstructTypeHost; diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSCanvasShortArrayConstructor.h b/src/3rdparty/webkit/WebCore/bindings/js/JSWebGLShortArrayConstructor.h index df21825..7807a13 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSCanvasShortArrayConstructor.h +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSWebGLShortArrayConstructor.h @@ -23,17 +23,17 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef JSCanvasShortArrayConstructor_h -#define JSCanvasShortArrayConstructor_h +#ifndef JSWebGLShortArrayConstructor_h +#define JSWebGLShortArrayConstructor_h #include "JSDOMBinding.h" #include "JSDocument.h" namespace WebCore { - class JSCanvasShortArrayConstructor : public DOMConstructorObject { + class JSWebGLShortArrayConstructor : public DOMConstructorObject { public: - JSCanvasShortArrayConstructor(JSC::ExecState*, JSDOMGlobalObject*); + JSWebGLShortArrayConstructor(JSC::ExecState*, JSDOMGlobalObject*); static const JSC::ClassInfo s_info; private: @@ -43,4 +43,4 @@ namespace WebCore { } -#endif // JSCanvasShortArrayConstructor_h +#endif // JSWebGLShortArrayConstructor_h diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSCanvasUnsignedIntArrayCustom.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSWebGLShortArrayCustom.cpp index 95a80a7..899b0c9 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSCanvasUnsignedIntArrayCustom.cpp +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSWebGLShortArrayCustom.cpp @@ -27,22 +27,50 @@ #if ENABLE(3D_CANVAS) -#include "JSCanvasUnsignedIntArray.h" +#include "JSWebGLArrayHelper.h" +#include "JSWebGLShortArray.h" -#include "CanvasUnsignedIntArray.h" +#include "WebGLShortArray.h" using namespace JSC; namespace WebCore { -void JSCanvasUnsignedIntArray::indexSetter(JSC::ExecState* exec, unsigned index, JSC::JSValue value) +void JSWebGLShortArray::indexSetter(JSC::ExecState* exec, unsigned index, JSC::JSValue value) { - impl()->set(index, static_cast<unsigned int>(value.toInt32(exec))); + impl()->set(index, static_cast<signed short>(value.toInt32(exec))); } -JSC::JSValue toJS(JSC::ExecState* exec, JSDOMGlobalObject* globalObject, CanvasUnsignedIntArray* object) +JSC::JSValue toJS(JSC::ExecState* exec, JSDOMGlobalObject* globalObject, WebGLShortArray* object) { - return getDOMObjectWrapper<JSCanvasUnsignedIntArray>(exec, globalObject, object); + return getDOMObjectWrapper<JSWebGLShortArray>(exec, globalObject, object); +} + +JSC::JSValue JSWebGLShortArray::set(JSC::ExecState* exec, JSC::ArgList const& args) +{ + if (args.size() > 2) + return throwError(exec, SyntaxError); + + if (args.size() == 2 && args.at(0).isInt32()) { + // void set(in unsigned long index, in long value); + unsigned index = args.at(0).toUInt32(exec); + impl()->set(index, static_cast<signed short>(args.at(1).toInt32(exec))); + return jsUndefined(); + } + + WebGLShortArray* shortArray = toWebGLShortArray(args.at(0)); + if (shortArray) { + // void set(in WebGLShortArray array, [Optional] in unsigned long offset); + unsigned offset = 0; + if (args.size() == 2) + offset = args.at(1).toInt32(exec); + ExceptionCode ec = 0; + impl()->set(shortArray, offset, ec); + setDOMException(exec, ec); + return jsUndefined(); + } + + return setWebGLArrayFromArray(exec, impl(), args); } } // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSCanvasUnsignedByteArrayConstructor.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSWebGLUnsignedByteArrayConstructor.cpp index 5d0800e..dcb940e 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSCanvasUnsignedByteArrayConstructor.cpp +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSWebGLUnsignedByteArrayConstructor.cpp @@ -27,36 +27,41 @@ #if ENABLE(3D_CANVAS) -#include "JSCanvasUnsignedByteArrayConstructor.h" +#include "JSWebGLUnsignedByteArrayConstructor.h" #include "Document.h" -#include "CanvasUnsignedByteArray.h" -#include "JSCanvasArrayBuffer.h" -#include "JSCanvasArrayBufferConstructor.h" -#include "JSCanvasUnsignedByteArray.h" +#include "ExceptionCode.h" +#include "WebGLUnsignedByteArray.h" +#include "JSWebGLArrayBuffer.h" +#include "JSWebGLArrayBufferConstructor.h" +#include "JSWebGLUnsignedByteArray.h" #include <runtime/Error.h> namespace WebCore { using namespace JSC; -const ClassInfo JSCanvasUnsignedByteArrayConstructor::s_info = { "CanvasUnsignedByteArrayConstructor", &JSCanvasArray::s_info, 0, 0 }; +const ClassInfo JSWebGLUnsignedByteArrayConstructor::s_info = { "WebGLUnsignedByteArrayConstructor", &JSWebGLArray::s_info, 0, 0 }; -JSCanvasUnsignedByteArrayConstructor::JSCanvasUnsignedByteArrayConstructor(ExecState* exec, JSDOMGlobalObject* globalObject) - : DOMConstructorObject(JSCanvasUnsignedByteArrayConstructor::createStructure(globalObject->objectPrototype()), globalObject) +JSWebGLUnsignedByteArrayConstructor::JSWebGLUnsignedByteArrayConstructor(ExecState* exec, JSDOMGlobalObject* globalObject) + : DOMConstructorObject(JSWebGLUnsignedByteArrayConstructor::createStructure(globalObject->objectPrototype()), globalObject) { - putDirect(exec->propertyNames().prototype, JSCanvasUnsignedByteArrayPrototype::self(exec, globalObject), None); + putDirect(exec->propertyNames().prototype, JSWebGLUnsignedByteArrayPrototype::self(exec, globalObject), None); putDirect(exec->propertyNames().length, jsNumber(exec, 2), ReadOnly|DontDelete|DontEnum); } static JSObject* constructCanvasUnsignedByteArray(ExecState* exec, JSObject* constructor, const ArgList& args) { - JSCanvasUnsignedByteArrayConstructor* jsConstructor = static_cast<JSCanvasUnsignedByteArrayConstructor*>(constructor); - RefPtr<CanvasUnsignedByteArray> array = static_cast<CanvasUnsignedByteArray*>(construct<CanvasUnsignedByteArray, unsigned char>(exec, args).get()); + JSWebGLUnsignedByteArrayConstructor* jsConstructor = static_cast<JSWebGLUnsignedByteArrayConstructor*>(constructor); + RefPtr<WebGLUnsignedByteArray> array = static_cast<WebGLUnsignedByteArray*>(construct<WebGLUnsignedByteArray, unsigned char>(exec, args).get()); + if (!array.get()) { + setDOMException(exec, INDEX_SIZE_ERR); + return 0; + } return asObject(toJS(exec, jsConstructor->globalObject(), array.get())); } -JSC::ConstructType JSCanvasUnsignedByteArrayConstructor::getConstructData(JSC::ConstructData& constructData) +JSC::ConstructType JSWebGLUnsignedByteArrayConstructor::getConstructData(JSC::ConstructData& constructData) { constructData.native.function = constructCanvasUnsignedByteArray; return ConstructTypeHost; diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSCanvasUnsignedIntArrayConstructor.h b/src/3rdparty/webkit/WebCore/bindings/js/JSWebGLUnsignedByteArrayConstructor.h index 6016159..d90ce96 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSCanvasUnsignedIntArrayConstructor.h +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSWebGLUnsignedByteArrayConstructor.h @@ -23,17 +23,17 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef JSCanvasUnsignedIntArrayConstructor_h -#define JSCanvasUnsignedIntArrayConstructor_h +#ifndef JSWebGLUnsignedByteArrayConstructor_h +#define JSWebGLUnsignedByteArrayConstructor_h #include "JSDOMBinding.h" #include "JSDocument.h" namespace WebCore { - class JSCanvasUnsignedIntArrayConstructor : public DOMConstructorObject { + class JSWebGLUnsignedByteArrayConstructor : public DOMConstructorObject { public: - JSCanvasUnsignedIntArrayConstructor(JSC::ExecState*, JSDOMGlobalObject*); + JSWebGLUnsignedByteArrayConstructor(JSC::ExecState*, JSDOMGlobalObject*); static const JSC::ClassInfo s_info; private: @@ -43,4 +43,4 @@ namespace WebCore { } -#endif // JSCanvasUnsignedIntArrayConstructor_h +#endif // JSWebGLUnsignedByteArrayConstructor_h diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSCanvasUnsignedByteArrayCustom.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSWebGLUnsignedByteArrayCustom.cpp index f2b0c74..b576374 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSCanvasUnsignedByteArrayCustom.cpp +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSWebGLUnsignedByteArrayCustom.cpp @@ -27,22 +27,50 @@ #if ENABLE(3D_CANVAS) -#include "JSCanvasUnsignedByteArray.h" +#include "JSWebGLArrayHelper.h" +#include "JSWebGLUnsignedByteArray.h" -#include "CanvasUnsignedByteArray.h" +#include "WebGLUnsignedByteArray.h" using namespace JSC; namespace WebCore { -void JSCanvasUnsignedByteArray::indexSetter(JSC::ExecState* exec, unsigned index, JSC::JSValue value) +void JSWebGLUnsignedByteArray::indexSetter(JSC::ExecState* exec, unsigned index, JSC::JSValue value) { impl()->set(index, static_cast<unsigned char>(value.toInt32(exec))); } -JSC::JSValue toJS(JSC::ExecState* exec, JSDOMGlobalObject* globalObject, CanvasUnsignedByteArray* object) +JSC::JSValue toJS(JSC::ExecState* exec, JSDOMGlobalObject* globalObject, WebGLUnsignedByteArray* object) { - return getDOMObjectWrapper<JSCanvasUnsignedByteArray>(exec, globalObject, object); + return getDOMObjectWrapper<JSWebGLUnsignedByteArray>(exec, globalObject, object); +} + +JSC::JSValue JSWebGLUnsignedByteArray::set(JSC::ExecState* exec, JSC::ArgList const& args) +{ + if (args.size() > 2) + return throwError(exec, SyntaxError); + + if (args.size() == 2 && args.at(0).isInt32()) { + // void set(in unsigned long index, in long value); + unsigned index = args.at(0).toUInt32(exec); + impl()->set(index, static_cast<unsigned char>(args.at(1).toInt32(exec))); + return jsUndefined(); + } + + WebGLUnsignedByteArray* array = toWebGLUnsignedByteArray(args.at(0)); + if (array) { + // void set(in WebGLUnsignedByteArray array, [Optional] in unsigned long offset); + unsigned offset = 0; + if (args.size() == 2) + offset = args.at(1).toInt32(exec); + ExceptionCode ec = 0; + impl()->set(array, offset, ec); + setDOMException(exec, ec); + return jsUndefined(); + } + + return setWebGLArrayFromArray(exec, impl(), args); } } // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSCanvasUnsignedIntArrayConstructor.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSWebGLUnsignedIntArrayConstructor.cpp index 5f145a7..23fccce 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSCanvasUnsignedIntArrayConstructor.cpp +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSWebGLUnsignedIntArrayConstructor.cpp @@ -27,36 +27,40 @@ #if ENABLE(3D_CANVAS) -#include "JSCanvasUnsignedIntArrayConstructor.h" +#include "JSWebGLUnsignedIntArrayConstructor.h" #include "Document.h" -#include "CanvasUnsignedIntArray.h" -#include "JSCanvasArrayBuffer.h" -#include "JSCanvasArrayBufferConstructor.h" -#include "JSCanvasUnsignedIntArray.h" +#include "WebGLUnsignedIntArray.h" +#include "JSWebGLArrayBuffer.h" +#include "JSWebGLArrayBufferConstructor.h" +#include "JSWebGLUnsignedIntArray.h" #include <runtime/Error.h> namespace WebCore { using namespace JSC; -const ClassInfo JSCanvasUnsignedIntArrayConstructor::s_info = { "CanvasUnsignedIntArrayConstructor", &JSCanvasArray::s_info, 0, 0 }; +const ClassInfo JSWebGLUnsignedIntArrayConstructor::s_info = { "WebGLUnsignedIntArrayConstructor", &JSWebGLArray::s_info, 0, 0 }; -JSCanvasUnsignedIntArrayConstructor::JSCanvasUnsignedIntArrayConstructor(ExecState* exec, JSDOMGlobalObject* globalObject) - : DOMConstructorObject(JSCanvasUnsignedIntArrayConstructor::createStructure(globalObject->objectPrototype()), globalObject) +JSWebGLUnsignedIntArrayConstructor::JSWebGLUnsignedIntArrayConstructor(ExecState* exec, JSDOMGlobalObject* globalObject) + : DOMConstructorObject(JSWebGLUnsignedIntArrayConstructor::createStructure(globalObject->objectPrototype()), globalObject) { - putDirect(exec->propertyNames().prototype, JSCanvasUnsignedIntArrayPrototype::self(exec, globalObject), None); + putDirect(exec->propertyNames().prototype, JSWebGLUnsignedIntArrayPrototype::self(exec, globalObject), None); putDirect(exec->propertyNames().length, jsNumber(exec, 2), ReadOnly|DontDelete|DontEnum); } static JSObject* constructCanvasUnsignedIntArray(ExecState* exec, JSObject* constructor, const ArgList& args) { - JSCanvasUnsignedIntArrayConstructor* jsConstructor = static_cast<JSCanvasUnsignedIntArrayConstructor*>(constructor); - RefPtr<CanvasUnsignedIntArray> array = static_cast<CanvasUnsignedIntArray*>(construct<CanvasUnsignedIntArray, unsigned int>(exec, args).get()); + JSWebGLUnsignedIntArrayConstructor* jsConstructor = static_cast<JSWebGLUnsignedIntArrayConstructor*>(constructor); + RefPtr<WebGLUnsignedIntArray> array = static_cast<WebGLUnsignedIntArray*>(construct<WebGLUnsignedIntArray, unsigned int>(exec, args).get()); + if (!array.get()) { + setDOMException(exec, INDEX_SIZE_ERR); + return 0; + } return asObject(toJS(exec, jsConstructor->globalObject(), array.get())); } -JSC::ConstructType JSCanvasUnsignedIntArrayConstructor::getConstructData(JSC::ConstructData& constructData) +JSC::ConstructType JSWebGLUnsignedIntArrayConstructor::getConstructData(JSC::ConstructData& constructData) { constructData.native.function = constructCanvasUnsignedIntArray; return ConstructTypeHost; diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSWebGLUnsignedIntArrayConstructor.h b/src/3rdparty/webkit/WebCore/bindings/js/JSWebGLUnsignedIntArrayConstructor.h new file mode 100644 index 0000000..7eabbc1 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSWebGLUnsignedIntArrayConstructor.h @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2009 Apple 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 JSWebGLUnsignedIntArrayConstructor_h +#define JSWebGLUnsignedIntArrayConstructor_h + +#include "JSDOMBinding.h" +#include "JSDocument.h" + +namespace WebCore { + + class JSWebGLUnsignedIntArrayConstructor : public DOMConstructorObject { + public: + JSWebGLUnsignedIntArrayConstructor(JSC::ExecState*, JSDOMGlobalObject*); + static const JSC::ClassInfo s_info; + + private: + virtual JSC::ConstructType getConstructData(JSC::ConstructData&); + virtual const JSC::ClassInfo* classInfo() const { return &s_info; } + }; + +} + +#endif // JSWebGLUnsignedIntArrayConstructor_h diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSWebGLUnsignedIntArrayCustom.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSWebGLUnsignedIntArrayCustom.cpp new file mode 100644 index 0000000..c8b7454 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSWebGLUnsignedIntArrayCustom.cpp @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2009 Apple 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(3D_CANVAS) + +#include "JSWebGLArrayHelper.h" +#include "JSWebGLUnsignedIntArray.h" + +#include "WebGLUnsignedIntArray.h" + +using namespace JSC; + +namespace WebCore { + +void JSWebGLUnsignedIntArray::indexSetter(JSC::ExecState* exec, unsigned index, JSC::JSValue value) +{ + impl()->set(index, static_cast<unsigned int>(value.toUInt32(exec))); +} + +JSC::JSValue toJS(JSC::ExecState* exec, JSDOMGlobalObject* globalObject, WebGLUnsignedIntArray* object) +{ + return getDOMObjectWrapper<JSWebGLUnsignedIntArray>(exec, globalObject, object); +} + +JSC::JSValue JSWebGLUnsignedIntArray::set(JSC::ExecState* exec, JSC::ArgList const& args) +{ + if (args.size() > 2) + return throwError(exec, SyntaxError); + + if (args.size() == 2 && args.at(0).isInt32()) { + // void set(in unsigned long index, in long value); + unsigned index = args.at(0).toUInt32(exec); + impl()->set(index, static_cast<unsigned int>(args.at(1).toUInt32(exec))); + return jsUndefined(); + } + + WebGLUnsignedIntArray* array = toWebGLUnsignedIntArray(args.at(0)); + if (array) { + // void set(in WebGLUnsignedIntArray array, [Optional] in unsigned long offset); + unsigned offset = 0; + if (args.size() == 2) + offset = args.at(1).toInt32(exec); + ExceptionCode ec = 0; + impl()->set(array, offset, ec); + setDOMException(exec, ec); + return jsUndefined(); + } + + return setWebGLArrayFromArray(exec, impl(), args); +} + +} // namespace WebCore + +#endif // ENABLE(3D_CANVAS) diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSCanvasUnsignedShortArrayConstructor.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSWebGLUnsignedShortArrayConstructor.cpp index 9735693..d8c2cfb 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSCanvasUnsignedShortArrayConstructor.cpp +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSWebGLUnsignedShortArrayConstructor.cpp @@ -27,36 +27,40 @@ #if ENABLE(3D_CANVAS) -#include "JSCanvasUnsignedShortArrayConstructor.h" +#include "JSWebGLUnsignedShortArrayConstructor.h" #include "Document.h" -#include "CanvasUnsignedShortArray.h" -#include "JSCanvasArrayBuffer.h" -#include "JSCanvasArrayBufferConstructor.h" -#include "JSCanvasUnsignedShortArray.h" +#include "WebGLUnsignedShortArray.h" +#include "JSWebGLArrayBuffer.h" +#include "JSWebGLArrayBufferConstructor.h" +#include "JSWebGLUnsignedShortArray.h" #include <runtime/Error.h> namespace WebCore { using namespace JSC; -const ClassInfo JSCanvasUnsignedShortArrayConstructor::s_info = { "CanvasUnsignedShortArrayConstructor", &JSCanvasArray::s_info, 0, 0 }; +const ClassInfo JSWebGLUnsignedShortArrayConstructor::s_info = { "WebGLUnsignedShortArrayConstructor", &JSWebGLArray::s_info, 0, 0 }; -JSCanvasUnsignedShortArrayConstructor::JSCanvasUnsignedShortArrayConstructor(ExecState* exec, JSDOMGlobalObject* globalObject) - : DOMConstructorObject(JSCanvasUnsignedShortArrayConstructor::createStructure(globalObject->objectPrototype()), globalObject) +JSWebGLUnsignedShortArrayConstructor::JSWebGLUnsignedShortArrayConstructor(ExecState* exec, JSDOMGlobalObject* globalObject) + : DOMConstructorObject(JSWebGLUnsignedShortArrayConstructor::createStructure(globalObject->objectPrototype()), globalObject) { - putDirect(exec->propertyNames().prototype, JSCanvasUnsignedShortArrayPrototype::self(exec, globalObject), None); + putDirect(exec->propertyNames().prototype, JSWebGLUnsignedShortArrayPrototype::self(exec, globalObject), None); putDirect(exec->propertyNames().length, jsNumber(exec, 2), ReadOnly|DontDelete|DontEnum); } static JSObject* constructCanvasUnsignedShortArray(ExecState* exec, JSObject* constructor, const ArgList& args) { - JSCanvasUnsignedShortArrayConstructor* jsConstructor = static_cast<JSCanvasUnsignedShortArrayConstructor*>(constructor); - RefPtr<CanvasUnsignedShortArray> array = static_cast<CanvasUnsignedShortArray*>(construct<CanvasUnsignedShortArray, unsigned short>(exec, args).get()); + JSWebGLUnsignedShortArrayConstructor* jsConstructor = static_cast<JSWebGLUnsignedShortArrayConstructor*>(constructor); + RefPtr<WebGLUnsignedShortArray> array = static_cast<WebGLUnsignedShortArray*>(construct<WebGLUnsignedShortArray, unsigned short>(exec, args).get()); + if (!array.get()) { + setDOMException(exec, INDEX_SIZE_ERR); + return 0; + } return asObject(toJS(exec, jsConstructor->globalObject(), array.get())); } -JSC::ConstructType JSCanvasUnsignedShortArrayConstructor::getConstructData(JSC::ConstructData& constructData) +JSC::ConstructType JSWebGLUnsignedShortArrayConstructor::getConstructData(JSC::ConstructData& constructData) { constructData.native.function = constructCanvasUnsignedShortArray; return ConstructTypeHost; diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSCanvasUnsignedByteArrayConstructor.h b/src/3rdparty/webkit/WebCore/bindings/js/JSWebGLUnsignedShortArrayConstructor.h index 9cfb721..5eba20d 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSCanvasUnsignedByteArrayConstructor.h +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSWebGLUnsignedShortArrayConstructor.h @@ -23,17 +23,17 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef JSCanvasUnsignedByteArrayConstructor_h -#define JSCanvasUnsignedByteArrayConstructor_h +#ifndef JSWebGLUnsignedShortArrayConstructor_h +#define JSWebGLUnsignedShortArrayConstructor_h #include "JSDOMBinding.h" #include "JSDocument.h" namespace WebCore { - class JSCanvasUnsignedByteArrayConstructor : public DOMConstructorObject { + class JSWebGLUnsignedShortArrayConstructor : public DOMConstructorObject { public: - JSCanvasUnsignedByteArrayConstructor(JSC::ExecState*, JSDOMGlobalObject*); + JSWebGLUnsignedShortArrayConstructor(JSC::ExecState*, JSDOMGlobalObject*); static const JSC::ClassInfo s_info; private: @@ -43,4 +43,4 @@ namespace WebCore { } -#endif // JSCanvasUnsignedByteArrayConstructor_h +#endif // JSWebGLUnsignedShortArrayConstructor_h diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSCanvasUnsignedShortArrayCustom.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSWebGLUnsignedShortArrayCustom.cpp index 290cd4b..0c82c3e 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSCanvasUnsignedShortArrayCustom.cpp +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSWebGLUnsignedShortArrayCustom.cpp @@ -27,22 +27,50 @@ #if ENABLE(3D_CANVAS) -#include "JSCanvasUnsignedShortArray.h" +#include "JSWebGLArrayHelper.h" +#include "JSWebGLUnsignedShortArray.h" -#include "CanvasUnsignedShortArray.h" +#include "WebGLUnsignedShortArray.h" using namespace JSC; namespace WebCore { -void JSCanvasUnsignedShortArray::indexSetter(JSC::ExecState* exec, unsigned index, JSC::JSValue value) +void JSWebGLUnsignedShortArray::indexSetter(JSC::ExecState* exec, unsigned index, JSC::JSValue value) { impl()->set(index, static_cast<unsigned short>(value.toInt32(exec))); } -JSC::JSValue toJS(JSC::ExecState* exec, JSDOMGlobalObject* globalObject, CanvasUnsignedShortArray* object) +JSC::JSValue toJS(JSC::ExecState* exec, JSDOMGlobalObject* globalObject, WebGLUnsignedShortArray* object) { - return getDOMObjectWrapper<JSCanvasUnsignedShortArray>(exec, globalObject, object); + return getDOMObjectWrapper<JSWebGLUnsignedShortArray>(exec, globalObject, object); +} + +JSC::JSValue JSWebGLUnsignedShortArray::set(JSC::ExecState* exec, JSC::ArgList const& args) +{ + if (args.size() > 2) + return throwError(exec, SyntaxError); + + if (args.size() == 2 && args.at(0).isInt32()) { + // void set(in unsigned long index, in long value); + unsigned index = args.at(0).toUInt32(exec); + impl()->set(index, static_cast<unsigned short>(args.at(1).toInt32(exec))); + return jsUndefined(); + } + + WebGLUnsignedShortArray* array = toWebGLUnsignedShortArray(args.at(0)); + if (array) { + // void set(in WebGLUnsignedShortArray array, [Optional] in unsigned long offset); + unsigned offset = 0; + if (args.size() == 2) + offset = args.at(1).toInt32(exec); + ExceptionCode ec = 0; + impl()->set(array, offset, ec); + setDOMException(exec, ec); + return jsUndefined(); + } + + return setWebGLArrayFromArray(exec, impl(), args); } } // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSWebSocketConstructor.h b/src/3rdparty/webkit/WebCore/bindings/js/JSWebSocketConstructor.h index 069647a..633e612 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSWebSocketConstructor.h +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSWebSocketConstructor.h @@ -31,6 +31,8 @@ #ifndef JSWebSocketConstructor_h #define JSWebSocketConstructor_h +#if ENABLE(WEB_SOCKETS) + #include "JSDOMBinding.h" namespace WebCore { @@ -45,6 +47,8 @@ class JSWebSocketConstructor : public DOMConstructorObject { virtual const JSC::ClassInfo* classInfo() const { return &s_info; } }; -} // namespace WebCore +} // namespace WebCore + +#endif // ENABLE(WEB_SOCKETS) -#endif // JSWebSocketConstructor_h +#endif // JSWebSocketConstructor_h diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSWebSocketCustom.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSWebSocketCustom.cpp index 33c3fcd..d610f01 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSWebSocketCustom.cpp +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSWebSocketCustom.cpp @@ -38,7 +38,6 @@ #include "KURL.h" #include "JSEventListener.h" #include "WebSocket.h" -#include "NotImplemented.h" #include <runtime/Error.h> using namespace JSC; @@ -66,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(); } @@ -76,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/src/3rdparty/webkit/WebCore/bindings/js/JSWorkerContextBase.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSWorkerContextBase.cpp index 741a269..2491f4d 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSWorkerContextBase.cpp +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSWorkerContextBase.cpp @@ -42,10 +42,10 @@ namespace WebCore { ASSERT_CLASS_FITS_IN_CELL(JSWorkerContextBase); -const ClassInfo JSWorkerContextBase::s_info = { "WorkerContext", 0, 0, 0 }; +const ClassInfo JSWorkerContextBase::s_info = { "WorkerContext", &JSDOMGlobalObject::s_info, 0, 0 }; JSWorkerContextBase::JSWorkerContextBase(NonNullPassRefPtr<JSC::Structure> structure, PassRefPtr<WorkerContext> impl) - : JSDOMGlobalObject(structure, new JSDOMGlobalObjectData, this) + : JSDOMGlobalObject(structure, new JSDOMGlobalObjectData(normalWorld(*impl->script()->globalData())), this) , m_impl(impl) { } diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSWorkerContextCustom.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSWorkerContextCustom.cpp index 490d9b1..bf9409c 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSWorkerContextCustom.cpp +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSWorkerContextCustom.cpp @@ -32,8 +32,10 @@ #include "JSDOMBinding.h" #include "JSDOMGlobalObject.h" #include "JSEventListener.h" +#include "JSEventSourceConstructor.h" #include "JSMessageChannelConstructor.h" #include "JSMessagePort.h" +#include "JSWebSocketConstructor.h" #include "JSWorkerLocation.h" #include "JSWorkerNavigator.h" #include "JSXMLHttpRequestConstructor.h" @@ -43,10 +45,6 @@ #include "WorkerNavigator.h" #include <interpreter/Interpreter.h> -#if ENABLE(EVENTSOURCE) -#include "JSEventSourceConstructor.h" -#endif - using namespace JSC; namespace WebCore { @@ -62,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) @@ -93,6 +91,13 @@ JSValue JSWorkerContext::xmlHttpRequest(ExecState* exec) const return getDOMConstructor<JSXMLHttpRequestConstructor>(exec, this); } +#if ENABLE(WEB_SOCKETS) +JSValue JSWorkerContext::webSocket(ExecState* exec) const +{ + return getDOMConstructor<JSWebSocketConstructor>(exec, this); +} +#endif + JSValue JSWorkerContext::importScripts(ExecState* exec, const ArgList& args) { if (!args.size()) @@ -122,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(); } @@ -132,26 +137,26 @@ 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(); } JSValue JSWorkerContext::setTimeout(ExecState* exec, const ArgList& args) { - ScheduledAction* action = ScheduledAction::create(exec, args, currentWorld(exec)); + OwnPtr<ScheduledAction> action = ScheduledAction::create(exec, args, currentWorld(exec)); if (exec->hadException()) return jsUndefined(); int delay = args.at(1).toInt32(exec); - return jsNumber(exec, impl()->setTimeout(action, delay)); + return jsNumber(exec, impl()->setTimeout(action.release(), delay)); } JSValue JSWorkerContext::setInterval(ExecState* exec, const ArgList& args) { - ScheduledAction* action = ScheduledAction::create(exec, args, currentWorld(exec)); + OwnPtr<ScheduledAction> action = ScheduledAction::create(exec, args, currentWorld(exec)); if (exec->hadException()) return jsUndefined(); int delay = args.at(1).toInt32(exec); - return jsNumber(exec, impl()->setInterval(action, delay)); + return jsNumber(exec, impl()->setInterval(action.release(), delay)); } diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSXMLHttpRequestCustom.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSXMLHttpRequestCustom.cpp index 7ee2720..ede5a25 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSXMLHttpRequestCustom.cpp +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSXMLHttpRequestCustom.cpp @@ -29,18 +29,20 @@ #include "config.h" #include "JSXMLHttpRequest.h" +#include "Blob.h" +#include "DOMFormData.h" #include "DOMWindow.h" #include "Document.h" #include "Event.h" -#include "File.h" #include "Frame.h" #include "FrameLoader.h" #include "HTMLDocument.h" +#include "JSBlob.h" +#include "JSDOMFormData.h" #include "JSDOMWindowCustom.h" #include "JSDocument.h" #include "JSEvent.h" #include "JSEventListener.h" -#include "JSFile.h" #include "XMLHttpRequest.h" #include <runtime/Error.h> #include <interpreter/Interpreter.h> @@ -56,7 +58,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 @@ -67,21 +69,23 @@ JSValue JSXMLHttpRequest::open(ExecState* exec, const ArgList& args) const KURL& url = impl()->scriptExecutionContext()->completeURL(args.at(1).toString(exec)); String method = args.at(0).toString(exec); - bool async = true; - if (args.size() >= 3) - async = args.at(2).toBoolean(exec); ExceptionCode ec = 0; - if (args.size() >= 4 && !args.at(3).isUndefined()) { - String user = valueToStringWithNullCheck(exec, args.at(3)); - - if (args.size() >= 5 && !args.at(4).isUndefined()) { - String password = valueToStringWithNullCheck(exec, args.at(4)); - impl()->open(method, url, async, user, password, ec); + if (args.size() >= 3) { + bool async = args.at(2).toBoolean(exec); + + if (args.size() >= 4 && !args.at(3).isUndefined()) { + String user = valueToStringWithNullCheck(exec, args.at(3)); + + if (args.size() >= 5 && !args.at(4).isUndefined()) { + String password = valueToStringWithNullCheck(exec, args.at(4)); + impl()->open(method, url, async, user, password, ec); + } else + impl()->open(method, url, async, user, ec); } else - impl()->open(method, url, async, user, ec); + impl()->open(method, url, async, ec); } else - impl()->open(method, url, async, ec); + impl()->open(method, url, ec); setDOMException(exec, ec); return jsUndefined(); @@ -109,8 +113,10 @@ JSValue JSXMLHttpRequest::send(ExecState* exec, const ArgList& args) impl()->send(ec); else if (val.inherits(&JSDocument::s_info)) impl()->send(toDocument(val), ec); - else if (val.inherits(&JSFile::s_info)) - impl()->send(toFile(val), ec); + else if (val.inherits(&JSBlob::s_info)) + impl()->send(toBlob(val), ec); + else if (val.inherits(&JSDOMFormData::s_info)) + impl()->send(toDOMFormData(val), ec); else impl()->send(val.toString(exec), ec); } @@ -153,7 +159,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 +169,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/src/3rdparty/webkit/WebCore/bindings/js/JSXMLHttpRequestUploadCustom.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSXMLHttpRequestUploadCustom.cpp index fa7cfec..857c12d 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSXMLHttpRequestUploadCustom.cpp +++ b/src/3rdparty/webkit/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/src/3rdparty/webkit/WebCore/bindings/js/JavaScriptProfile.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JavaScriptProfile.cpp new file mode 100644 index 0000000..8e56ed8 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/bindings/js/JavaScriptProfile.cpp @@ -0,0 +1,183 @@ +/* + * Copyright (C) 2008 Apple 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 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 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" +#include "JavaScriptProfile.h" + +#if ENABLE(JAVASCRIPT_DEBUGGER) + +#include "JavaScriptProfileNode.h" +#include <JavaScriptCore/APICast.h> +#include <JavaScriptCore/JSObjectRef.h> +#include <JavaScriptCore/JSStringRef.h> +#include <JavaScriptCore/OpaqueJSString.h> +#include <profiler/Profile.h> +#include <runtime/JSObject.h> +#include <runtime/JSValue.h> +#include <wtf/StdLibExtras.h> + +using namespace JSC; + +namespace WebCore { + +// Cache + +typedef HashMap<Profile*, JSObject*> ProfileMap; + +static ProfileMap& profileCache() +{ + DEFINE_STATIC_LOCAL(ProfileMap, staticProfiles, ()); + return staticProfiles; +} + +// Static Values + +static JSClassRef ProfileClass(); + +static JSValueRef getTitleCallback(JSContextRef ctx, JSObjectRef thisObject, JSStringRef, JSValueRef*) +{ + if (!JSValueIsObjectOfClass(ctx, thisObject, ProfileClass())) + return JSValueMakeUndefined(ctx); + + Profile* profile = static_cast<Profile*>(JSObjectGetPrivate(thisObject)); + return JSValueMakeString(ctx, OpaqueJSString::create(profile->title()).get()); +} + +static JSValueRef getHeadCallback(JSContextRef ctx, JSObjectRef thisObject, JSStringRef, JSValueRef*) +{ + if (!JSValueIsObjectOfClass(ctx, thisObject, ProfileClass())) + return JSValueMakeUndefined(ctx); + + ExecState* exec = toJS(ctx); + Profile* profile = static_cast<Profile*>(JSObjectGetPrivate(thisObject)); + return toRef(exec, toJS(exec, profile->head())); +} + +static JSValueRef getUniqueIdCallback(JSContextRef ctx, JSObjectRef thisObject, JSStringRef, JSValueRef*) +{ + if (!JSValueIsObjectOfClass(ctx, thisObject, ProfileClass())) + return JSValueMakeUndefined(ctx); + + Profile* profile = static_cast<Profile*>(JSObjectGetPrivate(thisObject)); + return JSValueMakeNumber(ctx, profile->uid()); +} + +// Static Functions + +static JSValueRef focus(JSContextRef ctx, JSObjectRef /*function*/, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* /*exception*/) +{ + if (!JSValueIsObjectOfClass(ctx, thisObject, ProfileClass())) + return JSValueMakeUndefined(ctx); + + if (argumentCount < 1) + return JSValueMakeUndefined(ctx); + + if (!JSValueIsObjectOfClass(ctx, arguments[0], ProfileNodeClass())) + return JSValueMakeUndefined(ctx); + + Profile* profile = static_cast<Profile*>(JSObjectGetPrivate(thisObject)); + profile->focus(static_cast<ProfileNode*>(JSObjectGetPrivate(const_cast<JSObjectRef>(arguments[0])))); + + return JSValueMakeUndefined(ctx); +} + +static JSValueRef exclude(JSContextRef ctx, JSObjectRef /*function*/, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* /*exception*/) +{ + if (!JSValueIsObjectOfClass(ctx, thisObject, ProfileClass())) + return JSValueMakeUndefined(ctx); + + if (argumentCount < 1) + return JSValueMakeUndefined(ctx); + + if (!JSValueIsObjectOfClass(ctx, arguments[0], ProfileNodeClass())) + return JSValueMakeUndefined(ctx); + + Profile* profile = static_cast<Profile*>(JSObjectGetPrivate(thisObject)); + profile->exclude(static_cast<ProfileNode*>(JSObjectGetPrivate(const_cast<JSObjectRef>(arguments[0])))); + + return JSValueMakeUndefined(ctx); +} + +static JSValueRef restoreAll(JSContextRef ctx, JSObjectRef /*function*/, JSObjectRef thisObject, size_t /*argumentCount*/, const JSValueRef[] /*arguments*/, JSValueRef* /*exception*/) +{ + if (!JSValueIsObjectOfClass(ctx, thisObject, ProfileClass())) + return JSValueMakeUndefined(ctx); + + Profile* profile = static_cast<Profile*>(JSObjectGetPrivate(thisObject)); + profile->restoreAll(); + + return JSValueMakeUndefined(ctx); +} + +static void finalize(JSObjectRef object) +{ + Profile* profile = static_cast<Profile*>(JSObjectGetPrivate(object)); + profileCache().remove(profile); + profile->deref(); +} + +JSClassRef ProfileClass() +{ + static JSStaticValue staticValues[] = { + { "title", getTitleCallback, 0, kJSPropertyAttributeNone }, + { "head", getHeadCallback, 0, kJSPropertyAttributeNone }, + { "uid", getUniqueIdCallback, 0, kJSPropertyAttributeNone }, + { 0, 0, 0, 0 } + }; + + static JSStaticFunction staticFunctions[] = { + { "focus", focus, kJSPropertyAttributeNone }, + { "exclude", exclude, kJSPropertyAttributeNone }, + { "restoreAll", restoreAll, kJSPropertyAttributeNone }, + { 0, 0, 0 } + }; + + static JSClassDefinition classDefinition = { + 0, kJSClassAttributeNone, "Profile", 0, staticValues, staticFunctions, + 0, finalize, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }; + + static JSClassRef profileClass = JSClassCreate(&classDefinition); + return profileClass; +} + +JSValue toJS(ExecState* exec, Profile* profile) +{ + if (!profile) + return jsNull(); + + JSObject* profileWrapper = profileCache().get(profile); + if (profileWrapper) + return profileWrapper; + + profile->ref(); + profileWrapper = toJS(JSObjectMake(toRef(exec), ProfileClass(), static_cast<void*>(profile))); + profileCache().set(profile, profileWrapper); + return profileWrapper; +} + +} // namespace WebCore + +#endif // ENABLE(JAVASCRIPT_DEBUGGER) diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JavaScriptProfile.h b/src/3rdparty/webkit/WebCore/bindings/js/JavaScriptProfile.h new file mode 100644 index 0000000..7b75b97 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/bindings/js/JavaScriptProfile.h @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2008 Apple 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 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 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 JavaScriptProfile_h +#define JavaScriptProfile_h + +#if ENABLE(JAVASCRIPT_DEBUGGER) + +#include <runtime/JSValue.h> + +namespace JSC { +class ExecState; +class Profile; +} + +namespace WebCore { + +JSC::JSValue toJS(JSC::ExecState*, JSC::Profile*); + +} // namespace WebCore + +#endif // ENABLE(JAVASCRIPT_DEBUGGER) + +#endif diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JavaScriptProfileNode.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JavaScriptProfileNode.cpp new file mode 100644 index 0000000..7d60b24 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/bindings/js/JavaScriptProfileNode.cpp @@ -0,0 +1,236 @@ +/* + * Copyright (C) 2008 Apple 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 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 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" +#include "JavaScriptProfileNode.h" + +#if ENABLE(JAVASCRIPT_DEBUGGER) + +#include "JSDOMBinding.h" +#include <JavaScriptCore/APICast.h> +#include <JavaScriptCore/JSContextRef.h> +#include <JavaScriptCore/JSObjectRef.h> +#include <JavaScriptCore/JSRetainPtr.h> +#include <JavaScriptCore/JSStringRef.h> +#include <profiler/ProfileNode.h> +#include <runtime/JSLock.h> +#include <runtime/JSValue.h> +#include <wtf/StdLibExtras.h> + +using namespace JSC; + +namespace WebCore { + +// Cache + +typedef HashMap<ProfileNode*, JSObject*> ProfileNodeMap; + +static ProfileNodeMap& profileNodeCache() +{ + DEFINE_STATIC_LOCAL(ProfileNodeMap, staticProfileNodes, ()); + return staticProfileNodes; +} + +static JSValueRef getFunctionName(JSContextRef ctx, JSObjectRef thisObject, JSStringRef, JSValueRef*) +{ + if (!JSValueIsObjectOfClass(ctx, thisObject, ProfileNodeClass())) + return JSValueMakeUndefined(ctx); + + ProfileNode* profileNode = static_cast<ProfileNode*>(JSObjectGetPrivate(thisObject)); + JSRetainPtr<JSStringRef> functionNameString(Adopt, JSStringCreateWithCharacters(profileNode->functionName().data(), profileNode->functionName().size())); + return JSValueMakeString(ctx, functionNameString.get()); +} + +static JSValueRef getURL(JSContextRef ctx, JSObjectRef thisObject, JSStringRef, JSValueRef*) +{ + if (!JSValueIsObjectOfClass(ctx, thisObject, ProfileNodeClass())) + return JSValueMakeUndefined(ctx); + + ProfileNode* profileNode = static_cast<ProfileNode*>(JSObjectGetPrivate(thisObject)); + JSRetainPtr<JSStringRef> urlString(Adopt, JSStringCreateWithCharacters(profileNode->url().data(), profileNode->url().size())); + return JSValueMakeString(ctx, urlString.get()); +} + +static JSValueRef getLineNumber(JSContextRef ctx, JSObjectRef thisObject, JSStringRef, JSValueRef*) +{ + if (!JSValueIsObjectOfClass(ctx, thisObject, ProfileNodeClass())) + return JSValueMakeUndefined(ctx); + + ProfileNode* profileNode = static_cast<ProfileNode*>(JSObjectGetPrivate(thisObject)); + return JSValueMakeNumber(ctx, profileNode->lineNumber()); +} + +static JSValueRef getTotalTime(JSContextRef ctx, JSObjectRef thisObject, JSStringRef, JSValueRef*) +{ + JSC::JSLock lock(SilenceAssertionsOnly); + + if (!JSValueIsObjectOfClass(ctx, thisObject, ProfileNodeClass())) + return JSValueMakeUndefined(ctx); + + ProfileNode* profileNode = static_cast<ProfileNode*>(JSObjectGetPrivate(thisObject)); + return JSValueMakeNumber(ctx, profileNode->totalTime()); +} + +static JSValueRef getSelfTime(JSContextRef ctx, JSObjectRef thisObject, JSStringRef, JSValueRef*) +{ + JSC::JSLock lock(SilenceAssertionsOnly); + + if (!JSValueIsObjectOfClass(ctx, thisObject, ProfileNodeClass())) + return JSValueMakeUndefined(ctx); + + ProfileNode* profileNode = static_cast<ProfileNode*>(JSObjectGetPrivate(thisObject)); + return JSValueMakeNumber(ctx, profileNode->selfTime()); +} + +static JSValueRef getNumberOfCalls(JSContextRef ctx, JSObjectRef thisObject, JSStringRef, JSValueRef*) +{ + JSC::JSLock lock(SilenceAssertionsOnly); + + if (!JSValueIsObjectOfClass(ctx, thisObject, ProfileNodeClass())) + return JSValueMakeUndefined(ctx); + + ProfileNode* profileNode = static_cast<ProfileNode*>(JSObjectGetPrivate(thisObject)); + return JSValueMakeNumber(ctx, profileNode->numberOfCalls()); +} + +static JSValueRef getChildren(JSContextRef ctx, JSObjectRef thisObject, JSStringRef, JSValueRef* exception) +{ + JSC::JSLock lock(SilenceAssertionsOnly); + + if (!JSValueIsObjectOfClass(ctx, thisObject, ProfileNodeClass())) + return JSValueMakeUndefined(ctx); + + ProfileNode* profileNode = static_cast<ProfileNode*>(JSObjectGetPrivate(thisObject)); + const Vector<RefPtr<ProfileNode> >& children = profileNode->children(); + + JSObjectRef global = JSContextGetGlobalObject(ctx); + + JSRetainPtr<JSStringRef> arrayString(Adopt, JSStringCreateWithUTF8CString("Array")); + + JSValueRef arrayProperty = JSObjectGetProperty(ctx, global, arrayString.get(), exception); + if (exception && *exception) + return JSValueMakeUndefined(ctx); + + JSObjectRef arrayConstructor = JSValueToObject(ctx, arrayProperty, exception); + if (exception && *exception) + return JSValueMakeUndefined(ctx); + + JSObjectRef result = JSObjectCallAsConstructor(ctx, arrayConstructor, 0, 0, exception); + if (exception && *exception) + return JSValueMakeUndefined(ctx); + + JSRetainPtr<JSStringRef> pushString(Adopt, JSStringCreateWithUTF8CString("push")); + + JSValueRef pushProperty = JSObjectGetProperty(ctx, result, pushString.get(), exception); + if (exception && *exception) + return JSValueMakeUndefined(ctx); + + JSObjectRef pushFunction = JSValueToObject(ctx, pushProperty, exception); + if (exception && *exception) + return JSValueMakeUndefined(ctx); + + ExecState* exec = toJS(ctx); + for (Vector<RefPtr<ProfileNode> >::const_iterator it = children.begin(); it != children.end(); ++it) { + JSValueRef arg0 = toRef(exec, toJS(exec, (*it).get() )); + JSObjectCallAsFunction(ctx, pushFunction, result, 1, &arg0, exception); + if (exception && *exception) + return JSValueMakeUndefined(ctx); + } + + return result; +} + +static JSValueRef getVisible(JSContextRef ctx, JSObjectRef thisObject, JSStringRef, JSValueRef*) +{ + JSC::JSLock lock(SilenceAssertionsOnly); + + if (!JSValueIsObjectOfClass(ctx, thisObject, ProfileNodeClass())) + return JSValueMakeUndefined(ctx); + + ProfileNode* profileNode = static_cast<ProfileNode*>(JSObjectGetPrivate(thisObject)); + return JSValueMakeBoolean(ctx, profileNode->visible()); +} + +static JSValueRef getCallUID(JSContextRef ctx, JSObjectRef thisObject, JSStringRef, JSValueRef*) +{ + JSC::JSLock lock(SilenceAssertionsOnly); + + if (!JSValueIsObjectOfClass(ctx, thisObject, ProfileNodeClass())) + return JSValueMakeUndefined(ctx); + + ProfileNode* profileNode = static_cast<ProfileNode*>(JSObjectGetPrivate(thisObject)); + return JSValueMakeNumber(ctx, profileNode->callIdentifier().hash()); +} + +static void finalize(JSObjectRef object) +{ + ProfileNode* profileNode = static_cast<ProfileNode*>(JSObjectGetPrivate(object)); + profileNodeCache().remove(profileNode); + profileNode->deref(); +} + +JSClassRef ProfileNodeClass() +{ + static JSStaticValue staticValues[] = { + { "functionName", getFunctionName, 0, kJSPropertyAttributeNone }, + { "url", getURL, 0, kJSPropertyAttributeNone }, + { "lineNumber", getLineNumber, 0, kJSPropertyAttributeNone }, + { "totalTime", getTotalTime, 0, kJSPropertyAttributeNone }, + { "selfTime", getSelfTime, 0, kJSPropertyAttributeNone }, + { "numberOfCalls", getNumberOfCalls, 0, kJSPropertyAttributeNone }, + { "children", getChildren, 0, kJSPropertyAttributeNone }, + { "visible", getVisible, 0, kJSPropertyAttributeNone }, + { "callUID", getCallUID, 0, kJSPropertyAttributeNone }, + { 0, 0, 0, 0 } + }; + + static JSClassDefinition classDefinition = { + 0, kJSClassAttributeNone, "ProfileNode", 0, staticValues, 0, + 0, finalize, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }; + + static JSClassRef profileNodeClass = JSClassCreate(&classDefinition); + return profileNodeClass; +} + +JSValue toJS(ExecState* exec, ProfileNode* profileNode) +{ + if (!profileNode) + return jsNull(); + + JSObject* profileNodeWrapper = profileNodeCache().get(profileNode); + if (profileNodeWrapper) + return profileNodeWrapper; + + profileNode->ref(); + + profileNodeWrapper = toJS(JSObjectMake(toRef(exec), ProfileNodeClass(), static_cast<void*>(profileNode))); + profileNodeCache().set(profileNode, profileNodeWrapper); + return profileNodeWrapper; +} + +} // namespace WebCore + +#endif // ENABLE(JAVASCRIPT_DEBUGGER) diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JavaScriptProfileNode.h b/src/3rdparty/webkit/WebCore/bindings/js/JavaScriptProfileNode.h new file mode 100644 index 0000000..f01be19 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/bindings/js/JavaScriptProfileNode.h @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2008 Apple 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 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 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 JavaScriptProfileNode_h +#define JavaScriptProfileNode_h + +#if ENABLE(JAVASCRIPT_DEBUGGER) + +#include <JavaScriptCore/JSBase.h> +#include <runtime/JSValue.h> + +namespace JSC { +class ExecState; +class ProfileNode; +} + +namespace WebCore { + +JSClassRef ProfileNodeClass(); +JSC::JSValue toJS(JSC::ExecState*, JSC::ProfileNode*); + +} // namespace WebCore + +#endif // ENABLE(JAVASCRIPT_DEBUGGER) + +#endif diff --git a/src/3rdparty/webkit/WebCore/bindings/js/ScheduledAction.cpp b/src/3rdparty/webkit/WebCore/bindings/js/ScheduledAction.cpp index 9a21b6b..6dea50e 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/ScheduledAction.cpp +++ b/src/3rdparty/webkit/WebCore/bindings/js/ScheduledAction.cpp @@ -47,7 +47,7 @@ using namespace JSC; namespace WebCore { -ScheduledAction* ScheduledAction::create(ExecState* exec, const ArgList& args, DOMWrapperWorld* isolatedWorld) +PassOwnPtr<ScheduledAction> ScheduledAction::create(ExecState* exec, const ArgList& args, DOMWrapperWorld* isolatedWorld) { JSValue v = args.at(0); CallData callData; @@ -103,7 +103,7 @@ void ScheduledAction::executeFunctionInContext(JSGlobalObject* globalObject, JSV args.append(m_args[i]); globalObject->globalData()->timeoutChecker.start(); - callInWorld(exec, m_function, callType, callData, thisValue, args, m_isolatedWorld.get()); + JSC::call(exec, m_function, callType, callData, thisValue, args); globalObject->globalData()->timeoutChecker.stop(); if (exec->hadException()) @@ -117,7 +117,7 @@ void ScheduledAction::execute(Document* document) return; RefPtr<Frame> frame = window->impl()->frame(); - if (!frame || !frame->script()->isEnabled()) + if (!frame || !frame->script()->canExecuteScripts(AboutToExecuteScript)) return; frame->script()->setProcessingTimerCallback(true); @@ -126,7 +126,7 @@ void ScheduledAction::execute(Document* document) executeFunctionInContext(window, window->shell()); Document::updateStyleForAllDocuments(); } else - frame->script()->executeScriptInIsolatedWorld(m_isolatedWorld.get(), m_code); + frame->script()->executeScriptInWorld(m_isolatedWorld.get(), m_code); frame->script()->setProcessingTimerCallback(false); } diff --git a/src/3rdparty/webkit/WebCore/bindings/js/ScheduledAction.h b/src/3rdparty/webkit/WebCore/bindings/js/ScheduledAction.h index 4ea727d..3b7e001 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/ScheduledAction.h +++ b/src/3rdparty/webkit/WebCore/bindings/js/ScheduledAction.h @@ -24,6 +24,7 @@ #include <JSDOMBinding.h> #include <runtime/JSCell.h> #include <runtime/Protect.h> +#include <wtf/PassOwnPtr.h> #include <wtf/Vector.h> namespace JSC { @@ -40,9 +41,9 @@ namespace WebCore { * time interval, either once or repeatedly. Used for window.setTimeout() * and window.setInterval() */ - class ScheduledAction { + class ScheduledAction : public Noncopyable { public: - static ScheduledAction* create(JSC::ExecState*, const JSC::ArgList&, DOMWrapperWorld* isolatedWorld); + static PassOwnPtr<ScheduledAction> create(JSC::ExecState*, const JSC::ArgList&, DOMWrapperWorld* isolatedWorld); void execute(ScriptExecutionContext*); @@ -56,7 +57,7 @@ namespace WebCore { void executeFunctionInContext(JSC::JSGlobalObject*, JSC::JSValue thisValue); void execute(Document*); -#if ENABLE(WORKERS) +#if ENABLE(WORKERS) void execute(WorkerContext*); #endif diff --git a/src/3rdparty/webkit/WebCore/bindings/js/ScriptArray.cpp b/src/3rdparty/webkit/WebCore/bindings/js/ScriptArray.cpp index 2c4075a..caecc40 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/ScriptArray.cpp +++ b/src/3rdparty/webkit/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/src/3rdparty/webkit/WebCore/bindings/js/ScriptCachedFrameData.cpp b/src/3rdparty/webkit/WebCore/bindings/js/ScriptCachedFrameData.cpp index e01324e..16f18d3 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/ScriptCachedFrameData.cpp +++ b/src/3rdparty/webkit/WebCore/bindings/js/ScriptCachedFrameData.cpp @@ -44,19 +44,26 @@ using namespace JSC; namespace WebCore { ScriptCachedFrameData::ScriptCachedFrameData(Frame* frame) + : m_domWindow(0) { JSLock lock(SilenceAssertionsOnly); ScriptController* scriptController = frame->script(); - // FIXME: explicitly save and restore isolated worlds' global objects when using the back/forward cache. <rdar://problem/7328111> - if (JSDOMWindowShell* windowShell = scriptController->existingWindowShell(mainThreadNormalWorld())) { - m_window = windowShell->window(); - scriptController->attachDebugger(0); + ScriptController::ShellMap& windowShells = scriptController->m_windowShells; + + ScriptController::ShellMap::iterator windowShellsEnd = windowShells.end(); + for (ScriptController::ShellMap::iterator iter = windowShells.begin(); iter != windowShellsEnd; ++iter) { + JSDOMWindow* window = iter->second->window(); + m_windows.add(iter->first.get(), window); + m_domWindow = window->impl(); } + + scriptController->attachDebugger(0); } -DOMWindow* ScriptCachedFrameData::domWindow() const { - return m_window ? m_window->impl() : 0; +DOMWindow* ScriptCachedFrameData::domWindow() const +{ + return m_domWindow; } ScriptCachedFrameData::~ScriptCachedFrameData() @@ -66,31 +73,37 @@ ScriptCachedFrameData::~ScriptCachedFrameData() void ScriptCachedFrameData::restore(Frame* frame) { - Page* page = frame->page(); - JSLock lock(SilenceAssertionsOnly); ScriptController* scriptController = frame->script(); - // FIXME: explicitly save and restore isolated worlds' global objects when using the back/forward cache. <rdar://problem/7328111> - if (JSDOMWindowShell* windowShell = scriptController->existingWindowShell(mainThreadNormalWorld())) { - if (m_window) - windowShell->setWindow(m_window.get()); + ScriptController::ShellMap& windowShells = scriptController->m_windowShells; + + ScriptController::ShellMap::iterator windowShellsEnd = windowShells.end(); + for (ScriptController::ShellMap::iterator iter = windowShells.begin(); iter != windowShellsEnd; ++iter) { + DOMWrapperWorld* world = iter->first.get(); + JSDOMWindowShell* windowShell = iter->second.get(); + + if (JSDOMWindow* window = m_windows.get(world)) + windowShell->setWindow(window); else { windowShell->setWindow(frame->domWindow()); - scriptController->attachDebugger(page->debugger()); - windowShell->window()->setProfileGroup(page->group().identifier()); + + if (Page* page = frame->page()) { + scriptController->attachDebugger(windowShell, page->debugger()); + windowShell->window()->setProfileGroup(page->group().identifier()); + } } } } void ScriptCachedFrameData::clear() { - JSLock lock(SilenceAssertionsOnly); + if (m_windows.isEmpty()) + return; - if (m_window) { - m_window = 0; - gcController().garbageCollectSoon(); - } + JSLock lock(SilenceAssertionsOnly); + m_windows.clear(); + gcController().garbageCollectSoon(); } } // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/bindings/js/ScriptCachedFrameData.h b/src/3rdparty/webkit/WebCore/bindings/js/ScriptCachedFrameData.h index c661f28..15c23c5 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/ScriptCachedFrameData.h +++ b/src/3rdparty/webkit/WebCore/bindings/js/ScriptCachedFrameData.h @@ -38,8 +38,11 @@ namespace WebCore { class Frame; class JSDOMWindow; class DOMWindow; + class DOMWrapperWorld; + + class ScriptCachedFrameData : public Noncopyable { + typedef HashMap< RefPtr<DOMWrapperWorld>, JSC::ProtectedPtr<JSDOMWindow> > JSDOMWindowSet; - class ScriptCachedFrameData { public: ScriptCachedFrameData(Frame*); ~ScriptCachedFrameData(); @@ -49,7 +52,8 @@ namespace WebCore { DOMWindow* domWindow() const; private: - JSC::ProtectedPtr<JSDOMWindow> m_window; + JSDOMWindowSet m_windows; + DOMWindow* m_domWindow; }; } // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/bindings/js/ScriptCallStack.cpp b/src/3rdparty/webkit/WebCore/bindings/js/ScriptCallStack.cpp index 021ede5..c8eadd1 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/ScriptCallStack.cpp +++ b/src/3rdparty/webkit/WebCore/bindings/js/ScriptCallStack.cpp @@ -54,14 +54,15 @@ ScriptCallStack::ScriptCallStack(ExecState* exec, const ArgList& args, unsigned exec->interpreter()->retrieveLastCaller(exec, signedLineNumber, sourceID, urlString, function); + unsigned lineNumber = signedLineNumber >= 0 ? signedLineNumber : 0; + if (function) { m_caller = asInternalFunction(function); - unsigned lineNumber = signedLineNumber >= 0 ? signedLineNumber : 0; - m_frames.append(ScriptCallFrame(m_caller->name(&m_exec->globalData()), urlString, lineNumber, args, skipArgumentCount)); + m_frames.append(ScriptCallFrame(m_caller->name(m_exec), urlString, lineNumber, args, skipArgumentCount)); } else { // Caller is unknown, but we should still add the frame, because // something called us, and gave us arguments. - m_frames.append(ScriptCallFrame(UString(), UString(), 0, args, skipArgumentCount)); + m_frames.append(ScriptCallFrame(UString(), urlString, lineNumber, args, skipArgumentCount)); } } @@ -94,10 +95,15 @@ void ScriptCallStack::initialize() while (!func.isNull()) { InternalFunction* internalFunction = asInternalFunction(func); ArgList emptyArgList; - m_frames.append(ScriptCallFrame(internalFunction->name(&m_exec->globalData()), UString(), 0, emptyArgList, 0)); + m_frames.append(ScriptCallFrame(internalFunction->name(m_exec), UString(), 0, emptyArgList, 0)); func = m_exec->interpreter()->retrieveCaller(m_exec, internalFunction); } m_initialized = true; } +bool ScriptCallStack::callLocation(String*, int*) +{ + return false; +} + } // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/bindings/js/ScriptCallStack.h b/src/3rdparty/webkit/WebCore/bindings/js/ScriptCallStack.h index 1907564..f5f8ae0 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/ScriptCallStack.h +++ b/src/3rdparty/webkit/WebCore/bindings/js/ScriptCallStack.h @@ -49,9 +49,11 @@ namespace WebCore { ~ScriptCallStack(); ScriptState* state() const { return m_exec; } + ScriptState* globalState() const { return m_exec->lexicalGlobalObject()->globalExec(); } // frame retrieval methods const ScriptCallFrame &at(unsigned); unsigned size(); + static bool callLocation(String*, int*); private: void initialize(); diff --git a/src/3rdparty/webkit/WebCore/bindings/js/ScriptController.cpp b/src/3rdparty/webkit/WebCore/bindings/js/ScriptController.cpp index 4a1d413..f6b779a 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/ScriptController.cpp +++ b/src/3rdparty/webkit/WebCore/bindings/js/ScriptController.cpp @@ -25,8 +25,10 @@ #include "Event.h" #include "EventNames.h" #include "Frame.h" +#include "FrameLoaderClient.h" #include "GCController.h" #include "HTMLPlugInElement.h" +#include "InspectorTimelineAgent.h" #include "JSDocument.h" #include "NP_jsobject.h" #include "Page.h" @@ -35,6 +37,7 @@ #include "ScriptValue.h" #include "Settings.h" #include "StorageNamespace.h" +#include "WebCoreJSClientData.h" #include "XSSAuditor.h" #include "npruntime_impl.h" #include "runtime_root.h" @@ -43,6 +46,7 @@ #include <runtime/JSLock.h> using namespace JSC; +using namespace std; namespace WebCore { @@ -79,9 +83,6 @@ ScriptController::ScriptController(Frame* frame) ScriptController::~ScriptController() { if (!m_windowShells.isEmpty()) { - for (ShellMap::iterator iter = m_windowShells.begin(); iter != m_windowShells.end(); ++iter) - iter->first->forgetScriptController(this); - m_windowShells.clear(); // It's likely that releasing the global object has created a lot of garbage. @@ -102,7 +103,7 @@ ScriptValue ScriptController::evaluateInWorld(const ScriptSourceCode& sourceCode } // evaluate code. Returns the JS return value or 0 - // if there was none, an error occured or the type couldn't be converted. + // if there was none, an error occurred or the type couldn't be converted. // inlineCode is true for <a href="javascript:doSomething()"> // and false for <script>doSomething()</script>. Check if it has the @@ -117,10 +118,20 @@ ScriptValue ScriptController::evaluateInWorld(const ScriptSourceCode& sourceCode RefPtr<Frame> protect = m_frame; +#if ENABLE(INSPECTOR) + if (InspectorTimelineAgent* timelineAgent = m_frame->page() ? m_frame->page()->inspectorTimelineAgent() : 0) + timelineAgent->willEvaluateScript(sourceURL, sourceCode.startLine()); +#endif + exec->globalData().timeoutChecker.start(); - Completion comp = WebCore::evaluateInWorld(exec, exec->dynamicGlobalObject()->globalScopeChain(), jsSourceCode, shell, world); + Completion comp = JSC::evaluate(exec, exec->dynamicGlobalObject()->globalScopeChain(), jsSourceCode, shell); exec->globalData().timeoutChecker.stop(); +#if ENABLE(INSPECTOR) + if (InspectorTimelineAgent* timelineAgent = m_frame->page() ? m_frame->page()->inspectorTimelineAgent() : 0) + timelineAgent->didEvaluateScript(); +#endif + // Evaluating the JavaScript could cause the frame to be deallocated // so we start the keep alive timer here. m_frame->keepAlive(); @@ -145,53 +156,26 @@ 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) + : DOMWrapperWorld(globalData, false) { JSGlobalData::ClientData* clientData = globalData->clientData; ASSERT(clientData); static_cast<WebCoreJSClientData*>(clientData)->rememberWorld(this); } - - static PassRefPtr<IsolatedWorld> create(JSGlobalData* globalData) { return adoptRef(new IsolatedWorld(globalData)); } }; -static PassRefPtr<IsolatedWorld> findWorld(unsigned worldID) +PassRefPtr<DOMWrapperWorld> ScriptController::createWorld() { - if (!worldID) - return IsolatedWorld::create(JSDOMWindow::commonJSGlobalData()); - - typedef HashMap<unsigned, RefPtr<IsolatedWorld> > WorldMap; - DEFINE_STATIC_LOCAL(WorldMap, isolatedWorlds, ()); - - WorldMap::iterator iter = isolatedWorlds.find(worldID); - if (iter != isolatedWorlds.end()) - return iter->second; - - RefPtr<IsolatedWorld> newWorld = IsolatedWorld::create(JSDOMWindow::commonJSGlobalData()); - isolatedWorlds.add(worldID, newWorld); - return newWorld; + return IsolatedWorld::create(JSDOMWindow::commonJSGlobalData()); } -JSDOMWindow* ScriptController::globalObject(unsigned worldID) +void ScriptController::getAllWorlds(Vector<DOMWrapperWorld*>& worlds) { - RefPtr<DOMWrapperWorld> world = findWorld(worldID); - return windowShell(world.get())->window(); -} - -ScriptValue ScriptController::evaluateInIsolatedWorld(unsigned worldID, const ScriptSourceCode& sourceCode) -{ - RefPtr<DOMWrapperWorld> world = findWorld(worldID); - return evaluateInWorld(sourceCode, world.get()); -} - -void ScriptController::evaluateInIsolatedWorld(unsigned worldID, const Vector<ScriptSourceCode>& sourceCode) -{ - RefPtr<DOMWrapperWorld> world = findWorld(worldID); - - unsigned size = sourceCode.size(); - for (unsigned i = 0; i < size; ++i) - evaluateInWorld(sourceCode[i], world.get()); + static_cast<WebCoreJSClientData*>(JSDOMWindow::commonJSGlobalData()->clientData)->getAllWorlds(worlds); } void ScriptController::clearWindowShell() @@ -201,19 +185,17 @@ void ScriptController::clearWindowShell() JSLock lock(SilenceAssertionsOnly); - // Clear the debugger from the current window before setting the new window. - DOMWrapperWorld* debugWorld = debuggerWorld(); - attachDebugger(0); - for (ShellMap::iterator iter = m_windowShells.begin(); iter != m_windowShells.end(); ++iter) { - DOMWrapperWorld* world = iter->first; JSDOMWindowShell* windowShell = iter->second; + + // Clear the debugger from the current window before setting the new window. + attachDebugger(windowShell, 0); + windowShell->window()->willRemoveFromWindowShell(); windowShell->setWindow(m_frame->domWindow()); if (Page* page = m_frame->page()) { - if (world == debugWorld) - attachDebugger(page->debugger()); + attachDebugger(windowShell, page->debugger()); windowShell->window()->setProfileGroup(page->group().identifier()); } } @@ -228,53 +210,33 @@ JSDOMWindowShell* ScriptController::initScript(DOMWrapperWorld* world) JSLock lock(SilenceAssertionsOnly); - JSDOMWindowShell* windowShell = new JSDOMWindowShell(m_frame->domWindow()); + JSDOMWindowShell* windowShell = new JSDOMWindowShell(m_frame->domWindow(), world); m_windowShells.add(world, windowShell); - world->rememberScriptController(this); - windowShell->window()->updateDocument(world); + windowShell->window()->updateDocument(); if (Page* page = m_frame->page()) { - if (world == debuggerWorld()) - attachDebugger(page->debugger()); + attachDebugger(windowShell, page->debugger()); windowShell->window()->setProfileGroup(page->group().identifier()); } - { - EnterDOMWrapperWorld worldEntry(*JSDOMWindow::commonJSGlobalData(), world); - m_frame->loader()->dispatchWindowObjectAvailable(); - } + m_frame->loader()->dispatchDidClearWindowObjectInWorld(world); return windowShell; } -bool ScriptController::processingUserGesture() const +bool ScriptController::processingUserGesture(DOMWrapperWorld* world) const { - return m_allowPopupsFromPlugin || processingUserGestureEvent() || isJavaScriptAnchorNavigation(); + return m_allowPopupsFromPlugin || processingUserGestureEvent(world) || isJavaScriptAnchorNavigation(); } -bool ScriptController::processingUserGestureEvent() const +bool ScriptController::processingUserGestureEvent(DOMWrapperWorld* world) const { - JSDOMWindowShell* shell = existingWindowShell(mainThreadNormalWorld()); + JSDOMWindowShell* shell = existingWindowShell(world); if (!shell) return false; - if (Event* event = shell->window()->currentEvent()) { - if (event->createdByDOM()) - return false; - - const AtomicString& type = event->type(); - if ( // mouse events - type == eventNames().clickEvent || type == eventNames().mousedownEvent || - type == eventNames().mouseupEvent || type == eventNames().dblclickEvent || - // keyboard events - type == eventNames().keydownEvent || type == eventNames().keypressEvent || - type == eventNames().keyupEvent || - // other accepted events - type == eventNames().selectEvent || type == eventNames().changeEvent || - type == eventNames().focusEvent || type == eventNames().blurEvent || - type == eventNames().submitEvent) - return true; - } + if (Event* event = shell->window()->currentEvent()) + return event->fromUserGesture(); return false; } @@ -300,7 +262,20 @@ bool ScriptController::anyPageIsProcessingUserGesture() const HashSet<Page*>::const_iterator end = pages.end(); for (HashSet<Page*>::const_iterator it = pages.begin(); it != end; ++it) { for (Frame* frame = page->mainFrame(); frame; frame = frame->tree()->traverseNext()) { - if (frame->script()->processingUserGesture()) + ScriptController* script = frame->script(); + + if (script->m_allowPopupsFromPlugin) + return true; + + const ShellMap::const_iterator iterEnd = m_windowShells.end(); + for (ShellMap::const_iterator iter = m_windowShells.begin(); iter != iterEnd; ++iter) { + JSDOMWindowShell* shell = iter->second.get(); + Event* event = shell->window()->currentEvent(); + if (event && event->fromUserGesture()) + return true; + } + + if (isJavaScriptAnchorNavigation()) return true; } } @@ -308,16 +283,14 @@ bool ScriptController::anyPageIsProcessingUserGesture() const return false; } -bool ScriptController::isEnabled() +void ScriptController::attachDebugger(JSC::Debugger* debugger) { - Settings* settings = m_frame->settings(); - return (settings && settings->isJavaScriptEnabled()); + for (ShellMap::iterator iter = m_windowShells.begin(); iter != m_windowShells.end(); ++iter) + attachDebugger(iter->second, debugger); } -void ScriptController::attachDebugger(JSC::Debugger* debugger) +void ScriptController::attachDebugger(JSDOMWindowShell* shell, JSC::Debugger* debugger) { - // FIXME: Should be able to debug isolated worlds. - JSDOMWindowShell* shell = existingWindowShell(debuggerWorld()); if (!shell) return; @@ -335,7 +308,7 @@ void ScriptController::updateDocument() JSLock lock(SilenceAssertionsOnly); for (ShellMap::iterator iter = m_windowShells.begin(); iter != m_windowShells.end(); ++iter) - iter->second->window()->updateDocument(iter->first); + iter->second->window()->updateDocument(); } void ScriptController::updateSecurityOrigin() @@ -345,7 +318,7 @@ void ScriptController::updateSecurityOrigin() Bindings::RootObject* ScriptController::bindingRootObject() { - if (!isEnabled()) + if (!canExecuteScripts(NotAboutToExecuteScript)) return 0; if (!m_bindingRootObject) { @@ -372,7 +345,7 @@ PassRefPtr<Bindings::RootObject> ScriptController::createRootObject(void* native NPObject* ScriptController::windowScriptNPObject() { if (!m_windowScriptNPObject) { - if (isEnabled()) { + if (canExecuteScripts(NotAboutToExecuteScript)) { // JavaScript is enabled, so there is a JavaScript window object. // Return an NPObject bound to the window object. JSC::JSLock lock(SilenceAssertionsOnly); @@ -405,7 +378,7 @@ NPObject* ScriptController::createScriptObjectForPluginElement(HTMLPlugInElement JSObject* ScriptController::jsObjectForPluginElement(HTMLPlugInElement* plugin) { // Can't create JSObjects when JavaScript is disabled - if (!isEnabled()) + if (!canExecuteScripts(NotAboutToExecuteScript)) return 0; // Create a JSObject bound to this element @@ -468,31 +441,11 @@ void ScriptController::clearScriptObjects() #endif } -ScriptValue ScriptController::executeScriptInIsolatedWorld(unsigned worldID, const String& script, bool forceUserGesture) -{ - ScriptSourceCode sourceCode(script, forceUserGesture ? KURL() : m_frame->loader()->url()); - - if (!isEnabled() || isPaused()) - return ScriptValue(); - - bool wasInExecuteScript = m_inExecuteScript; - m_inExecuteScript = true; - - ScriptValue result = evaluateInIsolatedWorld(worldID, sourceCode); - - if (!wasInExecuteScript) { - m_inExecuteScript = false; - Document::updateStyleForAllDocuments(); - } - - return result; -} - -ScriptValue ScriptController::executeScriptInIsolatedWorld(DOMWrapperWorld* world, const String& script, bool forceUserGesture) +ScriptValue ScriptController::executeScriptInWorld(DOMWrapperWorld* world, const String& script, bool forceUserGesture) { ScriptSourceCode sourceCode(script, forceUserGesture ? KURL() : m_frame->loader()->url()); - if (!isEnabled() || isPaused()) + if (!canExecuteScripts(AboutToExecuteScript) || isPaused()) return ScriptValue(); bool wasInExecuteScript = m_inExecuteScript; diff --git a/src/3rdparty/webkit/WebCore/bindings/js/ScriptController.h b/src/3rdparty/webkit/WebCore/bindings/js/ScriptController.h index f2a497d..6af1736 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/ScriptController.h +++ b/src/3rdparty/webkit/WebCore/bindings/js/ScriptController.h @@ -62,13 +62,21 @@ class XSSAuditor; typedef HashMap<void*, RefPtr<JSC::Bindings::RootObject> > RootObjectMap; +enum ReasonForCallingCanExecuteScripts { + AboutToExecuteScript, + NotAboutToExecuteScript +}; + class ScriptController { - typedef WTF::HashMap<DOMWrapperWorld*, JSC::ProtectedPtr<JSDOMWindowShell> > ShellMap; + friend class ScriptCachedFrameData; + typedef WTF::HashMap< RefPtr<DOMWrapperWorld>, JSC::ProtectedPtr<JSDOMWindowShell> > ShellMap; public: ScriptController(Frame*); ~ScriptController(); + static PassRefPtr<DOMWrapperWorld> createWorld(); + JSDOMWindowShell* windowShell(DOMWrapperWorld* world) { ShellMap::iterator iter = m_windowShells.find(world); @@ -83,17 +91,12 @@ public: { return windowShell(world)->window(); } - JSDOMWindow* globalObject(unsigned worldID); - void forgetWorld(DOMWrapperWorld* world) - { - m_windowShells.remove(world); - } + static void getAllWorlds(Vector<DOMWrapperWorld*>&); ScriptValue executeScript(const ScriptSourceCode&); ScriptValue executeScript(const String& script, bool forceUserGesture = false); - ScriptValue executeScriptInIsolatedWorld(unsigned worldID, const String& script, bool forceUserGesture = false); - ScriptValue executeScriptInIsolatedWorld(DOMWrapperWorld* world, const String& script, bool forceUserGesture = false); + ScriptValue executeScriptInWorld(DOMWrapperWorld* world, const String& script, bool forceUserGesture = false); // Returns true if argument is a JavaScript URL. bool executeIfJavaScriptURL(const KURL&, bool userGesture = false, bool replaceDocument = true); @@ -104,19 +107,19 @@ public: ScriptValue evaluate(const ScriptSourceCode&); ScriptValue evaluateInWorld(const ScriptSourceCode&, DOMWrapperWorld*); - ScriptValue evaluateInIsolatedWorld(unsigned /*worldID*/, const ScriptSourceCode&); - void evaluateInIsolatedWorld(unsigned /*worldID*/, const Vector<ScriptSourceCode>&); void setEventHandlerLineNumber(int lineno) { m_handlerLineNumber = lineno; } int eventHandlerLineNumber() { return m_handlerLineNumber; } void setProcessingTimerCallback(bool b) { m_processingTimerCallback = b; } - bool processingUserGesture() const; + bool processingUserGesture(DOMWrapperWorld*) const; bool anyPageIsProcessingUserGesture() const; - bool isEnabled(); + bool canExecuteScripts(ReasonForCallingCanExecuteScripts); - void attachDebugger(JSC::Debugger*); + // Debugger can be 0 to detach any existing Debugger. + void attachDebugger(JSC::Debugger*); // Attaches/detaches in all worlds/window shells. + void attachDebugger(JSDOMWindowShell*, JSC::Debugger*); void setPaused(bool b) { m_paused = b; } bool isPaused() const { return m_paused; } @@ -166,7 +169,7 @@ private: void disconnectPlatformScriptObjects(); - bool processingUserGestureEvent() const; + bool processingUserGestureEvent(DOMWrapperWorld*) const; bool isJavaScriptAnchorNavigation() const; ShellMap m_windowShells; diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSCanvasFloatArrayCustom.cpp b/src/3rdparty/webkit/WebCore/bindings/js/ScriptControllerBrew.cpp index 20cd805c0..d8d345a 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSCanvasFloatArrayCustom.cpp +++ b/src/3rdparty/webkit/WebCore/bindings/js/ScriptControllerBrew.cpp @@ -1,5 +1,8 @@ /* - * Copyright (C) 2009 Apple Inc. All rights reserved. + * Copyright (C) 2008 Apple Computer, Inc. + * Copyright (C) 2009 Company 100, Inc. + * + * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -20,31 +23,25 @@ * 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. + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "config.h" +#include "ScriptController.h" -#if ENABLE(3D_CANVAS) - -#include "JSCanvasFloatArray.h" - -#include "CanvasFloatArray.h" - -using namespace JSC; +#include "Bridge.h" +#include "PluginView.h" +#include "runtime_root.h" namespace WebCore { -void JSCanvasFloatArray::indexSetter(JSC::ExecState* exec, unsigned index, JSC::JSValue value) +PassRefPtr<JSC::Bindings::Instance> ScriptController::createScriptInstanceForWidget(WebCore::Widget* widget) { - impl()->set(index, static_cast<float>(value.toInt32(exec))); -} + if (!widget->isPluginView()) + return 0; + + return static_cast<PluginView*>(widget)->bindingInstance(); -JSC::JSValue toJS(JSC::ExecState* exec, JSDOMGlobalObject* globalObject, CanvasFloatArray* object) -{ - return getDOMObjectWrapper<JSCanvasFloatArray>(exec, globalObject, object); } } // namespace WebCore - -#endif // ENABLE(3D_CANVAS) diff --git a/src/3rdparty/webkit/WebCore/bindings/js/ScriptControllerGtk.cpp b/src/3rdparty/webkit/WebCore/bindings/js/ScriptControllerGtk.cpp index c906034..6ffae69 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/ScriptControllerGtk.cpp +++ b/src/3rdparty/webkit/WebCore/bindings/js/ScriptControllerGtk.cpp @@ -31,9 +31,9 @@ #include "config.h" #include "ScriptController.h" +#include "Bridge.h" #include "PluginView.h" #include "runtime_root.h" -#include "runtime.h" namespace WebCore { diff --git a/src/3rdparty/webkit/WebCore/bindings/js/ScriptControllerHaiku.cpp b/src/3rdparty/webkit/WebCore/bindings/js/ScriptControllerHaiku.cpp index 3fe471d..a1f1590 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/ScriptControllerHaiku.cpp +++ b/src/3rdparty/webkit/WebCore/bindings/js/ScriptControllerHaiku.cpp @@ -27,8 +27,8 @@ #include "config.h" #include "ScriptController.h" +#include "Bridge.h" #include "PluginView.h" -#include "runtime.h" #include "runtime_root.h" diff --git a/src/3rdparty/webkit/WebCore/bindings/js/ScriptControllerMac.mm b/src/3rdparty/webkit/WebCore/bindings/js/ScriptControllerMac.mm index 21ec0f2..a895489 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/ScriptControllerMac.mm +++ b/src/3rdparty/webkit/WebCore/bindings/js/ScriptControllerMac.mm @@ -29,6 +29,7 @@ #import "config.h" #import "ScriptController.h" +#import "Bridge.h" #import "DOMAbstractViewFrame.h" #import "DOMWindow.h" #import "Frame.h" @@ -37,6 +38,8 @@ #import "JSDOMWindow.h" #import "WebScriptObjectPrivate.h" #import "Widget.h" +#import "objc_instance.h" +#import "runtime_root.h" #import <JavaScriptCore/APICast.h> #import <runtime/JSLock.h> @@ -46,12 +49,8 @@ #import "npruntime_impl.h" #endif -#import "objc_instance.h" -#import "runtime_root.h" -#import "runtime.h" - #if ENABLE(MAC_JAVA_BRIDGE) -#import "jni_instance.h" +#import "JavaInstanceJSC.h" #endif @interface NSObject (WebPlugin) @@ -108,7 +107,7 @@ PassScriptInstance ScriptController::createScriptInstanceForWidget(Widget* widge WebScriptObject* ScriptController::windowScriptObject() { - if (!isEnabled()) + if (!canExecuteScripts(NotAboutToExecuteScript)) return 0; if (!m_windowScriptObject) { diff --git a/src/3rdparty/webkit/WebCore/bindings/js/ScriptControllerQt.cpp b/src/3rdparty/webkit/WebCore/bindings/js/ScriptControllerQt.cpp index 6b14190..55d4ba4 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/ScriptControllerQt.cpp +++ b/src/3rdparty/webkit/WebCore/bindings/js/ScriptControllerQt.cpp @@ -36,11 +36,11 @@ #include "config.h" #include "ScriptController.h" +#include "Bridge.h" #include "DOMWindow.h" #include "PluginView.h" #include "qt_instance.h" #include "runtime_root.h" -#include "runtime.h" #include <QWidget> diff --git a/src/3rdparty/webkit/WebCore/bindings/js/ScriptControllerWin.cpp b/src/3rdparty/webkit/WebCore/bindings/js/ScriptControllerWin.cpp index 703cf7c..e0a959e 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/ScriptControllerWin.cpp +++ b/src/3rdparty/webkit/WebCore/bindings/js/ScriptControllerWin.cpp @@ -27,8 +27,8 @@ #include "config.h" #include "ScriptController.h" +#include "Bridge.h" #include "PluginView.h" -#include "runtime.h" using namespace JSC::Bindings; diff --git a/src/3rdparty/webkit/WebCore/bindings/js/ScriptControllerWx.cpp b/src/3rdparty/webkit/WebCore/bindings/js/ScriptControllerWx.cpp index 1c14928..1d7b4ca 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/ScriptControllerWx.cpp +++ b/src/3rdparty/webkit/WebCore/bindings/js/ScriptControllerWx.cpp @@ -27,9 +27,9 @@ #include "config.h" #include "ScriptController.h" +#include "Bridge.h" #include "PluginView.h" #include "runtime_root.h" -#include "runtime.h" namespace WebCore { diff --git a/src/3rdparty/webkit/WebCore/bindings/js/ScriptDebugServer.cpp b/src/3rdparty/webkit/WebCore/bindings/js/ScriptDebugServer.cpp new file mode 100644 index 0000000..5305da3 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/bindings/js/ScriptDebugServer.cpp @@ -0,0 +1,586 @@ +/* + * Copyright (C) 2008, 2009 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. + * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "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 OR ITS 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" +#include "ScriptDebugServer.h" + +#if ENABLE(JAVASCRIPT_DEBUGGER) + +#include "DOMWindow.h" +#include "EventLoop.h" +#include "Frame.h" +#include "FrameTree.h" +#include "FrameView.h" +#include "JSDOMWindowCustom.h" +#include "JavaScriptCallFrame.h" +#include "Page.h" +#include "PageGroup.h" +#include "PluginView.h" +#include "ScriptBreakpoint.h" +#include "ScriptController.h" +#include "ScriptDebugListener.h" +#include "ScrollView.h" +#include "Widget.h" +#include <debugger/DebuggerCallFrame.h> +#include <parser/SourceCode.h> +#include <runtime/JSLock.h> +#include <wtf/MainThread.h> +#include <wtf/StdLibExtras.h> +#include <wtf/UnusedParam.h> + +using namespace JSC; + +namespace WebCore { + +ScriptDebugServer& ScriptDebugServer::shared() +{ + DEFINE_STATIC_LOCAL(ScriptDebugServer, server, ()); + return server; +} + +ScriptDebugServer::ScriptDebugServer() + : m_callingListeners(false) + , m_pauseOnExceptionsState(DontPauseOnExceptions) + , m_pauseOnNextStatement(false) + , m_paused(false) + , m_doneProcessingDebuggerEvents(true) + , m_breakpointsActivated(true) + , m_pauseOnCallFrame(0) + , m_recompileTimer(this, &ScriptDebugServer::recompileAllJSFunctions) +{ +} + +ScriptDebugServer::~ScriptDebugServer() +{ + deleteAllValues(m_pageListenersMap); +} + +void ScriptDebugServer::addListener(ScriptDebugListener* listener, Page* page) +{ + ASSERT_ARG(listener, listener); + ASSERT_ARG(page, page); + + pair<PageListenersMap::iterator, bool> result = m_pageListenersMap.add(page, 0); + if (result.second) + result.first->second = new ListenerSet; + + ListenerSet* listeners = result.first->second; + listeners->add(listener); + + didAddListener(page); +} + +void ScriptDebugServer::removeListener(ScriptDebugListener* listener, Page* page) +{ + ASSERT_ARG(listener, listener); + ASSERT_ARG(page, page); + + PageListenersMap::iterator it = m_pageListenersMap.find(page); + if (it == m_pageListenersMap.end()) + return; + + ListenerSet* listeners = it->second; + listeners->remove(listener); + if (listeners->isEmpty()) { + m_pageListenersMap.remove(it); + delete listeners; + } + + didRemoveListener(page); + if (!hasListeners()) + didRemoveLastListener(); +} + +void ScriptDebugServer::pageCreated(Page* page) +{ + ASSERT_ARG(page, page); + + if (!hasListenersInterestedInPage(page)) + return; + page->setDebugger(this); +} + +bool ScriptDebugServer::hasListenersInterestedInPage(Page* page) +{ + ASSERT_ARG(page, page); + + if (hasGlobalListeners()) + return true; + + return m_pageListenersMap.contains(page); +} + +void ScriptDebugServer::setBreakpoint(const String& sourceID, unsigned lineNumber, ScriptBreakpoint breakpoint) +{ + intptr_t sourceIDValue = sourceID.toIntPtr(); + BreakpointsMap::iterator it = m_breakpoints.find(sourceIDValue); + if (it == m_breakpoints.end()) + it = m_breakpoints.set(sourceIDValue, SourceBreakpoints()).first; + it->second.set(lineNumber, breakpoint); +} + +void ScriptDebugServer::removeBreakpoint(const String& sourceID, unsigned lineNumber) +{ + intptr_t sourceIDValue = sourceID.toIntPtr(); + BreakpointsMap::iterator it = m_breakpoints.find(sourceIDValue); + if (it != m_breakpoints.end()) + it->second.remove(lineNumber); +} + +bool ScriptDebugServer::hasBreakpoint(intptr_t sourceID, unsigned lineNumber) const +{ + if (!m_breakpointsActivated) + return false; + + BreakpointsMap::const_iterator it = m_breakpoints.find(sourceID); + if (it == m_breakpoints.end()) + return false; + SourceBreakpoints::const_iterator breakIt = it->second.find(lineNumber); + if (breakIt == it->second.end() || !breakIt->second.enabled) + return false; + + // An empty condition counts as no condition which is equivalent to "true". + if (breakIt->second.condition.isEmpty()) + return true; + + JSValue exception; + JSValue result = m_currentCallFrame->evaluate(breakIt->second.condition, exception); + if (exception) { + // An erroneous condition counts as "false". + return false; + } + return result.toBoolean(m_currentCallFrame->scopeChain()->globalObject->globalExec()); +} + +void ScriptDebugServer::clearBreakpoints() +{ + m_breakpoints.clear(); +} + +void ScriptDebugServer::setBreakpointsActivated(bool activated) +{ + m_breakpointsActivated = activated; +} + +void ScriptDebugServer::setPauseOnExceptionsState(PauseOnExceptionsState pause) +{ + m_pauseOnExceptionsState = pause; +} + +void ScriptDebugServer::pauseProgram() +{ + m_pauseOnNextStatement = true; +} + +void ScriptDebugServer::continueProgram() +{ + if (!m_paused) + return; + + m_pauseOnNextStatement = false; + m_doneProcessingDebuggerEvents = true; +} + +void ScriptDebugServer::stepIntoStatement() +{ + if (!m_paused) + return; + + m_pauseOnNextStatement = true; + m_doneProcessingDebuggerEvents = true; +} + +void ScriptDebugServer::stepOverStatement() +{ + if (!m_paused) + return; + + m_pauseOnCallFrame = m_currentCallFrame.get(); + m_doneProcessingDebuggerEvents = true; +} + +void ScriptDebugServer::stepOutOfFunction() +{ + if (!m_paused) + return; + + m_pauseOnCallFrame = m_currentCallFrame ? m_currentCallFrame->caller() : 0; + m_doneProcessingDebuggerEvents = true; +} + +JavaScriptCallFrame* ScriptDebugServer::currentCallFrame() +{ + if (!m_paused) + return 0; + return m_currentCallFrame.get(); +} + +ScriptState* ScriptDebugServer::currentCallFrameState() +{ + if (!m_paused) + return 0; + return m_currentCallFrame->scopeChain()->globalObject->globalExec(); +} + +void ScriptDebugServer::dispatchDidParseSource(const ListenerSet& listeners, const JSC::SourceCode& source) +{ + String sourceID = JSC::UString(JSC::UString::from(source.provider()->asID())); + String url = source.provider()->url(); + String data = JSC::UString(source.data(), source.length()); + int firstLine = source.firstLine(); + + Vector<ScriptDebugListener*> copy; + copyToVector(listeners, copy); + for (size_t i = 0; i < copy.size(); ++i) + copy[i]->didParseSource(sourceID, url, data, firstLine); +} + +void ScriptDebugServer::dispatchFailedToParseSource(const ListenerSet& listeners, const SourceCode& source, int errorLine, const String& errorMessage) +{ + String url = source.provider()->url(); + String data = JSC::UString(source.data(), source.length()); + int firstLine = source.firstLine(); + + Vector<ScriptDebugListener*> copy; + copyToVector(listeners, copy); + for (size_t i = 0; i < copy.size(); ++i) + copy[i]->failedToParseSource(url, data, firstLine, errorLine, errorMessage); +} + +static Page* toPage(JSGlobalObject* globalObject) +{ + ASSERT_ARG(globalObject, globalObject); + + JSDOMWindow* window = asJSDOMWindow(globalObject); + Frame* frame = window->impl()->frame(); + return frame ? frame->page() : 0; +} + +void ScriptDebugServer::detach(JSGlobalObject* globalObject) +{ + // If we're detaching from the currently executing global object, manually tear down our + // stack, since we won't get further debugger callbacks to do so. Also, resume execution, + // since there's no point in staying paused once a window closes. + if (m_currentCallFrame && m_currentCallFrame->dynamicGlobalObject() == globalObject) { + m_currentCallFrame = 0; + m_pauseOnCallFrame = 0; + continueProgram(); + } + Debugger::detach(globalObject); +} + +void ScriptDebugServer::sourceParsed(ExecState* exec, const SourceCode& source, int errorLine, const UString& errorMessage) +{ + if (m_callingListeners) + return; + + Page* page = toPage(exec->dynamicGlobalObject()); + if (!page) + return; + + m_callingListeners = true; + + bool isError = errorLine != -1; + + if (hasGlobalListeners()) { + if (isError) + dispatchFailedToParseSource(m_listeners, source, errorLine, errorMessage); + else + dispatchDidParseSource(m_listeners, source); + } + + if (ListenerSet* pageListeners = m_pageListenersMap.get(page)) { + ASSERT(!pageListeners->isEmpty()); + if (isError) + dispatchFailedToParseSource(*pageListeners, source, errorLine, errorMessage); + else + dispatchDidParseSource(*pageListeners, source); + } + + m_callingListeners = false; +} + +void ScriptDebugServer::dispatchFunctionToListeners(const ListenerSet& listeners, JavaScriptExecutionCallback callback) +{ + Vector<ScriptDebugListener*> copy; + copyToVector(listeners, copy); + for (size_t i = 0; i < copy.size(); ++i) + (copy[i]->*callback)(); +} + +void ScriptDebugServer::dispatchFunctionToListeners(JavaScriptExecutionCallback callback, Page* page) +{ + if (m_callingListeners) + return; + + m_callingListeners = true; + + ASSERT(hasListeners()); + + dispatchFunctionToListeners(m_listeners, callback); + + if (ListenerSet* pageListeners = m_pageListenersMap.get(page)) { + ASSERT(!pageListeners->isEmpty()); + dispatchFunctionToListeners(*pageListeners, callback); + } + + m_callingListeners = false; +} + +void ScriptDebugServer::setJavaScriptPaused(const PageGroup& pageGroup, bool paused) +{ + setMainThreadCallbacksPaused(paused); + + const HashSet<Page*>& pages = pageGroup.pages(); + + HashSet<Page*>::const_iterator end = pages.end(); + for (HashSet<Page*>::const_iterator it = pages.begin(); it != end; ++it) + setJavaScriptPaused(*it, paused); +} + +void ScriptDebugServer::setJavaScriptPaused(Page* page, bool paused) +{ + ASSERT_ARG(page, page); + + page->setDefersLoading(paused); + + for (Frame* frame = page->mainFrame(); frame; frame = frame->tree()->traverseNext()) + setJavaScriptPaused(frame, paused); +} + +void ScriptDebugServer::setJavaScriptPaused(Frame* frame, bool paused) +{ + ASSERT_ARG(frame, frame); + + if (!frame->script()->canExecuteScripts(NotAboutToExecuteScript)) + return; + + frame->script()->setPaused(paused); + + Document* document = frame->document(); + if (paused) + document->suspendActiveDOMObjects(); + else + document->resumeActiveDOMObjects(); + + setJavaScriptPaused(frame->view(), paused); +} + +void ScriptDebugServer::setJavaScriptPaused(FrameView* view, bool paused) +{ + if (!view) + return; + + const HashSet<RefPtr<Widget> >* children = view->children(); + ASSERT(children); + + HashSet<RefPtr<Widget> >::const_iterator end = children->end(); + for (HashSet<RefPtr<Widget> >::const_iterator it = children->begin(); it != end; ++it) { + Widget* widget = (*it).get(); + if (!widget->isPluginView()) + continue; + static_cast<PluginView*>(widget)->setJavaScriptPaused(paused); + } +} + +void ScriptDebugServer::pauseIfNeeded(Page* page) +{ + if (m_paused) + return; + + if (!page || !hasListenersInterestedInPage(page)) + return; + + bool pauseNow = m_pauseOnNextStatement; + pauseNow |= (m_pauseOnCallFrame == m_currentCallFrame); + pauseNow |= (m_currentCallFrame->line() > 0 && hasBreakpoint(m_currentCallFrame->sourceID(), m_currentCallFrame->line())); + if (!pauseNow) + return; + + m_pauseOnCallFrame = 0; + m_pauseOnNextStatement = false; + m_paused = true; + + dispatchFunctionToListeners(&ScriptDebugListener::didPause, page); + + setJavaScriptPaused(page->group(), true); + + TimerBase::fireTimersInNestedEventLoop(); + + EventLoop loop; + m_doneProcessingDebuggerEvents = false; + while (!m_doneProcessingDebuggerEvents && !loop.ended()) + loop.cycle(); + + setJavaScriptPaused(page->group(), false); + + m_paused = false; + + dispatchFunctionToListeners(&ScriptDebugListener::didContinue, page); +} + +void ScriptDebugServer::callEvent(const DebuggerCallFrame& debuggerCallFrame, intptr_t sourceID, int lineNumber) +{ + if (m_paused) + return; + + m_currentCallFrame = JavaScriptCallFrame::create(debuggerCallFrame, m_currentCallFrame, sourceID, lineNumber); + pauseIfNeeded(toPage(debuggerCallFrame.dynamicGlobalObject())); +} + +void ScriptDebugServer::atStatement(const DebuggerCallFrame& debuggerCallFrame, intptr_t sourceID, int lineNumber) +{ + if (m_paused) + return; + + ASSERT(m_currentCallFrame); + if (!m_currentCallFrame) + return; + + m_currentCallFrame->update(debuggerCallFrame, sourceID, lineNumber); + pauseIfNeeded(toPage(debuggerCallFrame.dynamicGlobalObject())); +} + +void ScriptDebugServer::returnEvent(const DebuggerCallFrame& debuggerCallFrame, intptr_t sourceID, int lineNumber) +{ + if (m_paused) + return; + + ASSERT(m_currentCallFrame); + if (!m_currentCallFrame) + return; + + m_currentCallFrame->update(debuggerCallFrame, sourceID, lineNumber); + pauseIfNeeded(toPage(debuggerCallFrame.dynamicGlobalObject())); + + // Treat stepping over a return statement like stepping out. + if (m_currentCallFrame == m_pauseOnCallFrame) + m_pauseOnCallFrame = m_currentCallFrame->caller(); + m_currentCallFrame = m_currentCallFrame->caller(); +} + +void ScriptDebugServer::exception(const DebuggerCallFrame& debuggerCallFrame, intptr_t sourceID, int lineNumber, bool hasHandler) +{ + if (m_paused) + return; + + ASSERT(m_currentCallFrame); + if (!m_currentCallFrame) + return; + + if (m_pauseOnExceptionsState == PauseOnAllExceptions || (m_pauseOnExceptionsState == PauseOnUncaughtExceptions && !hasHandler)) + m_pauseOnNextStatement = true; + + m_currentCallFrame->update(debuggerCallFrame, sourceID, lineNumber); + pauseIfNeeded(toPage(debuggerCallFrame.dynamicGlobalObject())); +} + +void ScriptDebugServer::willExecuteProgram(const DebuggerCallFrame& debuggerCallFrame, intptr_t sourceID, int lineNumber) +{ + if (m_paused) + return; + + m_currentCallFrame = JavaScriptCallFrame::create(debuggerCallFrame, m_currentCallFrame, sourceID, lineNumber); + pauseIfNeeded(toPage(debuggerCallFrame.dynamicGlobalObject())); +} + +void ScriptDebugServer::didExecuteProgram(const DebuggerCallFrame& debuggerCallFrame, intptr_t sourceID, int lineNumber) +{ + if (m_paused) + return; + + ASSERT(m_currentCallFrame); + if (!m_currentCallFrame) + return; + + m_currentCallFrame->update(debuggerCallFrame, sourceID, lineNumber); + pauseIfNeeded(toPage(debuggerCallFrame.dynamicGlobalObject())); + + // Treat stepping over the end of a program like stepping out. + if (m_currentCallFrame == m_pauseOnCallFrame) + m_pauseOnCallFrame = m_currentCallFrame->caller(); + m_currentCallFrame = m_currentCallFrame->caller(); +} + +void ScriptDebugServer::didReachBreakpoint(const DebuggerCallFrame& debuggerCallFrame, intptr_t sourceID, int lineNumber) +{ + if (m_paused) + return; + + ASSERT(m_currentCallFrame); + if (!m_currentCallFrame) + return; + + m_pauseOnNextStatement = true; + m_currentCallFrame->update(debuggerCallFrame, sourceID, lineNumber); + pauseIfNeeded(toPage(debuggerCallFrame.dynamicGlobalObject())); +} + +void ScriptDebugServer::recompileAllJSFunctionsSoon() +{ + m_recompileTimer.startOneShot(0); +} + +void ScriptDebugServer::recompileAllJSFunctions(Timer<ScriptDebugServer>*) +{ + JSLock lock(SilenceAssertionsOnly); + Debugger::recompileAllJSFunctions(JSDOMWindow::commonJSGlobalData()); +} + +void ScriptDebugServer::didAddListener(Page* page) +{ + recompileAllJSFunctionsSoon(); + + if (page) + page->setDebugger(this); + else + Page::setDebuggerForAllPages(this); +} + +void ScriptDebugServer::didRemoveListener(Page* page) +{ + if (hasGlobalListeners() || (page && hasListenersInterestedInPage(page))) + return; + + recompileAllJSFunctionsSoon(); + + if (page) + page->setDebugger(0); + else + Page::setDebuggerForAllPages(0); +} + +void ScriptDebugServer::didRemoveLastListener() +{ + m_doneProcessingDebuggerEvents = true; +} + +} // namespace WebCore + +#endif // ENABLE(JAVASCRIPT_DEBUGGER) diff --git a/src/3rdparty/webkit/WebCore/bindings/js/ScriptDebugServer.h b/src/3rdparty/webkit/WebCore/bindings/js/ScriptDebugServer.h new file mode 100644 index 0000000..4740585 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/bindings/js/ScriptDebugServer.h @@ -0,0 +1,153 @@ +/* + * Copyright (C) 2008 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. + * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "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 OR ITS 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 "PlatformString.h" +#include "ScriptBreakpoint.h" +#include "ScriptState.h" +#include "Timer.h" + +#include <debugger/Debugger.h> +#include <runtime/UString.h> +#include <wtf/HashMap.h> +#include <wtf/HashSet.h> +#include <wtf/RefPtr.h> + +namespace JSC { +class DebuggerCallFrame; +class JSGlobalObject; +} +namespace WebCore { + +class Frame; +class FrameView; +class Page; +class PageGroup; +class ScriptDebugListener; +class JavaScriptCallFrame; + +class ScriptDebugServer : JSC::Debugger, public Noncopyable { +public: + static ScriptDebugServer& shared(); + + void addListener(ScriptDebugListener*, Page*); + void removeListener(ScriptDebugListener*, Page*); + + void setBreakpoint(const String& sourceID, unsigned lineNumber, ScriptBreakpoint breakpoint); + void removeBreakpoint(const String& sourceID, unsigned lineNumber); + void clearBreakpoints(); + void setBreakpointsActivated(bool activated); + + enum PauseOnExceptionsState { + DontPauseOnExceptions, + PauseOnAllExceptions, + PauseOnUncaughtExceptions + }; + PauseOnExceptionsState pauseOnExceptionsState() const { return m_pauseOnExceptionsState; } + void setPauseOnExceptionsState(PauseOnExceptionsState); + + void pauseProgram(); + void continueProgram(); + void stepIntoStatement(); + void stepOverStatement(); + void stepOutOfFunction(); + + void recompileAllJSFunctionsSoon(); + void recompileAllJSFunctions(Timer<ScriptDebugServer>* = 0); + + JavaScriptCallFrame* currentCallFrame(); + ScriptState* currentCallFrameState(); + + void pageCreated(Page*); + +private: + typedef HashSet<ScriptDebugListener*> ListenerSet; + typedef void (ScriptDebugListener::*JavaScriptExecutionCallback)(); + + ScriptDebugServer(); + ~ScriptDebugServer(); + + bool hasBreakpoint(intptr_t sourceID, unsigned lineNumber) const; + bool hasListeners() const { return !m_listeners.isEmpty() || !m_pageListenersMap.isEmpty(); } + bool hasGlobalListeners() const { return !m_listeners.isEmpty(); } + bool hasListenersInterestedInPage(Page*); + + void setJavaScriptPaused(const PageGroup&, bool paused); + void setJavaScriptPaused(Page*, bool paused); + void setJavaScriptPaused(Frame*, bool paused); + void setJavaScriptPaused(FrameView*, bool paused); + + void dispatchFunctionToListeners(JavaScriptExecutionCallback, Page*); + void dispatchFunctionToListeners(const ListenerSet& listeners, JavaScriptExecutionCallback callback); + void dispatchDidParseSource(const ListenerSet& listeners, const JSC::SourceCode& source); + void dispatchFailedToParseSource(const ListenerSet& listeners, const JSC::SourceCode& source, int errorLine, const String& errorMessage); + + void pauseIfNeeded(Page*); + + virtual void detach(JSC::JSGlobalObject*); + + virtual void sourceParsed(JSC::ExecState*, const JSC::SourceCode&, int errorLine, const JSC::UString& errorMsg); + virtual void callEvent(const JSC::DebuggerCallFrame&, intptr_t sourceID, int lineNumber); + virtual void atStatement(const JSC::DebuggerCallFrame&, intptr_t sourceID, int firstLine); + virtual void returnEvent(const JSC::DebuggerCallFrame&, intptr_t sourceID, int lineNumber); + virtual void exception(const JSC::DebuggerCallFrame&, intptr_t sourceID, int lineNumber, bool hasHandler); + virtual void willExecuteProgram(const JSC::DebuggerCallFrame&, intptr_t sourceID, int lineno); + virtual void didExecuteProgram(const JSC::DebuggerCallFrame&, intptr_t sourceID, int lineno); + virtual void didReachBreakpoint(const JSC::DebuggerCallFrame&, intptr_t sourceID, int lineno); + + void didAddListener(Page*); + void didRemoveListener(Page*); + void didRemoveLastListener(); + + typedef HashMap<Page*, ListenerSet*> PageListenersMap; + typedef HashMap<intptr_t, SourceBreakpoints> BreakpointsMap; + + PageListenersMap m_pageListenersMap; + ListenerSet m_listeners; + bool m_callingListeners; + PauseOnExceptionsState m_pauseOnExceptionsState; + bool m_pauseOnNextStatement; + bool m_paused; + bool m_doneProcessingDebuggerEvents; + bool m_breakpointsActivated; + JavaScriptCallFrame* m_pauseOnCallFrame; + RefPtr<JavaScriptCallFrame> m_currentCallFrame; + BreakpointsMap m_breakpoints; + Timer<ScriptDebugServer> m_recompileTimer; +}; + +} // namespace WebCore + +#endif // ENABLE(JAVASCRIPT_DEBUGGER) + +#endif // ScriptDebugServer_h diff --git a/src/3rdparty/webkit/WebCore/bindings/js/ScriptEventListener.cpp b/src/3rdparty/webkit/WebCore/bindings/js/ScriptEventListener.cpp index 8399c7a..afa8784 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/ScriptEventListener.cpp +++ b/src/3rdparty/webkit/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; @@ -52,14 +53,18 @@ static const String& eventParameterName(bool isSVGEvent) PassRefPtr<JSLazyEventListener> createAttributeEventListener(Node* node, Attribute* attr) { ASSERT(node); + ASSERT(attr); + if (attr->isNull()) + return 0; 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()) { ScriptController* scriptController = frame->script(); - if (!scriptController->isEnabled()) + if (!scriptController->canExecuteScripts(AboutToExecuteScript)) return 0; if (!scriptController->xssAuditor()->canCreateInlineEventListener(attr->localName().string(), attr->value())) { @@ -69,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) @@ -79,11 +88,15 @@ PassRefPtr<JSLazyEventListener> createAttributeEventListener(Frame* frame, Attri if (!frame) return 0; + ASSERT(attr); + if (attr->isNull()) + return 0; + int lineNumber = 1; String sourceURL; ScriptController* scriptController = frame->script(); - if (!scriptController->isEnabled()) + if (!scriptController->canExecuteScripts(AboutToExecuteScript)) return 0; if (!scriptController->xssAuditor()->canCreateInlineEventListener(attr->localName().string(), attr->value())) { @@ -93,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/src/3rdparty/webkit/WebCore/bindings/js/ScriptFunctionCall.cpp b/src/3rdparty/webkit/WebCore/bindings/js/ScriptFunctionCall.cpp index 91b2a57..5001d3c 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/ScriptFunctionCall.cpp +++ b/src/3rdparty/webkit/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()); } @@ -72,14 +76,27 @@ void ScriptFunctionCall::appendArgument(const String& argument) void ScriptFunctionCall::appendArgument(const JSC::UString& argument) { + JSLock lock(SilenceAssertionsOnly); m_arguments.append(jsString(m_exec, argument)); } +void ScriptFunctionCall::appendArgument(const char* argument) +{ + JSLock lock(SilenceAssertionsOnly); + m_arguments.append(jsString(m_exec, UString(argument))); +} + void ScriptFunctionCall::appendArgument(JSC::JSValue argument) { m_arguments.append(argument); } +void ScriptFunctionCall::appendArgument(long argument) +{ + JSLock lock(SilenceAssertionsOnly); + m_arguments.append(jsNumber(m_exec, argument)); +} + void ScriptFunctionCall::appendArgument(long long argument) { JSLock lock(SilenceAssertionsOnly); @@ -92,6 +109,12 @@ void ScriptFunctionCall::appendArgument(unsigned int argument) m_arguments.append(jsNumber(m_exec, argument)); } +void ScriptFunctionCall::appendArgument(unsigned long argument) +{ + JSLock lock(SilenceAssertionsOnly); + m_arguments.append(jsNumber(m_exec, argument)); +} + void ScriptFunctionCall::appendArgument(int argument) { JSLock lock(SilenceAssertionsOnly); @@ -123,8 +146,7 @@ ScriptValue ScriptFunctionCall::call(bool& hadException, bool reportExceptions) if (callType == CallTypeNone) return ScriptValue(); - // FIXME: Should this function take a worldID? - only used by inspector? - JSValue result = callInWorld(m_exec, function, callType, callData, thisObject, m_arguments, debuggerWorld()); + JSValue result = JSC::call(m_exec, function, callType, callData, thisObject, m_arguments); if (m_exec->hadException()) { if (reportExceptions) reportException(m_exec, m_exec->exception()); @@ -162,8 +184,7 @@ ScriptObject ScriptFunctionCall::construct(bool& hadException, bool reportExcept if (constructType == ConstructTypeNone) return ScriptObject(); - // FIXME: Currently this method constructs objects in debuggerWorld(). We could use the current world, or pass a worldID to this function? - JSValue result = constructInWorld(m_exec, constructor, constructType, constructData, m_arguments, debuggerWorld()); + JSValue result = JSC::construct(m_exec, constructor, constructType, constructData, m_arguments); if (m_exec->hadException()) { if (reportExceptions) reportException(m_exec, m_exec->exception()); diff --git a/src/3rdparty/webkit/WebCore/bindings/js/ScriptFunctionCall.h b/src/3rdparty/webkit/WebCore/bindings/js/ScriptFunctionCall.h index 079ac21..9742e8f 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/ScriptFunctionCall.h +++ b/src/3rdparty/webkit/WebCore/bindings/js/ScriptFunctionCall.h @@ -48,17 +48,20 @@ 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&); void appendArgument(const ScriptString&); void appendArgument(const ScriptValue&); void appendArgument(const String&); + void appendArgument(const char*); void appendArgument(const JSC::UString&); void appendArgument(JSC::JSValue); + void appendArgument(long); void appendArgument(long long); void appendArgument(unsigned int); + void appendArgument(unsigned long); void appendArgument(int); void appendArgument(bool); ScriptValue call(bool& hadException, bool reportExceptions = true); @@ -70,6 +73,12 @@ namespace WebCore { ScriptObject m_thisObject; String m_name; JSC::MarkedArgumentBuffer m_arguments; + + private: + // MarkedArgumentBuffer must be stack allocated, so prevent heap + // alloc of ScriptFunctionCall as well. + void* operator new(size_t) { ASSERT_NOT_REACHED(); return reinterpret_cast<void*>(0xbadbeef); } + void* operator new[](size_t) { ASSERT_NOT_REACHED(); return reinterpret_cast<void*>(0xbadbeef); } }; } // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/bindings/js/ScriptInstance.h b/src/3rdparty/webkit/WebCore/bindings/js/ScriptInstance.h index 3095df9..0b3b59f 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/ScriptInstance.h +++ b/src/3rdparty/webkit/WebCore/bindings/js/ScriptInstance.h @@ -31,8 +31,8 @@ #ifndef ScriptInstance_h #define ScriptInstance_h +#include "Bridge.h" #include <wtf/RefPtr.h> -#include "runtime.h" namespace WebCore { diff --git a/src/3rdparty/webkit/WebCore/bindings/js/ScriptObject.cpp b/src/3rdparty/webkit/WebCore/bindings/js/ScriptObject.cpp index 1172e8e..7948219 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/ScriptObject.cpp +++ b/src/3rdparty/webkit/WebCore/bindings/js/ScriptObject.cpp @@ -32,10 +32,15 @@ #include "ScriptObject.h" #include "JSDOMBinding.h" -#include "JSInspectorBackend.h" #include <runtime/JSLock.h> +#if ENABLE(INSPECTOR) +#include "JSInjectedScriptHost.h" +#include "JSInspectorBackend.h" +#include "JSInspectorFrontendHost.h" +#endif + using namespace JSC; namespace WebCore { @@ -65,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); @@ -87,6 +96,14 @@ bool ScriptObject::set(const char* name, double value) return handleException(m_scriptState); } +bool ScriptObject::set(const char* name, long value) +{ + JSLock lock(SilenceAssertionsOnly); + PutPropertySlot slot; + jsObject()->put(m_scriptState, Identifier(m_scriptState, name), jsNumber(m_scriptState, value), slot); + return handleException(m_scriptState); +} + bool ScriptObject::set(const char* name, long long value) { JSLock lock(SilenceAssertionsOnly); @@ -111,6 +128,14 @@ bool ScriptObject::set(const char* name, unsigned value) return handleException(m_scriptState); } +bool ScriptObject::set(const char* name, unsigned long value) +{ + JSLock lock(SilenceAssertionsOnly); + PutPropertySlot slot; + jsObject()->put(m_scriptState, Identifier(m_scriptState, name), jsNumber(m_scriptState, value), slot); + return handleException(m_scriptState); +} + bool ScriptObject::set(const char* name, bool value) { JSLock lock(SilenceAssertionsOnly); @@ -140,6 +165,22 @@ bool ScriptGlobalObject::set(ScriptState* scriptState, const char* name, Inspect globalObject->putDirect(Identifier(scriptState, name), toJS(scriptState, globalObject, value)); return handleException(scriptState); } + +bool ScriptGlobalObject::set(ScriptState* scriptState, const char* name, InspectorFrontendHost* value) +{ + JSLock lock(SilenceAssertionsOnly); + JSDOMGlobalObject* globalObject = static_cast<JSDOMGlobalObject*>(scriptState->lexicalGlobalObject()); + globalObject->putDirect(Identifier(scriptState, name), toJS(scriptState, globalObject, value)); + return handleException(scriptState); +} + +bool ScriptGlobalObject::set(ScriptState* scriptState, const char* name, InjectedScriptHost* value) +{ + JSLock lock(SilenceAssertionsOnly); + JSDOMGlobalObject* globalObject = static_cast<JSDOMGlobalObject*>(scriptState->lexicalGlobalObject()); + globalObject->putDirect(Identifier(scriptState, name), toJS(scriptState, globalObject, value)); + return handleException(scriptState); +} #endif // ENABLE(INSPECTOR) bool ScriptGlobalObject::get(ScriptState* scriptState, const char* name, ScriptObject& value) diff --git a/src/3rdparty/webkit/WebCore/bindings/js/ScriptObject.h b/src/3rdparty/webkit/WebCore/bindings/js/ScriptObject.h index 31381f3..0c993e1 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/ScriptObject.h +++ b/src/3rdparty/webkit/WebCore/bindings/js/ScriptObject.h @@ -38,21 +38,26 @@ #include <runtime/Protect.h> namespace WebCore { + class InjectedScriptHost; class InspectorBackend; + class InspectorFrontendHost; class ScriptObject : public ScriptValue { public: ScriptObject(ScriptState*, JSC::JSObject*); ScriptObject() {} JSC::JSObject* jsObject() const { return asObject(jsValue()); } + ScriptState* scriptState() const { return m_scriptState; } bool set(const String& name, const String&); bool set(const char* name, const ScriptObject&); bool set(const char* name, const String&); bool set(const char* name, double); + bool set(const char* name, long); bool set(const char* name, long long); bool set(const char* name, int); bool set(const char* name, unsigned); + bool set(const char* name, unsigned long); bool set(const char* name, bool); static ScriptObject createNew(ScriptState*); @@ -66,6 +71,8 @@ namespace WebCore { static bool set(ScriptState*, const char* name, const ScriptObject&); #if ENABLE(INSPECTOR) static bool set(ScriptState*, const char* name, InspectorBackend*); + static bool set(ScriptState*, const char* name, InspectorFrontendHost*); + static bool set(ScriptState*, const char* name, InjectedScriptHost*); #endif static bool get(ScriptState*, const char* name, ScriptObject&); static bool remove(ScriptState*, const char* name); diff --git a/src/3rdparty/webkit/WebCore/bindings/js/ScriptObjectQuarantine.cpp b/src/3rdparty/webkit/WebCore/bindings/js/ScriptObjectQuarantine.cpp deleted file mode 100644 index 313530f..0000000 --- a/src/3rdparty/webkit/WebCore/bindings/js/ScriptObjectQuarantine.cpp +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Copyright (C) 2009 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: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * 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. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "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 THE COPYRIGHT - * OWNER 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" -#include "ScriptObjectQuarantine.h" - -#if ENABLE(INSPECTOR) - -#include "Document.h" -#include "Frame.h" -#include "JSDOMBinding.h" -#include "JSInspectedObjectWrapper.h" -#include "JSNode.h" -#include "ScriptObject.h" -#include "ScriptValue.h" -#include "Storage.h" - -#include <runtime/JSLock.h> - -#if ENABLE(DATABASE) -#include "Database.h" -#include "JSDatabase.h" -#endif - -#if ENABLE(DOM_STORAGE) -#include "JSStorage.h" -#endif - -using namespace JSC; - -namespace WebCore { - -ScriptValue quarantineValue(ScriptState* scriptState, const ScriptValue& value) -{ - JSLock lock(SilenceAssertionsOnly); - return ScriptValue(JSInspectedObjectWrapper::wrap(scriptState, value.jsValue())); -} - -#if ENABLE(DATABASE) -bool getQuarantinedScriptObject(Database* database, ScriptObject& quarantinedObject) -{ - ASSERT(database); - - Frame* frame = database->document()->frame(); - if (!frame) - return false; - - JSDOMGlobalObject* globalObject = toJSDOMWindow(frame, debuggerWorld()); - ExecState* exec = globalObject->globalExec(); - - JSLock lock(SilenceAssertionsOnly); - quarantinedObject = ScriptObject(exec, asObject(JSInspectedObjectWrapper::wrap(exec, toJS(exec, globalObject, database)))); - - return true; -} -#endif - -#if ENABLE(DOM_STORAGE) -bool getQuarantinedScriptObject(Storage* storage, ScriptObject& quarantinedObject) -{ - ASSERT(storage); - Frame* frame = storage->frame(); - ASSERT(frame); - - JSDOMGlobalObject* globalObject = toJSDOMWindow(frame, debuggerWorld()); - ExecState* exec = globalObject->globalExec(); - - JSLock lock(SilenceAssertionsOnly); - quarantinedObject = ScriptObject(exec, asObject(JSInspectedObjectWrapper::wrap(exec, toJS(exec, globalObject, storage)))); - - return true; -} -#endif - -bool getQuarantinedScriptObject(Node* node, ScriptObject& quarantinedObject) -{ - ExecState* exec = scriptStateFromNode(node); - if (!exec) - return false; - - JSLock lock(SilenceAssertionsOnly); - // FIXME: Should use some sort of globalObjectFromNode() - quarantinedObject = ScriptObject(exec, asObject(JSInspectedObjectWrapper::wrap(exec, toJS(exec, deprecatedGlobalObjectForPrototype(exec), node)))); - - return true; -} - -bool getQuarantinedScriptObject(DOMWindow* domWindow, ScriptObject& quarantinedObject) -{ - ASSERT(domWindow); - - JSDOMWindow* window = toJSDOMWindow(domWindow->frame(), debuggerWorld()); - ExecState* exec = window->globalExec(); - - JSLock lock(SilenceAssertionsOnly); - quarantinedObject = ScriptObject(exec, asObject(JSInspectedObjectWrapper::wrap(exec, window))); - - return true; -} - - -} // namespace WebCore - -#endif // ENABLE(INSPECTOR) diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSCanvasShortArrayCustom.cpp b/src/3rdparty/webkit/WebCore/bindings/js/ScriptProfile.h index 21af0a6..32095e3 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSCanvasShortArrayCustom.cpp +++ b/src/3rdparty/webkit/WebCore/bindings/js/ScriptProfile.h @@ -1,5 +1,6 @@ /* - * Copyright (C) 2009 Apple Inc. All rights reserved. + * 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 @@ -20,31 +21,21 @@ * 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. + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "config.h" +#ifndef ScriptProfile_h +#define ScriptProfile_h -#if ENABLE(3D_CANVAS) - -#include "JSCanvasShortArray.h" - -#include "CanvasShortArray.h" - -using namespace JSC; +#if ENABLE(JAVASCRIPT_DEBUGGER) +#include <profiler/Profile.h> namespace WebCore { -void JSCanvasShortArray::indexSetter(JSC::ExecState* exec, unsigned index, JSC::JSValue value) -{ - impl()->set(index, static_cast<signed short>(value.toInt32(exec))); -} - -JSC::JSValue toJS(JSC::ExecState* exec, JSDOMGlobalObject* globalObject, CanvasShortArray* object) -{ - return getDOMObjectWrapper<JSCanvasShortArray>(exec, globalObject, object); -} +typedef JSC::Profile ScriptProfile; } // namespace WebCore -#endif // ENABLE(3D_CANVAS) +#endif // ENABLE(JAVASCRIPT_DEBUGGER) + +#endif // ScriptProfile_h diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSCanvasIntArrayCustom.cpp b/src/3rdparty/webkit/WebCore/bindings/js/ScriptProfiler.cpp index 8442b87..789e3d3 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSCanvasIntArrayCustom.cpp +++ b/src/3rdparty/webkit/WebCore/bindings/js/ScriptProfiler.cpp @@ -1,5 +1,6 @@ /* - * Copyright (C) 2009 Apple Inc. All rights reserved. + * 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 @@ -20,31 +21,29 @@ * 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. + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "config.h" -#if ENABLE(3D_CANVAS) +#if ENABLE(JAVASCRIPT_DEBUGGER) -#include "JSCanvasIntArray.h" +#include "ScriptProfiler.h" -#include "CanvasIntArray.h" - -using namespace JSC; +#include <profiler/Profiler.h> namespace WebCore { -void JSCanvasIntArray::indexSetter(JSC::ExecState* exec, unsigned index, JSC::JSValue value) +void ScriptProfiler::start(ScriptState* state, const String& title) { - impl()->set(index, static_cast<signed int>(value.toInt32(exec))); + JSC::Profiler::profiler()->startProfiling(state, title); } -JSC::JSValue toJS(JSC::ExecState* exec, JSDOMGlobalObject* globalObject, CanvasIntArray* object) +PassRefPtr<ScriptProfile> ScriptProfiler::stop(ScriptState* state, const String& title) { - return getDOMObjectWrapper<JSCanvasIntArray>(exec, globalObject, object); + return JSC::Profiler::profiler()->stopProfiling(state, title); } } // namespace WebCore -#endif // ENABLE(3D_CANVAS) +#endif // ENABLE(JAVASCRIPT_DEBUGGER) diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSCanvasByteArrayCustom.cpp b/src/3rdparty/webkit/WebCore/bindings/js/ScriptProfiler.h index 04697ce..a86bcfb 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSCanvasByteArrayCustom.cpp +++ b/src/3rdparty/webkit/WebCore/bindings/js/ScriptProfiler.h @@ -1,5 +1,6 @@ /* - * Copyright (C) 2009 Apple Inc. All rights reserved. + * 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 @@ -20,31 +21,28 @@ * 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. + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "config.h" +#ifndef ScriptProfiler_h +#define ScriptProfiler_h -#if ENABLE(3D_CANVAS) +#if ENABLE(JAVASCRIPT_DEBUGGER) +#include "ScriptProfile.h" +#include "ScriptState.h" -#include "JSCanvasByteArray.h" - -#include "CanvasByteArray.h" - -using namespace JSC; +#include <wtf/Noncopyable.h> namespace WebCore { -void JSCanvasByteArray::indexSetter(JSC::ExecState* exec, unsigned index, JSC::JSValue value) -{ - impl()->set(index, static_cast<signed char>(value.toInt32(exec))); -} - -JSC::JSValue toJS(JSC::ExecState* exec, JSDOMGlobalObject* globalObject, CanvasByteArray* object) -{ - return getDOMObjectWrapper<JSCanvasByteArray>(exec, globalObject, object); -} +class ScriptProfiler : public Noncopyable { +public: + static void start(ScriptState* state, const String& title); + static PassRefPtr<ScriptProfile> stop(ScriptState* state, const String& title); +}; } // namespace WebCore -#endif // ENABLE(3D_CANVAS) +#endif // ENABLE(JAVASCRIPT_DEBUGGER) + +#endif // ScriptProfiler_h diff --git a/src/3rdparty/webkit/WebCore/bindings/js/ScriptState.cpp b/src/3rdparty/webkit/WebCore/bindings/js/ScriptState.cpp index 60ba2a0..3edd1bd 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/ScriptState.cpp +++ b/src/3rdparty/webkit/WebCore/bindings/js/ScriptState.cpp @@ -38,7 +38,13 @@ namespace WebCore { -ScriptState* scriptStateFromNode(Node* node) +ScriptState* mainWorldScriptState(Frame* frame) +{ + JSDOMWindowShell* shell = frame->script()->windowShell(mainThreadNormalWorld()); + return shell->window()->globalExec(); +} + +ScriptState* scriptStateFromNode(DOMWrapperWorld* world, Node* node) { if (!node) return 0; @@ -48,14 +54,14 @@ ScriptState* scriptStateFromNode(Node* node) Frame* frame = document->frame(); if (!frame) return 0; - if (!frame->script()->isEnabled()) + if (!frame->script()->canExecuteScripts(NotAboutToExecuteScript)) return 0; - return frame->script()->globalObject(mainThreadCurrentWorld())->globalExec(); + return frame->script()->globalObject(world)->globalExec(); } -ScriptState* scriptStateFromPage(Page* page) +ScriptState* scriptStateFromPage(DOMWrapperWorld* world, Page* page) { - return page->mainFrame()->script()->globalObject(mainThreadCurrentWorld())->globalExec(); + return page->mainFrame()->script()->globalObject(world)->globalExec(); } } diff --git a/src/3rdparty/webkit/WebCore/bindings/js/ScriptState.h b/src/3rdparty/webkit/WebCore/bindings/js/ScriptState.h index 279234e..0c7c575 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/ScriptState.h +++ b/src/3rdparty/webkit/WebCore/bindings/js/ScriptState.h @@ -36,6 +36,7 @@ namespace WebCore { class DOMWrapperWorld; + class Frame; class Node; class Page; @@ -45,8 +46,10 @@ namespace WebCore { // For now, the separation is purely by convention. typedef JSC::ExecState ScriptState; - ScriptState* scriptStateFromNode(Node*); - ScriptState* scriptStateFromPage(Page*); + ScriptState* mainWorldScriptState(Frame*); + + ScriptState* scriptStateFromNode(DOMWrapperWorld*, Node*); + ScriptState* scriptStateFromPage(DOMWrapperWorld*, Page*); } // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/bindings/js/ScriptString.h b/src/3rdparty/webkit/WebCore/bindings/js/ScriptString.h index 6dab9a0..18964b8 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/ScriptString.h +++ b/src/3rdparty/webkit/WebCore/bindings/js/ScriptString.h @@ -33,6 +33,7 @@ #include "PlatformString.h" #include <runtime/UString.h> +#include <runtime/StringBuilder.h> namespace WebCore { @@ -57,7 +58,10 @@ public: ScriptString& operator+=(const String& s) { - m_str += s; + JSC::StringBuilder buffer; + buffer.append(m_str); + buffer.append(s); + m_str = buffer.build(); return *this; } diff --git a/src/3rdparty/webkit/WebCore/bindings/js/ScriptValue.cpp b/src/3rdparty/webkit/WebCore/bindings/js/ScriptValue.cpp index 6eac102..005c329 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/ScriptValue.cpp +++ b/src/3rdparty/webkit/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> @@ -40,13 +42,13 @@ using namespace JSC; namespace WebCore { -bool ScriptValue::getString(String& result) const +bool ScriptValue::getString(ScriptState* scriptState, String& result) const { if (!m_value) return false; JSLock lock(SilenceAssertionsOnly); UString ustring; - if (!m_value.get().getString(ustring)) + if (!m_value.get().getString(scriptState, ustring)) return false; result = ustring; return true; @@ -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/src/3rdparty/webkit/WebCore/bindings/js/ScriptValue.h b/src/3rdparty/webkit/WebCore/bindings/js/ScriptValue.h index 19bb693..3d0d944 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/ScriptValue.h +++ b/src/3rdparty/webkit/WebCore/bindings/js/ScriptValue.h @@ -33,11 +33,14 @@ #include "PlatformString.h" #include "ScriptState.h" +#include <runtime/JSValue.h> #include <runtime/Protect.h> +#include <wtf/PassRefPtr.h> namespace WebCore { class String; +class SerializedScriptValue; class ScriptValue { public: @@ -45,7 +48,7 @@ public: virtual ~ScriptValue() {} JSC::JSValue jsValue() const { return m_value.get(); } - bool getString(String& result) const; + bool getString(ScriptState*, String& result) const; String toString(ScriptState* scriptState) const { return m_value.get().toString(scriptState); } bool isEqual(ScriptState*, const ScriptValue&) const; bool isNull() const; @@ -53,6 +56,11 @@ public: bool isObject() const; bool hasNoValue() const { return m_value == JSC::JSValue(); } + PassRefPtr<SerializedScriptValue> serialize(ScriptState*); + static ScriptValue deserialize(ScriptState*, SerializedScriptValue*); + + static ScriptValue undefined() { return ScriptValue(JSC::jsUndefined()); } + private: JSC::ProtectedJSValue m_value; }; diff --git a/src/3rdparty/webkit/WebCore/bindings/js/ScriptWrappable.h b/src/3rdparty/webkit/WebCore/bindings/js/ScriptWrappable.h new file mode 100644 index 0000000..5e99c1c --- /dev/null +++ b/src/3rdparty/webkit/WebCore/bindings/js/ScriptWrappable.h @@ -0,0 +1,65 @@ +/* + * 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: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "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 THE COPYRIGHT + * OWNER 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 ScriptWrappable_h +#define ScriptWrappable_h + +#include "JSDOMWrapper.h" +#include <runtime/WeakGCPtr.h> + +namespace WebCore { + +class ScriptWrappable { +public: + ScriptWrappable() : m_wrapper(0) { } + + DOMObject* wrapper() const + { + return m_wrapper.get(); + } + + void setWrapper(DOMObject* wrapper) + { + ASSERT(wrapper); + m_wrapper = wrapper; + } + + void clearWrapper(DOMObject* wrapper) + { + m_wrapper.clear(wrapper); + } + +private: + JSC::WeakGCPtr<DOMObject> m_wrapper; +}; + +} // namespace WebCore + +#endif // ScriptWrappable_h diff --git a/src/3rdparty/webkit/WebCore/bindings/js/SerializedScriptValue.cpp b/src/3rdparty/webkit/WebCore/bindings/js/SerializedScriptValue.cpp index 48cd92d..fbf8899 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/SerializedScriptValue.cpp +++ b/src/3rdparty/webkit/WebCore/bindings/js/SerializedScriptValue.cpp @@ -27,9 +27,19 @@ #include "config.h" #include "SerializedScriptValue.h" +#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> @@ -136,6 +146,52 @@ private: unsigned m_length; }; +class SerializedFileList : public SharedSerializedData { +public: + static PassRefPtr<SerializedFileList> create(const FileList* list) + { + return adoptRef(new SerializedFileList(list)); + } + + unsigned length() const { return m_files.size(); } + const String& item(unsigned idx) { return m_files[idx]; } + +private: + SerializedFileList(const FileList* list) + { + unsigned length = list->length(); + m_files.reserveCapacity(length); + for (unsigned i = 0; i < length; i++) + m_files.append(list->item(i)->path().crossThreadString()); + } + + 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) @@ -148,6 +204,24 @@ SerializedScriptValueData::SerializedScriptValueData(RefPtr<SerializedArray> dat { } +SerializedScriptValueData::SerializedScriptValueData(const FileList* fileList) + : m_type(FileListType) + , m_sharedData(SerializedFileList::create(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()) +{ +} + SerializedArray* SharedSerializedData::asArray() { return static_cast<SerializedArray*>(this); @@ -158,6 +232,16 @@ SerializedObject* SharedSerializedData::asObject() return static_cast<SerializedObject*>(this); } +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 }; @@ -470,7 +554,7 @@ struct SerializingTreeWalker : public BaseWalker { return SerializedScriptValueData(value); if (value.isString()) - return SerializedScriptValueData(asString(value)->value()); + return SerializedScriptValueData(asString(value)->value(m_exec)); if (value.isNumber()) return SerializedScriptValueData(SerializedScriptValueData::NumberType, value.uncheckedGetNumber()); @@ -481,10 +565,19 @@ struct SerializingTreeWalker : public BaseWalker { if (isArray(value)) return SerializedScriptValueData(); - CallData unusedData; - if (value.isObject() && value.getCallData(unusedData) == CallTypeNone) - return SerializedScriptValueData(); - + if (value.isObject()) { + JSObject* obj = asObject(value); + if (obj->inherits(&JSFile::s_info)) + 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) + return SerializedScriptValueData(); + } // Any other types are expected to serialize as null. return SerializedScriptValueData(jsNull()); } @@ -559,8 +652,10 @@ struct DeserializingTreeWalker : public BaseWalker { typedef JSObject* OutputObject; typedef SerializedObject::PropertyNameList PropertyList; - DeserializingTreeWalker(ExecState* exec, bool mustCopy) + DeserializingTreeWalker(ExecState* exec, JSGlobalObject* globalObject, bool mustCopy) : BaseWalker(exec) + , m_globalObject(globalObject) + , m_isDOMGlobalObject(globalObject->inherits(&JSDOMGlobalObject::s_info)) , m_mustCopy(mustCopy) { } @@ -589,14 +684,14 @@ struct DeserializingTreeWalker : public BaseWalker { JSArray* createOutputArray(unsigned length) { - JSArray* array = constructEmptyArray(m_exec); + JSArray* array = constructEmptyArray(m_exec, m_globalObject); array->setLength(length); return array; } JSObject* createOutputObject() { - return constructEmptyObject(m_exec); + return constructEmptyObject(m_exec, m_globalObject); } uint32_t length(RefPtr<SerializedArray> array) @@ -639,11 +734,35 @@ struct DeserializingTreeWalker : public BaseWalker { case SerializedScriptValueData::NumberType: return jsNumber(m_exec, value.asDouble()); case SerializedScriptValueData::DateType: - return new (m_exec) DateInstance(m_exec, value.asDouble()); - default: + return new (m_exec) DateInstance(m_exec, m_globalObject->dateStructure(), value.asDouble()); + case SerializedScriptValueData::FileType: + if (!m_isDOMGlobalObject) + return jsNull(); + return toJS(m_exec, static_cast<JSDOMGlobalObject*>(m_globalObject), File::create(value.asString().crossThreadString())); + case SerializedScriptValueData::FileListType: { + if (!m_isDOMGlobalObject) + return jsNull(); + RefPtr<FileList> result = FileList::create(); + SerializedFileList* serializedFileList = value.asFileList(); + unsigned length = serializedFileList->length(); + for (unsigned i = 0; i < length; i++) + 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 JSValue(); + return jsNull(); } + ASSERT_NOT_REACHED(); + return jsNull(); } void getPropertyNames(RefPtr<SerializedObject> object, Vector<SerializedObject::PropertyNameList, 16>& properties) @@ -681,12 +800,15 @@ struct DeserializingTreeWalker : public BaseWalker { } private: + void* operator new(size_t); + JSGlobalObject* m_globalObject; + bool m_isDOMGlobalObject; bool m_mustCopy; }; -JSValue SerializedScriptValueData::deserialize(ExecState* exec, bool mustCopy) const +JSValue SerializedScriptValueData::deserialize(ExecState* exec, JSGlobalObject* global, bool mustCopy) const { - DeserializingTreeWalker context(exec, mustCopy); + DeserializingTreeWalker context(exec, global, mustCopy); return walk<DeserializingTreeWalker>(context, *this); } @@ -790,11 +912,15 @@ struct TeardownTreeWalker { case SerializedScriptValueData::StringType: case SerializedScriptValueData::ImmediateType: case SerializedScriptValueData::NumberType: + case SerializedScriptValueData::DateType: + case SerializedScriptValueData::EmptyType: + case SerializedScriptValueData::FileType: + case SerializedScriptValueData::FileListType: + case SerializedScriptValueData::ImageDataType: return true; - default: - ASSERT_NOT_REACHED(); - return JSValue(); } + ASSERT_NOT_REACHED(); + return true; } void getPropertyNames(RefPtr<SerializedObject> object, Vector<SerializedObject::PropertyNameList, 16>& properties) @@ -836,4 +962,38 @@ void SerializedScriptValueData::tearDownSerializedData() walk<TeardownTreeWalker>(context, *this); } +SerializedScriptValue::~SerializedScriptValue() +{ +} + +PassRefPtr<SerializedScriptValue> SerializedScriptValue::create(JSContextRef originContext, JSValueRef apiValue, JSValueRef* exception) +{ + JSLock lock(SilenceAssertionsOnly); + ExecState* exec = toJS(originContext); + JSValue value = toJS(exec, apiValue); + PassRefPtr<SerializedScriptValue> serializedValue = SerializedScriptValue::create(exec, value); + if (exec->hadException()) { + if (exception) + *exception = toRef(exec, exec->exception()); + exec->clearException(); + return 0; + } + + return serializedValue; +} + +JSValueRef SerializedScriptValue::deserialize(JSContextRef destinationContext, JSValueRef* exception) +{ + JSLock lock(SilenceAssertionsOnly); + ExecState* exec = toJS(destinationContext); + JSValue value = deserialize(exec, exec->lexicalGlobalObject()); + if (exec->hadException()) { + if (exception) + *exception = toRef(exec, exec->exception()); + exec->clearException(); + return 0; + } + return toRef(exec, value); +} + } diff --git a/src/3rdparty/webkit/WebCore/bindings/js/SerializedScriptValue.h b/src/3rdparty/webkit/WebCore/bindings/js/SerializedScriptValue.h index f8a126f..93bd0de 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/SerializedScriptValue.h +++ b/src/3rdparty/webkit/WebCore/bindings/js/SerializedScriptValue.h @@ -29,15 +29,25 @@ #include "ScriptValue.h" +typedef const struct OpaqueJSContext* JSContextRef; +typedef const struct OpaqueJSValue* JSValueRef; + namespace WebCore { - class SerializedObject; + class File; + class FileList; + class ImageData; class SerializedArray; + class SerializedFileList; + class SerializedImageData; + class SerializedObject; class SharedSerializedData : public RefCounted<SharedSerializedData> { public: virtual ~SharedSerializedData() { } SerializedArray* asArray(); SerializedObject* asObject(); + SerializedFileList* asFileList(); + SerializedImageData* asImageData(); }; class SerializedScriptValue; @@ -51,12 +61,15 @@ namespace WebCore { ImmediateType, ObjectType, ArrayType, - StringType + StringType, + FileType, + FileListType, + ImageDataType }; SerializedType type() const { return m_type; } static SerializedScriptValueData serialize(JSC::ExecState*, JSC::JSValue); - JSC::JSValue deserialize(JSC::ExecState*, bool mustCopy) const; + JSC::JSValue deserialize(JSC::ExecState*, JSC::JSGlobalObject*, bool mustCopy) const; ~SerializedScriptValueData() { @@ -74,6 +87,10 @@ namespace WebCore { , m_string(string.crossThreadString()) // FIXME: Should be able to just share the Rep { } + + explicit SerializedScriptValueData(const File*); + explicit SerializedScriptValueData(const FileList*); + explicit SerializedScriptValueData(const ImageData*); explicit SerializedScriptValueData(JSC::JSValue value) : m_type(ImmediateType) @@ -105,7 +122,7 @@ namespace WebCore { String asString() const { - ASSERT(m_type == StringType); + ASSERT(m_type == StringType || m_type == FileType); return m_string; } @@ -123,6 +140,20 @@ namespace WebCore { return m_sharedData->asArray(); } + SerializedFileList* asFileList() const + { + ASSERT(m_type == FileListType); + 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; } SerializedScriptValueData release() @@ -150,6 +181,8 @@ namespace WebCore { return adoptRef(new SerializedScriptValue(SerializedScriptValueData::serialize(exec, value))); } + static PassRefPtr<SerializedScriptValue> create(JSContextRef, JSValueRef value, JSValueRef* exception); + static PassRefPtr<SerializedScriptValue> create(String string) { return adoptRef(new SerializedScriptValue(SerializedScriptValueData(string))); @@ -175,14 +208,15 @@ namespace WebCore { return m_value.asString(); } - JSC::JSValue deserialize(JSC::ExecState* exec) + JSC::JSValue deserialize(JSC::ExecState* exec, JSC::JSGlobalObject* globalObject) { if (!m_value) return JSC::jsNull(); - return m_value.deserialize(exec, m_mustCopy); + return m_value.deserialize(exec, globalObject, m_mustCopy); } - ~SerializedScriptValue() {} + JSValueRef deserialize(JSContextRef, JSValueRef* exception); + ~SerializedScriptValue(); private: SerializedScriptValue(SerializedScriptValueData value) diff --git a/src/3rdparty/webkit/WebCore/bindings/js/WebCoreJSClientData.h b/src/3rdparty/webkit/WebCore/bindings/js/WebCoreJSClientData.h new file mode 100644 index 0000000..e0d2e4e --- /dev/null +++ b/src/3rdparty/webkit/WebCore/bindings/js/WebCoreJSClientData.h @@ -0,0 +1,78 @@ +/* + * Copyright (C) 1999-2001 Harri Porten (porten@kde.org) + * Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Apple Inc. All rights reserved. + * Copyright (C) 2007 Samuel Weinig <sam@webkit.org> + * Copyright (C) 2009 Google, Inc. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef WebCoreJSClientData_h +#define WebCoreJSClientData_h + +#include "DOMWrapperWorld.h" +#include "DOMObjectHashTableMap.h" +#include <wtf/Noncopyable.h> +#include <wtf/HashSet.h> +#include <wtf/RefPtr.h> + +namespace WebCore { + +class WebCoreJSClientData : public JSC::JSGlobalData::ClientData, public Noncopyable { + friend class JSGlobalDataWorldIterator; +public: + WebCoreJSClientData(JSC::JSGlobalData* globalData) + : m_normalWorld(DOMWrapperWorld::create(globalData, true)) + { + m_worldSet.add(m_normalWorld.get()); + } + + virtual ~WebCoreJSClientData() + { + ASSERT(m_worldSet.contains(m_normalWorld.get())); + ASSERT(m_worldSet.size() == 1); + ASSERT(m_normalWorld->hasOneRef()); + m_normalWorld.clear(); + ASSERT(m_worldSet.isEmpty()); + } + + DOMWrapperWorld* normalWorld() { return m_normalWorld.get(); } + + void getAllWorlds(Vector<DOMWrapperWorld*>& worlds) + { + copyToVector(m_worldSet, worlds); + } + + void rememberWorld(DOMWrapperWorld* world) + { + ASSERT(!m_worldSet.contains(world)); + m_worldSet.add(world); + } + void forgetWorld(DOMWrapperWorld* world) + { + ASSERT(m_worldSet.contains(world)); + m_worldSet.remove(world); + } + + DOMObjectHashTableMap hashTableMap; + +private: + HashSet<DOMWrapperWorld*> m_worldSet; + RefPtr<DOMWrapperWorld> m_normalWorld; +}; + +} // namespace WebCore + +#endif // WebCoreJSClientData_h diff --git a/src/3rdparty/webkit/WebCore/bindings/js/WorkerScriptController.cpp b/src/3rdparty/webkit/WebCore/bindings/js/WorkerScriptController.cpp index b66b0e8..e371423 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/WorkerScriptController.cpp +++ b/src/3rdparty/webkit/WebCore/bindings/js/WorkerScriptController.cpp @@ -30,11 +30,11 @@ #include "WorkerScriptController.h" -#include "JSDOMBinding.h" #include "JSDedicatedWorkerContext.h" #include "JSSharedWorkerContext.h" #include "ScriptSourceCode.h" #include "ScriptValue.h" +#include "WebCoreJSClientData.h" #include "WorkerContext.h" #include "WorkerObjectProxy.h" #include "WorkerThread.h" @@ -58,9 +58,6 @@ WorkerScriptController::WorkerScriptController(WorkerContext* workerContext) WorkerScriptController::~WorkerScriptController() { m_workerContextWrapper = 0; // Unprotect the global object. - - ASSERT(!m_globalData->heap.protectedObjectCount()); - ASSERT(!m_globalData->heap.isBusy()); m_globalData->heap.destroy(); } @@ -123,7 +120,7 @@ ScriptValue WorkerScriptController::evaluate(const ScriptSourceCode& sourceCode, ExecState* exec = m_workerContextWrapper->globalExec(); m_workerContextWrapper->globalData()->timeoutChecker.start(); - Completion comp = evaluateInWorld(exec, exec->dynamicGlobalObject()->globalScopeChain(), sourceCode.jsSourceCode(), m_workerContextWrapper, currentWorld(exec)); + Completion comp = JSC::evaluate(exec, exec->dynamicGlobalObject()->globalScopeChain(), sourceCode.jsSourceCode(), m_workerContextWrapper); m_workerContextWrapper->globalData()->timeoutChecker.stop(); if (comp.complType() == Normal || comp.complType() == ReturnValue) diff --git a/src/3rdparty/webkit/WebCore/bindings/scripts/CodeGenerator.pm b/src/3rdparty/webkit/WebCore/bindings/scripts/CodeGenerator.pm index c1cb0a0..487a4b3 100644 --- a/src/3rdparty/webkit/WebCore/bindings/scripts/CodeGenerator.pm +++ b/src/3rdparty/webkit/WebCore/bindings/scripts/CodeGenerator.pm @@ -1,26 +1,26 @@ # # WebKit IDL parser -# +# # Copyright (C) 2005 Nikolas Zimmermann <wildfox@kde.org> # Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com> # Copyright (C) 2007 Apple Inc. All rights reserved. # Copyright (C) 2009 Cameron McCormack <cam@mcc.id.au> -# +# # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Library General Public # License as published by the Free Software Foundation; either # version 2 of the License, or (at your option) any later version. -# +# # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Library General Public License for more details. -# +# # You should have received a copy of the GNU Library General Public License -# aint with this library; see the file COPYING.LIB. If not, write to +# along with this library; see the file COPYING.LIB. If not, write to # the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, # Boston, MA 02110-1301, USA. -# +# package CodeGenerator; @@ -39,14 +39,15 @@ my $codeGenerator = 0; my $verbose = 0; -my %primitiveTypeHash = ("int" => 1, "short" => 1, "long" => 1, "long long" => 1, +my %primitiveTypeHash = ("int" => 1, "short" => 1, "long" => 1, "long long" => 1, "unsigned int" => 1, "unsigned short" => 1, - "unsigned long" => 1, "unsigned long long" => 1, - "float" => 1, "double" => 1, - "boolean" => 1, "void" => 1); + "unsigned long" => 1, "unsigned long long" => 1, + "float" => 1, "double" => 1, + "boolean" => 1, "void" => 1, + "Date" => 1); my %podTypeHash = ("SVGNumber" => 1, "SVGTransform" => 1); -my %podTypesWithWritablePropertiesHash = ("SVGLength" => 1, "SVGMatrix" => 1, "SVGPoint" => 1, "SVGRect" => 1); +my %podTypesWithWritablePropertiesHash = ("SVGAngle" => 1, "SVGLength" => 1, "SVGMatrix" => 1, "SVGPoint" => 1, "SVGPreserveAspectRatio" => 1, "SVGRect" => 1); my %stringTypeHash = ("DOMString" => 1, "AtomicString" => 1); my %nonPointerTypeHash = ("DOMTimeStamp" => 1, "CompareHow" => 1, "SVGPaintType" => 1); @@ -327,10 +328,10 @@ sub IsSVGAnimatedType my $type = shift; return 1 if $svgAnimatedTypeHash{$type}; - return 0; + return 0; } -# Uppercase the first letter while respecting WebKit style guidelines. +# Uppercase the first letter while respecting WebKit style guidelines. # E.g., xmlEncoding becomes XMLEncoding, but xmlllang becomes Xmllang. sub WK_ucfirst { @@ -340,12 +341,13 @@ sub WK_ucfirst return $ret; } -# Lowercase the first letter while respecting WebKit style guidelines. +# Lowercase the first letter while respecting WebKit style guidelines. # URL becomes url, but SetURL becomes setURL. sub WK_lcfirst { my ($object, $param) = @_; my $ret = lcfirst($param); + $ret =~ s/hTML/html/ if $ret =~ /^hTML/; $ret =~ s/uRL/url/ if $ret =~ /^uRL/; $ret =~ s/jS/js/ if $ret =~ /^jS/; $ret =~ s/xML/xml/ if $ret =~ /^xML/; diff --git a/src/3rdparty/webkit/WebCore/bindings/scripts/CodeGeneratorCOM.pm b/src/3rdparty/webkit/WebCore/bindings/scripts/CodeGeneratorCOM.pm deleted file mode 100644 index 4ca441b..0000000 --- a/src/3rdparty/webkit/WebCore/bindings/scripts/CodeGeneratorCOM.pm +++ /dev/null @@ -1,1319 +0,0 @@ -# -# Copyright (C) 2005, 2006 Nikolas Zimmermann <zimmermann@kde.org> -# Copyright (C) 2006 Anders Carlsson <andersca@mac.com> -# Copyright (C) 2006, 2007 Samuel Weinig <sam@webkit.org> -# Copyright (C) 2006 Alexey Proskuryakov <ap@webkit.org> -# Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Library General Public -# License as published by the Free Software Foundation; either -# version 2 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Library General Public License for more details. -# -# You should have received a copy of the GNU Library General Public License -# aint with this library; see the file COPYING.LIB. If not, write to -# the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -# Boston, MA 02111-1307, USA. - -package CodeGeneratorCOM; - -use File::stat; - -# Global Variables -my $module = ""; -my $outputDir = ""; - -my @IDLHeader = (); -my @IDLContent = (); -my %IDLIncludes = (); -my %IDLForwardDeclarations = (); -my %IDLDontForwardDeclare = (); -my %IDLImports = (); -my %IDLDontImport = (); - -my @CPPInterfaceHeader = (); - -my @CPPHeaderHeader = (); -my @CPPHeaderContent = (); -my %CPPHeaderIncludes = (); -my %CPPHeaderIncludesAngle = (); -my %CPPHeaderForwardDeclarations = (); -my %CPPHeaderDontForwardDeclarations = (); - -my @CPPImplementationHeader = (); -my @CPPImplementationContent = (); -my %CPPImplementationIncludes = (); -my %CPPImplementationWebCoreIncludes = (); -my %CPPImplementationIncludesAngle = (); -my %CPPImplementationDontIncludes = (); - -my @additionalInterfaceDefinitions = (); - -my $DASHES = "----------------------------------------"; -my $TEMP_PREFIX = "GEN_"; - -# Hashes - -my %includeCorrector = map {($_, 1)} qw{UIEvent KeyboardEvent MouseEvent - MutationEvent OverflowEvent WheelEvent}; - -my %conflictMethod = ( - # FIXME: Add C language keywords? -); - -# Default License Templates -my @licenseTemplate = split(/\r/, << "EOF"); -/* - * Copyright (C) 2007 Apple 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. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "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 OR ITS 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. - */ -EOF - -# Default constructor -sub new -{ - my $object = shift; - my $reference = { }; - - $codeGenerator = shift; - $outputDir = shift; - - bless($reference, $object); - return $reference; -} - -sub finish -{ - my $object = shift; -} - -# Params: 'domClass' struct -sub GenerateInterface -{ - my $object = shift; - my $dataNode = shift; - my $defines = shift; - - my $name = $dataNode->name; - - my $pureInterface = $dataNode->extendedAttributes->{"PureInterface"}; - - # Start actual generation.. - $object->GenerateIDL($dataNode, $pureInterface); - if ($pureInterface) { - $object->GenerateInterfaceHeader($dataNode); - } else { - $object->GenerateCPPHeader($dataNode); - $object->GenerateCPPImplementation($dataNode); - } - - # Write changes. - $object->WriteData($name, $pureInterface); -} - -# Params: 'idlDocument' struct -sub GenerateModule -{ - my $object = shift; - my $dataNode = shift; - - $module = $dataNode->module; -} - -sub GetInterfaceName -{ - my $name = $codeGenerator->StripModule(shift); - - die "GetInterfaceName should only be used on interfaces." if ($codeGenerator->IsStringType($name) or $codeGenerator->IsPrimitiveType($name)); - - # special cases - return "I" . $TEMP_PREFIX . "DOMAbstractView" if $name eq "DOMWindow"; - return "I" . $TEMP_PREFIX . $name if $name eq "DOMImplementation" or $name eq "DOMTimeStamp"; - - # Default, assume COM type has the same type name as - # idl type prefixed with "IDOM". - return "I" . $TEMP_PREFIX . "DOM" . $name; -} - -sub GetClassName -{ - my $name = $codeGenerator->StripModule(shift); - - # special cases - return "BSTR" if $codeGenerator->IsStringType($name); - return "BOOL" if $name eq "boolean"; - return "unsigned" if $name eq "unsigned long"; - return "int" if $name eq "long"; - return $name if $codeGenerator->IsPrimitiveType($name); - return $TEMP_PREFIX . "DOMAbstractView" if $name eq "DOMWindow"; - return $TEMP_PREFIX . $name if $name eq "DOMImplementation" or $name eq "DOMTimeStamp"; - - # Default, assume COM type has the same type name as - # idl type prefixed with "DOM". - return $TEMP_PREFIX . "DOM" . $name; -} - -sub GetCOMType -{ - my ($type) = @_; - - die "Don't use GetCOMType for string types, use one of In/Out variants instead." if $codeGenerator->IsStringType($type); - - return "BOOL" if $type eq "boolean"; - return "UINT" if $type eq "unsigned long"; - return "INT" if $type eq "long"; - return $type if $codeGenerator->IsPrimitiveType($type) or $type eq "DOMTimeStamp"; - # return "unsigned short" if $type eq "CompareHow" or $type eq "SVGPaintType"; - - return GetInterfaceName($type) . "*"; -} - -sub GetCOMTypeIn -{ - my ($type) = @_; - return "LPCTSTR" if $codeGenerator->IsStringType($type); - return GetCOMType($type); -} - -sub GetCOMTypeOut -{ - my ($type) = @_; - return "BSTR" if $codeGenerator->IsStringType($type); - return GetCOMType($type); -} - -sub IDLTypeToImplementationType -{ - my $type = $codeGenerator->StripModule(shift); - - return "bool" if $type eq "boolean"; - return "unsigned" if $type eq "unsigned long"; - return "int" if $type eq "long"; - return $type if $codeGenerator->IsPrimitiveType($type); - - return "WebCore::String" if $codeGenerator->IsStringType($type); - return "WebCore::${type}"; -} - -sub StripNamespace -{ - my ($type) = @_; - - $type =~ s/^WebCore:://; - - return $type; -} - -sub GetParentInterface -{ - my ($dataNode) = @_; - return "I" . $TEMP_PREFIX . "DOMObject" if (@{$dataNode->parents} == 0); - return GetInterfaceName($codeGenerator->StripModule($dataNode->parents(0))); -} - -sub GetParentClass -{ - my ($dataNode) = @_; - return $TEMP_PREFIX . "DOMObject" if (@{$dataNode->parents} == 0); - return GetClassName($codeGenerator->StripModule($dataNode->parents(0))); -} - -sub AddForwardDeclarationsForTypeInIDL -{ - my $type = $codeGenerator->StripModule(shift); - - return if $codeGenerator->IsNonPointerType($type) or $codeGenerator->IsStringType($type); - - my $interface = GetInterfaceName($type); - $IDLForwardDeclarations{$interface} = 1; - $IDLImports{$interface} = 1; -} - -sub AddIncludesForTypeInCPPHeader -{ - my $type = $codeGenerator->StripModule(shift); - my $useAngleBrackets = shift; - - return if $codeGenerator->IsNonPointerType($type); - - # Add special Cases HERE - - if ($type =~ m/^I/) { - $type = "WebKit"; - } - - if ($useAngleBrackets) { - $CPPHeaderIncludesAngle{"$type.h"} = 1; - return; - } - - if ($type eq "GEN_DOMImplementation") { - $CPPHeaderIncludes{"GEN_DOMDOMImplementation.h"} = 1; - return; - } - - if ($type eq "IGEN_DOMImplementation") { - $CPPHeaderIncludes{"IGEN_DOMDOMImplementation.h"} = 1; - return; - } - - $CPPHeaderIncludes{"$type.h"} = 1; -} - -sub AddForwardDeclarationsForTypeInCPPHeader -{ - my $type = $codeGenerator->StripModule(shift); - - return if $codeGenerator->IsNonPointerType($type) or $codeGenerator->IsStringType($type); - - my $interface = GetInterfaceName($type); - $CPPHeaderForwardDeclarations{$interface} = 1; -} - -sub AddIncludesForTypeInCPPImplementation -{ - my $type = $codeGenerator->StripModule(shift); - - die "Include type not supported!" if $includeCorrector{$type}; - - return if $codeGenerator->IsNonPointerType($type); - - if ($codeGenerator->IsStringType($type)) { - $CPPImplementationWebCoreIncludes{"AtomicString.h"} = 1; - $CPPImplementationWebCoreIncludes{"BString.h"} = 1; - $CPPImplementationWebCoreIncludes{"KURL.h"} = 1; - return; - } - - # Special casing - $CPPImplementationWebCoreIncludes{"NameNodeList.h"} = 1 if $type eq "NodeList"; - $CPPImplementationWebCoreIncludes{"CSSMutableStyleDeclaration.h"} = 1 if $type eq "CSSStyleDeclaration"; - - # Add implementation type - $CPPImplementationWebCoreIncludes{StripNamespace(IDLTypeToImplementationType($type)) . ".h"} = 1; - - my $COMClassName = GetClassName($type); - $CPPImplementationIncludes{"${COMClassName}.h"} = 1; -} - -sub GetAdditionalInterfaces -{ - # This function does nothing, but it stays here for future multiple inheritance support. - my $type = $codeGenerator->StripModule(shift); - return (); -} - -sub GenerateIDL -{ - my ($object, $dataNode, $pureInterface) = @_; - - my $inInterfaceName = $dataNode->name; - my $outInterfaceName = GetInterfaceName($inInterfaceName); - my $uuid = $dataNode->extendedAttributes->{"InterfaceUUID"} || die "All classes require an InterfaceUUID extended attribute."; - - my $parentInterfaceName = ($pureInterface) ? "IUnknown" : GetParentInterface($dataNode); - - my $numConstants = @{$dataNode->constants}; - my $numAttributes = @{$dataNode->attributes}; - my $numFunctions = @{$dataNode->functions}; - - # - Add default header template - @IDLHeader = @licenseTemplate; - push(@IDLHeader, "\n"); - - # - INCLUDES - - push(@IDLHeader, "#ifndef DO_NO_IMPORTS\n"); - push(@IDLHeader, "import \"oaidl.idl\";\n"); - push(@IDLHeader, "import \"ocidl.idl\";\n"); - push(@IDLHeader, "#endif\n\n"); - - unless ($pureInterface) { - push(@IDLHeader, "#ifndef DO_NO_IMPORTS\n"); - push(@IDLHeader, "import \"${parentInterfaceName}.idl\";\n"); - push(@IDLHeader, "#endif\n\n"); - - $IDLDontForwardDeclare{$outInterfaceName} = 1; - $IDLDontImport{$outInterfaceName} = 1; - $IDLDontForwardDeclare{$parentInterfaceName} = 1; - $IDLDontImport{$parentInterfaceName} = 1; - } - - # - Begin - # -- Attributes - push(@IDLContent, "[\n"); - push(@IDLContent, " object,\n"); - push(@IDLContent, " oleautomation,\n"); - push(@IDLContent, " uuid(" . $uuid . "),\n"); - push(@IDLContent, " pointer_default(unique)\n"); - push(@IDLContent, "]\n"); - - # -- Interface - push(@IDLContent, "interface " . $outInterfaceName . " : " . $parentInterfaceName . "\n"); - push(@IDLContent, "{\n"); - - - # - FIXME: Add constants. - - - # - Add attribute getters/setters. - if ($numAttributes > 0) { - foreach my $attribute (@{$dataNode->attributes}) { - my $attributeName = $attribute->signature->name; - my $attributeIDLType = $attribute->signature->type; - my $attributeTypeIn = GetCOMTypeIn($attributeIDLType); - my $attributeTypeOut = GetCOMTypeOut($attributeIDLType); - my $attributeIsReadonly = ($attribute->type =~ /^readonly/); - - AddForwardDeclarationsForTypeInIDL($attributeIDLType); - - unless ($attributeIsReadonly) { - # Setter - my $setterName = "set" . $codeGenerator->WK_ucfirst($attributeName); - my $setter = " HRESULT " . $setterName . "([in] " . $attributeTypeIn . ");\n"; - push(@IDLContent, $setter); - } - - # Getter - my $getter = " HRESULT " . $attributeName . "([out, retval] " . $attributeTypeOut . "*);\n\n"; - push(@IDLContent, $getter); - } - } - - # - Add functions. - if ($numFunctions > 0) { - foreach my $function (@{$dataNode->functions}) { - my $functionName = $function->signature->name; - my $returnIDLType = $function->signature->type; - my $returnType = GetCOMTypeOut($returnIDLType); - my $noReturn = ($returnType eq "void"); - - AddForwardDeclarationsForTypeInIDL($returnIDLType); - - my @paramArgList = (); - foreach my $param (@{$function->parameters}) { - my $paramName = $param->name; - my $paramIDLType = $param->type; - my $paramType = GetCOMTypeIn($param->type); - - AddForwardDeclarationsForTypeInIDL($paramIDLType); - - # Form parameter - my $parameter = "[in] ${paramType} ${paramName}"; - - # Add parameter to function signature - push(@paramArgList, $parameter); - } - - unless ($noReturn) { - my $resultParameter = "[out, retval] " . $returnType . "* result"; - push(@paramArgList, $resultParameter); - } - - my $functionSig = " HRESULT " . $functionName . "("; - $functionSig .= join(", ", @paramArgList); - $functionSig .= ");\n\n"; - push(@IDLContent, $functionSig); - } - } - - # - End - push(@IDLContent, "}\n\n"); -} - -sub GenerateInterfaceHeader -{ - my ($object, $dataNode) = @_; - - my $IDLType = $dataNode->name; - my $implementationClass = IDLTypeToImplementationType($IDLType); - my $implementationClassWithoutNamespace = StripNamespace($implementationClass); - my $className = GetClassName($IDLType); - my $interfaceName = GetInterfaceName($IDLType); - - # - Add default header template - @CPPInterfaceHeader = @licenseTemplate; - push(@CPPInterfaceHeader, "\n"); - - # - Header guards - - push(@CPPInterfaceHeader, "#ifndef " . $className . "_h\n"); - push(@CPPInterfaceHeader, "#define " . $className . "_h\n\n"); - - # - Forward Declarations - - push(@CPPInterfaceHeader, "interface ${interfaceName};\n\n"); - push(@CPPInterfaceHeader, "namespace WebCore {\n"); - push(@CPPInterfaceHeader, " class ${implementationClassWithoutNamespace};\n"); - push(@CPPInterfaceHeader, "}\n\n"); - - # - Default Interface Creator - - push(@CPPInterfaceHeader, "${interfaceName}* to${interfaceName}(${implementationClass}*) { return 0; }\n\n"); - - push(@CPPInterfaceHeader, "#endif // " . $className . "_h\n"); -} - -# ----------------------------------------------------------------------------- -# CPP Helper Functions -# ----------------------------------------------------------------------------- - -sub GenerateCPPAttributeSignature -{ - my ($attribute, $className, $options) = @_; - - my $attributeName = $attribute->signature->name; - my $isReadonly = ($attribute->type =~ /^readonly/); - - my $newline = $$options{"NewLines"} ? "\n" : ""; - my $indent = $$options{"Indent"} ? " " x $$options{"Indent"} : ""; - my $semicolon = $$options{"IncludeSemiColon"} ? ";" : ""; - my $virtual = $$options{"AddVirtualKeyword"} ? "virtual " : ""; - my $class = $$options{"UseClassName"} ? "${className}::" : ""; - my $forwarder = $$options{"Forwarder"} ? 1 : 0; - my $joiner = ($$options{"NewLines"} ? "\n" . $indent . " " : ""); - - my %attributeSignatures = (); - - unless ($isReadonly) { - my $attributeTypeIn = GetCOMTypeIn($attribute->signature->type); - my $setterName = "set" . $codeGenerator->WK_ucfirst($attributeName); - my $setter = $indent . $virtual . "HRESULT STDMETHODCALLTYPE ". $class . $setterName . "("; - $setter .= $joiner . "/* [in] */ ${attributeTypeIn} ${attributeName})" . $semicolon . $newline; - if ($forwarder) { - $setter .= " { return " . $$options{"Forwarder"} . "::" . $setterName . "(${attributeName}); }\n"; - } - $attributeSignatures{"Setter"} = $setter; - } - - my $attributeTypeOut = GetCOMTypeOut($attribute->signature->type); - my $getter = $indent . $virtual . "HRESULT STDMETHODCALLTYPE " . $class . $attributeName . "("; - $getter .= $joiner . "/* [retval][out] */ ${attributeTypeOut}* result)" . $semicolon . $newline; - if ($forwarder) { - $getter .= " { return " . $$options{"Forwarder"} . "::" . $attributeName . "(result); }\n"; - } - $attributeSignatures{"Getter"} = $getter; - - return %attributeSignatures; -} - - -sub GenerateCPPAttribute -{ - my ($attribute, $className, $implementationClass, $IDLType) = @_; - - my $implementationClassWithoutNamespace = StripNamespace($implementationClass); - - my $attributeName = $attribute->signature->name; - my $attributeIDLType = $attribute->signature->type; - my $hasSetterException = @{$attribute->setterExceptions}; - my $hasGetterException = @{$attribute->getterExceptions}; - my $isReadonly = ($attribute->type =~ /^readonly/); - my $attributeTypeIsPrimitive = $codeGenerator->IsPrimitiveType($attributeIDLType); - my $attributeTypeIsString = $codeGenerator->IsStringType($attributeIDLType); - my $attributeImplementationType = IDLTypeToImplementationType($attributeIDLType); - my $attributeImplementationTypeWithoutNamespace = StripNamespace($attributeImplementationType); - my $attributeTypeCOMClassName = GetClassName($attributeIDLType); - - $CPPImplementationWebCoreIncludes{"ExceptionCode.h"} = 1 if $hasSetterException or $hasGetterException; - - my %signatures = GenerateCPPAttributeSignature($attribute, $className, { "NewLines" => 1, - "Indent" => 0, - "IncludeSemiColon" => 0, - "UseClassName" => 1, - "AddVirtualKeyword" => 0 }); - - my %attrbutesToReturn = (); - - unless ($isReadonly) { - my @setterImplementation = (); - push(@setterImplementation, $signatures{"Setter"}); - push(@setterImplementation, "{\n"); - - my $setterName = "set" . $codeGenerator->WK_ucfirst($attributeName); - - my @setterParams = (); - if ($attributeTypeIsString) { - push(@setterParams, $attributeName); - if ($hasSetterException) { - push(@setterImplementation, " WebCore::ExceptionCode ec = 0;\n"); - push(@setterParams, "ec"); - } - } elsif ($attributeTypeIsPrimitive) { - if ($attribute->signature->extendedAttributes->{"ConvertFromString"}) { - push(@setterParams, "WebCore::String::number(${attributeName})"); - } elsif ($attributeIDLType eq "boolean") { - push(@setterParams, "!!${attributeName}"); - } else { - my $primitiveImplementationType = IDLTypeToImplementationType($attributeIDLType); - push(@setterParams, "static_cast<${primitiveImplementationType}>(${attributeName})"); - } - - if ($hasSetterException) { - push(@setterImplementation, " WebCore::ExceptionCode ec = 0;\n"); - push(@setterParams, "ec"); - } - } else { - $CPPImplementationWebCoreIncludes{"COMPtr.h"} = 1; - - push(@setterImplementation, " if (!${attributeName})\n"); - push(@setterImplementation, " return E_POINTER;\n\n"); - push(@setterImplementation, " COMPtr<${attributeTypeCOMClassName}> ptr(Query, ${attributeName});\n"); - push(@setterImplementation, " if (!ptr)\n"); - push(@setterImplementation, " return E_NOINTERFACE;\n"); - - push(@setterParams, "ptr->impl${attributeImplementationTypeWithoutNamespace}()"); - if ($hasSetterException) { - push(@setterImplementation, " WebCore::ExceptionCode ec = 0;\n"); - push(@setterParams, "ec"); - } - } - - # FIXME: CHECK EXCEPTION AND DO SOMETHING WITH IT - - my $reflect = $attribute->signature->extendedAttributes->{"Reflect"}; - my $reflectURL = $attribute->signature->extendedAttributes->{"ReflectURL"}; - if ($reflect || $reflectURL) { - my $contentAttributeName = (($reflect || $reflectURL) eq "1") ? $attributeName : ($reflect || $reflectURL); - my $namespace = $codeGenerator->NamespaceForAttributeName($IDLType, $contentAttributeName); - $CPPImplementationWebCoreIncludes{"${namespace}.h"} = 1; - push(@setterImplementation, " impl${implementationClassWithoutNamespace}()->setAttribute(WebCore::${namespace}::${contentAttributeName}Attr, " . join(", ", @setterParams) . ");\n"); - } else { - push(@setterImplementation, " impl${implementationClassWithoutNamespace}()->${setterName}(" . join(", ", @setterParams) . ");\n"); - } - push(@setterImplementation, " return S_OK;\n"); - push(@setterImplementation, "}\n\n"); - - $attrbutesToReturn{"Setter"} = join("", @setterImplementation); - } - - my @getterImplementation = (); - push(@getterImplementation, $signatures{"Getter"}); - push(@getterImplementation, "{\n"); - push(@getterImplementation, " if (!result)\n"); - push(@getterImplementation, " return E_POINTER;\n\n"); - - my $implementationGetter; - my $reflect = $attribute->signature->extendedAttributes->{"Reflect"}; - my $reflectURL = $attribute->signature->extendedAttributes->{"ReflectURL"}; - if ($reflect || $reflectURL) { - my $contentAttributeName = (($reflect || $reflectURL) eq "1") ? $attributeName : ($reflect || $reflectURL); - my $namespace = $codeGenerator->NamespaceForAttributeName($IDLType, $contentAttributeName); - $implIncludes{"${namespace}.h"} = 1; - my $getAttributeFunctionName = $reflectURL ? "getURLAttribute" : "getAttribute"; - $implementationGetter = "impl${implementationClassWithoutNamespace}()->${getAttributeFunctionName}(WebCore::${namespace}::${contentAttributeName}Attr)"; - } else { - $implementationGetter = "impl${implementationClassWithoutNamespace}()->" . $codeGenerator->WK_lcfirst($attributeName) . "(" . ($hasGetterException ? "ec" : ""). ")"; - } - - push(@getterImplementation, " WebCore::ExceptionCode ec = 0;\n") if $hasGetterException; - - if ($attributeTypeIsString) { - push(@getterImplementation, " *result = WebCore::BString(${implementationGetter}).release();\n"); - } elsif ($attributeTypeIsPrimitive) { - if ($attribute->signature->extendedAttributes->{"ConvertFromString"}) { - push(@getterImplementation, " *result = static_cast<${attributeTypeCOMClassName}>(${implementationGetter}.toInt());\n"); - } else { - push(@getterImplementation, " *result = static_cast<${attributeTypeCOMClassName}>(${implementationGetter});\n"); - } - } else { - $CPPImplementationIncludesAngle{"wtf/GetPtr.h"} = 1; - my $attributeTypeCOMInterfaceName = GetInterfaceName($attributeIDLType); - push(@getterImplementation, " *result = 0;\n"); - push(@getterImplementation, " ${attributeImplementationType}* resultImpl = WTF::getPtr(${implementationGetter});\n"); - push(@getterImplementation, " if (!resultImpl)\n"); - push(@getterImplementation, " return E_POINTER;\n\n"); - push(@getterImplementation, " *result = to${attributeTypeCOMInterfaceName}(resultImpl);\n"); - } - - # FIXME: CHECK EXCEPTION AND DO SOMETHING WITH IT - - push(@getterImplementation, " return S_OK;\n"); - push(@getterImplementation, "}\n\n"); - - $attrbutesToReturn{"Getter"} = join("", @getterImplementation); - - return %attrbutesToReturn; -} - -sub GenerateCPPFunctionSignature -{ - my ($function, $className, $options) = @_; - - my $functionName = $function->signature->name; - my $returnIDLType = $function->signature->type; - my $returnType = GetCOMTypeOut($returnIDLType); - my $noReturn = ($returnType eq "void"); - - my $newline = $$options{"NewLines"} ? "\n" : ""; - my $indent = $$options{"Indent"} ? " " x $$options{"Indent"} : ""; - my $semicolon = $$options{"IncludeSemiColon"} ? ";" : ""; - my $virtual = $$options{"AddVirtualKeyword"} ? "virtual " : ""; - my $class = $$options{"UseClassName"} ? "${className}::" : ""; - my $forwarder = $$options{"Forwarder"} ? 1 : 0; - my $joiner = ($$options{"NewLines"} ? "\n" . $indent . " " : " "); - - my @paramArgList = (); - foreach my $param (@{$function->parameters}) { - my $paramName = $param->name; - my $paramType = GetCOMTypeIn($param->type); - my $parameter = "/* [in] */ ${paramType} ${paramName}"; - push(@paramArgList, $parameter); - } - - unless ($noReturn) { - my $resultParameter .= "/* [out, retval] */ ${returnType}* result"; - push(@paramArgList, $resultParameter); - } - - my $functionSig = $indent . $virtual . "HRESULT STDMETHODCALLTYPE " . $class . $functionName . "("; - $functionSig .= $joiner . join("," . $joiner, @paramArgList) if @paramArgList > 0; - $functionSig .= ")" . $semicolon . $newline; - if ($forwarder) { - my @paramNameList = (); - push(@paramNameList, $_->name) foreach (@{$function->parameters}); - push(@paramNameList, "result") unless $noReturn; - $functionSig .= " { return " . $$options{"Forwarder"} . "::" . $functionName . "(" . join(", ", @paramNameList) . "); }\n"; - } - - return $functionSig -} - -sub GenerateCPPFunction -{ - my ($function, $className, $implementationClass) = @_; - - my @functionImplementation = (); - - my $signature = GenerateCPPFunctionSignature($function, $className, { "NewLines" => 1, - "Indent" => 0, - "IncludeSemiColon" => 0, - "UseClassName" => 1, - "AddVirtualKeyword" => 0 }); - - my $implementationClassWithoutNamespace = StripNamespace($implementationClass); - - my $functionName = $function->signature->name; - my $returnIDLType = $function->signature->type; - my $noReturn = ($returnIDLType eq "void"); - my $raisesExceptions = @{$function->raisesExceptions}; - - AddIncludesForTypeInCPPImplementation($returnIDLType); - $CPPImplementationWebCoreIncludes{"ExceptionCode.h"} = 1 if $raisesExceptions; - - my %needsCustom = (); - my @parameterInitialization = (); - my @parameterList = (); - foreach my $param (@{$function->parameters}) { - my $paramName = $param->name; - my $paramIDLType = $param->type; - - my $paramTypeIsPrimitive = $codeGenerator->IsPrimitiveType($paramIDLType); - my $paramTypeIsString = $codeGenerator->IsStringType($paramIDLType); - - $needsCustom{"NodeToReturn"} = $paramName if $param->extendedAttributes->{"Return"}; - - AddIncludesForTypeInCPPImplementation($paramIDLType); - - # FIXME: We may need to null check the arguments as well - - if ($paramTypeIsString) { - push(@parameterList, $paramName); - } elsif ($paramTypeIsPrimitive) { - if ($paramIDLType eq "boolean") { - push(@parameterList, "!!${paramName}"); - } else { - my $primitiveImplementationType = IDLTypeToImplementationType($paramIDLType); - push(@parameterList, "static_cast<${primitiveImplementationType}>(${paramName})"); - } - } else { - $CPPImplementationWebCoreIncludes{"COMPtr.h"} = 1; - - $needsCustom{"CanReturnEarly"} = 1; - - my $paramTypeCOMClassName = GetClassName($paramIDLType); - my $paramTypeImplementationWithoutNamespace = StripNamespace(IDLTypeToImplementationType($paramIDLType)); - my $ptrName = "ptrFor" . $codeGenerator->WK_ucfirst($paramName); - my $paramInit = " COMPtr<${paramTypeCOMClassName}> ${ptrName}(Query, ${paramName});\n"; - $paramInit .= " if (!${ptrName})\n"; - $paramInit .= " return E_NOINTERFACE;"; - push(@parameterInitialization, $paramInit); - push(@parameterList, "${ptrName}->impl${paramTypeImplementationWithoutNamespace}()"); - } - } - - push(@parameterList, "ec") if $raisesExceptions; - - my $implementationGetter = "impl${implementationClassWithoutNamespace}()"; - - my $callSigBegin = " "; - my $callSigMiddle = "${implementationGetter}->" . $codeGenerator->WK_lcfirst($functionName) . "(" . join(", ", @parameterList) . ")"; - my $callSigEnd = ";\n"; - - if (defined $needsCustom{"NodeToReturn"}) { - my $nodeToReturn = $needsCustom{"NodeToReturn"}; - $callSigBegin .= "if ("; - $callSigEnd = ")\n"; - $callSigEnd .= " *result = ${nodeToReturn};"; - } elsif (!$noReturn) { - my $returnTypeIsString = $codeGenerator->IsStringType($returnIDLType); - my $returnTypeIsPrimitive = $codeGenerator->IsPrimitiveType($returnIDLType); - - if ($returnTypeIsString) { - $callSigBegin .= "*result = WebCore::BString("; - $callSigEnd = ").release();\n"; - } elsif ($returnTypeIsPrimitive) { - my $primitiveCOMType = GetClassName($returnIDLType); - $callSigBegin .= "*result = static_cast<${primitiveCOMType}>("; - $callSigEnd = ");"; - } else { - $CPPImplementationIncludesAngle{"wtf/GetPtr.h"} = 1; - my $returnImplementationType = IDLTypeToImplementationType($returnIDLType); - my $returnTypeCOMInterfaceName = GetInterfaceName($returnIDLType); - $callSigBegin .= "${returnImplementationType}* resultImpl = WTF::getPtr("; - $callSigEnd = ");\n"; - $callSigEnd .= " if (!resultImpl)\n"; - $callSigEnd .= " return E_POINTER;\n\n"; - $callSigEnd .= " *result = to${returnTypeCOMInterfaceName}(resultImpl);"; - } - } - - push(@functionImplementation, $signature); - push(@functionImplementation, "{\n"); - unless ($noReturn) { - push(@functionImplementation, " if (!result)\n"); - push(@functionImplementation, " return E_POINTER;\n\n"); - push(@functionImplementation, " *result = 0;\n\n") if $needsCustom{"CanReturnEarly"}; - } - push(@functionImplementation, " WebCore::ExceptionCode ec = 0;\n") if $raisesExceptions; # FIXME: CHECK EXCEPTION AND DO SOMETHING WITH IT - push(@functionImplementation, join("\n", @parameterInitialization) . (@parameterInitialization > 0 ? "\n" : "")); - push(@functionImplementation, $callSigBegin . $callSigMiddle . $callSigEnd . "\n"); - push(@functionImplementation, " return S_OK;\n"); - push(@functionImplementation, "}\n\n"); - - return join("", @functionImplementation); -} - - -# ----------------------------------------------------------------------------- -# CPP Header -# ----------------------------------------------------------------------------- - -sub GenerateCPPHeader -{ - my ($object, $dataNode) = @_; - - my $IDLType = $dataNode->name; - my $implementationClass = IDLTypeToImplementationType($IDLType); - my $implementationClassWithoutNamespace = StripNamespace($implementationClass); - my $className = GetClassName($IDLType); - my $interfaceName = GetInterfaceName($IDLType); - - my $parentClassName = GetParentClass($dataNode); - my @otherInterfacesImplemented = GetAdditionalInterfaces($IDLType); - foreach my $otherInterface (@otherInterfacesImplemented) { - push(@additionalInterfaceDefinitions, $codeGenerator->ParseInterface($otherInterface)); - } - - # FIXME: strip whitespace from UUID - my $uuid = $dataNode->extendedAttributes->{"ImplementationUUID"} || die "All classes require an ImplementationUUID extended attribute."; - - my $numAttributes = @{$dataNode->attributes}; - my $numFunctions = @{$dataNode->functions}; - - # - Add default header template - @CPPHeaderHeader = @licenseTemplate; - push(@CPPHeaderHeader, "\n"); - - # - Header guards - - push(@CPPHeaderHeader, "#ifndef " . $className . "_h\n"); - push(@CPPHeaderHeader, "#define " . $className . "_h\n\n"); - - AddIncludesForTypeInCPPHeader($interfaceName); - AddIncludesForTypeInCPPHeader($parentClassName); - $CPPHeaderDontForwardDeclarations{$className} = 1; - $CPPHeaderDontForwardDeclarations{$interfaceName} = 1; - $CPPHeaderDontForwardDeclarations{$parentClassName} = 1; - - # -- Forward declare implementation type - push(@CPPHeaderContent, "namespace WebCore {\n"); - push(@CPPHeaderContent, " class ". StripNamespace($implementationClass) . ";\n"); - push(@CPPHeaderContent, "}\n\n"); - - # -- Start Class -- - my @parentsClasses = ($parentClassName, $interfaceName); - push(@parentsClasses, map { GetInterfaceName($_) } @otherInterfacesImplemented); - push(@CPPHeaderContent, "class __declspec(uuid(\"$uuid\")) ${className} : " . join(", ", map { "public $_" } @parentsClasses) . " {\n"); - - # Add includes for all additional interfaces to implement - map { AddIncludesForTypeInCPPHeader(GetInterfaceName($_)) } @otherInterfacesImplemented; - - # -- BASICS -- - # FIXME: The constructor and destructor should be protected, but the current design of - # createInstance requires them to be public. One solution is to friend the constructor - # of the top-level-class with every one of its child classes, but that requires information - # this script currently does not have, though possibly could determine. - push(@CPPHeaderContent, "public:\n"); - push(@CPPHeaderContent, " ${className}(${implementationClass}*);\n"); - push(@CPPHeaderContent, " virtual ~${className}();\n\n"); - - push(@CPPHeaderContent, "public:\n"); - push(@CPPHeaderContent, " static ${className}* createInstance(${implementationClass}*);\n\n"); - - push(@CPPHeaderContent, " // IUnknown\n"); - push(@CPPHeaderContent, " virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID, void** ppvObject);\n"); - push(@CPPHeaderContent, " virtual ULONG STDMETHODCALLTYPE AddRef() { return ${parentClassName}::AddRef(); }\n"); - push(@CPPHeaderContent, " virtual ULONG STDMETHODCALLTYPE Release() { return ${parentClassName}::Release(); }\n\n"); - - - # -- Parent Class Forwards -- - if (@{$dataNode->parents}) { - my %attributeNameSet = map {($_->signature->name, 1)} @{$dataNode->attributes}; - my %functionNameSet = map {($_->signature->name, 1)} @{$dataNode->functions}; - - my @parentLists = $codeGenerator->GetMethodsAndAttributesFromParentClasses($dataNode); - push(@CPPHeaderContent, "\n"); - foreach my $parentHash (@parentLists) { - - push(@CPPHeaderContent, " // " . GetInterfaceName($parentHash->{'name'}) . $DASHES . "\n"); - - my @attributeList = @{$parentHash->{'attributes'}}; - push(@CPPHeaderContent, " // Attributes\n"); - foreach my $attribute (@attributeList) { - # Don't forward an attribute that this class redefines. - next if $attributeNameSet{$attribute->signature->name}; - - AddForwardDeclarationsForTypeInCPPHeader($attribute->signature->type); - - my %attributes = GenerateCPPAttributeSignature($attribute, $className, { "NewLines" => 0, - "Indent" => 4, - "IncludeSemiColon" => 0, - "AddVirtualKeyword" => 1, - "UseClassName" => 0, - "Forwarder" => $parentClassName }); - push(@CPPHeaderContent, values(%attributes)); - } - - # Add attribute names to attribute names set in case other ancestors - # also define them. - $attributeNameSet{$_->signature->name} = 1 foreach @attributeList; - - push(@CPPHeaderContent, "\n"); - - my @functionList = @{$parentHash->{'functions'}}; - push(@CPPHeaderContent, " // Functions\n"); - foreach my $function (@functionList) { - # Don't forward a function that this class redefines. - next if $functionNameSet{$function->signature->name}; - - AddForwardDeclarationsForTypeInCPPHeader($function->signature->type); - AddForwardDeclarationsForTypeInCPPHeader($_->type) foreach (@{$function->parameters}); - - my $functionSig = GenerateCPPFunctionSignature($function, $className, { "NewLines" => 0, - "Indent" => 4, - "IncludeSemiColon" => 0, - "AddVirtualKeyword" => 1, - "UseClassName" => 0, - "Forwarder" => $parentClassName }); - - push(@CPPHeaderContent, $functionSig); - } - # Add functions names to functions names set in case other ancestors - # also define them. - $functionNameSet{$_->signature->name} = 1 foreach @functionList; - - push(@CPPHeaderContent, "\n"); - } - } - - # - Additional interfaces to implement - - foreach my $interfaceToImplement (@additionalInterfaceDefinitions) { - my $IDLTypeOfInterfaceToImplement = $interfaceToImplement->name; - my $nameOfInterfaceToImplement = GetInterfaceName($IDLTypeOfInterfaceToImplement); - my $numAttributesInInterface = @{$interfaceToImplement->attributes}; - my $numFunctionsInInterface = @{$interfaceToImplement->functions}; - - push(@CPPHeaderContent, " // ${nameOfInterfaceToImplement} ${DASHES}\n\n"); - - # - Add attribute getters/setters. - if ($numAttributesInInterface > 0) { - push(@CPPHeaderContent, " // Attributes\n\n"); - foreach my $attribute (@{$interfaceToImplement->attributes}) { - AddForwardDeclarationsForTypeInCPPHeader($attribute->signature->type); - - my %attributeSigs = GenerateCPPAttributeSignature($attribute, $className, { "NewLines" => 1, - "Indent" => 4, - "IncludeSemiColon" => 1, - "AddVirtualKeyword" => 1, - "UseClassName" => 0 }); - - push(@CPPHeaderContent, values(%attributeSigs)); - push(@CPPHeaderContent, "\n"); - } - } - - # - Add functions. - if ($numFunctionsInInterface > 0) { - push(@CPPHeaderContent, " // Functions\n\n"); - foreach my $function (@{$interfaceToImplement->functions}) { - AddForwardDeclarationsForTypeInCPPHeader($function->signature->type); - AddForwardDeclarationsForTypeInCPPHeader($_->type) foreach (@{$function->parameters}); - - my $functionSig = GenerateCPPFunctionSignature($function, $className, { "NewLines" => 1, - "Indent" => 4, - "IncludeSemiColon" => 1, - "AddVirtualKeyword" => 1, - "UseClassName" => 0 }); - - push(@CPPHeaderContent, $functionSig); - push(@CPPHeaderContent, "\n"); - } - } - } - - if ($numAttributes > 0 || $numFunctions > 0) { - push(@CPPHeaderContent, " // ${interfaceName} ${DASHES}\n\n"); - } - - # - Add constants COMING SOON - - # - Add attribute getters/setters. - if ($numAttributes > 0) { - push(@CPPHeaderContent, " // Attributes\n\n"); - foreach my $attribute (@{$dataNode->attributes}) { - AddForwardDeclarationsForTypeInCPPHeader($attribute->signature->type); - - my %attributeSigs = GenerateCPPAttributeSignature($attribute, $className, { "NewLines" => 1, - "Indent" => 4, - "IncludeSemiColon" => 1, - "AddVirtualKeyword" => 1, - "UseClassName" => 0 }); - - push(@CPPHeaderContent, values(%attributeSigs)); - push(@CPPHeaderContent, "\n"); - } - } - - # - Add functions. - if ($numFunctions > 0) { - push(@CPPHeaderContent, " // Functions\n\n"); - foreach my $function (@{$dataNode->functions}) { - AddForwardDeclarationsForTypeInCPPHeader($function->signature->type); - AddForwardDeclarationsForTypeInCPPHeader($_->type) foreach (@{$function->parameters}); - - my $functionSig = GenerateCPPFunctionSignature($function, $className, { "NewLines" => 1, - "Indent" => 4, - "IncludeSemiColon" => 1, - "AddVirtualKeyword" => 1, - "UseClassName" => 0 }); - - push(@CPPHeaderContent, $functionSig); - push(@CPPHeaderContent, "\n"); - } - } - - push(@CPPHeaderContent, " ${implementationClass}* impl${implementationClassWithoutNamespace}() const;\n"); - - if (@{$dataNode->parents} == 0) { - AddIncludesForTypeInCPPHeader("wtf/RefPtr", 1); - push(@CPPHeaderContent, "\n"); - push(@CPPHeaderContent, " ${implementationClass}* impl() const { return m_impl.get(); }\n\n"); - push(@CPPHeaderContent, "private:\n"); - push(@CPPHeaderContent, " RefPtr<${implementationClass}> m_impl;\n"); - } - - # -- End Class -- - push(@CPPHeaderContent, "};\n\n"); - - # -- Default Interface Creator -- - push(@CPPHeaderContent, "${interfaceName}* to${interfaceName}(${implementationClass}*);\n\n"); - - push(@CPPHeaderContent, "#endif // " . $className . "_h\n"); -} - - -# ----------------------------------------------------------------------------- -# CPP Implementation -# ----------------------------------------------------------------------------- - -sub GenerateCPPImplementation -{ - my ($object, $dataNode) = @_; - - my $IDLType = $dataNode->name; - my $implementationClass = IDLTypeToImplementationType($IDLType); - my $implementationClassWithoutNamespace = StripNamespace($implementationClass); - my $className = GetClassName($IDLType); - my $interfaceName = GetInterfaceName($IDLType); - - my $parentClassName = GetParentClass($dataNode); - my $isBaseClass = (@{$dataNode->parents} == 0); - - my $uuid = $dataNode->extendedAttributes->{"ImplementationUUID"} || die "All classes require an ImplementationUUID extended attribute."; - - my $numAttributes = @{$dataNode->attributes}; - my $numFunctions = @{$dataNode->functions}; - - # - Add default header template - @CPPImplementationHeader = @licenseTemplate; - push(@CPPImplementationHeader, "\n"); - - push(@CPPImplementationHeader, "#include \"config.h\"\n"); - push(@CPPImplementationHeader, "#include \"WebKitDLL.h\"\n"); - push(@CPPImplementationHeader, "#include " . ($className eq "GEN_DOMImplementation" ? "\"GEN_DOMDOMImplementation.h\"" : "\"${className}.h\"") . "\n"); - $CPPImplementationDontIncludes{"${className}.h"} = 1; - $CPPImplementationWebCoreIncludes{"${implementationClassWithoutNamespace}.h"} = 1; - - # -- Constructor -- - push(@CPPImplementationContent, "${className}::${className}(${implementationClass}* impl)\n"); - if ($isBaseClass) { - push(@CPPImplementationContent, " : m_impl(impl)\n"); - push(@CPPImplementationContent, "{\n"); - push(@CPPImplementationContent, " ASSERT_ARG(impl, impl);\n"); - push(@CPPImplementationContent, "}\n\n"); - } else { - push(@CPPImplementationContent, " : ${parentClassName}(impl)\n"); - push(@CPPImplementationContent, "{\n"); - push(@CPPImplementationContent, "}\n\n"); - } - - # -- Destructor -- - push(@CPPImplementationContent, "${className}::~${className}()\n"); - push(@CPPImplementationContent, "{\n"); - if ($isBaseClass) { - $CPPImplementationIncludes{"DOMCreateInstance.h"} = 1; - push(@CPPImplementationContent, " removeDOMWrapper(impl());\n"); - } - push(@CPPImplementationContent, "}\n\n"); - - push(@CPPImplementationContent, "${implementationClass}* ${className}::impl${implementationClassWithoutNamespace}() const\n"); - push(@CPPImplementationContent, "{\n"); - push(@CPPImplementationContent, " return static_cast<${implementationClass}*>(impl());\n"); - push(@CPPImplementationContent, "}\n\n"); - - # Base classes must implement the createInstance method externally. - if (@{$dataNode->parents} != 0) { - push(@CPPImplementationContent, "${className}* ${className}::createInstance(${implementationClass}* impl)\n"); - push(@CPPImplementationContent, "{\n"); - push(@CPPImplementationContent, " return static_cast<${className}*>(${parentClassName}::createInstance(impl));\n"); - push(@CPPImplementationContent, "}\n"); - } - - push(@CPPImplementationContent, "// IUnknown $DASHES\n\n"); - - # -- QueryInterface -- - push(@CPPImplementationContent, "HRESULT STDMETHODCALLTYPE ${className}::QueryInterface(REFIID riid, void** ppvObject)\n"); - push(@CPPImplementationContent, "{\n"); - push(@CPPImplementationContent, " *ppvObject = 0;\n"); - push(@CPPImplementationContent, " if (IsEqualGUID(riid, IID_${interfaceName}))\n"); - push(@CPPImplementationContent, " *ppvObject = reinterpret_cast<${interfaceName}*>(this);\n"); - push(@CPPImplementationContent, " else if (IsEqualGUID(riid, __uuidof(${className})))\n"); - push(@CPPImplementationContent, " *ppvObject = reinterpret_cast<${className}*>(this);\n"); - push(@CPPImplementationContent, " else\n"); - push(@CPPImplementationContent, " return ${parentClassName}::QueryInterface(riid, ppvObject);\n\n"); - push(@CPPImplementationContent, " AddRef();\n"); - push(@CPPImplementationContent, " return S_OK;\n"); - push(@CPPImplementationContent, "}\n\n"); - - # - Additional interfaces to implement - - foreach my $interfaceToImplement (@additionalInterfaceDefinitions) { - my $IDLTypeOfInterfaceToImplement = $interfaceToImplement->name; - my $nameOfInterfaceToImplement = GetInterfaceName($IDLTypeOfInterfaceToImplement); - my $numAttributesInInterface = @{$interfaceToImplement->attributes}; - my $numFunctionsInInterface = @{$interfaceToImplement->functions}; - - push(@CPPImplementationContent, " // ${nameOfInterfaceToImplement} ${DASHES}\n\n"); - - if ($numAttributesInInterface > 0) { - push(@CPPImplementationContent, "// Attributes\n\n"); - foreach my $attribute (@{$interfaceToImplement->attributes}) { - # FIXME: Do this in one step. - # FIXME: Implement exception handling. - - AddIncludesForTypeInCPPImplementation($attribute->signature->type); - - my %attributes = GenerateCPPAttribute($attribute, $className, $implementationClass, $IDLType); - push(@CPPImplementationContent, values(%attributes)); - } - } - - # - Add functions. - if ($numFunctionsInInterface > 0) { - push(@CPPImplementationContent, "// Functions\n\n"); - - foreach my $function (@{$interfaceToImplement->functions}) { - my $functionImplementation = GenerateCPPFunction($function, $className, $implementationClass); - push(@CPPImplementationContent, $functionImplementation); - } - } - } - - push(@CPPImplementationContent, "// ${interfaceName} $DASHES\n\n"); - - # - Add attribute getters/setters. - if ($numAttributes > 0) { - push(@CPPImplementationContent, "// Attributes\n\n"); - foreach my $attribute (@{$dataNode->attributes}) { - # FIXME: do this in one step - my $hasSetterException = @{$attribute->setterExceptions}; - my $hasGetterException = @{$attribute->getterExceptions}; - - AddIncludesForTypeInCPPImplementation($attribute->signature->type); - - my %attributes = GenerateCPPAttribute($attribute, $className, $implementationClass, $IDLType); - push(@CPPImplementationContent, values(%attributes)); - } - } - - # - Add functions. - if ($numFunctions > 0) { - push(@CPPImplementationContent, "// Functions\n\n"); - - foreach my $function (@{$dataNode->functions}) { - my $functionImplementation = GenerateCPPFunction($function, $className, $implementationClass); - push(@CPPImplementationContent, $functionImplementation); - } - } - - # - Default implementation for interface creator. - # FIXME: add extended attribute to add custom implementation if necessary. - push(@CPPImplementationContent, "${interfaceName}* to${interfaceName}(${implementationClass}* impl)\n"); - push(@CPPImplementationContent, "{\n"); - push(@CPPImplementationContent, " return ${className}::createInstance(impl);\n"); - push(@CPPImplementationContent, "}\n"); -} - -sub WriteData -{ - my ($object, $name, $pureInterface) = @_; - - # -- IDL -- - my $IDLFileName = "$outputDir/I" . $TEMP_PREFIX . "DOM" . $name . ".idl"; - unlink($IDLFileName); - - # Write to output IDL. - open(OUTPUTIDL, ">$IDLFileName") or die "Couldn't open file $IDLFileName"; - - # Add header - print OUTPUTIDL @IDLHeader; - - # Add forward declarations and imorts - delete $IDLForwardDeclarations{keys(%IDLDontForwardDeclare)}; - delete $IDLImports{keys(%IDLDontImport)}; - - print OUTPUTIDL map { "cpp_quote(\"interface $_;\")\n" } sort keys(%IDLForwardDeclarations); - print OUTPUTIDL "\n"; - - print OUTPUTIDL map { "interface $_;\n" } sort keys(%IDLForwardDeclarations); - print OUTPUTIDL "\n"; - print OUTPUTIDL "#ifndef DO_NO_IMPORTS\n"; - print OUTPUTIDL map { ($_ eq "IGEN_DOMImplementation") ? "import \"IGEN_DOMDOMImplementation.idl\";\n" : "import \"$_.idl\";\n" } sort keys(%IDLImports); - print OUTPUTIDL "#endif\n"; - print OUTPUTIDL "\n"; - - # Add content - print OUTPUTIDL @IDLContent; - - close(OUTPUTIDL); - - @IDLHeader = (); - @IDLContent = (); - - if ($pureInterface) { - my $CPPInterfaceHeaderFileName = "$outputDir/" . $TEMP_PREFIX . "DOM" . $name . ".h"; - unlink($CPPInterfaceHeaderFileName); - - open(OUTPUTCPPInterfaceHeader, ">$CPPInterfaceHeaderFileName") or die "Couldn't open file $CPPInterfaceHeaderFileName"; - - print OUTPUTCPPInterfaceHeader @CPPInterfaceHeader; - - close(OUTPUTCPPInterfaceHeader); - - @CPPInterfaceHeader = (); - } else { - my $CPPHeaderFileName = "$outputDir/" . $TEMP_PREFIX . "DOM" . $name . ".h"; - unlink($CPPHeaderFileName); - - # -- CPP Header -- - open(OUTPUTCPPHeader, ">$CPPHeaderFileName") or die "Couldn't open file $CPPHeaderFileName"; - - # Add header - print OUTPUTCPPHeader @CPPHeaderHeader; - - # Add includes - print OUTPUTCPPHeader map { ($_ eq "GEN_DOMImplementation.h") ? "#include \"GEN_DOMDOMImplementation.h\"\n" : "#include \"$_\"\n" } sort keys(%CPPHeaderIncludes); - print OUTPUTCPPHeader map { "#include <$_>\n" } sort keys(%CPPHeaderIncludesAngle); - - foreach my $dontDeclare (keys(%CPPHeaderDontForwardDeclarations)) { - delete $CPPHeaderForwardDeclarations{$dontDeclare} if ($CPPHeaderForwardDeclarations{$dontDeclare}); - } - print OUTPUTCPPHeader "\n"; - print OUTPUTCPPHeader map { "interface $_;\n" } sort keys(%CPPHeaderForwardDeclarations); - print OUTPUTCPPHeader "\n"; - - # Add content - print OUTPUTCPPHeader @CPPHeaderContent; - - close(OUTPUTCPPHeader); - - @CPPHeaderHeader = (); - @CPPHeaderContent = (); - - - # -- CPP Implementation -- - my $CPPImplementationFileName = "$outputDir/" . $TEMP_PREFIX . "DOM" . $name . ".cpp"; - unlink($CPPImplementationFileName); - - open(OUTPUTCPPImplementation, ">$CPPImplementationFileName") or die "Couldn't open file $CPPImplementationFileName"; - - # Add header - print OUTPUTCPPImplementation @CPPImplementationHeader; - print OUTPUTCPPImplementation "\n"; - - # Add includes - foreach my $dontInclude (keys(%CPPImplementationDontIncludes)) { - delete $CPPImplementationIncludes{$dontInclude} if ($CPPImplementationIncludes{$dontInclude}); - } - print OUTPUTCPPImplementation map { ($_ eq "GEN_DOMImplementation.h") ? "#include \"GEN_DOMDOMImplementation.h\"\n" : "#include \"$_\"\n" } sort keys(%CPPImplementationIncludes); - print OUTPUTCPPImplementation map { "#include <$_>\n" } sort keys(%CPPImplementationIncludesAngle); - print OUTPUTCPPImplementation "\n"; - - print OUTPUTCPPImplementation "#pragma warning(push, 0)\n"; - print OUTPUTCPPImplementation map { "#include <WebCore/$_>\n" } sort keys(%CPPImplementationWebCoreIncludes); - print OUTPUTCPPImplementation "#pragma warning(pop)\n"; - - # Add content - print OUTPUTCPPImplementation @CPPImplementationContent; - - close(OUTPUTCPPImplementation); - - @CPPImplementationHeader = (); - @CPPImplementationContent = (); - } -} - -1; diff --git a/src/3rdparty/webkit/WebCore/bindings/scripts/CodeGeneratorJS.pm b/src/3rdparty/webkit/WebCore/bindings/scripts/CodeGeneratorJS.pm index d8367ac..1aed11d 100644 --- a/src/3rdparty/webkit/WebCore/bindings/scripts/CodeGeneratorJS.pm +++ b/src/3rdparty/webkit/WebCore/bindings/scripts/CodeGeneratorJS.pm @@ -17,7 +17,7 @@ # Library General Public License for more details. # # You should have received a copy of the GNU Library General Public License -# aint with this library; see the file COPYING.LIB. If not, write to +# along with this library; see the file COPYING.LIB. If not, write to # the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, # Boston, MA 02110-1301, USA. @@ -32,11 +32,14 @@ my $writeDependencies = 0; my @headerContentHeader = (); my @headerContent = (); my %headerIncludes = (); +my %headerTrailingIncludes = (); my @implContentHeader = (); my @implContent = (); my %implIncludes = (); my @depsContent = (); +my $numCachedAttributes = 0; +my $currentCachedAttribute = 0; # Default .h template my $headerTemplate = << "EOF"; @@ -132,15 +135,7 @@ sub GetParentClassName my $dataNode = shift; return $dataNode->extendedAttributes->{"LegacyParent"} if $dataNode->extendedAttributes->{"LegacyParent"}; - if (@{$dataNode->parents} eq 0) { - # FIXME: SVG types requiring a context() pointer do not have enough - # space to hold a globalObject pointer as well w/o hitting the CELL_SIZE limit. - # This could be fixed by moving context() into the various impl() classes. - # Until then, we special case these SVG bindings and allow them to return - # the wrong prototypes and constructors during x-frame access. See bug 27088. - return "DOMObjectWithSVGContext" if IsSVGTypeNeedingContextParameter($dataNode->name); - return "DOMObjectWithGlobalPointer"; - } + return "DOMObjectWithGlobalPointer" if (@{$dataNode->parents} eq 0); return "JS" . $codeGenerator->StripModule($dataNode->parents(0)); } @@ -149,6 +144,7 @@ sub GetVisibleClassName my $className = shift; return "DOMException" if $className eq "DOMCoreException"; + return "FormData" if $className eq "DOMFormData"; return $className; } @@ -169,16 +165,6 @@ sub IndexGetterReturnsStrings return 0; } -sub CreateSVGContextInterfaceName -{ - my $type = shift; - - return $type if $codeGenerator->IsSVGAnimatedType($type); - return "SVGPathSeg" if $type =~ /^SVGPathSeg/ and $type ne "SVGPathSegList"; - - return ""; -} - sub AddIncludesForType { my $type = $codeGenerator->StripModule(shift); @@ -316,7 +302,14 @@ sub GenerateGetOwnPropertySlotBody if ($dataNode->extendedAttributes->{"HasIndexGetter"} || $dataNode->extendedAttributes->{"HasCustomIndexGetter"} || $dataNode->extendedAttributes->{"HasNumericIndexGetter"}) { push(@getOwnPropertySlotImpl, " bool ok;\n"); push(@getOwnPropertySlotImpl, " unsigned index = propertyName.toUInt32(&ok, false);\n"); - push(@getOwnPropertySlotImpl, " if (ok && index < static_cast<$implClassName*>(impl())->length()) {\n"); + + # If the item function returns a string then we let the ConvertNullStringTo handle the cases + # where the index is out of range. + if (IndexGetterReturnsStrings($implClassName)) { + push(@getOwnPropertySlotImpl, " if (ok) {\n"); + } else { + push(@getOwnPropertySlotImpl, " if (ok && index < static_cast<$implClassName*>(impl())->length()) {\n"); + } if ($dataNode->extendedAttributes->{"HasCustomIndexGetter"} || $dataNode->extendedAttributes->{"HasNumericIndexGetter"}) { push(@getOwnPropertySlotImpl, " slot.setValue(getByIndex(exec, index));\n"); } else { @@ -368,6 +361,14 @@ sub GenerateGetOwnPropertyDescriptorBody my $namespaceMaybe = ($inlined ? "JSC::" : ""); my @getOwnPropertyDescriptorImpl = (); + if ($dataNode->extendedAttributes->{"CheckDomainSecurity"}) { + if ($interfaceName eq "DOMWindow") { + push(@implContent, " if (!static_cast<$className*>(thisObject)->allowsAccessFrom(exec))\n"); + } else { + push(@implContent, " if (!allowsAccessFromFrame(exec, static_cast<$className*>(thisObject)->impl()->frame()))\n"); + } + push(@implContent, " return false;\n"); + } if ($interfaceName eq "NamedNodeMap" or $interfaceName eq "HTMLCollection" or $interfaceName eq "HTMLAllCollection") { push(@getOwnPropertyDescriptorImpl, " ${namespaceMaybe}JSValue proto = prototype();\n"); @@ -476,7 +477,6 @@ sub GenerateHeader my $hasParent = $hasLegacyParent || $hasRealParent; my $parentClassName = GetParentClassName($dataNode); my $conditional = $dataNode->extendedAttributes->{"Conditional"}; - my $needsSVGContext = IsSVGTypeNeedingContextParameter($interfaceName); my $eventTarget = $dataNode->extendedAttributes->{"EventTarget"}; my $needsMarkChildren = $dataNode->extendedAttributes->{"CustomMarkFunction"} || $dataNode->extendedAttributes->{"EventTarget"}; @@ -496,8 +496,7 @@ sub GenerateHeader if ($hasParent) { $headerIncludes{"$parentClassName.h"} = 1; } else { - $headerIncludes{"DOMObjectWithSVGContext.h"} = $needsSVGContext; - $headerIncludes{"JSDOMBinding.h"} = !$needsSVGContext; + $headerIncludes{"JSDOMBinding.h"} = 1; $headerIncludes{"<runtime/JSGlobalObject.h>"} = 1; $headerIncludes{"<runtime/ObjectPrototype.h>"} = 1; } @@ -520,6 +519,7 @@ sub GenerateHeader # Get correct pass/store types respecting PODType flag my $podType = $dataNode->extendedAttributes->{"PODType"}; my $implType = $podType ? "JSSVGPODTypeWrapper<$podType> " : $implClassName; + $headerIncludes{"$podType.h"} = 1 if $podType and $podType ne "float"; $headerIncludes{"JSSVGPODTypeWrapper.h"} = 1 if $podType; @@ -544,22 +544,23 @@ sub GenerateHeader push(@headerContent, " $className(NonNullPassRefPtr<JSC::Structure>, PassRefPtr<$implType>, JSDOMWindowShell*);\n"); } elsif ($dataNode->extendedAttributes->{"IsWorkerContext"}) { push(@headerContent, " $className(NonNullPassRefPtr<JSC::Structure>, PassRefPtr<$implType>);\n"); - } elsif (IsSVGTypeNeedingContextParameter($implClassName)) { - push(@headerContent, " $className(NonNullPassRefPtr<JSC::Structure>, JSDOMGlobalObject*, PassRefPtr<$implType>, SVGElement* context);\n"); } else { push(@headerContent, " $className(NonNullPassRefPtr<JSC::Structure>, JSDOMGlobalObject*, PassRefPtr<$implType>);\n"); } # Destructor - push(@headerContent, " virtual ~$className();\n") if (!$hasParent or $eventTarget or $interfaceName eq "Document" or $interfaceName eq "DOMWindow"); + push(@headerContent, " virtual ~$className();\n") if (!$hasParent or $eventTarget or $interfaceName eq "DOMWindow"); # Prototype push(@headerContent, " static JSC::JSObject* createPrototype(JSC::ExecState*, JSC::JSGlobalObject*);\n") unless ($dataNode->extendedAttributes->{"ExtendsDOMGlobalObject"}); - $implIncludes{"${className}Custom.h"} = 1 if $dataNode->extendedAttributes->{"CustomHeader"} || $dataNode->extendedAttributes->{"CustomPutFunction"} || $dataNode->extendedAttributes->{"DelegatingPutFunction"}; + $headerTrailingIncludes{"${className}Custom.h"} = 1 if $dataNode->extendedAttributes->{"CustomHeader"}; + + $implIncludes{"${className}Custom.h"} = 1 if !$dataNode->extendedAttributes->{"CustomHeader"} && ($dataNode->extendedAttributes->{"CustomPutFunction"} || $dataNode->extendedAttributes->{"DelegatingPutFunction"}); my $hasGetter = $numAttributes > 0 - || $dataNode->extendedAttributes->{"GenerateConstructor"} + || !($dataNode->extendedAttributes->{"OmitConstructor"} + || $dataNode->extendedAttributes->{"CustomConstructor"}) || $dataNode->extendedAttributes->{"HasIndexGetter"} || $dataNode->extendedAttributes->{"HasCustomIndexGetter"} || $dataNode->extendedAttributes->{"HasNumericIndexGetter"} @@ -610,7 +611,7 @@ sub GenerateHeader push(@headerContent, " static PassRefPtr<JSC::Structure> createStructure(JSC::JSValue prototype)\n" . " {\n" . - " return JSC::Structure::create(prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags));\n" . + " return JSC::Structure::create(prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), AnonymousSlotCount);\n" . " }\n\n"); # markChildren function @@ -630,7 +631,7 @@ sub GenerateHeader # Custom getPropertyNames function exists on DOMWindow if ($interfaceName eq "DOMWindow") { - push(@headerContent, " virtual void getPropertyNames(JSC::ExecState*, JSC::PropertyNameArray&);\n"); + push(@headerContent, " virtual void getPropertyNames(JSC::ExecState*, JSC::PropertyNameArray&, JSC::EnumerationMode mode = JSC::ExcludeDontEnumProperties);\n"); $structureFlags{"JSC::OverridesGetPropertyNames"} = 1; } @@ -639,13 +640,10 @@ sub GenerateHeader # Custom getOwnPropertyNames function if ($dataNode->extendedAttributes->{"CustomGetPropertyNames"} || $dataNode->extendedAttributes->{"HasIndexGetter"} || $dataNode->extendedAttributes->{"HasCustomIndexGetter"} || $dataNode->extendedAttributes->{"HasNumericIndexGetter"}) { - push(@headerContent, " virtual void getOwnPropertyNames(JSC::ExecState*, JSC::PropertyNameArray&);\n"); + push(@headerContent, " virtual void getOwnPropertyNames(JSC::ExecState*, JSC::PropertyNameArray&, JSC::EnumerationMode mode = JSC::ExcludeDontEnumProperties);\n"); $structureFlags{"JSC::OverridesGetPropertyNames"} = 1; } - # Custom getPropertyAttributes function - push(@headerContent, " virtual bool getPropertyAttributes(JSC::ExecState*, const JSC::Identifier&, unsigned& attributes) const;\n") if $dataNode->extendedAttributes->{"CustomGetPropertyAttributes"}; - # Custom defineGetter function push(@headerContent, " virtual void defineGetter(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::JSObject* getterFunction, unsigned attributes);\n") if $dataNode->extendedAttributes->{"CustomDefineGetter"}; @@ -665,7 +663,7 @@ sub GenerateHeader } # Constructor object getter - push(@headerContent, " static JSC::JSValue getConstructor(JSC::ExecState*, JSC::JSGlobalObject*);\n") if $dataNode->extendedAttributes->{"GenerateConstructor"}; + push(@headerContent, " static JSC::JSValue getConstructor(JSC::ExecState*, JSC::JSGlobalObject*);\n") if (!($dataNode->extendedAttributes->{"OmitConstructor"} || $dataNode->extendedAttributes->{"CustomConstructor"})); my $numCustomFunctions = 0; my $numCustomAttributes = 0; @@ -677,9 +675,17 @@ sub GenerateHeader $numCustomAttributes++ if $attribute->signature->extendedAttributes->{"Custom"} || $attribute->signature->extendedAttributes->{"JSCCustom"}; $numCustomAttributes++ if $attribute->signature->extendedAttributes->{"CustomGetter"} || $attribute->signature->extendedAttributes->{"JSCCustomGetter"}; $numCustomAttributes++ if $attribute->signature->extendedAttributes->{"CustomSetter"} || $attribute->signature->extendedAttributes->{"JSCCustomSetter"}; + if ($attribute->signature->extendedAttributes->{"CachedAttribute"}) { + push(@headerContent, " static const unsigned " . $attribute->signature->name . "Slot = $numCachedAttributes + Base::AnonymousSlotCount;\n"); + $numCachedAttributes++; + } } } + if ($numCachedAttributes > 0) { + push(@headerContent, " using $parentClassName" . "::putAnonymousValue;\n"); + push(@headerContent, " using $parentClassName" . "::getAnonymousValue;\n"); + } if ($numCustomAttributes > 0) { push(@headerContent, "\n // Custom attributes\n"); @@ -726,6 +732,12 @@ sub GenerateHeader push(@headerContent, " }\n"); } + # anonymous slots + if ($numCachedAttributes) { + push(@headerContent, "public:\n"); + push(@headerContent, " static const unsigned AnonymousSlotCount = $numCachedAttributes + Base::AnonymousSlotCount;\n"); + } + # structure flags push(@headerContent, "protected:\n"); push(@headerContent, " static const unsigned StructureFlags = "); @@ -736,7 +748,7 @@ sub GenerateHeader # Index getter if ($dataNode->extendedAttributes->{"HasIndexGetter"}) { - push(@headerContent, " static JSC::JSValue indexGetter(JSC::ExecState*, const JSC::Identifier&, const JSC::PropertySlot&);\n"); + push(@headerContent, " static JSC::JSValue indexGetter(JSC::ExecState*, JSC::JSValue, unsigned);\n"); } if ($dataNode->extendedAttributes->{"HasCustomIndexGetter"} || $dataNode->extendedAttributes->{"HasNumericIndexGetter"}) { push(@headerContent, " JSC::JSValue getByIndex(JSC::ExecState*, unsigned index);\n"); @@ -751,7 +763,7 @@ sub GenerateHeader if ($dataNode->extendedAttributes->{"HasNameGetter"} || $dataNode->extendedAttributes->{"HasOverridingNameGetter"}) { push(@headerContent, "private:\n"); push(@headerContent, " static bool canGetItemsForName(JSC::ExecState*, $implClassName*, const JSC::Identifier&);\n"); - push(@headerContent, " static JSC::JSValue nameGetter(JSC::ExecState*, const JSC::Identifier&, const JSC::PropertySlot&);\n"); + push(@headerContent, " static JSC::JSValue nameGetter(JSC::ExecState*, JSC::JSValue, const JSC::Identifier&);\n"); } push(@headerContent, "};\n\n"); @@ -769,7 +781,7 @@ sub GenerateHeader if (!$hasParent || $dataNode->extendedAttributes->{"GenerateToJS"} || $dataNode->extendedAttributes->{"CustomToJS"}) { if ($podType) { - push(@headerContent, "JSC::JSValue toJS(JSC::ExecState*, JSDOMGlobalObject*, JSSVGPODTypeWrapper<$podType>*, SVGElement* context);\n"); + push(@headerContent, "JSC::JSValue toJS(JSC::ExecState*, JSDOMGlobalObject*, JSSVGPODTypeWrapper<$podType>*, SVGElement*);\n"); } elsif (IsSVGTypeNeedingContextParameter($implClassName)) { push(@headerContent, "JSC::JSValue toJS(JSC::ExecState*, JSDOMGlobalObject*, $implType*, SVGElement* context);\n"); } else { @@ -818,7 +830,7 @@ sub GenerateHeader push(@headerContent, " static PassRefPtr<JSC::Structure> createStructure(JSC::JSValue prototype)\n" . " {\n" . - " return JSC::Structure::create(prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags));\n" . + " return JSC::Structure::create(prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), AnonymousSlotCount);\n" . " }\n"); if ($dataNode->extendedAttributes->{"DelegatingPrototypePutFunction"}) { push(@headerContent, " virtual void put(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::JSValue, JSC::PutPropertySlot&);\n"); @@ -848,20 +860,20 @@ sub GenerateHeader } } - if ($numAttributes > 0 || $dataNode->extendedAttributes->{"GenerateConstructor"}) { + if ($numAttributes > 0 || !($dataNode->extendedAttributes->{"OmitConstructor"} || $dataNode->extendedAttributes->{"CustomConstructor"})) { push(@headerContent,"// Attributes\n\n"); foreach my $attribute (@{$dataNode->attributes}) { my $getter = "js" . $interfaceName . $codeGenerator->WK_ucfirst($attribute->signature->name) . ($attribute->signature->type =~ /Constructor$/ ? "Constructor" : ""); - push(@headerContent, "JSC::JSValue ${getter}(JSC::ExecState*, const JSC::Identifier&, const JSC::PropertySlot&);\n"); + push(@headerContent, "JSC::JSValue ${getter}(JSC::ExecState*, JSC::JSValue, const JSC::Identifier&);\n"); unless ($attribute->type =~ /readonly/) { my $setter = "setJS" . $interfaceName . $codeGenerator->WK_ucfirst($attribute->signature->name) . ($attribute->signature->type =~ /Constructor$/ ? "Constructor" : ""); push(@headerContent, "void ${setter}(JSC::ExecState*, JSC::JSObject*, JSC::JSValue);\n"); } } - if ($dataNode->extendedAttributes->{"GenerateConstructor"}) { + if (!($dataNode->extendedAttributes->{"OmitConstructor"} || $dataNode->extendedAttributes->{"CustomConstructor"})) { my $getter = "js" . $interfaceName . "Constructor"; - push(@headerContent, "JSC::JSValue ${getter}(JSC::ExecState*, const JSC::Identifier&, const JSC::PropertySlot&);\n"); + push(@headerContent, "JSC::JSValue ${getter}(JSC::ExecState*, JSC::JSValue, const JSC::Identifier&);\n"); } } @@ -869,7 +881,7 @@ sub GenerateHeader push(@headerContent,"// Constants\n\n"); foreach my $constant (@{$dataNode->constants}) { my $getter = "js" . $interfaceName . $codeGenerator->WK_ucfirst($constant->name); - push(@headerContent, "JSC::JSValue ${getter}(JSC::ExecState*, const JSC::Identifier&, const JSC::PropertySlot&);\n"); + push(@headerContent, "JSC::JSValue ${getter}(JSC::ExecState*, JSC::JSValue, const JSC::Identifier&);\n"); } } @@ -928,7 +940,7 @@ sub GenerateImplementation # - Add all attributes in a hashtable definition my $numAttributes = @{$dataNode->attributes}; - $numAttributes++ if $dataNode->extendedAttributes->{"GenerateConstructor"}; + $numAttributes++ if (!($dataNode->extendedAttributes->{"OmitConstructor"} || $dataNode->extendedAttributes->{"CustomConstructor"})); if ($numAttributes > 0) { my $hashSize = $numAttributes; @@ -969,7 +981,7 @@ sub GenerateImplementation } } - if ($dataNode->extendedAttributes->{"GenerateConstructor"}) { + if (!($dataNode->extendedAttributes->{"OmitConstructor"} || $dataNode->extendedAttributes->{"CustomConstructor"})) { push(@hashKeys, "constructor"); my $getter = "js" . $interfaceName . "Constructor"; push(@hashValue1, $getter); @@ -987,7 +999,7 @@ sub GenerateImplementation my $numFunctions = @{$dataNode->functions}; # - Add all constants - if ($dataNode->extendedAttributes->{"GenerateConstructor"}) { + if (!($dataNode->extendedAttributes->{"OmitConstructor"} || $dataNode->extendedAttributes->{"CustomConstructor"})) { $hashSize = $numConstants; $hashName = $className . "ConstructorTable"; @@ -1159,9 +1171,6 @@ sub GenerateImplementation my $podType = $dataNode->extendedAttributes->{"PODType"}; my $implType = $podType ? "JSSVGPODTypeWrapper<$podType> " : $implClassName; - my $needsSVGContext = IsSVGTypeNeedingContextParameter($implClassName); - my $parentNeedsSVGContext = ($needsSVGContext and $parentClassName =~ /SVG/); - # Constructor if ($interfaceName eq "DOMWindow") { AddIncludesForType("JSDOMWindowShell"); @@ -1172,16 +1181,19 @@ sub GenerateImplementation push(@implContent, "${className}::$className(NonNullPassRefPtr<Structure> structure, PassRefPtr<$implType> impl)\n"); push(@implContent, " : $parentClassName(structure, impl)\n"); } else { - my $contextArg = $needsSVGContext ? ", SVGElement* context" : ""; - push(@implContent, "${className}::$className(NonNullPassRefPtr<Structure> structure, JSDOMGlobalObject* globalObject, PassRefPtr<$implType> impl$contextArg)\n"); + push(@implContent, "${className}::$className(NonNullPassRefPtr<Structure> structure, JSDOMGlobalObject* globalObject, PassRefPtr<$implType> impl)\n"); if ($hasParent) { - push(@implContent, " : $parentClassName(structure, globalObject, impl" . ($parentNeedsSVGContext ? ", context" : "") . ")\n"); + push(@implContent, " : $parentClassName(structure, globalObject, impl)\n"); } else { - push(@implContent, " : $parentClassName(structure, globalObject" . ($needsSVGContext ? ", context" : "") . ")\n"); + push(@implContent, " : $parentClassName(structure, globalObject)\n"); push(@implContent, " , m_impl(impl)\n"); } } push(@implContent, "{\n"); + if ($numCachedAttributes > 0) { + push(@implContent, " for (unsigned i = Base::AnonymousSlotCount; i < AnonymousSlotCount; i++)\n"); + push(@implContent, " putAnonymousValue(i, JSValue());\n"); + } push(@implContent, "}\n\n"); # Destructor @@ -1191,41 +1203,27 @@ sub GenerateImplementation if ($eventTarget) { $implIncludes{"RegisteredEventListener.h"} = 1; - push(@implContent, " impl()->invalidateEventListeners();\n"); + push(@implContent, " impl()->invalidateJSEventListeners(this);\n"); } if (!$dataNode->extendedAttributes->{"ExtendsDOMGlobalObject"}) { if ($interfaceName eq "Node") { push(@implContent, " forgetDOMNode(this, impl(), impl()->document());\n"); } else { - if ($podType) { - my $animatedType = $implClassName; - $animatedType =~ s/SVG/SVGAnimated/; - - # Special case for JSSVGNumber - if ($codeGenerator->IsSVGAnimatedType($animatedType) and $podType ne "float") { - push(@implContent, " JSSVGDynamicPODTypeWrapperCache<$podType, $animatedType>::forgetWrapper(m_impl.get());\n"); - } - } push(@implContent, " forgetDOMObject(this, impl());\n"); } + + push(@implContent, " JSSVGContextCache::forgetWrapper(this);\n") if IsSVGTypeNeedingContextParameter($implClassName); } push(@implContent, "}\n\n"); } - # Document needs a special destructor because it's a special case for caching. It needs - # its own special handling rather than relying on the caching that Node normally does. - if ($interfaceName eq "Document") { - push(@implContent, "${className}::~$className()\n"); - push(@implContent, "{\n forgetDOMObject(this, static_cast<${implClassName}*>(impl()));\n}\n\n"); - } - if ($needsMarkChildren && !$dataNode->extendedAttributes->{"CustomMarkFunction"}) { push(@implContent, "void ${className}::markChildren(MarkStack& markStack)\n"); push(@implContent, "{\n"); push(@implContent, " Base::markChildren(markStack);\n"); - push(@implContent, " impl()->markEventListeners(markStack);\n"); + push(@implContent, " impl()->markJSEventListeners(markStack);\n"); push(@implContent, "}\n\n"); } @@ -1241,7 +1239,8 @@ sub GenerateImplementation } my $hasGetter = $numAttributes > 0 - || $dataNode->extendedAttributes->{"GenerateConstructor"} + || !($dataNode->extendedAttributes->{"OmitConstructor"} + || $dataNode->extendedAttributes->{"CustomConstructor"}) || $dataNode->extendedAttributes->{"HasIndexGetter"} || $dataNode->extendedAttributes->{"HasCustomIndexGetter"} || $dataNode->extendedAttributes->{"HasNumericIndexGetter"} @@ -1292,9 +1291,9 @@ sub GenerateImplementation push(@implContent, "#if ${conditionalString}\n"); } - push(@implContent, "JSValue ${getFunctionName}(ExecState* exec, const Identifier&, const PropertySlot& slot)\n"); + push(@implContent, "JSValue ${getFunctionName}(ExecState* exec, JSValue slotBase, const Identifier&)\n"); push(@implContent, "{\n"); - push(@implContent, " ${className}* castedThis = static_cast<$className*>(asObject(slot.slotBase()));\n"); + push(@implContent, " ${className}* castedThis = static_cast<$className*>(asObject(slotBase));\n"); my $implClassNameForValueConversion = ""; if (!$podType and ($codeGenerator->IsSVGAnimatedType($implClassName) or $attribute->type !~ /^readonly/)) { @@ -1324,12 +1323,14 @@ sub GenerateImplementation push(@implContent, " UNUSED_PARAM(exec);\n"); push(@implContent, " $implClassName* imp = static_cast<$implClassName*>(castedThis->impl());\n"); push(@implContent, " if (EventListener* listener = imp->$implGetterFunctionName()) {\n"); + push(@implContent, " if (const JSEventListener* jsListener = JSEventListener::cast(listener)) {\n"); if ($implClassName eq "Document" || $implClassName eq "WorkerContext" || $implClassName eq "SharedWorkerContext" || $implClassName eq "DedicatedWorkerContext") { - push(@implContent, " if (JSObject* jsFunction = listener->jsFunction(imp))\n"); + push(@implContent, " if (JSObject* jsFunction = jsListener->jsFunction(imp))\n"); } else { - push(@implContent, " if (JSObject* jsFunction = listener->jsFunction(imp->scriptExecutionContext()))\n"); + push(@implContent, " if (JSObject* jsFunction = jsListener->jsFunction(imp->scriptExecutionContext()))\n"); } - push(@implContent, " return jsFunction;\n"); + push(@implContent, " return jsFunction;\n"); + push(@implContent, " }\n"); push(@implContent, " }\n"); push(@implContent, " return jsNull();\n"); } elsif ($attribute->signature->type =~ /Constructor$/) { @@ -1340,12 +1341,19 @@ sub GenerateImplementation push(@implContent, " return JS" . $constructorType . "::getConstructor(exec, castedThis);\n"); } elsif (!@{$attribute->getterExceptions}) { push(@implContent, " UNUSED_PARAM(exec);\n"); + my $cacheIndex = 0; + if ($attribute->signature->extendedAttributes->{"CachedAttribute"}) { + $cacheIndex = $currentCachedAttribute; + $currentCachedAttribute++; + push(@implContent, " if (JSValue cachedValue = castedThis->getAnonymousValue(" . $className . "::" . $attribute->signature->name . "Slot))\n"); + push(@implContent, " return cachedValue;\n"); + } if ($podType) { push(@implContent, " $podType imp(*castedThis->impl());\n"); if ($podType eq "float") { # Special case for JSSVGNumber - push(@implContent, " return " . NativeToJSValue($attribute->signature, 0, $implClassName, "", "imp", "castedThis") . ";\n"); + push(@implContent, " JSValue result = " . NativeToJSValue($attribute->signature, 0, $implClassName, "", "imp", "castedThis") . ";\n"); } else { - push(@implContent, " return " . NativeToJSValue($attribute->signature, 0, $implClassName, "", "imp.$implGetterFunctionName()", "castedThis") . ";\n"); + push(@implContent, " JSValue result = " . NativeToJSValue($attribute->signature, 0, $implClassName, "", "imp.$implGetterFunctionName()", "castedThis") . ";\n"); } } else { push(@implContent, " $implClassName* imp = static_cast<$implClassName*>(castedThis->impl());\n"); @@ -1364,11 +1372,15 @@ sub GenerateImplementation my $jsType = NativeToJSValue($attribute->signature, 0, $implClassName, $implClassNameForValueConversion, $value, "castedThis"); if ($codeGenerator->IsSVGAnimatedType($type)) { push(@implContent, " RefPtr<$type> obj = $jsType;\n"); - push(@implContent, " return toJS(exec, castedThis->globalObject(), obj.get(), imp);\n"); + push(@implContent, " JSValue result = toJS(exec, castedThis->globalObject(), obj.get(), imp);\n"); } else { - push(@implContent, " return $jsType;\n"); + push(@implContent, " JSValue result = $jsType;\n"); } } + + push(@implContent, " castedThis->putAnonymousValue(" . $className . "::" . $attribute->signature->name . "Slot, result);\n") if ($attribute->signature->extendedAttributes->{"CachedAttribute"}); + push(@implContent, " return result;\n"); + } else { push(@implContent, " ExceptionCode ec = 0;\n"); if ($podType) { @@ -1392,20 +1404,13 @@ sub GenerateImplementation push(@implContent, "\n"); } - if ($dataNode->extendedAttributes->{"GenerateConstructor"}) { + if (!($dataNode->extendedAttributes->{"OmitConstructor"} || $dataNode->extendedAttributes->{"CustomConstructor"})) { my $constructorFunctionName = "js" . $interfaceName . "Constructor"; - push(@implContent, "JSValue ${constructorFunctionName}(ExecState* exec, const Identifier&, const PropertySlot& slot)\n"); + push(@implContent, "JSValue ${constructorFunctionName}(ExecState* exec, JSValue slotBase, const Identifier&)\n"); push(@implContent, "{\n"); - if (IsSVGTypeNeedingContextParameter($interfaceName)) { - # FIXME: SVG bindings with a context pointer have no space to store a globalObject - # so we use deprecatedGlobalObjectForPrototype instead. - push(@implContent, " UNUSED_PARAM(slot);\n"); - push(@implContent, " return ${className}::getConstructor(exec, deprecatedGlobalObjectForPrototype(exec));\n"); - } else { - push(@implContent, " ${className}* domObject = static_cast<$className*>(asObject(slot.slotBase()));\n"); - push(@implContent, " return ${className}::getConstructor(exec, domObject->globalObject());\n"); - } + push(@implContent, " ${className}* domObject = static_cast<$className*>(asObject(slotBase));\n"); + push(@implContent, " return ${className}::getConstructor(exec, domObject->globalObject());\n"); push(@implContent, "}\n"); } } @@ -1479,36 +1484,30 @@ sub GenerateImplementation $implIncludes{"JSEventListener.h"} = 1; push(@implContent, " UNUSED_PARAM(exec);\n"); push(@implContent, " $implClassName* imp = static_cast<$implClassName*>(static_cast<$className*>(thisObject)->impl());\n"); - if ($dataNode->extendedAttributes->{"ExtendsDOMGlobalObject"}) { - push(@implContent, " JSDOMGlobalObject* globalObject = static_cast<$className*>(thisObject);\n"); - } else { - $implIncludes{"Frame.h"} = 1; - $implIncludes{"JSDOMGlobalObject.h"} = 1; - push(@implContent, " JSDOMGlobalObject* globalObject = toJSDOMGlobalObject(imp->scriptExecutionContext(), exec);\n"); - push(@implContent, " if (!globalObject)\n"); - push(@implContent, " return;\n"); - } - push(@implContent, " imp->set$implSetterFunctionName(globalObject->createJSAttributeEventListener(value));\n"); + push(@implContent, " imp->set$implSetterFunctionName(createJSAttributeEventListener(exec, value, thisObject));\n"); } elsif ($attribute->signature->type =~ /Constructor$/) { my $constructorType = $attribute->signature->type; $constructorType =~ s/Constructor$//; - $implIncludes{"JS" . $constructorType . ".h"} = 1; + if ($constructorType ne "DOMObject") { + $implIncludes{"JS" . $constructorType . ".h"} = 1; + } push(@implContent, " // Shadowing a built-in constructor\n"); push(@implContent, " static_cast<$className*>(thisObject)->putDirect(Identifier(exec, \"$name\"), value);\n"); } elsif ($attribute->signature->extendedAttributes->{"Replaceable"}) { push(@implContent, " // Shadowing a built-in object\n"); push(@implContent, " static_cast<$className*>(thisObject)->putDirect(Identifier(exec, \"$name\"), value);\n"); } else { + push(@implContent, " $className* castedThisObj = static_cast<$className*>(thisObject);\n"); + push(@implContent, " $implType* imp = static_cast<$implType*>(castedThisObj->impl());\n"); if ($podType) { - push(@implContent, " $podType imp(*static_cast<$className*>(thisObject)->impl());\n"); + push(@implContent, " $podType podImp(*imp);\n"); if ($podType eq "float") { # Special case for JSSVGNumber - push(@implContent, " imp = " . JSValueToNative($attribute->signature, "value") . ";\n"); + push(@implContent, " podImp = " . JSValueToNative($attribute->signature, "value") . ";\n"); } else { - push(@implContent, " imp.set$implSetterFunctionName(" . JSValueToNative($attribute->signature, "value") . ");\n"); + push(@implContent, " podImp.set$implSetterFunctionName(" . JSValueToNative($attribute->signature, "value") . ");\n"); } - push(@implContent, " static_cast<$className*>(thisObject)->impl()->commitChange(imp, static_cast<$className*>(thisObject)->context());\n"); + push(@implContent, " imp->commitChange(podImp, castedThisObj);\n"); } else { - push(@implContent, " $implClassName* imp = static_cast<$implClassName*>(static_cast<$className*>(thisObject)->impl());\n"); my $nativeValue = JSValueToNative($attribute->signature, "value"); push(@implContent, " ExceptionCode ec = 0;\n") if @{$attribute->setterExceptions}; my $reflect = $attribute->signature->extendedAttributes->{"Reflect"}; @@ -1524,10 +1523,8 @@ sub GenerateImplementation push(@implContent, ", ec") if @{$attribute->setterExceptions}; push(@implContent, ");\n"); push(@implContent, " setDOMException(exec, ec);\n") if @{$attribute->setterExceptions}; - if (IsSVGTypeNeedingContextParameter($implClassName)) { - push(@implContent, " if (static_cast<$className*>(thisObject)->context())\n"); - push(@implContent, " static_cast<$className*>(thisObject)->context()->svgAttributeChanged(static_cast<$className*>(thisObject)->impl()->associatedAttributeName());\n"); + push(@implContent, " JSSVGContextCache::propagateSVGDOMChange(castedThisObj, imp->associatedAttributeName());\n"); } } } @@ -1540,17 +1537,17 @@ sub GenerateImplementation } if (($dataNode->extendedAttributes->{"HasIndexGetter"} || $dataNode->extendedAttributes->{"HasCustomIndexGetter"} || $dataNode->extendedAttributes->{"HasNumericIndexGetter"}) && !$dataNode->extendedAttributes->{"CustomGetPropertyNames"}) { - push(@implContent, "void ${className}::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames)\n"); + push(@implContent, "void ${className}::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode)\n"); push(@implContent, "{\n"); if ($dataNode->extendedAttributes->{"HasIndexGetter"} || $dataNode->extendedAttributes->{"HasCustomIndexGetter"} || $dataNode->extendedAttributes->{"HasNumericIndexGetter"}) { push(@implContent, " for (unsigned i = 0; i < static_cast<${implClassName}*>(impl())->length(); ++i)\n"); push(@implContent, " propertyNames.add(Identifier::from(exec, i));\n"); } - push(@implContent, " Base::getOwnPropertyNames(exec, propertyNames);\n"); + push(@implContent, " Base::getOwnPropertyNames(exec, propertyNames, mode);\n"); push(@implContent, "}\n\n"); } - if ($dataNode->extendedAttributes->{"GenerateConstructor"}) { + if (!($dataNode->extendedAttributes->{"OmitConstructor"} || $dataNode->extendedAttributes->{"CustomConstructor"})) { push(@implContent, "JSValue ${className}::getConstructor(ExecState* exec, JSGlobalObject* globalObject)\n{\n"); push(@implContent, " return getDOMConstructor<${className}Constructor>(exec, static_cast<JSDOMGlobalObject*>(globalObject));\n"); push(@implContent, "}\n\n"); @@ -1590,15 +1587,31 @@ sub GenerateImplementation push(@implContent, " return jsUndefined();\n"); } + # Special case for JSSVGLengthList / JSSVGTransformList / JSSVGPointList / JSSVGNumberList + # Instead of having JSSVG*Custom.cpp implementations for the SVGList interface for all of these + # classes, we directly forward the calls to JSSVGPODListCustom, which centralizes the otherwise + # duplicated code for the JSSVG*List classes mentioned above. + my $svgPODListType; + if ($implClassName =~ /SVG.*List/) { + $svgPODListType = $implClassName; + $svgPODListType =~ s/List$//; + $svgPODListType = "" unless $codeGenerator->IsPodType($svgPODListType); + + # Ignore additional (non-SVGList) SVGTransformList methods, that are not handled through JSSVGPODListCustom + $svgPODListType = "" if $functionImplementationName =~ /createSVGTransformFromMatrix/; + $svgPODListType = "" if $functionImplementationName =~ /consolidate/; + } + if ($function->signature->extendedAttributes->{"Custom"} || $function->signature->extendedAttributes->{"JSCCustom"}) { push(@implContent, " return castedThisObj->" . $functionImplementationName . "(exec, args);\n"); + } elsif ($svgPODListType) { + $implIncludes{"JS${svgPODListType}.h"} = 1; + $implIncludes{"JSSVGPODListCustom.h"} = 1; + push(@implContent, " return JSSVGPODListCustom::$functionImplementationName<$className, " . GetNativeType($svgPODListType) + . ">(castedThisObj, exec, args, to" . $svgPODListType . ");\n"); } else { - if ($podType) { - push(@implContent, " JSSVGPODTypeWrapper<$podType>* wrapper = castedThisObj->impl();\n"); - push(@implContent, " $podType imp(*wrapper);\n"); - } else { - push(@implContent, " $implClassName* imp = static_cast<$implClassName*>(castedThisObj->impl());\n"); - } + push(@implContent, " $implType* imp = static_cast<$implType*>(castedThisObj->impl());\n"); + push(@implContent, " $podType podImp(*imp);\n") if $podType; my $numParameters = @{$function->parameters}; @@ -1618,7 +1631,7 @@ sub GenerateImplementation } my $paramIndex = 0; - my $functionString = "imp" . ($podType ? "." : "->") . $functionImplementationName . "("; + my $functionString = ($podType ? "podImp." : "imp->") . $functionImplementationName . "("; my $hasOptionalArguments = 0; @@ -1672,7 +1685,12 @@ sub GenerateImplementation } else { $functionString .= $name; } + $paramIndex++; + } + if ($function->signature->extendedAttributes->{"NeedsUserGestureCheck"}) { + $functionString .= ", " if $paramIndex; + $functionString .= "processingUserGesture(exec)"; $paramIndex++; } @@ -1690,7 +1708,7 @@ sub GenerateImplementation my $getter = "js" . $interfaceName . $codeGenerator->WK_ucfirst($constant->name); # FIXME: this casts into int to match our previous behavior which turned 0xFFFFFFFF in -1 for NodeFilter.SHOW_ALL - push(@implContent, "JSValue ${getter}(ExecState* exec, const Identifier&, const PropertySlot&)\n"); + push(@implContent, "JSValue ${getter}(ExecState* exec, JSValue, const Identifier&)\n"); push(@implContent, "{\n"); push(@implContent, " return jsNumber(exec, static_cast<int>(" . $constant->value . "));\n"); push(@implContent, "}\n\n"); @@ -1698,14 +1716,14 @@ sub GenerateImplementation } if ($dataNode->extendedAttributes->{"HasIndexGetter"}) { - push(@implContent, "\nJSValue ${className}::indexGetter(ExecState* exec, const Identifier&, const PropertySlot& slot)\n"); + push(@implContent, "\nJSValue ${className}::indexGetter(ExecState* exec, JSValue slotBase, unsigned index)\n"); push(@implContent, "{\n"); - push(@implContent, " ${className}* thisObj = static_cast<$className*>(asObject(slot.slotBase()));\n"); + push(@implContent, " ${className}* thisObj = static_cast<$className*>(asObject(slotBase));\n"); if (IndexGetterReturnsStrings($implClassName)) { $implIncludes{"KURL.h"} = 1; - push(@implContent, " return jsStringOrNull(exec, thisObj->impl()->item(slot.index()));\n"); + push(@implContent, " return jsStringOrNull(exec, thisObj->impl()->item(index));\n"); } else { - push(@implContent, " return toJS(exec, thisObj->globalObject(), static_cast<$implClassName*>(thisObj->impl())->item(slot.index()));\n"); + push(@implContent, " return toJS(exec, thisObj->globalObject(), static_cast<$implClassName*>(thisObj->impl())->item(index));\n"); } push(@implContent, "}\n"); if ($interfaceName eq "HTMLCollection" or $interfaceName eq "HTMLAllCollection") { @@ -1729,11 +1747,10 @@ sub GenerateImplementation if ($podType) { push(@implContent, "JSC::JSValue toJS(JSC::ExecState* exec, JSDOMGlobalObject* globalObject, JSSVGPODTypeWrapper<$podType>* object, SVGElement* context)\n"); } elsif (IsSVGTypeNeedingContextParameter($implClassName)) { - push(@implContent, "JSC::JSValue toJS(JSC::ExecState* exec, JSDOMGlobalObject* globalObject, $implType* object, SVGElement* context)\n"); + push(@implContent, "JSC::JSValue toJS(JSC::ExecState* exec, JSDOMGlobalObject* globalObject, $implType* object, SVGElement* context)\n"); } else { push(@implContent, "JSC::JSValue toJS(JSC::ExecState* exec, JSDOMGlobalObject* globalObject, $implType* object)\n"); } - push(@implContent, "{\n"); if ($podType) { push(@implContent, " return getDOMObjectWrapper<$className, JSSVGPODTypeWrapper<$podType> >(exec, globalObject, object, context);\n"); @@ -1791,11 +1808,7 @@ sub GenerateImplementationFunctionCall() if ($function->signature->type eq "void") { push(@implContent, $indent . "$functionString;\n"); push(@implContent, $indent . "setDOMException(exec, ec);\n") if @{$function->raisesExceptions}; - - if ($podType) { - push(@implContent, $indent . "wrapper->commitChange(imp, castedThisObj->context());\n"); - } - + push(@implContent, $indent . "imp->commitChange(podImp, castedThisObj);\n") if $podType; push(@implContent, $indent . "return jsUndefined();\n"); } else { push(@implContent, "\n" . $indent . "JSC::JSValue result = " . NativeToJSValue($function->signature, 1, $implClassName, "", $functionString, "castedThisObj") . ";\n"); @@ -1804,7 +1817,7 @@ sub GenerateImplementationFunctionCall() if ($podType and not $function->signature->extendedAttributes->{"Immutable"}) { # Immutable methods do not commit changes back to the instance, thus producing # a new instance rather than mutating existing one. - push(@implContent, $indent . "wrapper->commitChange(imp, castedThisObj->context());\n"); + push(@implContent, $indent . "imp->commitChange(podImp, castedThisObj);\n"); } push(@implContent, $indent . "return result;\n"); @@ -1827,11 +1840,14 @@ sub GetNativeTypeFromSignature my %nativeType = ( "CompareHow" => "Range::CompareHow", "DOMString" => "const UString&", + "DOMObject" => "ScriptValue", "NodeFilter" => "RefPtr<NodeFilter>", + "SVGAngle" => "SVGAngle", "SVGLength" => "SVGLength", - "SVGMatrix" => "TransformationMatrix", + "SVGMatrix" => "AffineTransform", "SVGNumber" => "float", "SVGPaintType" => "SVGPaint::SVGPaintType", + "SVGPreserveAspectRatio" => "SVGPreserveAspectRatio", "SVGPoint" => "FloatPoint", "SVGRect" => "FloatRect", "SVGTransform" => "SVGTransform", @@ -1841,6 +1857,8 @@ my %nativeType = ( "long" => "int", "unsigned long" => "unsigned", "unsigned short" => "unsigned short", + "long long" => "long long", + "unsigned long long" => "unsigned long long", ); sub GetNativeType @@ -1864,7 +1882,9 @@ sub JSValueToNative return "$value.toNumber(exec)" if $type eq "double"; return "$value.toFloat(exec)" if $type eq "float" or $type eq "SVGNumber"; return "$value.toInt32(exec)" if $type eq "unsigned long" or $type eq "long" or $type eq "unsigned short"; + return "static_cast<$type>($value.toInteger(exec))" if $type eq "long long" or $type eq "unsigned long long"; + return "valueToDate(exec, $value)" if $type eq "Date"; return "static_cast<Range::CompareHow>($value.toInt32(exec))" if $type eq "CompareHow"; return "static_cast<SVGPaint::SVGPaintType>($value.toInt32(exec))" if $type eq "SVGPaintType"; @@ -1874,7 +1894,11 @@ sub JSValueToNative return "$value.toString(exec)"; } - if ($type eq "SerializedScriptValue") { + if ($type eq "DOMObject") { + return "$value"; + } + + if ($type eq "SerializedScriptValue" or $type eq "any") { $implIncludes{"SerializedScriptValue.h"} = 1; return "SerializedScriptValue::create(exec, $value)"; } @@ -1902,7 +1926,11 @@ sub NativeToJSValue my $type = $codeGenerator->StripModule($signature->type); return "jsBoolean($value)" if $type eq "boolean"; - + + # Need to check Date type before IsPrimitiveType(). + if ($type eq "Date") { + return "jsDateOrNull(exec, $value)"; + } if ($codeGenerator->IsPrimitiveType($type) or $type eq "SVGPaintType" or $type eq "DOMTimeStamp") { $implIncludes{"<runtime/JSNumberCell.h>"} = 1; return "jsNumber(exec, $value)"; @@ -1922,9 +1950,7 @@ sub NativeToJSValue return "jsString(exec, $value)"; } - # Some SVG bindings don't have space to store a globalObject pointer, for those, we use the deprecatedGlobalObjectForPrototype hack for now. - my $globalObject = IsSVGTypeNeedingContextParameter($implClassName) ? "deprecatedGlobalObjectForPrototype(exec)" : "$thisValue->globalObject()"; - + my $globalObject = "$thisValue->globalObject()"; if ($codeGenerator->IsPodType($type)) { $implIncludes{"JS$type.h"} = 1; @@ -1942,25 +1968,16 @@ sub NativeToJSValue and $codeGenerator->IsPodTypeWithWriteableProperties($type) and not defined $signature->extendedAttributes->{"Immutable"}) { if ($codeGenerator->IsPodType($implClassName)) { - return "toJS(exec, $globalObject, JSSVGStaticPODTypeWrapperWithPODTypeParent<$nativeType, $implClassName>::create($value, $thisValue->impl()).get(), $thisValue->context())"; + return "toJS(exec, $globalObject, JSSVGStaticPODTypeWrapperWithPODTypeParent<$nativeType, $implClassName>::create($value, $thisValue->impl()).get(), JSSVGContextCache::svgContextForDOMObject(castedThis))"; } else { return "toJS(exec, $globalObject, JSSVGStaticPODTypeWrapperWithParent<$nativeType, $implClassName>::create(imp, &${implClassName}::$getter, &${implClassName}::$setter).get(), imp)"; } } if ($implClassNameForValueConversion eq "") { - # SVGZoomEvent has no context() pointer, and is also not an SVGElement. - # This is not a problem, because SVGZoomEvent has no read/write properties. - return "toJS(exec, $globalObject, JSSVGStaticPODTypeWrapper<$nativeType>::create($value).get(), 0)" if $implClassName eq "SVGZoomEvent"; - - if (IsSVGTypeNeedingContextParameter($implClassName)) { - return "toJS(exec, $globalObject, JSSVGStaticPODTypeWrapper<$nativeType>::create($value).get(), castedThisObj->context())" if $inFunctionCall; - return "toJS(exec, $globalObject, JSSVGStaticPODTypeWrapper<$nativeType>::create($value).get(), $thisValue->context())"; - } else { - return "toJS(exec, $globalObject, JSSVGStaticPODTypeWrapper<$nativeType>::create($value).get(), imp)"; - } - } else { # These classes, always have a m_context pointer! - return "toJS(exec, $globalObject, JSSVGDynamicPODTypeWrapperCache<$nativeType, $implClassNameForValueConversion>::lookupOrCreateWrapper(imp, &${implClassNameForValueConversion}::$getter, &${implClassNameForValueConversion}::$setter).get(), $thisValue->context())"; + return "toJS(exec, $globalObject, JSSVGStaticPODTypeWrapper<$nativeType>::create($value).get(), 0 /* no context on purpose */)"; + } else { + return "toJS(exec, $globalObject, JSSVGDynamicPODTypeWrapperCache<$nativeType, $implClassNameForValueConversion>::lookupOrCreateWrapper(imp, &${implClassNameForValueConversion}::$getter, &${implClassNameForValueConversion}::$setter).get(), JSSVGContextCache::svgContextForDOMObject(castedThis));" } } @@ -1980,15 +1997,19 @@ sub NativeToJSValue } if ($type eq "DOMObject") { - $implIncludes{"JSCanvasRenderingContext2D.h"} = 1; + if ($implClassName eq "Document") { + $implIncludes{"JSCanvasRenderingContext2D.h"} = 1; + } else { + return "$value.jsValue();"; + } } elsif ($type =~ /SVGPathSeg/) { $implIncludes{"JS$type.h"} = 1; $joinedName = $type; $joinedName =~ s/Abs|Rel//; $implIncludes{"$joinedName.h"} = 1; - } elsif ($type eq "SerializedScriptValue") { - $implIncludes{"$type.h"} = 1; - return "$value->deserialize(exec)"; + } elsif ($type eq "SerializedScriptValue" or $type eq "any") { + $implIncludes{"SerializedScriptValue.h"} = 1; + return "$value ? $value->deserialize(exec, castedThis->globalObject()) : jsNull()"; } else { # Default, include header with same name. $implIncludes{"JS$type.h"} = 1; @@ -1998,7 +2019,7 @@ sub NativeToJSValue return $value if $codeGenerator->IsSVGAnimatedType($type); if (IsSVGTypeNeedingContextParameter($type)) { - my $contextPtr = IsSVGTypeNeedingContextParameter($implClassName) ? "$thisValue->context()" : "imp"; + my $contextPtr = IsSVGTypeNeedingContextParameter($implClassName) ? "JSSVGContextCache::svgContextForDOMObject(castedThis)" : "imp"; return "toJS(exec, $globalObject, WTF::getPtr($value), $contextPtr)"; } @@ -2118,6 +2139,7 @@ tableSizeLoop: $i = 0; foreach my $key (@{$keys}) { my $conditional; + my $targetType; if ($conditionals) { $conditional = $conditionals->{$key}; @@ -2126,7 +2148,13 @@ tableSizeLoop: my $conditionalString = "ENABLE(" . join(") && ENABLE(", split(/&/, $conditional)) . ")"; push(@implContent, "#if ${conditionalString}\n"); } - push(@implContent, " { \"$key\", @$specials[$i], (intptr_t)@$value1[$i], (intptr_t)@$value2[$i] },\n"); + + if ("@$specials[$i]" =~ m/Function/) { + $targetType = "static_cast<NativeFunction>"; + } else { + $targetType = "static_cast<PropertySlot::GetValueFunc>"; + } + push(@implContent, " { \"$key\", @$specials[$i], (intptr_t)" . $targetType . "(@$value1[$i]), (intptr_t)@$value2[$i] },\n"); if ($conditional) { push(@implContent, "#endif\n"); } @@ -2241,12 +2269,23 @@ sub WriteData } print $HEADER @headerContent; + + @includes = (); + foreach my $include (keys %headerTrailingIncludes) { + $include = "\"$include\"" unless $include =~ /^["<]/; # " + push @includes, $include; + } + foreach my $include (sort @includes) { + print $HEADER "#include $include\n"; + } + close($HEADER); undef($HEADER); @headerContentHeader = (); @headerContent = (); %headerIncludes = (); + %headerTrailingIncludes = (); } if (defined($DEPS)) { @@ -2283,7 +2322,7 @@ public: static PassRefPtr<Structure> createStructure(JSValue proto) { - return Structure::create(proto, TypeInfo(ObjectType, StructureFlags)); + return Structure::create(proto, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount); } protected: diff --git a/src/3rdparty/webkit/WebCore/bindings/scripts/CodeGeneratorObjC.pm b/src/3rdparty/webkit/WebCore/bindings/scripts/CodeGeneratorObjC.pm index 91248c5..3c5fe45 100644 --- a/src/3rdparty/webkit/WebCore/bindings/scripts/CodeGeneratorObjC.pm +++ b/src/3rdparty/webkit/WebCore/bindings/scripts/CodeGeneratorObjC.pm @@ -17,7 +17,7 @@ # Library General Public License for more details. # # You should have received a copy of the GNU Library General Public License -# aint with this library; see the file COPYING.LIB. If not, write to +# along with this library; see the file COPYING.LIB. If not, write to # the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, # Boston, MA 02110-1301, USA. # @@ -66,7 +66,7 @@ my %nativeObjCTypeHash = ("URL" => 1, "Color" => 1); my %baseTypeHash = ("Object" => 1, "Node" => 1, "NodeList" => 1, "NamedNodeMap" => 1, "DOMImplementation" => 1, "Event" => 1, "CSSRule" => 1, "CSSValue" => 1, "StyleSheet" => 1, "MediaList" => 1, "Counter" => 1, "Rect" => 1, "RGBColor" => 1, "XPathExpression" => 1, "XPathResult" => 1, - "NodeIterator" => 1, "TreeWalker" => 1, "AbstractView" => 1, + "NodeIterator" => 1, "TreeWalker" => 1, "AbstractView" => 1, "Blob" => 1, "SVGAngle" => 1, "SVGAnimatedAngle" => 1, "SVGAnimatedBoolean" => 1, "SVGAnimatedEnumeration" => 1, "SVGAnimatedInteger" => 1, "SVGAnimatedLength" => 1, "SVGAnimatedLengthList" => 1, "SVGAnimatedNumber" => 1, "SVGAnimatedNumberList" => 1, "SVGAnimatedPoints" => 1, @@ -222,7 +222,13 @@ sub ReadPublicInterfaces %publicInterfaces = (); my $fileName = "WebCore/bindings/objc/PublicDOMInterfaces.h"; - open FILE, "-|", "/usr/bin/gcc", "-E", "-P", "-x", "objective-c", + my $gccLocation = ""; + if (($Config::Config{'osname'}) =~ /solaris/i) { + $gccLocation = "/usr/sfw/bin/gcc"; + } else { + $gccLocation = "/usr/bin/gcc"; + } + open FILE, "-|", $gccLocation, "-E", "-P", "-x", "objective-c", (map { "-D$_" } split(/ +/, $defines)), "-DOBJC_CODE_GENERATION", $fileName or die "Could not open $fileName"; my @documentContent = <FILE>; close FILE; @@ -316,6 +322,7 @@ sub GetClassName return "BOOL" if $name eq "boolean"; return "unsigned" if $name eq "unsigned long"; return "int" if $name eq "long"; + return "NSTimeInterval" if $name eq "Date"; return "DOMAbstractView" if $name eq "DOMWindow"; return $name if $codeGenerator->IsPrimitiveType($name) or $name eq "DOMImplementation" or $name eq "DOMTimeStamp"; @@ -577,7 +584,7 @@ sub AddIncludesForType } if ($type eq "SVGMatrix") { - $implIncludes{"TransformationMatrix.h"} = 1; + $implIncludes{"AffineTransform.h"} = 1; $implIncludes{"DOMSVGMatrixInternal.h"} = 1; $implIncludes{"SVGException.h"} = 1; return; @@ -1040,6 +1047,7 @@ sub GenerateImplementation $implIncludes{$classHeaderName . "Internal.h"} = 1; # FIXME: These includes are only needed when the class is a subclass of one of these polymorphic classes. + $implIncludes{"DOMBlobInternal.h"} = 1; $implIncludes{"DOMCSSRuleInternal.h"} = 1; $implIncludes{"DOMCSSValueInternal.h"} = 1; $implIncludes{"DOMEventInternal.h"} = 1; @@ -1221,7 +1229,7 @@ sub GenerateImplementation $getterContentTail .= ")"; } elsif ($attribute->signature->extendedAttributes->{"ConvertFromString"}) { $getterContentTail .= ".toInt()"; - } elsif ($codeGenerator->IsPodType($idlType)) { + } elsif ($codeGenerator->IsPodType($idlType) or $idlType eq "Date") { $getterContentHead = "kit($getterContentHead"; $getterContentTail .= ")"; } elsif (IsProtocolType($idlType) and $idlType ne "EventTarget") { @@ -1292,6 +1300,10 @@ sub GenerateImplementation push(@implContent, " ASSERT($argName);\n\n"); } + if ($idlType eq "Date") { + $arg = "core(" . $arg . ")"; + } + if ($podType) { # Special case for DOMSVGNumber if ($podType eq "float") { @@ -1420,8 +1432,8 @@ sub GenerateImplementation } # FIXME! We need [Custom] support for ObjC, to move these hacks into DOMSVGLength/MatrixCustom.mm - my $svgMatrixRotateFromVector = ($podType and $podType eq "TransformationMatrix" and $functionName eq "rotateFromVector"); - my $svgMatrixInverse = ($podType and $podType eq "TransformationMatrix" and $functionName eq "inverse"); + my $svgMatrixRotateFromVector = ($podType and $podType eq "AffineTransform" and $functionName eq "rotateFromVector"); + my $svgMatrixInverse = ($podType and $podType eq "AffineTransform" and $functionName eq "inverse"); my $svgLengthConvertToSpecifiedUnits = ($podType and $podType eq "SVGLength" and $functionName eq "convertToSpecifiedUnits"); push(@parameterNames, "ec") if $raisesExceptions and !($svgMatrixRotateFromVector || $svgMatrixInverse); diff --git a/src/3rdparty/webkit/WebCore/bindings/scripts/CodeGeneratorV8.pm b/src/3rdparty/webkit/WebCore/bindings/scripts/CodeGeneratorV8.pm index 95b2aa2..68007e2 100644 --- a/src/3rdparty/webkit/WebCore/bindings/scripts/CodeGeneratorV8.pm +++ b/src/3rdparty/webkit/WebCore/bindings/scripts/CodeGeneratorV8.pm @@ -7,8 +7,6 @@ # Copyright (C) 2007, 2008, 2009 Google Inc. # Copyright (C) 2009 Cameron McCormack <cam@mcc.id.au> # -# This file is part of the KDE project -# # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Library General Public # License as published by the Free Software Foundation; either @@ -20,7 +18,7 @@ # Library General Public License for more details. # # You should have received a copy of the GNU Library General Public License -# aint with this library; see the file COPYING.LIB. If not, write to +# along with this library; see the file COPYING.LIB. If not, write to # the Free Software Foundation, Inc., 59 Temple Place - Suite 330, # Boston, MA 02111-1307, USA. # @@ -86,11 +84,6 @@ sub finish $object->WriteData(); } -sub leftShift($$) { - my ($value, $distance) = @_; - return (($value << $distance) & 0xFFFFFFFF); -} - # Workaround for V8 bindings difference where RGBColor is not a POD type. sub IsPodType { @@ -128,13 +121,6 @@ sub GenerateModule $module = $dataNode->module; } -sub GetLegacyHeaderIncludes -{ - my $legacyParent = shift; - - die "Don't know what headers to include for module $module"; -} - sub AvoidInclusionOfType { my $type = shift; @@ -144,28 +130,21 @@ sub AvoidInclusionOfType return 0; } -sub UsesManualToJSImplementation -{ - my $type = shift; - - return 1 if $type eq "SVGPathSeg"; - return 0; -} - sub AddIncludesForType { my $type = $codeGenerator->StripModule(shift); # When we're finished with the one-file-per-class # reorganization, we won't need these special cases. - if ($codeGenerator->IsPrimitiveType($type) or AvoidInclusionOfType($type)) { - } elsif ($type =~ /SVGPathSeg/) { - $joinedName = $type; - $joinedName =~ s/Abs|Rel//; - $implIncludes{"${joinedName}.h"} = 1; - } else { + if (!$codeGenerator->IsPrimitiveType($type) and !AvoidInclusionOfType($type) and $type ne "Date") { # default, include the same named file - $implIncludes{GetImplementationFileName(${type})} = 1; + $implIncludes{GetV8HeaderName(${type})} = 1; + + if ($type =~ /SVGPathSeg/) { + $joinedName = $type; + $joinedName =~ s/Abs|Rel//; + $implIncludes{"${joinedName}.h"} = 1; + } } # additional includes (things needed to compile the bindings but not the header) @@ -204,25 +183,6 @@ sub AddIncludesForSVGAnimatedType $implIncludes{"SVGAnimatedTemplate.h"} = 1; } -sub AddClassForwardIfNeeded -{ - my $implClassName = shift; - - # SVGAnimatedLength/Number/etc.. are typedefs to SVGAnimtatedTemplate, so don't use class forwards for them! - push(@headerContent, "class $implClassName;\n\n") unless $codeGenerator->IsSVGAnimatedType($implClassName); -} - -sub GetImplementationFileName -{ - my $iface = shift; - return "Event.h" if $iface eq "DOMTimeStamp"; - return "NamedAttrMap.h" if $iface eq "NamedNodeMap"; - return "NameNodeList.h" if $iface eq "NodeList"; - return "XMLHttpRequest.h" if $iface eq "XMLHttpRequest"; - - return "${iface}.h"; -} - # If the node has a [Conditional=XXX] attribute, returns an "ENABLE(XXX)" string for use in an #if. sub GenerateConditionalString { @@ -260,39 +220,109 @@ sub GenerateHeader # Get correct pass/store types respecting PODType flag my $podType = $dataNode->extendedAttributes->{"PODType"}; - my $passType = $podType ? "JSSVGPODTypeWrapper<$podType>*" : "$implClassName*"; push(@headerContent, "#include \"$podType.h\"\n") if $podType and ($podType ne "double" and $podType ne "float" and $podType ne "RGBA32"); push(@headerContent, "#include <v8.h>\n"); push(@headerContent, "#include <wtf/HashMap.h>\n"); push(@headerContent, "#include \"StringHash.h\"\n"); - - push(@headerContent, "\nnamespace WebCore {\n\n"); - push(@headerContent, "class V8ClassIndex;\n"); + push(@headerContent, "#include \"WrapperTypeInfo.h\"\n"); + push(@headerContent, GetHeaderClassInclude($implClassName)); + push(@headerContent, "\nnamespace WebCore {\n"); + if ($podType) { + push(@headerContent, "\ntemplate<typename PODType> class V8SVGPODTypeWrapper;\n"); + } push(@headerContent, "\nclass $className {\n"); + + my $nativeType = GetNativeTypeForConversions($interfaceName); + if ($podType) { + $nativeType = "V8SVGPODTypeWrapper<${nativeType} >"; + } + my $forceNewObjectParameter = IsDOMNodeType($interfaceName) ? ", bool forceNewObject = false" : ""; push(@headerContent, <<END); - public: - static bool HasInstance(v8::Handle<v8::Value> value); - static v8::Persistent<v8::FunctionTemplate> GetRawTemplate(); +public: + static bool HasInstance(v8::Handle<v8::Value> value); + static v8::Persistent<v8::FunctionTemplate> GetRawTemplate(); + static v8::Persistent<v8::FunctionTemplate> GetTemplate(); + static ${nativeType}* toNative(v8::Handle<v8::Object>); + static v8::Handle<v8::Object> wrap(${nativeType}*${forceNewObjectParameter}); + static void derefObject(void*); + static WrapperTypeInfo info; END + if (IsActiveDomType($implClassName)) { + push(@headerContent, " static ActiveDOMObject* toActiveDOMObject(v8::Handle<v8::Object>);\n"); + } if ($implClassName eq "DOMWindow") { - push(@headerContent, <<END); - static v8::Persistent<v8::ObjectTemplate> GetShadowObjectTemplate(); + push(@headerContent, <<END); + static v8::Persistent<v8::ObjectTemplate> GetShadowObjectTemplate(); END } - push(@headerContent, <<END); + my @enabledAtRuntime; + foreach my $function (@{$dataNode->functions}) { + my $name = $function->signature->name; + my $attrExt = $function->signature->extendedAttributes; - private: - static v8::Persistent<v8::FunctionTemplate> GetTemplate(); + if ($attrExt->{"Custom"} || $attrExt->{"V8Custom"}) { + push(@headerContent, <<END); + static v8::Handle<v8::Value> ${name}Callback(const v8::Arguments&); +END + } + + if ($attrExt->{"EnabledAtRuntime"}) { + push(@enabledAtRuntime, $function); + } + } + + if ($dataNode->extendedAttributes->{"CustomConstructor"} || $dataNode->extendedAttributes->{"CanBeConstructed"}) { + push(@headerContent, <<END); + static v8::Handle<v8::Value> constructorCallback(const v8::Arguments& args); +END + } + + foreach my $attribute (@{$dataNode->attributes}) { + my $name = $attribute->signature->name; + my $attrExt = $attribute->signature->extendedAttributes; + if ($attrExt->{"V8CustomGetter"} || $attrExt->{"CustomGetter"} + || $attrExt->{"V8Custom"} || $attrExt->{"Custom"}) { + push(@headerContent, <<END); + static v8::Handle<v8::Value> ${name}AccessorGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info); +END + } + if ($attrExt->{"V8CustomSetter"} || $attrExt->{"CustomSetter"} + || $attrExt->{"V8Custom"} || $attrExt->{"Custom"}) { + push(@headerContent, <<END); + static void ${name}AccessorSetter(v8::Local<v8::String> name, v8::Local<v8::Value> value, const v8::AccessorInfo& info); +END + } + if ($attrExt->{"EnabledAtRuntime"}) { + push(@enabledAtRuntime, $attribute); + } + } + + GenerateHeaderNamedAndIndexedPropertyAccessors($dataNode); + GenerateHeaderCustomCall($dataNode); + GenerateHeaderCustomInternalFieldIndices($dataNode); + + if ($dataNode->extendedAttributes->{"CheckDomainSecurity"}) { + push(@headerContent, <<END); + static bool namedSecurityCheck(v8::Local<v8::Object> host, v8::Local<v8::Value> key, v8::AccessType, v8::Local<v8::Value> data); + static bool indexedSecurityCheck(v8::Local<v8::Object> host, uint32_t index, v8::AccessType, v8::Local<v8::Value> data); +END + } - friend class V8ClassIndex; + push(@headerContent, <<END); }; + v8::Handle<v8::Value> toV8(${nativeType}*${forceNewObjectParameter}); +END + if (IsRefPtrType($implClassName)) { + push(@headerContent, <<END); + v8::Handle<v8::Value> toV8(PassRefPtr<${nativeType} >${forceNewObjectParameter}); END + } push(@headerContent, "}\n\n"); push(@headerContent, "#endif // $className" . "_H\n"); @@ -300,6 +330,151 @@ END push(@headerContent, "#endif // ${conditionalString}\n\n") if $conditionalString; } +sub GetInternalFields +{ + my $dataNode = shift; + my $name = $dataNode->name; + + my @customInternalFields = (); + + # We can't ask whether a parent type has a given extendedAttribute, so special-case Node, AbstractWorker and WorkerContext to include all sub-types. + # FIXME: SVGElementInstance should probably have the EventTarget extended attribute, but doesn't. + if ($dataNode->extendedAttributes->{"EventTarget"} || IsNodeSubType($dataNode) || IsSubType($dataNode, "AbstractWorker") || IsSubType($dataNode, "WorkerContext") + || $name eq "SVGElementInstance") { + push(@customInternalFields, "eventListenerCacheIndex"); + } + + if (IsSubType($dataNode, "Document")) { + push(@customInternalFields, "implementationIndex"); + if ($name eq "HTMLDocument") { + push(@customInternalFields, ("markerIndex", "shadowIndex")); + } + } elsif (IsSubType($dataNode, "StyleSheet") || $name eq "NamedNodeMap") { + push(@customInternalFields, "ownerNodeIndex"); + } elsif ($name eq "MessageChannel") { + push(@customInternalFields, ("port1Index", "port2Index")); + } elsif ($name eq "DOMWindow") { + push(@customInternalFields, ("consoleIndex", "historyIndex", "locationbarIndex", "menubarIndex", "navigatorIndex", + "personalbarIndex", "screenIndex", "scrollbarsIndex", "selectionIndex", "statusbarIndex", "toolbarIndex", "locationIndex", + "domSelectionIndex", "enteredIsolatedWorldIndex")); + } + return @customInternalFields; +} + +sub GetHeaderClassInclude +{ + my $className = shift; + if ($className =~ /SVGPathSeg/) { + $className =~ s/Abs|Rel//; + } + return "" if (AvoidInclusionOfType($className)); + return "#include \"SVGAnimatedTemplate.h\"\n" if ($codeGenerator->IsSVGAnimatedType($className)); + return "#include \"${className}.h\"\n"; +} + +sub GenerateHeaderCustomInternalFieldIndices +{ + my $dataNode = shift; + my @customInternalFields = GetInternalFields($dataNode); + my $customFieldCounter = 0; + foreach my $customInternalField (@customInternalFields) { + push(@headerContent, <<END); + static const int ${customInternalField} = v8DefaultWrapperInternalFieldCount + ${customFieldCounter}; +END + $customFieldCounter++; + } + push(@headerContent, <<END); + static const int internalFieldCount = v8DefaultWrapperInternalFieldCount + ${customFieldCounter}; +END +} + +my %indexerSpecialCases = ( + "Storage" => 1, + "HTMLAppletElement" => 1, + "HTMLDocument" => 1, + "HTMLEmbedElement" => 1, + "HTMLObjectElement" => 1 +); + +sub GenerateHeaderNamedAndIndexedPropertyAccessors +{ + my $dataNode = shift; + my $interfaceName = $dataNode->name; + my $hasCustomIndexedGetter = $dataNode->extendedAttributes->{"HasIndexGetter"} || $dataNode->extendedAttributes->{"CustomGetOwnPropertySlot"}; + my $hasCustomIndexedSetter = $dataNode->extendedAttributes->{"HasCustomIndexSetter"} && !$dataNode->extendedAttributes->{"HasNumericIndexGetter"}; + my $hasCustomNamedGetter = $dataNode->extendedAttributes->{"HasNameGetter"} || $dataNode->extendedAttributes->{"HasOverridingNameGetter"} || $dataNode->extendedAttributes->{"CustomGetOwnPropertySlot"}; + my $hasCustomNamedSetter = $dataNode->extendedAttributes->{"DelegatingPutFunction"}; + my $hasCustomDeleters = $dataNode->extendedAttributes->{"CustomDeleteProperty"}; + my $hasCustomEnumerator = $dataNode->extendedAttributes->{"CustomGetPropertyNames"}; + if ($interfaceName eq "HTMLOptionsCollection") { + $interfaceName = "HTMLCollection"; + $hasCustomIndexedGetter = 1; + $hasCustomNamedGetter = 1; + } + if ($interfaceName eq "DOMWindow") { + $hasCustomDeleterr = 0; + $hasEnumerator = 0; + } + if ($interfaceName eq "HTMLSelectElement" || $interfaceName eq "HTMLAppletElement" || $interfaceName eq "HTMLEmbedElement" || $interfaceName eq "HTMLObjectElement") { + $hasCustomNamedGetter = 1; + } + my $isIndexerSpecialCase = exists $indexerSpecialCases{$interfaceName}; + + if ($hasCustomIndexedGetter || $isIndexerSpecialCase) { + push(@headerContent, <<END); + static v8::Handle<v8::Value> indexedPropertyGetter(uint32_t index, const v8::AccessorInfo& info); +END + } + + if ($isIndexerSpecialCase || $hasCustomIndexedSetter) { + push(@headerContent, <<END); + static v8::Handle<v8::Value> indexedPropertySetter(uint32_t index, v8::Local<v8::Value> value, const v8::AccessorInfo& info); +END + } + if ($hasCustomDeleters) { + push(@headerContent, <<END); + static v8::Handle<v8::Boolean> indexedPropertyDeleter(uint32_t index, const v8::AccessorInfo& info); +END + } + if ($hasCustomNamedGetter) { + push(@headerContent, <<END); + static v8::Handle<v8::Value> namedPropertyGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info); +END + } + if ($hasCustomNamedSetter) { + push(@headerContent, <<END); + static v8::Handle<v8::Value> namedPropertySetter(v8::Local<v8::String> name, v8::Local<v8::Value> value, const v8::AccessorInfo& info); +END + } + if ($hasCustomDeleters || $interfaceName eq "HTMLDocument") { + push(@headerContent, <<END); + static v8::Handle<v8::Boolean> namedPropertyDeleter(v8::Local<v8::String> name, const v8::AccessorInfo& info); +END + } + if ($hasCustomEnumerator) { + push(@headerContent, <<END); + static v8::Handle<v8::Array> namedPropertyEnumerator(const v8::AccessorInfo& info); +END + } +} + +sub GenerateHeaderCustomCall +{ + my $dataNode = shift; + + if ($dataNode->extendedAttributes->{"CustomCall"}) { + push(@headerContent, " static v8::Handle<v8::Value> callAsFunctionCallback(const v8::Arguments&);\n"); + } + if ($dataNode->name eq "Event") { + push(@headerContent, " static v8::Handle<v8::Value> dataTransferAccessorGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info);\n"); + push(@headerContent, " static void valueAccessorSetter(v8::Local<v8::String> name, v8::Local<v8::Value> value, const v8::AccessorInfo& info);\n"); + } + if ($dataNode->name eq "Location") { + push(@headerContent, " static v8::Handle<v8::Value> assignAccessorGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info);\n"); + push(@headerContent, " static v8::Handle<v8::Value> reloadAccessorGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info);\n"); + push(@headerContent, " static v8::Handle<v8::Value> replaceAccessorGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info);\n"); + } +} sub GenerateSetDOMException { @@ -314,66 +489,30 @@ sub GenerateSetDOMException return $result; } -sub IsNodeSubType +sub IsSubType { my $dataNode = shift; - return 1 if ($dataNode->name eq "Node"); + my $parentType = shift; + return 1 if ($dataNode->name eq $parentType); foreach (@allParents) { my $parent = $codeGenerator->StripModule($_); - return 1 if $parent eq "Node"; + return 1 if $parent eq $parentType; } return 0; } -sub GetHiddenDependencyIndex -{ - my $dataNode = shift; - my $attribute = shift; - my $name = $dataNode->name; - return "V8Custom::kNodeEventListenerCacheIndex" if IsNodeSubType($dataNode); - return "V8Custom::kSVGElementInstanceEventListenerCacheIndex" if $name eq "SVGElementInstance"; - return "V8Custom::kAbstractWorkerRequestCacheIndex" if $name eq "AbstractWorker"; - return "V8Custom::kWorkerRequestCacheIndex" if $name eq "Worker"; - return "V8Custom::kDedicatedWorkerContextRequestCacheIndex" if $name eq "DedicatedWorkerContext"; - return "V8Custom::kWorkerContextRequestCacheIndex" if $name eq "WorkerContext"; - return "V8Custom::kWorkerContextRequestCacheIndex" if $name eq "SharedWorkerContext"; - return "V8Custom::kMessagePortRequestCacheIndex" if $name eq "MessagePort"; - return "V8Custom::kWebSocketCacheIndex" if $name eq "WebSocket"; - return "V8Custom::kXMLHttpRequestCacheIndex" if $name eq "XMLHttpRequest"; - return "V8Custom::kXMLHttpRequestCacheIndex" if $name eq "XMLHttpRequestUpload"; - return "V8Custom::kDOMApplicationCacheCacheIndex" if $name eq "DOMApplicationCache"; - return "V8Custom::kNotificationRequestCacheIndex" if $name eq "Notification"; - return "V8Custom::kDOMWindowEventListenerCacheIndex" if $name eq "DOMWindow"; - die "Unexpected name " . $name . " when generating " . $attribute; -} - -sub HolderToNative +sub IsNodeSubType { my $dataNode = shift; - my $implClassName = shift; - my $classIndex = shift; - - if (IsNodeSubType($dataNode)) { - push(@implContentDecls, <<END); - $implClassName* imp = V8DOMWrapper::convertDOMWrapperToNode<$implClassName>(holder); -END - - } else { - push(@implContentDecls, <<END); - $implClassName* imp = V8DOMWrapper::convertToNativeObject<$implClassName>(V8ClassIndex::$classIndex, holder); -END - - } + return IsSubType($dataNode, "Node"); } sub GenerateDomainSafeFunctionGetter { my $function = shift; - my $dataNode = shift; - my $classIndex = shift; my $implClassName = shift; - my $className = "V8" . $dataNode->name; + my $className = "V8" . $implClassName; my $funcName = $function->signature->name; my $signature = "v8::Signature::New(" . $className . "::GetRawTemplate())"; @@ -381,36 +520,26 @@ sub GenerateDomainSafeFunctionGetter $signature = "v8::Local<v8::Signature>()"; } - my $newTemplateString = GenerateNewFunctionTemplate($function, $dataNode, $signature); - - $implIncludes{"V8Proxy.h"} = 1; + my $newTemplateString = GenerateNewFunctionTemplate($function, $implClassName, $signature); push(@implContentDecls, <<END); - static v8::Handle<v8::Value> ${funcName}AttrGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info) { +static v8::Handle<v8::Value> ${funcName}AttrGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info) +{ INC_STATS(\"DOM.$implClassName.$funcName._get\"); - static v8::Persistent<v8::FunctionTemplate> private_template = - v8::Persistent<v8::FunctionTemplate>::New($newTemplateString); - v8::Handle<v8::Object> holder = V8DOMWrapper::lookupDOMWrapper(V8ClassIndex::$classIndex, info.This()); + static v8::Persistent<v8::FunctionTemplate> private_template = v8::Persistent<v8::FunctionTemplate>::New($newTemplateString); + v8::Handle<v8::Object> holder = V8DOMWrapper::lookupDOMWrapper(${className}::GetTemplate(), info.This()); if (holder.IsEmpty()) { - // can only reach here by 'object.__proto__.func', and it should passed - // domain security check already - - return private_template->GetFunction(); + // can only reach here by 'object.__proto__.func', and it should passed + // domain security check already + return private_template->GetFunction(); } -END - - HolderToNative($dataNode, $implClassName, $classIndex); - - push(@implContentDecls, <<END); - if (!V8Proxy::canAccessFrame(imp->frame(), false)) { - static v8::Persistent<v8::FunctionTemplate> shared_template = - v8::Persistent<v8::FunctionTemplate>::New($newTemplateString); - return shared_template->GetFunction(); - - } else { - return private_template->GetFunction(); + ${implClassName}* imp = ${className}::toNative(holder); + if (!V8BindingSecurity::canAccessFrame(V8BindingState::Only(), imp->frame(), false)) { + static v8::Persistent<v8::FunctionTemplate> shared_template = v8::Persistent<v8::FunctionTemplate>::New($newTemplateString); + return shared_template->GetFunction(); } - } + return private_template->GetFunction(); +} END } @@ -418,37 +547,32 @@ END sub GenerateConstructorGetter { my $implClassName = shift; - my $classIndex = shift; push(@implContentDecls, <<END); - static v8::Handle<v8::Value> ${implClassName}ConstructorGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info) { +static v8::Handle<v8::Value> ${implClassName}ConstructorGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info) { INC_STATS(\"DOM.$implClassName.constructors._get\"); v8::Handle<v8::Value> data = info.Data(); - ASSERT(data->IsNumber()); - V8ClassIndex::V8WrapperType type = V8ClassIndex::FromInt(data->Int32Value()); + ASSERT(data->IsExternal() || data->IsNumber()); + WrapperTypeInfo* type = WrapperTypeInfo::unwrap(data); END - if ($classIndex eq "DOMWINDOW") { + if ($implClassName eq "DOMWindow") { push(@implContentDecls, <<END); - DOMWindow* window = V8DOMWrapper::convertToNativeObject<DOMWindow>(V8ClassIndex::DOMWINDOW, info.Holder()); // Get the proxy corresponding to the DOMWindow if possible to // make sure that the constructor function is constructed in the // context of the DOMWindow and not in the context of the caller. - return V8DOMWrapper::getConstructor(type, window); + return V8DOMWrapper::getConstructor(type, V8DOMWindow::toNative(info.Holder())); END - } elsif ($classIndex eq "DEDICATEDWORKERCONTEXT" or $classIndex eq "WORKERCONTEXT" or $classIndex eq "SHAREDWORKERCONTEXT") { - $implIncludes{"WorkerContextExecutionProxy.h"} = 1; + } elsif ($implClassName eq "DedicatedWorkerContext" or $implClassName eq "WorkerContext" or $implClassName eq "SharedWorkerContext") { push(@implContentDecls, <<END); - WorkerContext* workerContext = V8DOMWrapper::convertToNativeObject<WorkerContext>(V8ClassIndex::WORKERCONTEXT, info.Holder()); - return V8DOMWrapper::getConstructor(type, workerContext); + return V8DOMWrapper::getConstructor(type, V8WorkerContext::toNative(info.Holder())); END } else { - push(@implContentDecls, " return v8::Undefined();"); + push(@implContentDecls, " return v8::Handle<v8::Value>();"); } push(@implContentDecls, <<END); - - } +} END } @@ -457,23 +581,20 @@ sub GenerateNormalAttrGetter { my $attribute = shift; my $dataNode = shift; - my $classIndex = shift; my $implClassName = shift; my $interfaceName = shift; my $attrExt = $attribute->signature->extendedAttributes; my $attrName = $attribute->signature->name; - $implIncludes{"V8Proxy.h"} = 1; my $attrType = GetTypeFromSignature($attribute->signature); my $attrIsPodType = IsPodType($attrType); - my $nativeType = GetNativeTypeFromSignature($attribute->signature, 0); + my $nativeType = GetNativeTypeFromSignature($attribute->signature, -1); my $isPodType = IsPodType($implClassName); my $skipContext = 0; - if ($isPodType) { $implClassName = GetNativeType($implClassName); $implIncludes{"V8SVGPODTypeWrapper.h"} = 1; @@ -496,17 +617,18 @@ sub GenerateNormalAttrGetter $attrIsPodType = 0; } - my $getterStringUsesImp = $implClassName ne "double"; + my $getterStringUsesImp = $implClassName ne "float"; # Getter push(@implContentDecls, <<END); - static v8::Handle<v8::Value> ${attrName}AttrGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info) { +static v8::Handle<v8::Value> ${attrName}AttrGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info) +{ INC_STATS(\"DOM.$implClassName.$attrName._get\"); END if ($isPodType) { push(@implContentDecls, <<END); - V8SVGPODTypeWrapper<$implClassName>* imp_wrapper = V8DOMWrapper::convertToNativeObject<V8SVGPODTypeWrapper<$implClassName> >(V8ClassIndex::$classIndex, info.Holder()); + V8SVGPODTypeWrapper<$implClassName>* imp_wrapper = V8SVGPODTypeWrapper<$implClassName>::toNative(info.Holder()); $implClassName imp_instance = *imp_wrapper; END if ($getterStringUsesImp) { @@ -516,30 +638,42 @@ END } } elsif ($attrExt->{"v8OnProto"} || $attrExt->{"V8DisallowShadowing"}) { - if ($classIndex eq "DOMWINDOW") { - push(@implContentDecls, <<END); + if ($interfaceName eq "DOMWindow") { + push(@implContentDecls, <<END); v8::Handle<v8::Object> holder = info.Holder(); END - } else { - # perform lookup first + } else { + # perform lookup first + push(@implContentDecls, <<END); + v8::Handle<v8::Object> holder = V8DOMWrapper::lookupDOMWrapper(V8${interfaceName}::GetTemplate(), info.This()); + if (holder.IsEmpty()) return v8::Handle<v8::Value>(); +END + } push(@implContentDecls, <<END); - v8::Handle<v8::Object> holder = V8DOMWrapper::lookupDOMWrapper(V8ClassIndex::$classIndex, info.This()); - if (holder.IsEmpty()) return v8::Undefined(); + ${implClassName}* imp = V8${implClassName}::toNative(holder); END - } - HolderToNative($dataNode, $implClassName, $classIndex); } else { + my $reflect = $attribute->signature->extendedAttributes->{"Reflect"}; + if ($getterStringUsesImp && $reflect && IsNodeSubType($dataNode) && $codeGenerator->IsStringType($attrType)) { + # Generate super-compact call for regular attribute getter: + my $contentAttributeName = $reflect eq "1" ? $attrName : $reflect; + my $namespace = $codeGenerator->NamespaceForAttributeName($interfaceName, $contentAttributeName); + $implIncludes{"${namespace}.h"} = 1; + push(@implContentDecls, " return getElementStringAttr(info, ${namespace}::${contentAttributeName}Attr);\n"); + push(@implContentDecls, "}\n\n"); + return; + # Skip the rest of the function! + } push(@implContentDecls, <<END); - v8::Handle<v8::Object> holder = info.Holder(); + ${implClassName}* imp = V8${implClassName}::toNative(info.Holder()); END - HolderToNative($dataNode, $implClassName, $classIndex); } # Generate security checks if necessary if ($attribute->signature->extendedAttributes->{"CheckNodeSecurity"}) { - push(@implContentDecls, " if (!V8Proxy::checkNodeSecurity(imp->$attrName())) return v8::Undefined();\n\n"); + push(@implContentDecls, " if (!V8BindingSecurity::checkNodeSecurity(V8BindingState::Only(), imp->$attrName())) return v8::Handle<v8::Value>();\n\n"); } elsif ($attribute->signature->extendedAttributes->{"CheckFrameSecurity"}) { - push(@implContentDecls, " if (!V8Proxy::checkNodeSecurity(imp->contentDocument())) return v8::Undefined();\n\n"); + push(@implContentDecls, " if (!V8BindingSecurity::checkNodeSecurity(V8BindingState::Only(), imp->contentDocument())) return v8::Handle<v8::Value>();\n\n"); } my $useExceptions = 1 if @{$attribute->getterExceptions} and !($isPodType); @@ -553,7 +687,12 @@ END } my $getterFunc = $codeGenerator->WK_lcfirst($attrName); - $getterFunc .= "Animated" if $codeGenerator->IsSVGAnimatedType($attribute->signature->type); + + if ($codeGenerator->IsSVGAnimatedType($attribute->signature->type)) { + # Some SVGFE*Element.idl use 'operator' as attribute name; rewrite as '_operator' to avoid clashes with C/C++ + $getterFunc = "_" . $getterFunc if ($attrName =~ /operator/); + $getterFunc .= "Animated"; + } my $returnType = GetTypeFromSignature($attribute->signature); @@ -579,10 +718,6 @@ END $getterString = "imp_instance"; } - if ($nativeType eq "String") { - $getterString = "toString($getterString)"; - } - my $result; my $wrapper; @@ -619,7 +754,7 @@ END } else { if ($attribute->signature->type eq "EventListener" && $dataNode->name eq "DOMWindow") { push(@implContentDecls, " if (!imp->document())\n"); - push(@implContentDecls, " return v8::Undefined();\n"); + push(@implContentDecls, " return v8::Handle<v8::Value>();\n"); } if ($useExceptions) { @@ -635,60 +770,37 @@ END } if (IsSVGTypeNeedingContextParameter($attrType) && !$skipContext) { - my $resultObject = $result; if ($attrIsPodType) { - $resultObject = "wrapper"; + push(@implContentDecls, GenerateSVGContextAssignment($implClassName, "wrapper.get()", " ")); + } else { + push(@implContentDecls, GenerateSVGContextRetrieval($implClassName, " ")); + # The templating associated with passing withSVGContext()'s return value directly into toV8 can get compilers confused, + # so just manually set the return value to a PassRefPtr of the expected type. + push(@implContentDecls, " PassRefPtr<$attrType> resultAsPassRefPtr = V8Proxy::withSVGContext($result, context);\n"); + $result = "resultAsPassRefPtr"; } - $resultObject = "WTF::getPtr(" . $resultObject . ")"; - push(@implContentDecls, GenerateSVGContextAssignment($implClassName, $resultObject, " ")); } if ($attrIsPodType) { - my $classIndex = uc($attrType); - push(@implContentDecls, " return V8DOMWrapper::convertToV8Object(V8ClassIndex::$classIndex, wrapper.release());\n"); + $implIncludes{"V8${attrType}.h"} = 1; + push(@implContentDecls, " return toV8(wrapper.release().get());\n"); } else { push(@implContentDecls, " " . ReturnNativeToJSValue($attribute->signature, $result, " ").";\n"); } - push(@implContentDecls, " }\n\n"); # end of getter -} - - -sub GenerateReplaceableAttrSetter -{ - my $implClassName = shift; - - $implIncludes{"V8Proxy.h"} = 1; - - push(@implContentDecls, - " static void ${attrName}AttrSetter(v8::Local<v8::String> name," . - " v8::Local<v8::Value> value, const v8::AccessorInfo& info) {\n"); - - push(@implContentDecls, " INC_STATS(\"DOM.$implClassName.$attrName._set\");\n"); - - push(@implContentDecls, " v8::Local<v8::String> ${attrName}_string = v8::String::New(\"${attrName}\");\n"); - push(@implContentDecls, " info.Holder()->Delete(${attrName}_string);\n"); - push(@implContentDecls, " info.This()->Set(${attrName}_string, value);\n"); - push(@implContentDecls, " }\n\n"); + push(@implContentDecls, "}\n\n"); # end of getter } - sub GenerateNormalAttrSetter { my $attribute = shift; my $dataNode = shift; - my $classIndex = shift; my $implClassName = shift; my $interfaceName = shift; my $attrExt = $attribute->signature->extendedAttributes; - $implIncludes{"V8Proxy.h"} = 1; - - push(@implContentDecls, - " static void ${attrName}AttrSetter(v8::Local<v8::String> name," . - " v8::Local<v8::Value> value, const v8::AccessorInfo& info) {\n"); - + push(@implContentDecls, "static void ${attrName}AttrSetter(v8::Local<v8::String> name, v8::Local<v8::Value> value, const v8::AccessorInfo& info)\n{\n"); push(@implContentDecls, " INC_STATS(\"DOM.$implClassName.$attrName._set\");\n"); my $isPodType = IsPodType($implClassName); @@ -696,37 +808,51 @@ sub GenerateNormalAttrSetter if ($isPodType) { $implClassName = GetNativeType($implClassName); $implIncludes{"V8SVGPODTypeWrapper.h"} = 1; - push(@implContentDecls, " V8SVGPODTypeWrapper<$implClassName>* wrapper = V8DOMWrapper::convertToNativeObject<V8SVGPODTypeWrapper<$implClassName> >(V8ClassIndex::$classIndex, info.Holder());\n"); + push(@implContentDecls, " V8SVGPODTypeWrapper<$implClassName>* wrapper = V8SVGPODTypeWrapper<$implClassName>::toNative(info.Holder());\n"); push(@implContentDecls, " $implClassName imp_instance = *wrapper;\n"); push(@implContentDecls, " $implClassName* imp = &imp_instance;\n"); } elsif ($attrExt->{"v8OnProto"}) { - if ($classIndex eq "DOMWINDOW") { + if ($interfaceName eq "DOMWindow") { push(@implContentDecls, <<END); v8::Handle<v8::Object> holder = info.Holder(); END } else { # perform lookup first push(@implContentDecls, <<END); - v8::Handle<v8::Object> holder = V8DOMWrapper::lookupDOMWrapper(V8ClassIndex::$classIndex, info.This()); + v8::Handle<v8::Object> holder = V8DOMWrapper::lookupDOMWrapper(V8${interfaceName}::GetTemplate(), info.This()); if (holder.IsEmpty()) return; END } - HolderToNative($dataNode, $implClassName, $classIndex); + push(@implContentDecls, <<END); + ${implClassName}* imp = V8${implClassName}::toNative(holder); +END } else { + my $attrType = GetTypeFromSignature($attribute->signature); + my $reflect = $attribute->signature->extendedAttributes->{"Reflect"}; + my $reflectURL = $attribute->signature->extendedAttributes->{"ReflectURL"}; + if (($reflect || $reflectURL) && IsNodeSubType($dataNode) && $codeGenerator->IsStringType($attrType)) { + # Generate super-compact call for regular attribute setter: + my $contentAttributeName = ($reflect || $reflectURL) eq "1" ? $attrName : ($reflect || $reflectURL); + my $namespace = $codeGenerator->NamespaceForAttributeName($interfaceName, $contentAttributeName); + $implIncludes{"${namespace}.h"} = 1; + push(@implContentDecls, " setElementStringAttr(info, ${namespace}::${contentAttributeName}Attr, value);\n"); + push(@implContentDecls, "}\n\n"); + return; + # Skip the rest of the function! + } + push(@implContentDecls, <<END); - v8::Handle<v8::Object> holder = info.Holder(); + ${implClassName}* imp = V8${implClassName}::toNative(info.Holder()); END - HolderToNative($dataNode, $implClassName, $classIndex); } my $nativeType = GetNativeTypeFromSignature($attribute->signature, 0); if ($attribute->signature->type eq "EventListener") { if ($dataNode->name eq "DOMWindow") { push(@implContentDecls, " if (!imp->document())\n"); - push(@implContentDecls, " return;\n"); + push(@implContentDecls, " return;\n"); } - push(@implContentDecls, " $nativeType v = V8DOMWrapper::getEventListener(imp, value, true, ListenerFindOrCreate);\n"); } else { push(@implContentDecls, " $nativeType v = " . JSValueToNative($attribute->signature, "value") . ";\n"); } @@ -751,7 +877,7 @@ END push(@implContentDecls, " ExceptionCode ec = 0;\n"); } - if ($implClassName eq "double") { + if ($implClassName eq "float") { push(@implContentDecls, " *imp = $result;\n"); } else { my $implSetterFunctionName = $codeGenerator->WK_ucfirst($attrName); @@ -764,20 +890,10 @@ END push(@implContentDecls, " imp->setAttribute(${namespace}::${contentAttributeName}Attr, $result"); } elsif ($attribute->signature->type eq "EventListener") { $implIncludes{"V8AbstractEventListener.h"} = 1; - $implIncludes{"V8CustomBinding.h"} = 1; - $cacheIndex = GetHiddenDependencyIndex($dataNode, $attrName); - push(@implContentDecls, " $nativeType old = imp->$attrName();\n"); - push(@implContentDecls, " V8AbstractEventListener* oldListener = old ? V8AbstractEventListener::cast(old.get()) : 0;\n"); - push(@implContentDecls, " if (oldListener) {\n"); - push(@implContentDecls, " v8::Local<v8::Object> oldListenerObject = oldListener->getExistingListenerObject();\n"); - push(@implContentDecls, " if (!oldListenerObject.IsEmpty())\n"); - push(@implContentDecls, " removeHiddenDependency(holder, oldListenerObject, $cacheIndex);\n"); - push(@implContentDecls, " }\n"); - push(@implContentDecls, " imp->set$implSetterFunctionName($result);\n"); - push(@implContentDecls, " if ($result)\n"); - push(@implContentDecls, " createHiddenDependency(holder, value, $cacheIndex"); + push(@implContentDecls, " transferHiddenDependency(info.Holder(), imp->$attrName(), value, V8${interfaceName}::eventListenerCacheIndex);\n"); + push(@implContentDecls, " imp->set$implSetterFunctionName(V8DOMWrapper::getEventListener(value, true, ListenerFindOrCreate)"); } else { - push(@implContentDecls, " imp->set$implSetterFunctionName(" . $result); + push(@implContentDecls, " imp->set$implSetterFunctionName($result"); } push(@implContentDecls, ", ec") if $useExceptions; push(@implContentDecls, ");\n"); @@ -804,16 +920,14 @@ END } push(@implContentDecls, " return;\n"); - push(@implContentDecls, " }\n\n"); # end of setter + push(@implContentDecls, "}\n\n"); # end of setter } -sub GenerateNewFunctionTemplate +sub GetFunctionTemplateCallbackName { $function = shift; - $dataNode = shift; - $signature = shift; + $interfaceName = shift; - my $interfaceName = $dataNode->name; my $name = $function->signature->name; if ($function->signature->extendedAttributes->{"Custom"} || @@ -822,48 +936,85 @@ sub GenerateNewFunctionTemplate $function->signature->extendedAttributes->{"V8Custom"}) { die "Custom and V8Custom should be mutually exclusive!" } - my $customFunc = $function->signature->extendedAttributes->{"Custom"} || - $function->signature->extendedAttributes->{"V8Custom"}; - if ($customFunc eq 1) { - $customFunc = $interfaceName . $codeGenerator->WK_ucfirst($name); - } - return "v8::FunctionTemplate::New(V8Custom::v8${customFunc}Callback, v8::Handle<v8::Value>(), $signature)"; + return "V8${interfaceName}::${name}Callback"; } else { - return "v8::FunctionTemplate::New(${interfaceName}Internal::${name}Callback, v8::Handle<v8::Value>(), $signature)"; + return "${interfaceName}Internal::${name}Callback"; + } +} + +sub GenerateNewFunctionTemplate +{ + $function = shift; + $interfaceName = shift; + $signature = shift; + + my $callback = GetFunctionTemplateCallbackName($function, $interfaceName); + return "v8::FunctionTemplate::New($callback, v8::Handle<v8::Value>(), $signature)"; +} + +sub GenerateEventListenerCallback +{ + my $implClassName = shift; + my $functionName = shift; + my $lookupType = ($functionName eq "add") ? "OrCreate" : "Only"; + my $passRefPtrHandling = ($functionName eq "add") ? "" : ".get()"; + my $hiddenDependencyAction = ($functionName eq "add") ? "create" : "remove"; + + push(@implContentDecls, <<END); +static v8::Handle<v8::Value> ${functionName}EventListenerCallback(const v8::Arguments& args) +{ + INC_STATS("DOM.${implClassName}.${functionName}EventListener()"); + RefPtr<EventListener> listener = V8DOMWrapper::getEventListener(args[1], false, ListenerFind${lookupType}); + if (listener) { + V8${implClassName}::toNative(args.Holder())->${functionName}EventListener(v8ValueToAtomicWebCoreString(args[0]), listener${passRefPtrHandling}, args[2]->BooleanValue()); + ${hiddenDependencyAction}HiddenDependency(args.Holder(), args[1], V8${implClassName}::eventListenerCacheIndex); } + return v8::Undefined(); +} + +END } sub GenerateFunctionCallback { my $function = shift; my $dataNode = shift; - my $classIndex = shift; my $implClassName = shift; my $interfaceName = $dataNode->name; my $name = $function->signature->name; - push(@implContentDecls, -" static v8::Handle<v8::Value> ${name}Callback(const v8::Arguments& args) {\n" . -" INC_STATS(\"DOM.$implClassName.$name\");\n"); + # Adding and removing event listeners are not standard callback behavior, + # but they are extremely consistent across the various classes that take event listeners, + # so we can generate them as a "special case". + if ($name eq "addEventListener") { + GenerateEventListenerCallback($implClassName, "add"); + return; + } elsif ($name eq "removeEventListener") { + GenerateEventListenerCallback($implClassName, "remove"); + return; + } + + push(@implContentDecls, <<END); +static v8::Handle<v8::Value> ${name}Callback(const v8::Arguments& args) { + INC_STATS(\"DOM.$implClassName.$name\"); +END my $numParameters = @{$function->parameters}; if ($function->signature->extendedAttributes->{"RequiresAllArguments"}) { - push(@implContentDecls, - " if (args.Length() < $numParameters) return v8::Undefined();\n"); + push(@implContentDecls, " if (args.Length() < $numParameters) return v8::Handle<v8::Value>();\n"); } if (IsPodType($implClassName)) { my $nativeClassName = GetNativeType($implClassName); - push(@implContentDecls, " V8SVGPODTypeWrapper<$nativeClassName>* imp_wrapper = V8DOMWrapper::convertToNativeObject<V8SVGPODTypeWrapper<$nativeClassName> >(V8ClassIndex::$classIndex, args.Holder());\n"); + push(@implContentDecls, " V8SVGPODTypeWrapper<$nativeClassName>* imp_wrapper = V8SVGPODTypeWrapper<$nativeClassName>::toNative(args.Holder());\n"); push(@implContentDecls, " $nativeClassName imp_instance = *imp_wrapper;\n"); push(@implContentDecls, " $nativeClassName* imp = &imp_instance;\n"); } else { push(@implContentDecls, <<END); - v8::Handle<v8::Object> holder = args.Holder(); + ${implClassName}* imp = V8${implClassName}::toNative(args.Holder()); END - HolderToNative($dataNode, $implClassName, $classIndex); } # Check domain security if needed @@ -871,26 +1022,43 @@ END || $interfaceName eq "DOMWindow") && !$function->signature->extendedAttributes->{"DoNotCheckDomainSecurity"}) { # We have not find real use cases yet. - push(@implContentDecls, -" if (!V8Proxy::canAccessFrame(imp->frame(), true)) {\n". -" return v8::Undefined();\n" . -" }\n"); + push(@implContentDecls, <<END); + if (!V8BindingSecurity::canAccessFrame(V8BindingState::Only(), imp->frame(), true)) + return v8::Handle<v8::Value>(); +END } + my $raisesExceptions = @{$function->raisesExceptions}; + if (!$raisesExceptions) { + foreach my $parameter (@{$function->parameters}) { + if (TypeCanFailConversion($parameter) or $parameter->extendedAttributes->{"IsIndex"}) { + $raisesExceptions = 1; + } + } + } - if (@{$function->raisesExceptions}) { + if ($raisesExceptions) { $implIncludes{"ExceptionCode.h"} = 1; push(@implContentDecls, " ExceptionCode ec = 0;\n"); + push(@implContentDecls, " {\n"); + # The brace here is needed to prevent the ensuing 'goto fail's from jumping past constructors + # of objects (like Strings) declared later, causing compile errors. The block scope ends + # right before the label 'fail:'. } if ($function->signature->extendedAttributes->{"CustomArgumentHandling"}) { - push(@implContentDecls, " ScriptCallStack callStack(args, $numParameters);\n"); + push(@implContentDecls, <<END); + OwnPtr<ScriptCallStack> callStack(ScriptCallStack::create(args, $numParameters)); + if (!callStack) + return v8::Undefined(); +END $implIncludes{"ScriptCallStack.h"} = 1; } if ($function->signature->extendedAttributes->{"SVGCheckSecurityDocument"}) { - push(@implContentDecls, -" if (!V8Proxy::checkNodeSecurity(imp->getSVGDocument(ec)))\n" . -" return v8::Undefined();\n"); + push(@implContentDecls, <<END); + if (!V8BindingSecurity::checkNodeSecurity(V8BindingState::Only(), imp->getSVGDocument(ec))) + return v8::Handle<v8::Value>(); +END } my $paramIndex = 0; @@ -911,7 +1079,7 @@ END push(@implContentDecls, " bool ${parameterName}Ok;\n"); } - push(@implContentDecls, " " . GetNativeTypeFromSignature($parameter, 1) . " $parameterName = "); + push(@implContentDecls, " " . GetNativeTypeFromSignature($parameter, $paramIndex) . " $parameterName = "); push(@implContentDecls, JSValueToNative($parameter, "args[$paramIndex]", BasicTypeCanFailConversion($parameter) ? "${parameterName}Ok" : undef) . ";\n"); @@ -919,8 +1087,8 @@ END $implIncludes{"ExceptionCode.h"} = 1; push(@implContentDecls, " if (UNLIKELY(!$parameterName" . (BasicTypeCanFailConversion($parameter) ? "Ok" : "") . ")) {\n" . -" V8Proxy::setDOMException(TYPE_MISMATCH_ERR);\n" . -" return v8::Handle<v8::Value>();\n" . +" ec = TYPE_MISMATCH_ERR;\n" . +" goto fail;\n" . " }\n"); } @@ -928,8 +1096,8 @@ END $implIncludes{"ExceptionCode.h"} = 1; push(@implContentDecls, " if (UNLIKELY($parameterName < 0)) {\n" . -" V8Proxy::setDOMException(INDEX_SIZE_ERR);\n" . -" return v8::Handle<v8::Value>();\n" . +" ec = INDEX_SIZE_ERR;\n" . +" goto fail;\n" . " }\n"); } @@ -939,7 +1107,15 @@ END # Build the function call string. my $callString = GenerateFunctionCallString($function, $paramIndex, " ", $implClassName); push(@implContentDecls, "$callString"); - push(@implContentDecls, " }\n\n"); + + if ($raisesExceptions) { + push(@implContentDecls, " }\n"); + push(@implContentDecls, " fail:\n"); + push(@implContentDecls, " V8Proxy::setDOMException(ec);\n"); + push(@implContentDecls, " return v8::Handle<v8::Value>();\n"); + } + + push(@implContentDecls, "}\n\n"); } sub GenerateBatchedAttributeData @@ -991,7 +1167,7 @@ sub GenerateSingleBatchedAttribute ""; if ($customAccessor eq 1) { # use the naming convension, interface + (capitalize) attr name - $customAccessor = $interfaceName . $codeGenerator->WK_ucfirst($attrName); + $customAccessor = $interfaceName . "::" . $attrName; } my $getter; @@ -1008,17 +1184,17 @@ sub GenerateSingleBatchedAttribute } my $on_proto = "0 /* on instance */"; - my $data = "V8ClassIndex::INVALID_CLASS_INDEX /* no data */"; + my $data = "0 /* no data */"; # Constructor if ($attribute->signature->type =~ /Constructor$/) { my $constructorType = $codeGenerator->StripModule($attribute->signature->type); $constructorType =~ s/Constructor$//; - my $constructorIndex = uc($constructorType); + $implIncludes{"V8${constructorType}.h"} = 1; if ($customAccessor) { - $getter = "V8Custom::v8${customAccessor}AccessorGetter"; + $getter = "V8${customAccessor}AccessorGetter"; } else { - $data = "V8ClassIndex::${constructorIndex}"; + $data = "&V8${constructorType}::info"; $getter = "${interfaceName}Internal::${interfaceName}ConstructorGetter"; } $setter = "0"; @@ -1032,12 +1208,12 @@ sub GenerateSingleBatchedAttribute # Custom Setter if ($attrExt->{"CustomSetter"} || $attrExt->{"V8CustomSetter"} || $attrExt->{"Custom"} || $attrExt->{"V8Custom"}) { $hasCustomSetter = 1; - $setter = "V8Custom::v8${customAccessor}AccessorSetter"; + $setter = "V8${customAccessor}AccessorSetter"; } # Custom Getter - if ($attrExt->{"CustomGetter"} || $attrExt->{"Custom"} || $attrExt->{"V8Custom"}) { - $getter = "V8Custom::v8${customAccessor}AccessorGetter"; + if ($attrExt->{"CustomGetter"} || $attrExt->{"V8CustomGetter"} || $attrExt->{"Custom"} || $attrExt->{"V8Custom"}) { + $getter = "V8${customAccessor}AccessorGetter"; } } @@ -1078,14 +1254,184 @@ sub GenerateSingleBatchedAttribute END } +sub GenerateImplementationIndexer +{ + my $dataNode = shift; + my $indexer = shift; + my $interfaceName = $dataNode->name; + + # FIXME: Figure out what HasNumericIndexGetter is really supposed to do. Right now, it's only set on WebGL-related files. + my $hasCustomSetter = $dataNode->extendedAttributes->{"HasCustomIndexSetter"} && !$dataNode->extendedAttributes->{"HasNumericIndexGetter"}; + my $hasGetter = $dataNode->extendedAttributes->{"HasIndexGetter"} || $dataNode->extendedAttributes->{"CustomGetOwnPropertySlot"}; + + # FIXME: Find a way to not have to special-case HTMLOptionsCollection. + if ($interfaceName eq "HTMLOptionsCollection") { + $hasGetter = 1; + } + # FIXME: If the parent interface of $dataNode already has + # HasIndexGetter, we don't need to handle the getter here. + if ($interfaceName eq "WebKitCSSTransformValue") { + $hasGetter = 0; + } + + # FIXME: Investigate and remove this nastinesss. In V8, named property handling and indexer handling are apparently decoupled, + # which means that object[X] where X is a number doesn't reach named property indexer. So we need to provide + # simplistic, mirrored indexer handling in addition to named property handling. + my $isSpecialCase = exists $indexerSpecialCases{$interfaceName}; + if ($isSpecialCase) { + $hasGetter = 1; + if ($dataNode->extendedAttributes->{"DelegatingPutFunction"}) { + $hasCustomSetter = 1; + } + } + + if (!$hasGetter) { + return; + } + + $implIncludes{"V8Collection.h"} = 1; + + my $indexerType = $indexer ? $indexer->type : 0; + + # FIXME: Remove this once toV8 helper methods are implemented (see https://bugs.webkit.org/show_bug.cgi?id=32563). + if ($interfaceName eq "WebKitCSSKeyframesRule") { + $indexerType = "WebKitCSSKeyframeRule"; + } + + if ($indexerType && !$hasCustomSetter) { + if ($indexerType eq "DOMString") { + my $conversion = $indexer->extendedAttributes->{"ConvertNullStringTo"}; + if ($conversion && $conversion eq "Null") { + push(@implContent, <<END); + setCollectionStringOrNullIndexedGetter<${interfaceName}>(desc); +END + } else { + push(@implContent, <<END); + setCollectionStringIndexedGetter<${interfaceName}>(desc); +END + } + } else { + push(@implContent, <<END); + setCollectionIndexedGetter<${interfaceName}, ${indexerType}>(desc); +END + # Include the header for this indexer type, because setCollectionIndexedGetter() requires toV8() for this type. + $implIncludes{"V8${indexerType}.h"} = 1; + } + + return; + } + + my $hasDeleter = $dataNode->extendedAttributes->{"CustomDeleteProperty"}; + my $hasEnumerator = !$isSpecialCase && IsNodeSubType($dataNode); + my $setOn = "Instance"; + + # V8 has access-check callback API (see ObjectTemplate::SetAccessCheckCallbacks) and it's used on DOMWindow + # instead of deleters or enumerators. In addition, the getter should be set on prototype template, to + # get implementation straight out of the DOMWindow prototype regardless of what prototype is actually set + # on the object. + if ($interfaceName eq "DOMWindow") { + $setOn = "Prototype"; + $hasDeleter = 0; + } + + push(@implContent, " desc->${setOn}Template()->SetIndexedPropertyHandler(V8${interfaceName}::indexedPropertyGetter"); + push(@implContent, $hasCustomSetter ? ", V8${interfaceName}::indexedPropertySetter" : ", 0"); + push(@implContent, ", 0"); # IndexedPropertyQuery -- not being used at the moment. + push(@implContent, $hasDeleter ? ", V8${interfaceName}::indexedPropertyDeleter" : ", 0"); + push(@implContent, ", nodeCollectionIndexedPropertyEnumerator<${interfaceName}>") if $hasEnumerator; + push(@implContent, ");\n"); +} + +sub GenerateImplementationNamedPropertyGetter +{ + my $dataNode = shift; + my $namedPropertyGetter = shift; + my $interfaceName = $dataNode->name; + my $hasCustomGetter = $dataNode->extendedAttributes->{"HasOverridingNameGetter"} || $dataNode->extendedAttributes->{"CustomGetOwnPropertySlot"}; + + # FIXME: Remove hard-coded HTMLOptionsCollection reference by changing HTMLOptionsCollection to not inherit + # from HTMLCollection per W3C spec (http://www.w3.org/TR/2003/REC-DOM-Level-2-HTML-20030109/html.html#HTMLOptionsCollection). + if ($interfaceName eq "HTMLOptionsCollection") { + $interfaceName = "HTMLCollection"; + $hasCustomGetter = 1; + } + + if ($interfaceName eq "HTMLAppletElement" || $interfaceName eq "HTMLEmbedElement" || $interfaceName eq "HTMLObjectElement") { + $hasCustomGetter = 1; + } + + my $hasGetter = $dataNode->extendedAttributes->{"HasNameGetter"} || $hasCustomGetter || $namedPropertyGetter; + if (!$hasGetter) { + return; + } + + if ($namedPropertyGetter && $namedPropertyGetter->type ne "Node" && !$namedPropertyGetter->extendedAttributes->{"Custom"} && !$hasCustomGetter) { + $implIncludes{"V8Collection.h"} = 1; + my $type = $namedPropertyGetter->type; + push(@implContent, <<END); + setCollectionNamedGetter<${interfaceName}, ${type}>(desc); +END + return; + } + + my $hasSetter = $dataNode->extendedAttributes->{"DelegatingPutFunction"}; + # FIXME: Try to remove hard-coded HTMLDocument reference by aligning handling of document.all with JSC bindings. + my $hasDeleter = $dataNode->extendedAttributes->{"CustomDeleteProperty"} || $interfaceName eq "HTMLDocument"; + my $hasEnumerator = $dataNode->extendedAttributes->{"CustomGetPropertyNames"}; + my $setOn = "Instance"; + + # V8 has access-check callback API (see ObjectTemplate::SetAccessCheckCallbacks) and it's used on DOMWindow + # instead of deleters or enumerators. In addition, the getter should be set on prototype template, to + # get implementation straight out of the DOMWindow prototype regardless of what prototype is actually set + # on the object. + if ($interfaceName eq "DOMWindow") { + $setOn = "Prototype"; + $hasDeleter = 0; + $hasEnumerator = 0; + } + + push(@implContent, " desc->${setOn}Template()->SetNamedPropertyHandler(V8${interfaceName}::namedPropertyGetter, "); + push(@implContent, $hasSetter ? "V8${interfaceName}::namedPropertySetter, " : "0, "); + push(@implContent, "0, "); # NamedPropertyQuery -- not being used at the moment. + push(@implContent, $hasDeleter ? "V8${interfaceName}::namedPropertyDeleter, " : "0, "); + push(@implContent, $hasEnumerator ? "V8${interfaceName}::namedPropertyEnumerator" : "0"); + push(@implContent, ");\n"); +} + +sub GenerateImplementationCustomCall +{ + my $dataNode = shift; + my $interfaceName = $dataNode->name; + my $hasCustomCall = $dataNode->extendedAttributes->{"CustomCall"}; + + # FIXME: Remove hard-coded HTMLOptionsCollection reference. + if ($interfaceName eq "HTMLOptionsCollection") { + $interfaceName = "HTMLCollection"; + $hasCustomCall = 1; + } + + if ($hasCustomCall) { + push(@implContent, " desc->InstanceTemplate()->SetCallAsFunctionHandler(V8${interfaceName}::callAsFunctionCallback);\n"); + } +} + +sub GenerateImplementationMasqueradesAsUndefined +{ + my $dataNode = shift; + if ($dataNode->extendedAttributes->{"MasqueradesAsUndefined"}) + { + push(@implContent, " desc->InstanceTemplate()->MarkAsUndetectable();\n"); + } +} + sub GenerateImplementation { my $object = shift; my $dataNode = shift; my $interfaceName = $dataNode->name; + my $visibleInterfaceName = GetVisibleInterfaceName($interfaceName); my $className = "V8$interfaceName"; my $implClassName = $interfaceName; - my $classIndex = uc($codeGenerator->StripModule($interfaceName)); my $hasLegacyParent = $dataNode->extendedAttributes->{"LegacyParent"}; my $conditionalString = GenerateConditionalString($dataNode); @@ -1095,8 +1441,12 @@ sub GenerateImplementation push(@implFixedHeader, "#include \"config.h\"\n" . + "#include \"RuntimeEnabledFeatures.h\"\n" . "#include \"V8Proxy.h\"\n" . - "#include \"V8Binding.h\"\n\n" . + "#include \"V8Binding.h\"\n" . + "#include \"V8BindingState.h\"\n" . + "#include \"V8DOMWrapper.h\"\n" . + "#include \"V8IsolatedContext.h\"\n\n" . "#undef LOG\n\n"); push(@implFixedHeader, "\n#if ${conditionalString}\n\n") if $conditionalString; @@ -1108,14 +1458,15 @@ sub GenerateImplementation $implIncludes{"${className}.h"} = 1; AddIncludesForType($interfaceName); - $implIncludes{"V8Proxy.h"} = 1; - push(@implContentDecls, "namespace WebCore {\n"); + my $toActive = IsActiveDomType($interfaceName) ? "${className}::toActiveDOMObject" : "0"; + + push(@implContentDecls, "namespace WebCore {\n\n"); + push(@implContentDecls, "WrapperTypeInfo ${className}::info = { ${className}::GetTemplate, ${className}::derefObject, ${toActive} };\n\n"); push(@implContentDecls, "namespace ${interfaceName}Internal {\n\n"); push(@implContentDecls, "template <typename T> void V8_USE(T) { }\n\n"); my $hasConstructors = 0; - # Generate property accessors for attributes. for ($index = 0; $index < @{$dataNode->attributes}; $index++) { $attribute = @{$dataNode->attributes}[$index]; @@ -1124,9 +1475,8 @@ sub GenerateImplementation # Generate special code for the constructor attributes. if ($attrType =~ /Constructor$/) { - if ($attribute->signature->extendedAttributes->{"CustomGetter"}) { - $implIncludes{"V8CustomBinding.h"} = 1; - } else { + if (!($attribute->signature->extendedAttributes->{"CustomGetter"} || + $attribute->signature->extendedAttributes->{"V8CustomGetter"})) { $hasConstructors = 1; } next; @@ -1141,46 +1491,48 @@ sub GenerateImplementation # implementation. if ($attribute->signature->extendedAttributes->{"Custom"} || $attribute->signature->extendedAttributes->{"V8Custom"}) { - $implIncludes{"V8CustomBinding.h"} = 1; next; } # Generate the accessor. - if ($attribute->signature->extendedAttributes->{"CustomGetter"}) { - $implIncludes{"V8CustomBinding.h"} = 1; - } else { - GenerateNormalAttrGetter($attribute, $dataNode, $classIndex, $implClassName, $interfaceName); + if (!($attribute->signature->extendedAttributes->{"CustomGetter"} || + $attribute->signature->extendedAttributes->{"V8CustomGetter"})) { + GenerateNormalAttrGetter($attribute, $dataNode, $implClassName, $interfaceName); } - if ($attribute->signature->extendedAttributes->{"CustomSetter"} || - $attribute->signature->extendedAttributes->{"V8CustomSetter"}) { - $implIncludes{"V8CustomBinding.h"} = 1; - } elsif ($attribute->signature->extendedAttributes->{"Replaceable"}) { - $dataNode->extendedAttributes->{"ExtendsDOMGlobalObject"} || die "Replaceable attribute can only be used in interface that defines ExtendsDOMGlobalObject attribute!"; - # GenerateReplaceableAttrSetter($implClassName); - } elsif ($attribute->type !~ /^readonly/ && !$attribute->signature->extendedAttributes->{"V8ReadOnly"}) { - GenerateNormalAttrSetter($attribute, $dataNode, $classIndex, $implClassName, $interfaceName); + if (!$attribute->signature->extendedAttributes->{"CustomSetter"} && + !$attribute->signature->extendedAttributes->{"V8CustomSetter"} && + !$attribute->signature->extendedAttributes->{"Replaceable"} && + $attribute->type !~ /^readonly/ && + !$attribute->signature->extendedAttributes->{"V8ReadOnly"}) { + GenerateNormalAttrSetter($attribute, $dataNode, $implClassName, $interfaceName); } } if ($hasConstructors) { - GenerateConstructorGetter($implClassName, $classIndex); + GenerateConstructorGetter($implClassName); } + my $indexer; + my $namedPropertyGetter; # Generate methods for functions. foreach my $function (@{$dataNode->functions}) { - # hack for addEventListener/RemoveEventListener - # FIXME: avoid naming conflict - if ($function->signature->extendedAttributes->{"Custom"} || $function->signature->extendedAttributes->{"V8Custom"}) { - $implIncludes{"V8CustomBinding.h"} = 1; - } else { - GenerateFunctionCallback($function, $dataNode, $classIndex, $implClassName); + if (!($function->signature->extendedAttributes->{"Custom"} || $function->signature->extendedAttributes->{"V8Custom"})) { + GenerateFunctionCallback($function, $dataNode, $implClassName); + } + + if ($function->signature->name eq "item") { + $indexer = $function->signature; + } + + if ($function->signature->name eq "namedItem") { + $namedPropertyGetter = $function->signature; } # If the function does not need domain security check, we need to # generate an access getter that returns different function objects # for different calling context. if (($dataNode->extendedAttributes->{"CheckDomainSecurity"} || ($interfaceName eq "DOMWindow")) && $function->signature->extendedAttributes->{"DoNotCheckDomainSecurity"}) { - GenerateDomainSafeFunctionGetter($function, $dataNode, $classIndex, $implClassName); + GenerateDomainSafeFunctionGetter($function, $implClassName); } } @@ -1194,6 +1546,7 @@ sub GenerateImplementation my @enabledAtRuntime; my @normal; foreach my $attribute (@$attributes) { + if ($interfaceName eq "DOMWindow" && $attribute->signature->extendedAttributes->{"V8DisallowShadowing"}) { push(@disallowsShadowing, $attribute); } elsif ($attribute->signature->extendedAttributes->{"EnabledAtRuntime"}) { @@ -1218,6 +1571,38 @@ sub GenerateImplementation push(@implContent, "};\n"); } + # Setup table of standard callback functions + $num_callbacks = 0; + $has_callbacks = 0; + foreach my $function (@{$dataNode->functions}) { + my $attrExt = $function->signature->extendedAttributes; + # Don't put any nonstandard functions into this table: + if ($attrExt->{"V8OnInstance"}) { + next; + } + if ($attrExt->{"EnabledAtRuntime"} || RequiresCustomSignature($function) || $attrExt->{"V8DoNotCheckSignature"}) { + next; + } + if ($attrExt->{"DoNotCheckDomainSecurity"} && + ($dataNode->extendedAttributes->{"CheckDomainSecurity"} || $interfaceName eq "DOMWindow")) { + next; + } + if ($attrExt->{"DontEnum"} || $attrExt->{"V8ReadOnly"}) { + next; + } + if (!$has_callbacks) { + $has_callbacks = 1; + push(@implContent, "static const BatchedCallback ${interfaceName}_callbacks[] = {\n"); + } + my $name = $function->signature->name; + my $callback = GetFunctionTemplateCallbackName($function, $interfaceName); + push(@implContent, <<END); + {"$name", $callback}, +END + $num_callbacks++; + } + push(@implContent, "};\n") if $has_callbacks; + # Setup constants my $has_constants = 0; if (@{$dataNode->constants}) { @@ -1240,60 +1625,100 @@ END push(@implContentDecls, "} // namespace ${interfaceName}Internal\n\n"); - my $access_check = "/* no access check */"; + # In namespace WebCore, add generated implementation for 'CanBeConstructed'. + if ($dataNode->extendedAttributes->{"CanBeConstructed"} && !$dataNode->extendedAttributes->{"CustomConstructor"}) { + push(@implContent, <<END); +v8::Handle<v8::Value> ${className}::constructorCallback(const v8::Arguments& args) +{ + INC_STATS("DOM.${interfaceName}.Contructor"); + return V8Proxy::constructDOMObject<$interfaceName>(args, &info); +} +END + } + + my $access_check = ""; if ($dataNode->extendedAttributes->{"CheckDomainSecurity"} && !($interfaceName eq "DOMWindow")) { - $access_check = "instance->SetAccessCheckCallbacks(V8Custom::v8${interfaceName}NamedSecurityCheck, V8Custom::v8${interfaceName}IndexedSecurityCheck, v8::Integer::New(V8ClassIndex::ToInt(V8ClassIndex::${classIndex})));"; + $access_check = "instance->SetAccessCheckCallbacks(V8${interfaceName}::namedSecurityCheck, V8${interfaceName}::indexedSecurityCheck, v8::External::Wrap(&V8${interfaceName}::info));"; } # For the DOMWindow interface, generate the shadow object template # configuration method. if ($implClassName eq "DOMWindow") { push(@implContent, <<END); -static v8::Persistent<v8::ObjectTemplate> ConfigureShadowObjectTemplate(v8::Persistent<v8::ObjectTemplate> templ) { - batchConfigureAttributes(templ, - v8::Handle<v8::ObjectTemplate>(), - shadow_attrs, - sizeof(shadow_attrs)/sizeof(*shadow_attrs)); - return templ; +static v8::Persistent<v8::ObjectTemplate> ConfigureShadowObjectTemplate(v8::Persistent<v8::ObjectTemplate> templ) +{ + batchConfigureAttributes(templ, v8::Handle<v8::ObjectTemplate>(), shadow_attrs, sizeof(shadow_attrs)/sizeof(*shadow_attrs)); + + // Install a security handler with V8. + templ->SetAccessCheckCallbacks(V8DOMWindow::namedSecurityCheck, V8DOMWindow::indexedSecurityCheck, v8::External::Wrap(&V8DOMWindow::info)); + templ->SetInternalFieldCount(V8DOMWindow::internalFieldCount); + return templ; } END } + # find the super descriptor + my $parentClassTemplate = ""; + foreach (@{$dataNode->parents}) { + my $parent = $codeGenerator->StripModule($_); + if ($parent eq "EventTarget") { next; } + $implIncludes{"V8${parent}.h"} = 1; + $parentClassTemplate = "V8" . $parent . "::GetTemplate()"; + last; + } + if (!$parentClassTemplate) { + $parentClassTemplate = "v8::Persistent<v8::FunctionTemplate>()"; + } + # Generate the template configuration method push(@implContent, <<END); -static v8::Persistent<v8::FunctionTemplate> Configure${className}Template(v8::Persistent<v8::FunctionTemplate> desc) { - v8::Local<v8::ObjectTemplate> instance = desc->InstanceTemplate(); +static v8::Persistent<v8::FunctionTemplate> Configure${className}Template(v8::Persistent<v8::FunctionTemplate> desc) +{ + v8::Local<v8::Signature> default_signature = configureTemplate(desc, \"${visibleInterfaceName}\", $parentClassTemplate, V8${interfaceName}::internalFieldCount, END - if (IsNodeSubType($dataNode)) { + # Set up our attributes if we have them + if ($has_attributes) { push(@implContent, <<END); - instance->SetInternalFieldCount(V8Custom::kNodeMinimumInternalFieldCount); + ${interfaceName}_attrs, sizeof(${interfaceName}_attrs)/sizeof(*${interfaceName}_attrs), END } else { push(@implContent, <<END); - instance->SetInternalFieldCount(V8Custom::kDefaultWrapperInternalFieldCount); + NULL, 0, END } - push(@implContent, <<END); - v8::Local<v8::Signature> default_signature = v8::Signature::New(desc); - v8::Local<v8::ObjectTemplate> proto = desc->PrototypeTemplate(); - $access_check + if ($has_callbacks) { + push(@implContent, <<END); + ${interfaceName}_callbacks, sizeof(${interfaceName}_callbacks)/sizeof(*${interfaceName}_callbacks)); END + } else { + push(@implContent, <<END); + NULL, 0); +END + } - - # Set up our attributes if we have them - if ($has_attributes) { + if ($dataNode->extendedAttributes->{"CustomConstructor"} || $dataNode->extendedAttributes->{"CanBeConstructed"}) { push(@implContent, <<END); - batchConfigureAttributes(instance, proto, ${interfaceName}_attrs, sizeof(${interfaceName}_attrs)/sizeof(*${interfaceName}_attrs)); + desc->SetCallHandler(V8${interfaceName}::constructorCallback); END } + if ($access_check or @enabledAtRuntime or @{$dataNode->functions} or $has_constants) { + push(@implContent, <<END); + v8::Local<v8::ObjectTemplate> instance = desc->InstanceTemplate(); + v8::Local<v8::ObjectTemplate> proto = desc->PrototypeTemplate(); +END + } + + push(@implContent, " $access_check\n"); + # Setup the enable-at-runtime attrs if we have them foreach my $runtime_attr (@enabledAtRuntime) { - $enable_function = $interfaceName . $codeGenerator->WK_ucfirst($runtime_attr->signature->name); + # A function named RuntimeEnabledFeatures::{methodName}Enabled() need to be written by hand. + $enable_function = "RuntimeEnabledFeatures::" . $codeGenerator->WK_lcfirst($runtime_attr->signature->name) . "Enabled"; my $conditionalString = GenerateConditionalString($runtime_attr->signature); push(@implContent, "\n#if ${conditionalString}\n") if $conditionalString; - push(@implContent, " if (V8Custom::v8${enable_function}Enabled()) {\n"); + push(@implContent, " if (${enable_function}()) {\n"); push(@implContent, " static const BatchedAttribute attrData =\\\n"); GenerateSingleBatchedAttribute($interfaceName, $runtime_attr, ";", " "); push(@implContent, <<END); @@ -1303,8 +1728,15 @@ END push(@implContent, "\n#endif // ${conditionalString}\n") if $conditionalString; } + GenerateImplementationIndexer($dataNode, $indexer); + GenerateImplementationNamedPropertyGetter($dataNode, $namedPropertyGetter); + GenerateImplementationCustomCall($dataNode); + GenerateImplementationMasqueradesAsUndefined($dataNode); + # Define our functions with Set() or SetAccessor() + $total_functions = 0; foreach my $function (@{$dataNode->functions}) { + $total_functions++; my $attrExt = $function->signature->extendedAttributes; my $name = $function->signature->name; @@ -1326,8 +1758,8 @@ END my $conditional = ""; if ($attrExt->{"EnabledAtRuntime"}) { # Only call Set()/SetAccessor() if this method should be enabled - $enable_function = $interfaceName . $codeGenerator->WK_ucfirst($function->signature->name); - $conditional = "if (V8Custom::v8${enable_function}Enabled())\n"; + $enable_function = "RuntimeEnabledFeatures::" . $codeGenerator->WK_lcfirst($function->signature->name) . "Enabled"; + $conditional = "if (${enable_function}())\n "; } if ($attrExt->{"DoNotCheckDomainSecurity"} && @@ -1349,108 +1781,333 @@ END $property_attributes .= "|v8::ReadOnly"; push(@implContent, <<END); - // $commentInfo - $conditional $template->SetAccessor( - v8::String::New("$name"), - ${interfaceName}Internal::${name}AttrGetter, - 0, - v8::Handle<v8::Value>(), - v8::ALL_CAN_READ, - static_cast<v8::PropertyAttribute>($property_attributes)); + // $commentInfo + ${conditional}$template->SetAccessor(v8::String::New("$name"), ${interfaceName}Internal::${name}AttrGetter, 0, v8::Handle<v8::Value>(), v8::ALL_CAN_READ, static_cast<v8::PropertyAttribute>($property_attributes)); END + $num_callbacks++; next; } my $signature = "default_signature"; - if ($attrExt->{"V8DoNotCheckSignature"}){ + if ($attrExt->{"V8DoNotCheckSignature"}) { $signature = "v8::Local<v8::Signature>()"; } if (RequiresCustomSignature($function)) { $signature = "${name}_signature"; - push(@implContent, "\n // Custom Signature '$name'\n", CreateCustomSignature($function)); + push(@implContent, "\n // Custom Signature '$name'\n", CreateCustomSignature($function)); } # Normal function call is a template - my $templateFunction = GenerateNewFunctionTemplate($function, $dataNode, $signature); + my $callback = GetFunctionTemplateCallbackName($function, $interfaceName); + if ($property_attributes eq "v8::DontDelete") { + $property_attributes = ""; + } else { + $property_attributes = ", static_cast<v8::PropertyAttribute>($property_attributes)"; + } - push(@implContent, <<END); + if ($template eq "proto" && $conditional eq "" && $signature eq "default_signature" && $property_attributes eq "") { + # Standard type of callback, already created in the batch, so skip it here. + next; + } - // $commentInfo - $conditional ${template}->Set( - v8::String::New("$name"), - $templateFunction, - static_cast<v8::PropertyAttribute>($property_attributes)); + push(@implContent, <<END); + ${conditional}$template->Set(v8::String::New("$name"), v8::FunctionTemplate::New($callback, v8::Handle<v8::Value>(), ${signature})$property_attributes); END + $num_callbacks++; } - # set the super descriptor - foreach (@{$dataNode->parents}) { - my $parent = $codeGenerator->StripModule($_); - if ($parent eq "EventTarget") { next; } - $implIncludes{"V8${parent}.h"} = 1; - my $parentClassIndex = uc($codeGenerator->StripModule($parent)); - push(@implContent, " desc->Inherit(V8DOMWrapper::getTemplate(V8ClassIndex::${parentClassIndex}));\n"); - last; + die "Wrong number of callbacks generated for $interfaceName ($num_callbacks, should be $total_functions)" if $num_callbacks != $total_functions; + + if ($has_constants) { + push(@implContent, <<END); + batchConfigureConstants(desc, proto, ${interfaceName}_consts, sizeof(${interfaceName}_consts)/sizeof(*${interfaceName}_consts)); +END } - # Set the class name. This is used when printing objects. - push(@implContent, " desc->SetClassName(v8::String::New(\"${interfaceName}\"));\n"); + # Special cases + if ($interfaceName eq "DOMWindow") { + push(@implContent, <<END); - if ($has_constants) { + proto->SetInternalFieldCount(V8DOMWindow::internalFieldCount); + desc->SetHiddenPrototype(true); + instance->SetInternalFieldCount(V8DOMWindow::internalFieldCount); + // Set access check callbacks, but turned off initially. + // When a context is detached from a frame, turn on the access check. + // Turning on checks also invalidates inline caches of the object. + instance->SetAccessCheckCallbacks(V8DOMWindow::namedSecurityCheck, V8DOMWindow::indexedSecurityCheck, v8::External::Wrap(&V8DOMWindow::info), false); +END + } + if ($interfaceName eq "Location") { push(@implContent, <<END); - batchConfigureConstants(desc, proto, ${interfaceName}_consts, sizeof(${interfaceName}_consts)/sizeof(*${interfaceName}_consts)); + + // For security reasons, these functions are on the instance instead + // of on the prototype object to ensure that they cannot be overwritten. + instance->SetAccessor(v8::String::New("reload"), V8Location::reloadAccessorGetter, 0, v8::Handle<v8::Value>(), v8::ALL_CAN_READ, static_cast<v8::PropertyAttribute>(v8::DontDelete | v8::ReadOnly)); + instance->SetAccessor(v8::String::New("replace"), V8Location::replaceAccessorGetter, 0, v8::Handle<v8::Value>(), v8::ALL_CAN_READ, static_cast<v8::PropertyAttribute>(v8::DontDelete | v8::ReadOnly)); + instance->SetAccessor(v8::String::New("assign"), V8Location::assignAccessorGetter, 0, v8::Handle<v8::Value>(), v8::ALL_CAN_READ, static_cast<v8::PropertyAttribute>(v8::DontDelete | v8::ReadOnly)); END } + my $nativeType = GetNativeTypeForConversions($interfaceName); + if ($dataNode->extendedAttributes->{"PODType"}) { + $nativeType = "V8SVGPODTypeWrapper<${nativeType}>"; + } push(@implContent, <<END); - return desc; + + // Custom toString template + desc->Set(getToStringName(), getToStringTemplate()); + return desc; +} + +v8::Persistent<v8::FunctionTemplate> ${className}::GetRawTemplate() +{ + static v8::Persistent<v8::FunctionTemplate> ${className}_raw_cache_ = createRawTemplate(); + return ${className}_raw_cache_; } -v8::Persistent<v8::FunctionTemplate> ${className}::GetRawTemplate() { - static v8::Persistent<v8::FunctionTemplate> ${className}_raw_cache_; - if (${className}_raw_cache_.IsEmpty()) { - v8::HandleScope scope; - v8::Local<v8::FunctionTemplate> result = v8::FunctionTemplate::New(V8Proxy::checkNewLegal); - ${className}_raw_cache_ = v8::Persistent<v8::FunctionTemplate>::New(result); - } - return ${className}_raw_cache_; +v8::Persistent<v8::FunctionTemplate> ${className}::GetTemplate()\ +{ + static v8::Persistent<v8::FunctionTemplate> ${className}_cache_ = Configure${className}Template(GetRawTemplate()); + return ${className}_cache_; } -v8::Persistent<v8::FunctionTemplate> ${className}::GetTemplate() { - static v8::Persistent<v8::FunctionTemplate> ${className}_cache_; - if (${className}_cache_.IsEmpty()) - ${className}_cache_ = Configure${className}Template(GetRawTemplate()); - return ${className}_cache_; +${nativeType}* ${className}::toNative(v8::Handle<v8::Object> object) +{ + return reinterpret_cast<${nativeType}*>(object->GetPointerFromInternalField(v8DOMWrapperObjectIndex)); } -bool ${className}::HasInstance(v8::Handle<v8::Value> value) { - return GetRawTemplate()->HasInstance(value); +bool ${className}::HasInstance(v8::Handle<v8::Value> value) +{ + return GetRawTemplate()->HasInstance(value); } END + if (IsActiveDomType($interfaceName)) { + # MessagePort is handled like an active dom object even though it doesn't inherit + # from ActiveDOMObject, so don't try to cast it to ActiveDOMObject. + my $returnValue = $interfaceName eq "MessagePort" ? "0" : "toNative(object)"; + push(@implContent, <<END); +ActiveDOMObject* ${className}::toActiveDOMObject(v8::Handle<v8::Object> object) +{ + return ${returnValue}; +} +END + } + if ($implClassName eq "DOMWindow") { push(@implContent, <<END); -v8::Persistent<v8::ObjectTemplate> V8DOMWindow::GetShadowObjectTemplate() { - static v8::Persistent<v8::ObjectTemplate> V8DOMWindowShadowObject_cache_; - if (V8DOMWindowShadowObject_cache_.IsEmpty()) { - V8DOMWindowShadowObject_cache_ = v8::Persistent<v8::ObjectTemplate>::New(v8::ObjectTemplate::New()); - ConfigureShadowObjectTemplate(V8DOMWindowShadowObject_cache_); - } - return V8DOMWindowShadowObject_cache_; +v8::Persistent<v8::ObjectTemplate> V8DOMWindow::GetShadowObjectTemplate() +{ + static v8::Persistent<v8::ObjectTemplate> V8DOMWindowShadowObject_cache_; + if (V8DOMWindowShadowObject_cache_.IsEmpty()) { + V8DOMWindowShadowObject_cache_ = v8::Persistent<v8::ObjectTemplate>::New(v8::ObjectTemplate::New()); + ConfigureShadowObjectTemplate(V8DOMWindowShadowObject_cache_); + } + return V8DOMWindowShadowObject_cache_; } END } + GenerateToV8Converters($dataNode, $interfaceName, $className, $nativeType); + + push(@implContent, <<END); + +void ${className}::derefObject(void* object) +{ +END + + if (IsRefPtrType($interfaceName)) { + push(@implContent, <<END); + static_cast<${nativeType}*>(object)->deref(); +END + } + push(@implContent, <<END); +} + } // namespace WebCore END push(@implContent, "\n#endif // ${conditionalString}\n") if $conditionalString; } +sub GenerateToV8Converters +{ + my $dataNode = shift; + my $interfaceName = shift; + my $className = shift; + my $nativeType = shift; + + my $domMapFunction = GetDomMapFunction($dataNode, $interfaceName); + my $forceNewObjectInput = IsDOMNodeType($interfaceName) ? ", bool forceNewObject" : ""; + my $forceNewObjectCall = IsDOMNodeType($interfaceName) ? ", forceNewObject" : ""; + + push(@implContent, <<END); + +v8::Handle<v8::Object> ${className}::wrap(${nativeType}* impl${forceNewObjectInput}) +{ + v8::Handle<v8::Object> wrapper; + V8Proxy* proxy = 0; +END + + if (IsNodeSubType($dataNode)) { + push(@implContent, <<END); + if (impl->document()) { + proxy = V8Proxy::retrieve(impl->document()->frame()); + if (proxy && static_cast<Node*>(impl->document()) == static_cast<Node*>(impl)) + proxy->windowShell()->initContextIfNeeded(); + } + +END + } + + if ($domMapFunction) { + push(@implContent, " if (!forceNewObject) {\n") if IsDOMNodeType($interfaceName); + if (IsNodeSubType($dataNode)) { + push(@implContent, " wrapper = V8DOMWrapper::getWrapper(impl);\n"); + } else { + push(@implContent, " wrapper = ${domMapFunction}.get(impl);\n"); + } + push(@implContent, <<END); + if (!wrapper.IsEmpty()) + return wrapper; +END + push(@implContent, " }\n") if IsDOMNodeType($interfaceName); + } + if (IsNodeSubType($dataNode)) { + push(@implContent, <<END); + + v8::Handle<v8::Context> context; + if (proxy) + context = proxy->context(); + + // Enter the node's context and create the wrapper in that context. + if (!context.IsEmpty()) + context->Enter(); +END + } + + push(@implContent, <<END); + wrapper = V8DOMWrapper::instantiateV8Object(proxy, &info, impl); +END + + if (IsNodeSubType($dataNode)) { + push(@implContent, <<END); + // Exit the node's context if it was entered. + if (!context.IsEmpty()) + context->Exit(); +END + } + + push(@implContent, <<END); + if (wrapper.IsEmpty()) + return wrapper; +END + push(@implContent, "\n impl->ref();\n") if IsRefPtrType($interfaceName); + + if ($domMapFunction) { + push(@implContent, <<END); + ${domMapFunction}.set(impl, v8::Persistent<v8::Object>::New(wrapper)); +END + } + + push(@implContent, <<END); + return wrapper; +} +END + + if (IsRefPtrType($interfaceName)) { + push(@implContent, <<END); + +v8::Handle<v8::Value> toV8(PassRefPtr<${nativeType} > impl${forceNewObjectInput}) +{ + return toV8(impl.get()${forceNewObjectCall}); +} +END + } + + if (!HasCustomToV8Implementation($dataNode, $interfaceName)) { + push(@implContent, <<END); + +v8::Handle<v8::Value> toV8(${nativeType}* impl${forceNewObjectInput}) +{ + if (!impl) + return v8::Null(); + return ${className}::wrap(impl${forceNewObjectCall}); +} +END + } +} + +sub HasCustomToV8Implementation { + # FIXME: This subroutine is lame. Probably should be an .idl attribute (CustomToV8)? + $dataNode = shift; + $interfaceName = shift; + + # We generate a custom converter (but JSC doesn't) for the following: + return 1 if $interfaceName eq "BarInfo"; + return 1 if $interfaceName eq "CSSStyleSheet"; + return 1 if $interfaceName eq "CanvasPixelArray"; + return 1 if $interfaceName eq "DOMSelection"; + return 1 if $interfaceName eq "DOMWindow"; + return 1 if $interfaceName eq "Element"; + return 1 if $interfaceName eq "Location"; + return 1 if $interfaceName eq "HTMLDocument"; + return 1 if $interfaceName eq "HTMLElement"; + return 1 if $interfaceName eq "History"; + return 1 if $interfaceName eq "NamedNodeMap"; + return 1 if $interfaceName eq "Navigator"; + return 1 if $interfaceName eq "SVGDocument"; + return 1 if $interfaceName eq "SVGElement"; + return 1 if $interfaceName eq "Screen"; + return 1 if $interfaceName eq "WorkerContext"; + # We don't generate a custom converter (but JSC does) for the following: + return 0 if $interfaceName eq "AbstractWorker"; + return 0 if $interfaceName eq "CanvasRenderingContext"; + return 0 if $interfaceName eq "ImageData"; + return 0 if $interfaceName eq "SVGElementInstance"; + + # For everything else, do what JSC does. + return $dataNode->extendedAttributes->{"CustomToJS"}; +} + +sub GetDomMapFunction +{ + my $dataNode = shift; + my $type = shift; + return "getDOMSVGElementInstanceMap()" if $type eq "SVGElementInstance"; + return "getDOMNodeMap()" if IsNodeSubType($dataNode); + # Only use getDOMSVGObjectWithContextMap() for non-node svg objects + return "getDOMSVGObjectWithContextMap()" if $type =~ /SVG/; + return "" if $type eq "DOMImplementation"; + return "getActiveDOMObjectMap()" if IsActiveDomType($type); + return "getDOMObjectMap()"; +} + +sub IsActiveDomType +{ + # FIXME: Consider making this an .idl attribute. + my $type = shift; + return 1 if $type eq "MessagePort"; + return 1 if $type eq "XMLHttpRequest"; + return 1 if $type eq "WebSocket"; + return 1 if $type eq "Worker"; + return 1 if $type eq "SharedWorker"; + return 0; +} + +sub GetNativeTypeForConversions +{ + my $type = shift; + return "FloatRect" if $type eq "SVGRect"; + return "FloatPoint" if $type eq "SVGPoint"; + return "AffineTransform" if $type eq "SVGMatrix"; + return "float" if $type eq "SVGNumber"; + return $type; +} sub GenerateFunctionCallString() { @@ -1497,7 +2154,6 @@ sub GenerateFunctionCallString() my $first = 1; my $index = 0; - my $nodeToReturn = 0; foreach my $parameter (@{$function->parameters}) { if ($index eq $numberOfParameters) { @@ -1519,16 +2175,20 @@ sub GenerateFunctionCallString() } else { $functionString .= $paramName; } - - if ($parameter->extendedAttributes->{"Return"}) { - $nodeToReturn = $parameter->name; - } $index++; } if ($function->signature->extendedAttributes->{"CustomArgumentHandling"}) { $functionString .= ", " if not $first; - $functionString .= "&callStack"; + $functionString .= "callStack.get()"; + if ($first) { $first = 0; } + } + + if ($function->signature->extendedAttributes->{"NeedsUserGestureCheck"}) { + $functionString .= ", " if not $first; + # FIXME: We need to pass DOMWrapperWorld as a parameter. + # See http://trac.webkit.org/changeset/54182 + $functionString .= "processingUserGesture()"; if ($first) { $first = 0; } } @@ -1541,24 +2201,10 @@ sub GenerateFunctionCallString() my $return = "result"; my $returnIsRef = IsRefPtrType($returnType); - if ($nodeToReturn) { - # Special case for insertBefore, replaceChild, removeChild and - # appendChild functions from Node. - $result .= $indent . "bool success = $functionString;\n"; - if (@{$function->raisesExceptions}) { - $result .= GenerateSetDOMException($indent); - } - $result .= $indent . "if (success)\n"; - $result .= $indent . " " . - "return V8DOMWrapper::convertNodeToV8Object($nodeToReturn);\n"; - $result .= $indent . "return v8::Null();\n"; - return $result; - } elsif ($returnType eq "void") { + if ($returnType eq "void") { $result .= $indent . "$functionString;\n"; } elsif ($copyFirst) { - $result .= - $indent . GetNativeType($returnType, 0) . " result = *imp;\n" . - $indent . "$functionString;\n"; + $result .= $indent . GetNativeType($returnType, 0) . " result = *imp;\n" . $indent . "$functionString;\n"; } elsif ($returnsListItemPodType) { $result .= $indent . "RefPtr<SVGPODListItem<$nativeReturnType> > result = $functionString;\n"; } elsif (@{$function->raisesExceptions} or $returnsPodType or $isPodType or IsSVGTypeNeedingContextParameter($returnType)) { @@ -1570,7 +2216,7 @@ sub GenerateFunctionCallString() } if (@{$function->raisesExceptions}) { - $result .= GenerateSetDOMException($indent); + $result .= $indent . "if (UNLIKELY(ec)) goto fail;\n"; } # If the return type is a POD type, separate out the wrapper generation @@ -1612,8 +2258,8 @@ sub GenerateFunctionCallString() } if ($returnsPodType) { - my $classIndex = uc($returnType); - $result .= $indent . "return V8DOMWrapper::convertToV8Object(V8ClassIndex::$classIndex, wrapper.release());\n"; + $implIncludes{"V8${returnType}.h"} = 1; + $result .= $indent . "return toV8(wrapper.release());\n"; } else { $return .= ".release()" if ($returnIsRef); $result .= $indent . ReturnNativeToJSValue($function->signature, $return, $indent) . ";\n"; @@ -1627,19 +2273,14 @@ sub GetTypeFromSignature { my $signature = shift; - my $type = $codeGenerator->StripModule($signature->type); - if (($type eq "DOMString") && $signature->extendedAttributes->{"HintAtomic"}) { - $type = "AtomicString"; - } - - return $type; + return $codeGenerator->StripModule($signature->type); } sub GetNativeTypeFromSignature { my $signature = shift; - my $isParameter = shift; + my $parameterIndex = shift; my $type = GetTypeFromSignature($signature); @@ -1648,117 +2289,39 @@ sub GetNativeTypeFromSignature return "int"; } - return GetNativeType($type, $isParameter); -} - -sub IsRefPtrType -{ - my $type = shift; - return 1 if $type eq "Attr"; - return 1 if $type eq "CanvasActiveInfo"; - return 1 if $type eq "CanvasArray"; - return 1 if $type eq "CanvasArrayBuffer"; - return 1 if $type eq "CanvasBooleanArray"; - return 1 if $type eq "CanvasByteArray"; - return 1 if $type eq "CanvasBuffer"; - return 1 if $type eq "CanvasFloatArray"; - return 1 if $type eq "CanvasFramebuffer"; - return 1 if $type eq "CanvasGradient"; - return 1 if $type eq "CanvasIntArray"; - return 1 if $type eq "CanvasObject"; - return 1 if $type eq "CanvasProgram"; - return 1 if $type eq "CanvasRenderbuffer"; - return 1 if $type eq "CanvasShader"; - return 1 if $type eq "CanvasShortArray"; - return 1 if $type eq "CanvasTexture"; - return 1 if $type eq "CanvasUnsignedByteArray"; - return 1 if $type eq "CanvasUnsignedIntArray"; - return 1 if $type eq "CanvasUnsignedShortArray"; - return 1 if $type eq "ClientRect"; - return 1 if $type eq "ClientRectList"; - return 1 if $type eq "CDATASection"; - return 1 if $type eq "Comment"; - return 1 if $type eq "CSSRule"; - return 1 if $type eq "CSSStyleRule"; - return 1 if $type eq "CSSCharsetRule"; - return 1 if $type eq "CSSImportRule"; - return 1 if $type eq "CSSMediaRule"; - return 1 if $type eq "CSSFontFaceRule"; - return 1 if $type eq "CSSPageRule"; - return 1 if $type eq "CSSPrimitiveValue"; - return 1 if $type eq "CSSStyleSheet"; - return 1 if $type eq "CSSStyleDeclaration"; - return 1 if $type eq "CSSValue"; - return 1 if $type eq "CSSRuleList"; - return 1 if $type eq "Database"; - return 1 if $type eq "Document"; - return 1 if $type eq "DocumentFragment"; - return 1 if $type eq "DocumentType"; - return 1 if $type eq "Element"; - return 1 if $type eq "EntityReference"; - return 1 if $type eq "Event"; - return 1 if $type eq "EventListener"; - return 1 if $type eq "FileList"; - return 1 if $type eq "HTMLCollection"; - return 1 if $type eq "HTMLAllCollection"; - return 1 if $type eq "HTMLDocument"; - return 1 if $type eq "HTMLElement"; - return 1 if $type eq "HTMLOptionsCollection"; - return 1 if $type eq "ImageData"; - return 1 if $type eq "Media"; - return 1 if $type eq "MediaError"; - return 1 if $type eq "MimeType"; - return 1 if $type eq "Node"; - return 1 if $type eq "NodeList"; - return 1 if $type eq "NodeFilter"; - return 1 if $type eq "NodeIterator"; - return 1 if $type eq "NSResolver"; - return 1 if $type eq "Plugin"; - return 1 if $type eq "ProcessingInstruction"; - return 1 if $type eq "Range"; - return 1 if $type eq "RGBColor"; - return 1 if $type eq "Text"; - return 1 if $type eq "TextMetrics"; - return 1 if $type eq "TimeRanges"; - return 1 if $type eq "TreeWalker"; - return 1 if $type eq "WebKitCSSMatrix"; - return 1 if $type eq "WebKitPoint"; - return 1 if $type eq "XPathExpression"; - return 1 if $type eq "XPathNSResolver"; - return 1 if $type eq "XPathResult"; - - return 1 if $type eq "SVGAngle"; - return 1 if $type eq "SVGElementInstance"; - return 1 if $type eq "SVGElementInstanceList"; - return 1 if $type =~ /^SVGPathSeg/; - - return 1 if $type =~ /^SVGAnimated/; + $type = GetNativeType($type, $parameterIndex >= 0 ? 1 : 0); - return 0; -} - -sub IsVideoClassName -{ - my $class = shift; - return 1 if $class eq "V8HTMLAudioElement"; - return 1 if $class eq "V8HTMLMediaElement"; - return 1 if $class eq "V8HTMLSourceElement"; - return 1 if $class eq "V8HTMLVideoElement"; - return 1 if $class eq "V8MediaError"; - return 1 if $class eq "V8TimeRanges"; + if ($parameterIndex >= 0 && $type eq "V8Parameter") { + my $mode = ""; + if ($signature->extendedAttributes->{"ConvertUndefinedOrNullToNullString"}) { + $mode = "WithUndefinedOrNullCheck"; + } elsif ($signature->extendedAttributes->{"ConvertNullToNullString"}) { + $mode = "WithNullCheck"; + } + $type .= "<$mode>"; + } - return 0; + return $type; } -sub IsWorkerClassName +sub IsRefPtrType { - my $class = shift; - return 1 if $class eq "V8Worker"; - return 1 if $class eq "V8WorkerContext"; - return 1 if $class eq "V8WorkerLocation"; - return 1 if $class eq "V8WorkerNavigator"; + my $type = shift; - return 0; + return 0 if $type eq "boolean"; + return 0 if $type eq "float"; + return 0 if $type eq "int"; + return 0 if $type eq "Date"; + return 0 if $type eq "DOMString"; + return 0 if $type eq "double"; + return 0 if $type eq "short"; + return 0 if $type eq "long"; + return 0 if $type eq "unsigned"; + return 0 if $type eq "unsigned long"; + return 0 if $type eq "unsigned short"; + return 0 if $type eq "SVGAnimatedPoints"; + + return 1; } sub GetNativeType @@ -1766,28 +2329,34 @@ sub GetNativeType my $type = shift; my $isParameter = shift; - if ($type eq "float" or $type eq "AtomicString" or $type eq "double") { + if ($type eq "float" or $type eq "double") { return $type; } + return "V8Parameter" if ($type eq "DOMString" or $type eq "DOMUserData") and $isParameter; return "int" if $type eq "int"; return "int" if $type eq "short" or $type eq "unsigned short"; return "unsigned" if $type eq "unsigned long"; return "int" if $type eq "long"; + return "long long" if $type eq "long long"; return "unsigned long long" if $type eq "unsigned long long"; return "bool" if $type eq "boolean"; return "String" if $type eq "DOMString"; return "Range::CompareHow" if $type eq "CompareHow"; return "FloatRect" if $type eq "SVGRect"; return "FloatPoint" if $type eq "SVGPoint"; - return "TransformationMatrix" if $type eq "SVGMatrix"; + return "AffineTransform" if $type eq "SVGMatrix"; return "SVGTransform" if $type eq "SVGTransform"; return "SVGLength" if $type eq "SVGLength"; - return "double" if $type eq "SVGNumber"; + return "SVGAngle" if $type eq "SVGAngle"; + return "float" if $type eq "SVGNumber"; + return "SVGPreserveAspectRatio" if $type eq "SVGPreserveAspectRatio"; return "SVGPaint::SVGPaintType" if $type eq "SVGPaintType"; return "DOMTimeStamp" if $type eq "DOMTimeStamp"; return "unsigned" if $type eq "unsigned int"; return "Node*" if $type eq "EventTarget" and $isParameter; + return "double" if $type eq "Date"; + return "ScriptValue" if $type eq "DOMObject"; return "String" if $type eq "DOMUserData"; # FIXME: Temporary hack? @@ -1803,69 +2372,6 @@ sub GetNativeType return "${type}*"; } - -my %typeCanFailConversion = ( - "AtomicString" => 0, - "Attr" => 1, - "CanvasArray" => 0, - "CanvasBuffer" => 0, - "CanvasByteArray" => 0, - "CanvasFloatArray" => 0, - "CanvasFramebuffer" => 0, - "CanvasGradient" => 0, - "CanvasIntArray" => 0, - "CanvasPixelArray" => 0, - "CanvasProgram" => 0, - "CanvasRenderbuffer" => 0, - "CanvasShader" => 0, - "CanvasShortArray" => 0, - "CanvasTexture" => 0, - "CompareHow" => 0, - "DataGridColumn" => 0, - "DOMString" => 0, - "DOMWindow" => 0, - "DocumentType" => 0, - "Element" => 0, - "Event" => 0, - "EventListener" => 0, - "EventTarget" => 0, - "HTMLCanvasElement" => 0, - "HTMLElement" => 0, - "HTMLImageElement" => 0, - "HTMLOptionElement" => 0, - "HTMLVideoElement" => 0, - "Node" => 0, - "NodeFilter" => 0, - "MessagePort" => 0, - "NSResolver" => 0, - "Range" => 0, - "SQLResultSet" => 0, - "Storage" => 0, - "SVGAngle" => 0, - "SVGElement" => 0, - "SVGLength" => 1, - "SVGMatrix" => 1, - "SVGNumber" => 0, - "SVGPaintType" => 0, - "SVGPathSeg" => 0, - "SVGPoint" => 1, - "SVGRect" => 1, - "SVGTransform" => 1, - "VoidCallback" => 1, - "WebKitCSSMatrix" => 0, - "WebKitPoint" => 0, - "XPathEvaluator" => 0, - "XPathNSResolver" => 0, - "XPathResult" => 0, - "boolean" => 0, - "double" => 0, - "float" => 0, - "long" => 0, - "unsigned long" => 0, - "unsigned short" => 0, -); - - sub TranslateParameter { my $signature = shift; @@ -1881,9 +2387,11 @@ sub BasicTypeCanFailConversion my $signature = shift; my $type = GetTypeFromSignature($signature); + return 1 if $type eq "SVGAngle"; return 1 if $type eq "SVGLength"; return 1 if $type eq "SVGMatrix"; return 1 if $type eq "SVGPoint"; + return 1 if $type eq "SVGPreserveAspectRatio"; return 1 if $type eq "SVGRect"; return 1 if $type eq "SVGTransform"; return 0; @@ -1896,10 +2404,9 @@ sub TypeCanFailConversion my $type = GetTypeFromSignature($signature); $implIncludes{"ExceptionCode.h"} = 1 if $type eq "Attr"; - - return $typeCanFailConversion{$type} if exists $typeCanFailConversion{$type}; - - die "Don't know whether a JS value can fail conversion to type $type."; + return 1 if $type eq "Attr"; + return 1 if $type eq "VoidCallback"; + return BasicTypeCanFailConversion($signature); } sub JSValueToNative @@ -1917,19 +2424,13 @@ sub JSValueToNative return "$value->NumberValue()" if $type eq "SVGNumber"; return "toInt32($value${maybeOkParam})" if $type eq "unsigned long" or $type eq "unsigned short" or $type eq "long"; + return "toInt64($value)" if $type eq "unsigned long long" or $type eq "long long"; return "static_cast<Range::CompareHow>($value->Int32Value())" if $type eq "CompareHow"; return "static_cast<SVGPaint::SVGPaintType>($value->ToInt32()->Int32Value())" if $type eq "SVGPaintType"; + return "toWebCoreDate($value)" if $type eq "Date"; - if ($type eq "AtomicString") { - return "v8ValueToAtomicWebCoreStringWithNullCheck($value)" if $signature->extendedAttributes->{"ConvertNullToNullString"}; - return "v8ValueToAtomicWebCoreString($value)"; - } - - return "toWebCoreString($value)" if $type eq "DOMUserData"; - if ($type eq "DOMString") { - return "toWebCoreStringWithNullCheck($value)" if $signature->extendedAttributes->{"ConvertNullToNullString"}; - return "toWebCoreStringWithNullOrUndefinedCheck($value)" if $signature->extendedAttributes->{"ConvertUndefinedOrNullToNullString"}; - return "toWebCoreString($value)"; + if ($type eq "DOMString" or $type eq "DOMUserData") { + return $value; } if ($type eq "SerializedScriptValue") { @@ -1937,6 +2438,11 @@ sub JSValueToNative return "SerializedScriptValue::create($value)"; } + if ($type eq "DOMObject") { + $implIncludes{"ScriptValue.h"} = 1; + return "ScriptValue($value)"; + } + if ($type eq "NodeFilter") { return "V8DOMWrapper::wrapNativeNodeFilter($value)"; } @@ -1950,12 +2456,11 @@ sub JSValueToNative } # Default, assume autogenerated type conversion routines - $implIncludes{"V8Proxy.h"} = 1; if ($type eq "EventTarget") { $implIncludes{"V8Node.h"} = 1; # EventTarget is not in DOM hierarchy, but all Nodes are EventTarget. - return "V8Node::HasInstance($value) ? V8DOMWrapper::convertDOMWrapperToNode<Node>(v8::Handle<v8::Object>::Cast($value)) : 0"; + return "V8Node::HasInstance($value) ? V8Node::toNative(v8::Handle<v8::Object>::Cast($value)) : 0"; } if ($type eq "XPathNSResolver") { @@ -1963,51 +2468,49 @@ sub JSValueToNative } AddIncludesForType($type); - # $implIncludes{"$type.h"} = 1 unless AvoidInclusionOfType($type); if (IsDOMNodeType($type)) { $implIncludes{"V8${type}.h"} = 1; # Perform type checks on the parameter, if it is expected Node type, # return NULL. - return "V8${type}::HasInstance($value) ? V8DOMWrapper::convertDOMWrapperToNode<${type}>(v8::Handle<v8::Object>::Cast($value)) : 0"; + return "V8${type}::HasInstance($value) ? V8${type}::toNative(v8::Handle<v8::Object>::Cast($value)) : 0"; } else { - # TODO: Temporary to avoid Window name conflict. - my $classIndex = uc($type); - my $implClassName = ${type}; - $implIncludes{"V8$type.h"} = 1; if (IsPodType($type)) { my $nativeType = GetNativeType($type); $implIncludes{"V8SVGPODTypeWrapper.h"} = 1; - return "V8SVGPODTypeUtil::toSVGPODType<${nativeType}>(V8ClassIndex::${classIndex}, $value${maybeOkParam})" + return "V8SVGPODTypeUtil::toSVGPODType<${nativeType}>(&V8${type}::info, $value${maybeOkParam})" } $implIncludes{"V8${type}.h"} = 1; # Perform type checks on the parameter, if it is expected Node type, # return NULL. - return "V8${type}::HasInstance($value) ? V8DOMWrapper::convertToNativeObject<${implClassName}>(V8ClassIndex::${classIndex}, v8::Handle<v8::Object>::Cast($value)) : 0"; + return "V8${type}::HasInstance($value) ? V8${type}::toNative(v8::Handle<v8::Object>::Cast($value)) : 0"; } } - sub GetV8HeaderName { my $type = shift; - return "V8" . GetImplementationFileName($type); + return "V8Event.h" if $type eq "DOMTimeStamp"; + return "EventListener.h" if $type eq "EventListener"; + return "EventTarget.h" if $type eq "EventTarget"; + return "SerializedScriptValue.h" if $type eq "SerializedScriptValue"; + return "ScriptValue.h" if $type eq "DOMObject"; + return "V8${type}.h"; } - sub CreateCustomSignature { my $function = shift; my $count = @{$function->parameters}; my $name = $function->signature->name; - my $result = " const int ${name}_argc = ${count};\n" . - " v8::Handle<v8::FunctionTemplate> ${name}_argv[${name}_argc] = { "; + my $result = " const int ${name}_argc = ${count};\n" . + " v8::Handle<v8::FunctionTemplate> ${name}_argv[${name}_argc] = { "; my $first = 1; foreach my $parameter (@{$function->parameters}) { if ($first) { $first = 0; } @@ -2028,7 +2531,7 @@ sub CreateCustomSignature } } $result .= " };\n"; - $result .= " v8::Handle<v8::Signature> ${name}_signature = v8::Signature::New(desc, ${name}_argc, ${name}_argv);\n"; + $result .= " v8::Handle<v8::Signature> ${name}_signature = v8::Signature::New(desc, ${name}_argc, ${name}_argv);\n"; return $result; } @@ -2043,9 +2546,9 @@ sub RequiresCustomSignature } foreach my $parameter (@{$function->parameters}) { - if (IsWrapperType($parameter->type)) { - return 1; - } + if (IsWrapperType($parameter->type)) { + return 1; + } } return 0; } @@ -2053,17 +2556,20 @@ sub RequiresCustomSignature my %non_wrapper_types = ( 'float' => 1, - 'AtomicString' => 1, 'double' => 1, 'short' => 1, 'unsigned short' => 1, 'long' => 1, 'unsigned long' => 1, 'boolean' => 1, + 'long long' => 1, + 'unsigned long long' => 1, 'DOMString' => 1, 'CompareHow' => 1, + 'SVGAngle' => 1, 'SVGRect' => 1, 'SVGPoint' => 1, + 'SVGPreserveAspectRatio' => 1, 'SVGMatrix' => 1, 'SVGTransform' => 1, 'SVGLength' => 1, @@ -2071,6 +2577,7 @@ my %non_wrapper_types = ( 'SVGPaintType' => 1, 'DOMTimeStamp' => 1, 'JSObject' => 1, + 'DOMObject' => 1, 'EventTarget' => 1, 'NodeFilter' => 1, 'EventListener' => 1 @@ -2119,11 +2626,10 @@ sub ReturnNativeToJSValue my $value = shift; my $indent = shift; my $type = GetTypeFromSignature($signature); - my $className= "V8$type"; return "return v8::Date::New(static_cast<double>($value))" if $type eq "DOMTimeStamp"; - return "return $value ? v8::True() : v8::False()" if $type eq "boolean"; - return "return v8::Undefined()" if $type eq "void"; + return "return v8Boolean($value)" if $type eq "boolean"; + return "return v8::Handle<v8::Value>()" if $type eq "void"; # equivalent to v8::Undefined() # For all the types where we use 'int' as the representation type, # we use Integer::New which has a fast Smi conversion check. @@ -2131,7 +2637,9 @@ sub ReturnNativeToJSValue return "return v8::Integer::New($value)" if $nativeType eq "int"; return "return v8::Integer::NewFromUnsigned($value)" if $nativeType eq "unsigned"; + return "return v8DateOrNull($value);" if $type eq "Date"; return "return v8::Number::New($value)" if $codeGenerator->IsPrimitiveType($type) or $type eq "SVGPaintType"; + return "return $value.v8Value()" if $nativeType eq "ScriptValue"; if ($codeGenerator->IsStringType($type)) { my $conv = $signature->extendedAttributes->{"ConvertNullStringTo"}; @@ -2145,61 +2653,36 @@ sub ReturnNativeToJSValue return "return v8String($value)"; } - # V8 specific. - my $implClassName = $type; AddIncludesForType($type); - # $implIncludes{GetImplementationFileName($type)} = 1 unless AvoidInclusionOfType($type); # special case for non-DOM node interfaces if (IsDOMNodeType($type)) { - if ($signature->extendedAttributes->{"ReturnsNew"}) { - return "return V8DOMWrapper::convertNewNodeToV8Object($value)"; - } else { - return "return V8DOMWrapper::convertNodeToV8Object($value)"; - } + return "return toV8(${value}" . ($signature->extendedAttributes->{"ReturnsNew"} ? ", true)" : ")"); } - if ($type eq "EventTarget" or $type eq "SVGElementInstance") { + if ($type eq "EventTarget") { return "return V8DOMWrapper::convertEventTargetToV8Object($value)"; } - if ($type eq "Event") { - return "return V8DOMWrapper::convertEventToV8Object($value)"; - } - if ($type eq "EventListener") { - return "return V8DOMWrapper::convertEventListenerToV8Object(imp->scriptExecutionContext(), $value)"; + $implIncludes{"V8AbstractEventListener.h"} = 1; + return "return ${value} ? v8::Handle<v8::Value>(static_cast<V8AbstractEventListener*>(${value})->getListenerObject(imp->scriptExecutionContext())) : v8::Handle<v8::Value>(v8::Null())"; } if ($type eq "SerializedScriptValue") { $implIncludes{"$type.h"} = 1; - return "return v8String($value->toString())"; + return "return $value->deserialize()"; } - if ($type eq "DedicatedWorkerContext" or $type eq "WorkerContext" or $type eq "SharedWorkerContext") { - $implIncludes{"WorkerContextExecutionProxy.h"} = 1; - return "return WorkerContextExecutionProxy::convertWorkerContextToV8Object($value)"; - } - - if ($type eq "WorkerLocation" or $type eq "WorkerNavigator" or $type eq "NotificationCenter") { - $implIncludes{"WorkerContextExecutionProxy.h"} = 1; - my $classIndex = uc($type); + $implIncludes{"wtf/RefCounted.h"} = 1; + $implIncludes{"wtf/RefPtr.h"} = 1; + $implIncludes{"wtf/GetPtr.h"} = 1; - return "return WorkerContextExecutionProxy::convertToV8Object(V8ClassIndex::$classIndex, $value)"; + if (IsPodType($type)) { + $value = GenerateSVGStaticPodTypeWrapper($type, $value) . ".get()"; } - else { - $implIncludes{"wtf/RefCounted.h"} = 1; - $implIncludes{"wtf/RefPtr.h"} = 1; - $implIncludes{"wtf/GetPtr.h"} = 1; - my $classIndex = uc($type); - - if (IsPodType($type)) { - $value = GenerateSVGStaticPodTypeWrapper($type, $value); - } - - return "return V8DOMWrapper::convertToV8Object(V8ClassIndex::$classIndex, $value)"; - } + return "return toV8($value)"; } sub GenerateSVGStaticPodTypeWrapper { @@ -2333,6 +2816,15 @@ sub IsSVGListTypeNeedingSpecialHandling return 0; } +sub GetVisibleInterfaceName +{ + my $interfaceName = shift; + + return "DOMException" if $interfaceName eq "DOMCoreException"; + return "FormData" if $interfaceName eq "DOMFormData"; + return $interfaceName; +} + sub DebugPrint { my $output = shift; diff --git a/src/3rdparty/webkit/WebCore/bindings/scripts/IDLParser.pm b/src/3rdparty/webkit/WebCore/bindings/scripts/IDLParser.pm index 4abdb45..7db7747 100644 --- a/src/3rdparty/webkit/WebCore/bindings/scripts/IDLParser.pm +++ b/src/3rdparty/webkit/WebCore/bindings/scripts/IDLParser.pm @@ -3,8 +3,6 @@ # # Copyright (C) 2005 Nikolas Zimmermann <wildfox@kde.org> # -# This file is part of the KDE project -# # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Library General Public # License as published by the Free Software Foundation; either @@ -16,7 +14,7 @@ # Library General Public License for more details. # # You should have received a copy of the GNU Library General Public License -# aint with this library; see the file COPYING.LIB. If not, write to +# along with this library; see the file COPYING.LIB. If not, write to # the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, # Boston, MA 02110-1301, USA. # @@ -66,7 +64,14 @@ sub Parse $parentsOnly = shift; if (!$preprocessor) { - $preprocessor = "/usr/bin/gcc -E -P -x c++"; + require Config; + my $gccLocation = ""; + if (($Config::Config{'osname'}) =~ /solaris/i) { + $gccLocation = "/usr/sfw/bin/gcc"; + } else { + $gccLocation = "/usr/bin/gcc"; + } + $preprocessor = $gccLocation . " -E -P -x c++"; } if (!$defines) { @@ -160,6 +165,7 @@ sub parseExtendedAttributes # Attributes with no value are set to be true $value = 1 unless defined $value; $attrs{$name} = $value; + die("Invalid extended attribute name: '$name'\n") if $name =~ /\s/; } return \%attrs; @@ -372,7 +378,9 @@ sub DetermineParseMode $mode = MODE_INTERFACE; } elsif ($_ =~ /exception/) { $mode = MODE_EXCEPTION; - } elsif ($_ =~ /alias/) { + } elsif ($_ =~ /(\A|\b)alias/) { + # The (\A|\b) above is needed so we don't match attributes + # whose names contain the substring "alias". $mode = MODE_ALIAS; } diff --git a/src/3rdparty/webkit/WebCore/bindings/scripts/IDLStructure.pm b/src/3rdparty/webkit/WebCore/bindings/scripts/IDLStructure.pm index 5a59ff1..6224e54 100644 --- a/src/3rdparty/webkit/WebCore/bindings/scripts/IDLStructure.pm +++ b/src/3rdparty/webkit/WebCore/bindings/scripts/IDLStructure.pm @@ -3,8 +3,6 @@ # # Copyright (C) 2005 Nikolas Zimmermann <wildfox@kde.org> # -# This file is part of the KDE project -# # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Library General Public # License as published by the Free Software Foundation; either @@ -16,7 +14,7 @@ # Library General Public License for more details. # # You should have received a copy of the GNU Library General Public License -# aint with this library; see the file COPYING.LIB. If not, write to +# along with this library; see the file COPYING.LIB. If not, write to # the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, # Boston, MA 02110-1301, USA. # diff --git a/src/3rdparty/webkit/WebCore/bindings/scripts/generate-bindings.pl b/src/3rdparty/webkit/WebCore/bindings/scripts/generate-bindings.pl index c7adeb3..44ed4d3 100755 --- a/src/3rdparty/webkit/WebCore/bindings/scripts/generate-bindings.pl +++ b/src/3rdparty/webkit/WebCore/bindings/scripts/generate-bindings.pl @@ -16,7 +16,7 @@ # Library General Public License for more details. # # You should have received a copy of the GNU Library General Public License -# aint with this library; see the file COPYING.LIB. If not, write to +# along with this library; see the file COPYING.LIB. If not, write to # the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, # Boston, MA 02110-1301, USA. # @@ -56,7 +56,6 @@ my $idlFile = $ARGV[0]; die('Must specify input file.') unless defined($idlFile); die('Must specify IDL search path.') unless @idlDirectories; die('Must specify generator') unless defined($generator); -die('Must specify input file.') unless defined($idlFile); die('Must specify output directory.') unless defined($outputDirectory); die('Must specify defines') unless defined($defines); |