diff options
Diffstat (limited to 'WebCore/bindings/js')
131 files changed, 2358 insertions, 1200 deletions
diff --git a/WebCore/bindings/js/CachedScriptSourceProvider.h b/WebCore/bindings/js/CachedScriptSourceProvider.h index e943fa5..1cdd8aa 100644 --- a/WebCore/bindings/js/CachedScriptSourceProvider.h +++ b/WebCore/bindings/js/CachedScriptSourceProvider.h @@ -29,11 +29,12 @@ #include "CachedResourceClient.h" #include "CachedResourceHandle.h" #include "CachedScript.h" +#include "ScriptSourceProvider.h" #include <parser/SourceCode.h> namespace WebCore { - class CachedScriptSourceProvider : public JSC::SourceProvider, public CachedResourceClient { + class CachedScriptSourceProvider : public ScriptSourceProvider, public CachedResourceClient { public: static PassRefPtr<CachedScriptSourceProvider> create(CachedScript* cachedScript) { return adoptRef(new CachedScriptSourceProvider(cachedScript)); } @@ -45,10 +46,11 @@ namespace WebCore { JSC::UString getRange(int start, int end) const { return JSC::UString(m_cachedScript->script().characters() + start, end - start); } const UChar* data() const { return m_cachedScript->script().characters(); } int length() const { return m_cachedScript->script().length(); } + const String& source() const { return m_cachedScript->script(); } private: CachedScriptSourceProvider(CachedScript* cachedScript) - : SourceProvider(cachedScript->url()) + : ScriptSourceProvider(cachedScript->url()) , m_cachedScript(cachedScript) { m_cachedScript->addClient(this); diff --git a/WebCore/bindings/js/DOMObjectWithSVGContext.h b/WebCore/bindings/js/DOMObjectWithSVGContext.h new file mode 100644 index 0000000..570548d --- /dev/null +++ b/WebCore/bindings/js/DOMObjectWithSVGContext.h @@ -0,0 +1,57 @@ +/* + * 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(PassRefPtr<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/WebCore/bindings/js/GCController.cpp b/WebCore/bindings/js/GCController.cpp index db295c2..59bcfa3 100644 --- a/WebCore/bindings/js/GCController.cpp +++ b/WebCore/bindings/js/GCController.cpp @@ -44,7 +44,7 @@ namespace WebCore { static void* collect(void*) { - JSLock lock(false); + JSLock lock(SilenceAssertionsOnly); JSDOMWindow::commonJSGlobalData()->heap.collect(); return 0; } @@ -70,13 +70,13 @@ void GCController::garbageCollectSoon() void GCController::gcTimerFired(Timer<GCController>*) { - JSLock lock(false); + JSLock lock(SilenceAssertionsOnly); JSDOMWindow::commonJSGlobalData()->heap.collect(); } void GCController::garbageCollectNow() { - JSLock lock(false); + JSLock lock(SilenceAssertionsOnly); JSDOMWindow::commonJSGlobalData()->heap.collect(); } diff --git a/WebCore/bindings/js/GCController.h b/WebCore/bindings/js/GCController.h index 452019a..4c25407 100644 --- a/WebCore/bindings/js/GCController.h +++ b/WebCore/bindings/js/GCController.h @@ -31,7 +31,7 @@ namespace WebCore { - class GCController : Noncopyable { + class GCController : public Noncopyable { friend GCController& gcController(); public: diff --git a/WebCore/bindings/js/JSAbstractWorkerCustom.cpp b/WebCore/bindings/js/JSAbstractWorkerCustom.cpp new file mode 100644 index 0000000..003f544 --- /dev/null +++ b/WebCore/bindings/js/JSAbstractWorkerCustom.cpp @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2009 Google Inc. All rights reserved. + * 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: + * + * * 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" + +#if ENABLE(WORKERS) + +#include "JSAbstractWorker.h" + +#include "AbstractWorker.h" +#include "JSDOMGlobalObject.h" +#include "JSEventListener.h" +#include "JSEventTarget.h" + +using namespace JSC; + +namespace WebCore { + +void JSAbstractWorker::markChildren(MarkStack& markStack) +{ + Base::markChildren(markStack); + + markIfNotNull(markStack, m_impl->onerror()); + + typedef AbstractWorker::EventListenersMap EventListenersMap; + typedef AbstractWorker::ListenerVector ListenerVector; + EventListenersMap& eventListeners = m_impl->eventListeners(); + for (EventListenersMap::iterator mapIter = eventListeners.begin(); mapIter != eventListeners.end(); ++mapIter) { + for (ListenerVector::iterator vecIter = mapIter->second.begin(); vecIter != mapIter->second.end(); ++vecIter) + (*vecIter)->markJSFunction(markStack); + } +} + +JSValue JSAbstractWorker::addEventListener(ExecState* exec, const ArgList& args) +{ + JSDOMGlobalObject* globalObject = toJSDOMGlobalObject(impl()->scriptExecutionContext()); + if (!globalObject) + return jsUndefined(); + RefPtr<JSEventListener> listener = globalObject->findOrCreateJSEventListener(args.at(1)); + if (!listener) + return jsUndefined(); + impl()->addEventListener(args.at(0).toString(exec), listener.release(), args.at(2).toBoolean(exec)); + return jsUndefined(); +} + +JSValue JSAbstractWorker::removeEventListener(ExecState* exec, const ArgList& args) +{ + JSDOMGlobalObject* globalObject = toJSDOMGlobalObject(impl()->scriptExecutionContext()); + if (!globalObject) + return jsUndefined(); + JSEventListener* listener = globalObject->findJSEventListener(args.at(1)); + if (!listener) + return jsUndefined(); + impl()->removeEventListener(args.at(0).toString(exec), listener, args.at(2).toBoolean(exec)); + return jsUndefined(); +} + +} // namespace WebCore + +#endif // ENABLE(WORKERS) diff --git a/WebCore/bindings/js/JSAttrCustom.cpp b/WebCore/bindings/js/JSAttrCustom.cpp index 4f3c8ee..abd5ad5 100644 --- a/WebCore/bindings/js/JSAttrCustom.cpp +++ b/WebCore/bindings/js/JSAttrCustom.cpp @@ -47,7 +47,7 @@ void JSAttr::setValue(ExecState* exec, JSValue value) Element* ownerElement = imp->ownerElement(); if (ownerElement && (ownerElement->hasTagName(iframeTag) || ownerElement->hasTagName(frameTag))) { - if (equalIgnoringCase(imp->name(), "src") && protocolIsJavaScript(parseURL(attrValue))) { + if (equalIgnoringCase(imp->name(), "src") && protocolIsJavaScript(deprecatedParseURL(attrValue))) { if (!checkNodeSecurity(exec, static_cast<HTMLFrameElementBase*>(ownerElement)->contentDocument())) return; } diff --git a/WebCore/bindings/js/JSAudioConstructor.cpp b/WebCore/bindings/js/JSAudioConstructor.cpp index 74bcad5..87a3880 100644 --- a/WebCore/bindings/js/JSAudioConstructor.cpp +++ b/WebCore/bindings/js/JSAudioConstructor.cpp @@ -42,35 +42,27 @@ namespace WebCore { const ClassInfo JSAudioConstructor::s_info = { "AudioConstructor", 0, 0, 0 }; JSAudioConstructor::JSAudioConstructor(ExecState* exec, JSDOMGlobalObject* globalObject) - : DOMObject(JSAudioConstructor::createStructure(exec->lexicalGlobalObject()->objectPrototype())) - , m_globalObject(globalObject) + : DOMConstructorWithDocument(JSAudioConstructor::createStructure(globalObject->objectPrototype()), globalObject) { - ASSERT(globalObject->scriptExecutionContext()); - ASSERT(globalObject->scriptExecutionContext()->isDocument()); - - putDirect(exec->propertyNames().prototype, JSHTMLAudioElementPrototype::self(exec, exec->lexicalGlobalObject()), None); + putDirect(exec->propertyNames().prototype, JSHTMLAudioElementPrototype::self(exec, globalObject), None); putDirect(exec->propertyNames().length, jsNumber(exec, 1), ReadOnly|DontDelete|DontEnum); } -Document* JSAudioConstructor::document() const -{ - return static_cast<Document*>(m_globalObject->scriptExecutionContext()); -} - 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 = static_cast<JSAudioConstructor*>(constructor)->document(); + Document* document = jsAudio->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, audio.release())); + return asObject(toJS(exec, jsAudio->globalObject(), audio.release())); } ConstructType JSAudioConstructor::getConstructData(ConstructData& constructData) @@ -79,13 +71,6 @@ ConstructType JSAudioConstructor::getConstructData(ConstructData& constructData) return ConstructTypeHost; } -void JSAudioConstructor::mark() -{ - DOMObject::mark(); - if (!m_globalObject->marked()) - m_globalObject->mark(); -} - } // namespace WebCore #endif // ENABLE(VIDEO) diff --git a/WebCore/bindings/js/JSAudioConstructor.h b/WebCore/bindings/js/JSAudioConstructor.h index 0a3a7ea..3496897 100644 --- a/WebCore/bindings/js/JSAudioConstructor.h +++ b/WebCore/bindings/js/JSAudioConstructor.h @@ -34,21 +34,15 @@ namespace WebCore { - class JSAudioConstructor : public DOMObject { + class JSAudioConstructor : public DOMConstructorWithDocument { public: JSAudioConstructor(JSC::ExecState*, JSDOMGlobalObject*); - Document* document() const; - static const JSC::ClassInfo s_info; - - virtual void mark(); private: virtual JSC::ConstructType getConstructData(JSC::ConstructData&); virtual const JSC::ClassInfo* classInfo() const { return &s_info; } - - JSDOMGlobalObject* m_globalObject; }; } // namespace WebCore diff --git a/WebCore/bindings/js/JSCDATASectionCustom.cpp b/WebCore/bindings/js/JSCDATASectionCustom.cpp index 44a8957..c2738cc 100644 --- a/WebCore/bindings/js/JSCDATASectionCustom.cpp +++ b/WebCore/bindings/js/JSCDATASectionCustom.cpp @@ -32,12 +32,12 @@ using namespace JSC; namespace WebCore { -JSValue toJSNewlyCreated(ExecState* exec, CDATASection* section) +JSValue toJSNewlyCreated(ExecState* exec, JSDOMGlobalObject* globalObject, CDATASection* section) { if (!section) return jsNull(); - - return CREATE_DOM_NODE_WRAPPER(exec, CDATASection, section); + + return CREATE_DOM_NODE_WRAPPER(exec, globalObject, CDATASection, section); } } // namespace WebCore diff --git a/WebCore/bindings/js/JSCSSRuleCustom.cpp b/WebCore/bindings/js/JSCSSRuleCustom.cpp index 2c20431..1b96c06 100644 --- a/WebCore/bindings/js/JSCSSRuleCustom.cpp +++ b/WebCore/bindings/js/JSCSSRuleCustom.cpp @@ -49,46 +49,45 @@ using namespace JSC; namespace WebCore { -JSValue toJS(ExecState* exec, CSSRule* rule) +JSValue toJS(ExecState* exec, JSDOMGlobalObject* globalObject, CSSRule* rule) { if (!rule) return jsNull(); DOMObject* wrapper = getCachedDOMObjectWrapper(exec->globalData(), rule); - if (wrapper) return wrapper; switch (rule->type()) { case CSSRule::STYLE_RULE: - wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, CSSStyleRule, rule); + wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, globalObject, CSSStyleRule, rule); break; case CSSRule::MEDIA_RULE: - wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, CSSMediaRule, rule); + wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, globalObject, CSSMediaRule, rule); break; case CSSRule::FONT_FACE_RULE: - wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, CSSFontFaceRule, rule); + wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, globalObject, CSSFontFaceRule, rule); break; case CSSRule::PAGE_RULE: - wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, CSSPageRule, rule); + wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, globalObject, CSSPageRule, rule); break; case CSSRule::IMPORT_RULE: - wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, CSSImportRule, rule); + wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, globalObject, CSSImportRule, rule); break; case CSSRule::CHARSET_RULE: - wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, CSSCharsetRule, rule); + wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, globalObject, CSSCharsetRule, rule); break; case CSSRule::VARIABLES_RULE: - wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, CSSVariablesRule, rule); + wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, globalObject, CSSVariablesRule, rule); break; case CSSRule::WEBKIT_KEYFRAME_RULE: - wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, WebKitCSSKeyframeRule, rule); + wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, globalObject, WebKitCSSKeyframeRule, rule); break; case CSSRule::WEBKIT_KEYFRAMES_RULE: - wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, WebKitCSSKeyframesRule, rule); + wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, globalObject, WebKitCSSKeyframesRule, rule); break; default: - wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, CSSRule, rule); + wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, globalObject, CSSRule, rule); } return wrapper; diff --git a/WebCore/bindings/js/JSCSSStyleDeclarationCustom.cpp b/WebCore/bindings/js/JSCSSStyleDeclarationCustom.cpp index b07f201..280ec93 100644 --- a/WebCore/bindings/js/JSCSSStyleDeclarationCustom.cpp +++ b/WebCore/bindings/js/JSCSSStyleDeclarationCustom.cpp @@ -125,7 +125,7 @@ bool JSCSSStyleDeclaration::canGetItemsForName(ExecState*, CSSStyleDeclaration*, return isCSSPropertyName(propertyName); } -// FIXME: You can get these properties, and set them (see customPut below), +// 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) { @@ -156,7 +156,7 @@ JSValue JSCSSStyleDeclaration::nameGetter(ExecState* exec, const Identifier& pro } -bool JSCSSStyleDeclaration::customPut(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot&) +bool JSCSSStyleDeclaration::putDelegate(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot&) { if (!isCSSPropertyName(propertyName)) return false; diff --git a/WebCore/bindings/js/JSCSSValueCustom.cpp b/WebCore/bindings/js/JSCSSValueCustom.cpp index ad0cee1..87a5760 100644 --- a/WebCore/bindings/js/JSCSSValueCustom.cpp +++ b/WebCore/bindings/js/JSCSSValueCustom.cpp @@ -44,7 +44,7 @@ using namespace JSC; namespace WebCore { -JSValue toJS(ExecState* exec, CSSValue* value) +JSValue toJS(ExecState* exec, JSDOMGlobalObject* globalObject, CSSValue* value) { if (!value) return jsNull(); @@ -55,19 +55,19 @@ JSValue toJS(ExecState* exec, CSSValue* value) return wrapper; if (value->isWebKitCSSTransformValue()) - wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, WebKitCSSTransformValue, value); + wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, globalObject, WebKitCSSTransformValue, value); else if (value->isValueList()) - wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, CSSValueList, value); + wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, globalObject, CSSValueList, value); #if ENABLE(SVG) else if (value->isSVGPaint()) - wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, SVGPaint, value); + wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, globalObject, SVGPaint, value); else if (value->isSVGColor()) - wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, SVGColor, value); + wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, globalObject, SVGColor, value); #endif else if (value->isPrimitiveValue()) - wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, CSSPrimitiveValue, value); + wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, globalObject, CSSPrimitiveValue, value); else - wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, CSSValue, value); + wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, globalObject, CSSValue, value); return wrapper; } diff --git a/WebCore/bindings/js/JSCanvasRenderingContext2DCustom.cpp b/WebCore/bindings/js/JSCanvasRenderingContext2DCustom.cpp index 76db871..398a6799 100644 --- a/WebCore/bindings/js/JSCanvasRenderingContext2DCustom.cpp +++ b/WebCore/bindings/js/JSCanvasRenderingContext2DCustom.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006, 2007 Apple Inc. All rights reserved. + * Copyright (C) 2006, 2007, 2009 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 @@ -28,11 +28,13 @@ #include "FloatRect.h" #include "HTMLCanvasElement.h" #include "HTMLImageElement.h" +#include "HTMLVideoElement.h" #include "ImageData.h" #include "JSCanvasGradient.h" #include "JSCanvasPattern.h" #include "JSHTMLCanvasElement.h" #include "JSHTMLImageElement.h" +#include "JSHTMLVideoElement.h" #include "JSImageData.h" #include <runtime/Error.h> @@ -230,6 +232,29 @@ JSValue JSCanvasRenderingContext2D::drawImage(ExecState* exec, const ArgList& ar default: return throwError(exec, SyntaxError); } +#if ENABLE(VIDEO) + } else if (o->inherits(&JSHTMLVideoElement::s_info)) { + HTMLVideoElement* video = static_cast<HTMLVideoElement*>(static_cast<JSHTMLElement*>(o)->impl()); + switch (args.size()) { + case 3: + context->drawImage(video, args.at(1).toFloat(exec), args.at(2).toFloat(exec)); + break; + case 5: + context->drawImage(video, args.at(1).toFloat(exec), args.at(2).toFloat(exec), + args.at(3).toFloat(exec), args.at(4).toFloat(exec), ec); + setDOMException(exec, ec); + break; + case 9: + context->drawImage(video, FloatRect(args.at(1).toFloat(exec), args.at(2).toFloat(exec), + args.at(3).toFloat(exec), args.at(4).toFloat(exec)), + FloatRect(args.at(5).toFloat(exec), args.at(6).toFloat(exec), + args.at(7).toFloat(exec), args.at(8).toFloat(exec)), ec); + setDOMException(exec, ec); + break; + default: + return throwError(exec, SyntaxError); + } +#endif } else { setDOMException(exec, TYPE_MISMATCH_ERR); } diff --git a/WebCore/bindings/js/JSCustomPositionCallback.cpp b/WebCore/bindings/js/JSCustomPositionCallback.cpp index 6d892f0..ec2d8e3 100644 --- a/WebCore/bindings/js/JSCustomPositionCallback.cpp +++ b/WebCore/bindings/js/JSCustomPositionCallback.cpp @@ -48,11 +48,12 @@ void JSCustomPositionCallback::handleEvent(Geoposition* geoposition) if (!m_frame->script()->isEnabled()) return; - + + // FIXME: This is likely the wrong globalObject (for prototype chains at least) JSGlobalObject* globalObject = m_frame->script()->globalObject(); ExecState* exec = globalObject->globalExec(); - JSC::JSLock lock(false); + JSC::JSLock lock(SilenceAssertionsOnly); JSValue function = m_callback->get(exec, Identifier(exec, "handleEvent")); CallData callData; @@ -67,10 +68,10 @@ void JSCustomPositionCallback::handleEvent(Geoposition* geoposition) } RefPtr<JSCustomPositionCallback> protect(this); - + MarkedArgumentBuffer args; - args.append(toJS(exec, geoposition)); - + args.append(toJS(exec, deprecatedGlobalObjectForPrototype(exec), geoposition)); + globalObject->globalData()->timeoutChecker.start(); call(exec, function, callType, callData, m_callback, args); globalObject->globalData()->timeoutChecker.stop(); diff --git a/WebCore/bindings/js/JSCustomPositionErrorCallback.cpp b/WebCore/bindings/js/JSCustomPositionErrorCallback.cpp index cc6cd55..cda5738 100644 --- a/WebCore/bindings/js/JSCustomPositionErrorCallback.cpp +++ b/WebCore/bindings/js/JSCustomPositionErrorCallback.cpp @@ -48,11 +48,12 @@ void JSCustomPositionErrorCallback::handleEvent(PositionError* positionError) if (!m_frame->script()->isEnabled()) return; - + + // FIXME: This is likely the wrong globalObject (for prototype chains at least) JSGlobalObject* globalObject = m_frame->script()->globalObject(); ExecState* exec = globalObject->globalExec(); - JSC::JSLock lock(false); + JSC::JSLock lock(SilenceAssertionsOnly); JSValue function = m_callback->get(exec, Identifier(exec, "handleEvent")); CallData callData; @@ -69,7 +70,7 @@ void JSCustomPositionErrorCallback::handleEvent(PositionError* positionError) RefPtr<JSCustomPositionErrorCallback> protect(this); MarkedArgumentBuffer args; - args.append(toJS(exec, positionError)); + args.append(toJS(exec, deprecatedGlobalObjectForPrototype(exec), positionError)); globalObject->globalData()->timeoutChecker.start(); call(exec, function, callType, callData, m_callback, args); diff --git a/WebCore/bindings/js/JSCustomSQLStatementCallback.cpp b/WebCore/bindings/js/JSCustomSQLStatementCallback.cpp index 107a491..d0943de 100644 --- a/WebCore/bindings/js/JSCustomSQLStatementCallback.cpp +++ b/WebCore/bindings/js/JSCustomSQLStatementCallback.cpp @@ -54,10 +54,11 @@ void JSCustomSQLStatementCallback::handleEvent(SQLTransaction* transaction, SQLR if (!m_frame->script()->isEnabled()) return; + // FIXME: This is likely the wrong globalObject (for prototype chains at least) JSGlobalObject* globalObject = m_frame->script()->globalObject(); ExecState* exec = globalObject->globalExec(); - JSC::JSLock lock(false); + JSC::JSLock lock(SilenceAssertionsOnly); JSValue function = m_callback->get(exec, Identifier(exec, "handleEvent")); CallData callData; @@ -74,8 +75,8 @@ void JSCustomSQLStatementCallback::handleEvent(SQLTransaction* transaction, SQLR RefPtr<JSCustomSQLStatementCallback> protect(this); MarkedArgumentBuffer args; - args.append(toJS(exec, transaction)); - args.append(toJS(exec, resultSet)); + args.append(toJS(exec, deprecatedGlobalObjectForPrototype(exec), transaction)); + args.append(toJS(exec, deprecatedGlobalObjectForPrototype(exec), resultSet)); globalObject->globalData()->timeoutChecker.start(); call(exec, function, callType, callData, m_callback, args); diff --git a/WebCore/bindings/js/JSCustomSQLStatementErrorCallback.cpp b/WebCore/bindings/js/JSCustomSQLStatementErrorCallback.cpp index 018dabd..6c831ac 100644 --- a/WebCore/bindings/js/JSCustomSQLStatementErrorCallback.cpp +++ b/WebCore/bindings/js/JSCustomSQLStatementErrorCallback.cpp @@ -54,11 +54,12 @@ bool JSCustomSQLStatementErrorCallback::handleEvent(SQLTransaction* transaction, if (!m_frame->script()->isEnabled()) return true; - + + // FIXME: This is likely the wrong globalObject (for prototype chains at least) JSGlobalObject* globalObject = m_frame->script()->globalObject(); ExecState* exec = globalObject->globalExec(); - JSC::JSLock lock(false); + JSC::JSLock lock(SilenceAssertionsOnly); JSValue handleEventFunction = m_callback->get(exec, Identifier(exec, "handleEvent")); CallData handleEventCallData; @@ -77,8 +78,8 @@ bool JSCustomSQLStatementErrorCallback::handleEvent(SQLTransaction* transaction, RefPtr<JSCustomSQLStatementErrorCallback> protect(this); MarkedArgumentBuffer args; - args.append(toJS(exec, transaction)); - args.append(toJS(exec, error)); + args.append(toJS(exec, deprecatedGlobalObjectForPrototype(exec), transaction)); + args.append(toJS(exec, deprecatedGlobalObjectForPrototype(exec), error)); JSValue result; globalObject->globalData()->timeoutChecker.start(); diff --git a/WebCore/bindings/js/JSCustomSQLTransactionCallback.cpp b/WebCore/bindings/js/JSCustomSQLTransactionCallback.cpp index a41ac78..3d42f81 100644 --- a/WebCore/bindings/js/JSCustomSQLTransactionCallback.cpp +++ b/WebCore/bindings/js/JSCustomSQLTransactionCallback.cpp @@ -94,11 +94,12 @@ void JSCustomSQLTransactionCallback::handleEvent(SQLTransaction* transaction, bo if (!m_data->frame()->script()->isEnabled()) return; - + + // FIXME: This is likely the wrong globalObject (for prototype chains at least) JSGlobalObject* globalObject = m_data->frame()->script()->globalObject(); ExecState* exec = globalObject->globalExec(); - JSC::JSLock lock(false); + JSC::JSLock lock(SilenceAssertionsOnly); JSValue handleEventFunction = m_data->callback()->get(exec, Identifier(exec, "handleEvent")); CallData handleEventCallData; @@ -117,7 +118,7 @@ void JSCustomSQLTransactionCallback::handleEvent(SQLTransaction* transaction, bo RefPtr<JSCustomSQLTransactionCallback> protect(this); MarkedArgumentBuffer args; - args.append(toJS(exec, transaction)); + args.append(toJS(exec, deprecatedGlobalObjectForPrototype(exec), transaction)); globalObject->globalData()->timeoutChecker.start(); if (handleEventCallType != CallTypeNone) diff --git a/WebCore/bindings/js/JSCustomSQLTransactionErrorCallback.cpp b/WebCore/bindings/js/JSCustomSQLTransactionErrorCallback.cpp index 324e2bb..2d41bb8 100644 --- a/WebCore/bindings/js/JSCustomSQLTransactionErrorCallback.cpp +++ b/WebCore/bindings/js/JSCustomSQLTransactionErrorCallback.cpp @@ -54,10 +54,11 @@ void JSCustomSQLTransactionErrorCallback::handleEvent(SQLError* error) if (!m_frame->script()->isEnabled()) return; + // FIXME: This is likely the wrong globalObject (for prototype chains at least) JSGlobalObject* globalObject = m_frame->script()->globalObject(); ExecState* exec = globalObject->globalExec(); - JSC::JSLock lock(false); + JSC::JSLock lock(SilenceAssertionsOnly); JSValue function = m_callback->get(exec, Identifier(exec, "handleEvent")); CallData callData; @@ -74,7 +75,7 @@ void JSCustomSQLTransactionErrorCallback::handleEvent(SQLError* error) RefPtr<JSCustomSQLTransactionErrorCallback> protect(this); MarkedArgumentBuffer args; - args.append(toJS(exec, error)); + args.append(toJS(exec, deprecatedGlobalObjectForPrototype(exec), error)); globalObject->globalData()->timeoutChecker.start(); call(exec, function, callType, callData, m_callback, args); diff --git a/WebCore/bindings/js/JSCustomVoidCallback.cpp b/WebCore/bindings/js/JSCustomVoidCallback.cpp index f3f76c4..b4e525b 100644 --- a/WebCore/bindings/js/JSCustomVoidCallback.cpp +++ b/WebCore/bindings/js/JSCustomVoidCallback.cpp @@ -55,7 +55,7 @@ void JSCustomVoidCallback::handleEvent() JSGlobalObject* globalObject = m_frame->script()->globalObject(); ExecState* exec = globalObject->globalExec(); - JSC::JSLock lock(false); + JSC::JSLock lock(SilenceAssertionsOnly); JSValue function = m_callback->get(exec, Identifier(exec, "handleEvent")); CallData callData; diff --git a/WebCore/bindings/js/JSCustomXPathNSResolver.cpp b/WebCore/bindings/js/JSCustomXPathNSResolver.cpp index 6361e70..4476be5 100644 --- a/WebCore/bindings/js/JSCustomXPathNSResolver.cpp +++ b/WebCore/bindings/js/JSCustomXPathNSResolver.cpp @@ -72,7 +72,7 @@ String JSCustomXPathNSResolver::lookupNamespaceURI(const String& prefix) if (!m_frame->script()->isEnabled()) return String(); - JSLock lock(false); + JSLock lock(SilenceAssertionsOnly); JSGlobalObject* globalObject = m_frame->script()->globalObject(); ExecState* exec = globalObject->globalExec(); @@ -84,7 +84,7 @@ String JSCustomXPathNSResolver::lookupNamespaceURI(const String& prefix) callType = m_customResolver->getCallData(callData); if (callType == CallTypeNone) { // FIXME: Pass actual line number and source URL. - m_frame->domWindow()->console()->addMessage(JSMessageSource, ErrorMessageLevel, "XPathNSResolver does not have a lookupNamespaceURI method.", 0, String()); + m_frame->domWindow()->console()->addMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, "XPathNSResolver does not have a lookupNamespaceURI method.", 0, String()); return String(); } function = m_customResolver; diff --git a/WebCore/bindings/js/JSDOMApplicationCacheCustom.cpp b/WebCore/bindings/js/JSDOMApplicationCacheCustom.cpp index 7e8d9ce..109308c 100644 --- a/WebCore/bindings/js/JSDOMApplicationCacheCustom.cpp +++ b/WebCore/bindings/js/JSDOMApplicationCacheCustom.cpp @@ -42,25 +42,25 @@ using namespace JSC; namespace WebCore { -void JSDOMApplicationCache::mark() +void JSDOMApplicationCache::markChildren(MarkStack& markStack) { - DOMObject::mark(); + Base::markChildren(markStack); - markIfNotNull(m_impl->onchecking()); - markIfNotNull(m_impl->onerror()); - markIfNotNull(m_impl->onnoupdate()); - markIfNotNull(m_impl->ondownloading()); - markIfNotNull(m_impl->onprogress()); - markIfNotNull(m_impl->onupdateready()); - markIfNotNull(m_impl->oncached()); - markIfNotNull(m_impl->onobsolete()); + markIfNotNull(markStack, m_impl->onchecking()); + markIfNotNull(markStack, m_impl->onerror()); + markIfNotNull(markStack, m_impl->onnoupdate()); + markIfNotNull(markStack, m_impl->ondownloading()); + markIfNotNull(markStack, m_impl->onprogress()); + markIfNotNull(markStack, m_impl->onupdateready()); + markIfNotNull(markStack, m_impl->oncached()); + markIfNotNull(markStack, m_impl->onobsolete()); typedef DOMApplicationCache::EventListenersMap EventListenersMap; typedef DOMApplicationCache::ListenerVector ListenerVector; EventListenersMap& eventListeners = m_impl->eventListeners(); for (EventListenersMap::iterator mapIter = eventListeners.begin(); mapIter != eventListeners.end(); ++mapIter) { for (ListenerVector::iterator vecIter = mapIter->second.begin(); vecIter != mapIter->second.end(); ++vecIter) - (*vecIter)->markJSFunction(); + (*vecIter)->markJSFunction(markStack); } } diff --git a/WebCore/bindings/js/JSDOMBinding.cpp b/WebCore/bindings/js/JSDOMBinding.cpp index 4f58797..566b986 100644 --- a/WebCore/bindings/js/JSDOMBinding.cpp +++ b/WebCore/bindings/js/JSDOMBinding.cpp @@ -18,11 +18,6 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -// gcc 3.x can't handle including the HashMap pointer specialization in this file -#if defined __GNUC__ && !defined __GLIBCXX__ // less than gcc 3.4 -#define HASH_MAP_PTR_SPEC_WORKAROUND 1 -#endif - #include "config.h" #include "JSDOMBinding.h" @@ -32,6 +27,7 @@ #include "EventException.h" #include "ExceptionCode.h" #include "Frame.h" +#include "HTMLAudioElement.h" #include "HTMLImageElement.h" #include "HTMLScriptElement.h" #include "HTMLNames.h" @@ -288,23 +284,27 @@ static inline bool isObservableThroughDOM(JSNode* jsNode) return true; if (node->hasTagName(scriptTag) && !static_cast<HTMLScriptElement*>(node)->haveFiredLoadEvent()) return true; +#if ENABLE(VIDEO) + if (node->hasTagName(audioTag) && !static_cast<HTMLAudioElement*>(node)->paused()) + return true; +#endif } return false; } -void markDOMNodesForDocument(Document* doc) +void markDOMNodesForDocument(MarkStack& markStack, Document* doc) { JSWrapperCache& nodeDict = doc->wrapperCache(); JSWrapperCache::iterator nodeEnd = nodeDict.end(); for (JSWrapperCache::iterator nodeIt = nodeDict.begin(); nodeIt != nodeEnd; ++nodeIt) { JSNode* jsNode = nodeIt->second; - if (!jsNode->marked() && isObservableThroughDOM(jsNode)) - jsNode->mark(); + if (isObservableThroughDOM(jsNode)) + markStack.append(jsNode); } } -void markActiveObjectsForContext(JSGlobalData& globalData, ScriptExecutionContext* scriptExecutionContext) +void markActiveObjectsForContext(MarkStack& markStack, JSGlobalData& globalData, ScriptExecutionContext* scriptExecutionContext) { // If an element has pending activity that may result in event listeners being called // (e.g. an XMLHttpRequest), we need to keep JS wrappers alive. @@ -317,19 +317,19 @@ void markActiveObjectsForContext(JSGlobalData& globalData, ScriptExecutionContex // 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'. - if (wrapper && !wrapper->marked()) - wrapper->mark(); + if (wrapper) + markStack.append(wrapper); } } const HashSet<MessagePort*>& messagePorts = scriptExecutionContext->messagePorts(); HashSet<MessagePort*>::const_iterator portsEnd = messagePorts.end(); for (HashSet<MessagePort*>::const_iterator iter = messagePorts.begin(); iter != portsEnd; ++iter) { - if ((*iter)->hasPendingActivity()) { + // If the message port is remotely entangled, then always mark it as in-use because we can't determine reachability across threads. + if (!(*iter)->locallyEntangledPort() || (*iter)->hasPendingActivity()) { DOMObject* wrapper = getCachedDOMObjectWrapper(globalData, *iter); - // A port with pending activity must have a wrapper to mark its listeners, so no null check. - if (!wrapper->marked()) - wrapper->mark(); + if (wrapper) + markStack.append(wrapper); } } } @@ -346,14 +346,14 @@ void updateDOMNodeDocument(Node* node, Document* oldDocument, Document* newDocum addWrapper(wrapper); } -void markDOMObjectWrapper(JSGlobalData& globalData, void* object) +void markDOMObjectWrapper(MarkStack& markStack, JSGlobalData& globalData, void* object) { if (!object) return; DOMObject* wrapper = getCachedDOMObjectWrapper(globalData, object); - if (!wrapper || wrapper->marked()) + if (!wrapper) return; - wrapper->mark(); + markStack.append(wrapper); } JSValue jsStringOrNull(ExecState* exec, const String& s) @@ -450,31 +450,36 @@ void setDOMException(ExecState* exec, ExceptionCode ec) if (!ec || exec->hadException()) return; + // FIXME: All callers to setDOMException need to pass in the right global object + // for now, we're going to assume the lexicalGlobalObject. Which is wrong in cases like this: + // frames[0].document.createElement(null, null); // throws an exception which should have the subframes prototypes. + JSDOMGlobalObject* globalObject = deprecatedGlobalObjectForPrototype(exec); + ExceptionCodeDescription description; getExceptionCodeDescription(ec, description); JSValue errorObject; switch (description.type) { case DOMExceptionType: - errorObject = toJS(exec, DOMCoreException::create(description)); + errorObject = toJS(exec, globalObject, DOMCoreException::create(description)); break; case RangeExceptionType: - errorObject = toJS(exec, RangeException::create(description)); + errorObject = toJS(exec, globalObject, RangeException::create(description)); break; case EventExceptionType: - errorObject = toJS(exec, EventException::create(description)); + errorObject = toJS(exec, globalObject, EventException::create(description)); break; case XMLHttpRequestExceptionType: - errorObject = toJS(exec, XMLHttpRequestException::create(description)); + errorObject = toJS(exec, globalObject, XMLHttpRequestException::create(description)); break; #if ENABLE(SVG) case SVGExceptionType: - errorObject = toJS(exec, SVGException::create(description).get(), 0); + errorObject = toJS(exec, globalObject, SVGException::create(description).get(), 0); break; #endif #if ENABLE(XPATH) case XPathExceptionType: - errorObject = toJS(exec, XPathException::create(description)); + errorObject = toJS(exec, globalObject, XPathException::create(description)); break; #endif } @@ -545,7 +550,7 @@ KURL completeURL(ExecState* exec, const String& relativeURL) JSValue objectToStringFunctionGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot&) { - return new (exec) PrototypeFunction(exec, 0, propertyName, objectProtoFuncToString); + return new (exec) NativeFunctionWrapper(exec, exec->lexicalGlobalObject()->prototypeFunctionStructure(), 0, propertyName, objectProtoFuncToString); } Structure* getCachedDOMStructure(JSDOMGlobalObject* globalObject, const ClassInfo* classInfo) diff --git a/WebCore/bindings/js/JSDOMBinding.h b/WebCore/bindings/js/JSDOMBinding.h index 1378c91..64cfc3a 100644 --- a/WebCore/bindings/js/JSDOMBinding.h +++ b/WebCore/bindings/js/JSDOMBinding.h @@ -1,7 +1,8 @@ /* * Copyright (C) 1999-2001 Harri Porten (porten@kde.org) - * Copyright (C) 2003, 2004, 2005, 2006, 2008 Apple Inc. All rights reserved. + * 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 @@ -22,6 +23,7 @@ #define JSDOMBinding_h #include "JSDOMGlobalObject.h" +#include "Document.h" // For DOMConstructorWithDocument #include <runtime/Completion.h> #include <runtime/Lookup.h> #include <runtime/JSFunction.h> @@ -59,6 +61,72 @@ namespace WebCore { #endif }; + // FIXME: This class should colapse into DOMObject once all DOMObjects are + // updated to store a globalObject pointer. + class DOMObjectWithGlobalPointer : public DOMObject { + public: + JSDOMGlobalObject* globalObject() const { return m_globalObject; } + + ScriptExecutionContext* scriptExecutionContext() const + { + // FIXME: Should never be 0, but can be due to bug 27640. + return m_globalObject->scriptExecutionContext(); + } + + protected: + DOMObjectWithGlobalPointer(PassRefPtr<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()); + } + 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. + class DOMConstructorObject : public DOMObjectWithGlobalPointer { + public: + static PassRefPtr<JSC::Structure> createStructure(JSC::JSValue prototype) + { + return JSC::Structure::create(prototype, JSC::TypeInfo(JSC::ObjectType, JSC::HasStandardGetOwnPropertySlot | JSC::ImplementsHasInstance)); + } + + protected: + DOMConstructorObject(PassRefPtr<JSC::Structure> structure, JSDOMGlobalObject* globalObject) + : DOMObjectWithGlobalPointer(structure, globalObject) + { + } + }; + + // Constructors using this base class depend on being in a Document and + // can never be used from a WorkerContext. + class DOMConstructorWithDocument : public DOMConstructorObject { + public: + Document* document() const + { + return static_cast<Document*>(scriptExecutionContext()); + } + + protected: + DOMConstructorWithDocument(PassRefPtr<JSC::Structure> structure, JSDOMGlobalObject* globalObject) + : DOMConstructorObject(structure, globalObject) + { + ASSERT(globalObject->scriptExecutionContext()->isDocument()); + } + }; + DOMObject* getCachedDOMObjectWrapper(JSC::JSGlobalData&, void* objectHandle); void cacheDOMObjectWrapper(JSC::JSGlobalData&, void* objectHandle, DOMObject* wrapper); void forgetDOMObject(JSC::JSGlobalData&, void* objectHandle); @@ -68,9 +136,9 @@ namespace WebCore { void forgetDOMNode(Document*, Node*); void forgetAllDOMNodesForDocument(Document*); void updateDOMNodeDocument(Node*, Document* oldDocument, Document* newDocument); - void markDOMNodesForDocument(Document*); - void markActiveObjectsForContext(JSC::JSGlobalData&, ScriptExecutionContext*); - void markDOMObjectWrapper(JSC::JSGlobalData& globalData, void* object); + void markDOMNodesForDocument(JSC::MarkStack&, Document*); + void markActiveObjectsForContext(JSC::MarkStack&, JSC::JSGlobalData&, ScriptExecutionContext*); + void markDOMObjectWrapper(JSC::MarkStack&, JSC::JSGlobalData& globalData, void* object); JSC::Structure* getCachedDOMStructure(JSDOMGlobalObject*, const JSC::ClassInfo*); JSC::Structure* cacheDOMStructure(JSDOMGlobalObject*, PassRefPtr<JSC::Structure>, const JSC::ClassInfo*); @@ -80,74 +148,86 @@ namespace WebCore { JSC::JSObject* getCachedDOMConstructor(JSC::ExecState*, const JSC::ClassInfo*); void cacheDOMConstructor(JSC::ExecState*, const JSC::ClassInfo*, JSC::JSObject* constructor); + inline JSDOMGlobalObject* deprecatedGlobalObjectForPrototype(JSC::ExecState* exec) + { + // FIXME: Callers to this function should be using the global object + // from which the object is being created, instead of assuming the lexical one. + // e.g. subframe.document.body should use the subframe's global object, not the lexical one. + return static_cast<JSDOMGlobalObject*>(exec->lexicalGlobalObject()); + } + template<class WrapperClass> inline JSC::Structure* getDOMStructure(JSC::ExecState* exec, JSDOMGlobalObject* globalObject) { if (JSC::Structure* structure = getCachedDOMStructure(globalObject, &WrapperClass::s_info)) return structure; return cacheDOMStructure(globalObject, WrapperClass::createStructure(WrapperClass::createPrototype(exec, globalObject)), &WrapperClass::s_info); } - template<class WrapperClass> inline JSC::Structure* getDOMStructure(JSC::ExecState* exec) + template<class WrapperClass> inline JSC::Structure* deprecatedGetDOMStructure(JSC::ExecState* exec) { - return getDOMStructure<WrapperClass>(exec, static_cast<JSDOMGlobalObject*>(exec->lexicalGlobalObject())); + // FIXME: This function is wrong. It uses the wrong global object for creating the prototype structure. + return getDOMStructure<WrapperClass>(exec, deprecatedGlobalObjectForPrototype(exec)); } template<class WrapperClass> inline JSC::JSObject* getDOMPrototype(JSC::ExecState* exec, JSC::JSGlobalObject* globalObject) { return static_cast<JSC::JSObject*>(asObject(getDOMStructure<WrapperClass>(exec, static_cast<JSDOMGlobalObject*>(globalObject))->storedPrototype())); } - #define CREATE_DOM_OBJECT_WRAPPER(exec, className, object) createDOMObjectWrapper<JS##className>(exec, static_cast<className*>(object)) - template<class WrapperClass, class DOMClass> inline DOMObject* createDOMObjectWrapper(JSC::ExecState* exec, DOMClass* object) + #define CREATE_DOM_OBJECT_WRAPPER(exec, globalObject, className, object) createDOMObjectWrapper<JS##className>(exec, globalObject, static_cast<className*>(object)) + template<class WrapperClass, class DOMClass> inline DOMObject* createDOMObjectWrapper(JSC::ExecState* exec, JSDOMGlobalObject* globalObject, DOMClass* object) { ASSERT(object); ASSERT(!getCachedDOMObjectWrapper(exec->globalData(), object)); - WrapperClass* wrapper = new (exec) WrapperClass(getDOMStructure<WrapperClass>(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); return wrapper; } - template<class WrapperClass, class DOMClass> inline JSC::JSValue getDOMObjectWrapper(JSC::ExecState* exec, DOMClass* object) + 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)) return wrapper; - return createDOMObjectWrapper<WrapperClass>(exec, object); + return createDOMObjectWrapper<WrapperClass>(exec, globalObject, object); } #if ENABLE(SVG) - #define CREATE_SVG_OBJECT_WRAPPER(exec, className, object, context) createDOMObjectWrapper<JS##className>(exec, static_cast<className*>(object), context) - template<class WrapperClass, class DOMClass> inline DOMObject* createDOMObjectWrapper(JSC::ExecState* exec, DOMClass* object, SVGElement* context) + #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), object, context); + WrapperClass* wrapper = new (exec) WrapperClass(getDOMStructure<WrapperClass>(exec, globalObject), globalObject, object, context); cacheDOMObjectWrapper(exec->globalData(), object, wrapper); return wrapper; } - template<class WrapperClass, class DOMClass> inline JSC::JSValue getDOMObjectWrapper(JSC::ExecState* exec, DOMClass* object, SVGElement* context) + 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)) return wrapper; - return createDOMObjectWrapper<WrapperClass>(exec, object, context); + return createDOMObjectWrapper<WrapperClass>(exec, globalObject, object, context); } #endif - #define CREATE_DOM_NODE_WRAPPER(exec, className, object) createDOMNodeWrapper<JS##className>(exec, static_cast<className*>(object)) - template<class WrapperClass, class DOMClass> inline JSNode* createDOMNodeWrapper(JSC::ExecState* exec, DOMClass* node) + #define CREATE_DOM_NODE_WRAPPER(exec, globalObject, className, object) createDOMNodeWrapper<JS##className>(exec, globalObject, static_cast<className*>(object)) + template<class WrapperClass, class DOMClass> inline JSNode* createDOMNodeWrapper(JSC::ExecState* exec, JSDOMGlobalObject* globalObject, DOMClass* node) { ASSERT(node); ASSERT(!getCachedDOMNodeWrapper(node->document(), node)); - WrapperClass* wrapper = new (exec) WrapperClass(getDOMStructure<WrapperClass>(exec), 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); return wrapper; } - template<class WrapperClass, class DOMClass> inline JSC::JSValue getDOMNodeWrapper(JSC::ExecState* exec, DOMClass* node) + 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)) return wrapper; - return createDOMNodeWrapper<WrapperClass>(exec, node); + return createDOMNodeWrapper<WrapperClass>(exec, globalObject, node); } const JSC::HashTable* getHashTableForGlobalData(JSC::JSGlobalData&, const JSC::HashTable* staticTable); @@ -174,7 +254,28 @@ 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 - template <typename T> inline JSC::JSValue toJS(JSC::ExecState* exec, PassRefPtr<T> ptr) { return toJS(exec, ptr.get()); } + // 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) + { + return toJS(exec, deprecatedGlobalObjectForPrototype(exec), ptr); + } + template <typename T> + inline JSC::JSValue toJS(JSC::ExecState* exec, PassRefPtr<T> ptr) + { + return toJS(exec, deprecatedGlobalObjectForPrototype(exec), ptr.get()); + } + template <typename T> + inline JSC::JSValue toJSNewlyCreated(JSC::ExecState* exec, T* ptr) + { + return toJSNewlyCreated(exec, deprecatedGlobalObjectForPrototype(exec), ptr); + } + + template <typename T> + inline JSC::JSValue toJS(JSC::ExecState* exec, JSDOMGlobalObject* globalObject, PassRefPtr<T> ptr) + { + return toJS(exec, globalObject, ptr.get()); + } bool checkNodeSecurity(JSC::ExecState*, Node*); diff --git a/WebCore/bindings/js/JSDOMGlobalObject.cpp b/WebCore/bindings/js/JSDOMGlobalObject.cpp index a7f7b21..68a1db9 100644 --- a/WebCore/bindings/js/JSDOMGlobalObject.cpp +++ b/WebCore/bindings/js/JSDOMGlobalObject.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008 Apple Inc. All Rights Reserved. + * 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 @@ -58,19 +58,17 @@ JSDOMGlobalObject::~JSDOMGlobalObject() it->second->clearGlobalObject(); } -void JSDOMGlobalObject::mark() +void JSDOMGlobalObject::markChildren(MarkStack& markStack) { - Base::mark(); + Base::markChildren(markStack); JSDOMStructureMap::iterator end = structures().end(); for (JSDOMStructureMap::iterator it = structures().begin(); it != end; ++it) - it->second->mark(); + it->second->markAggregate(markStack); JSDOMConstructorMap::iterator end2 = constructors().end(); - for (JSDOMConstructorMap::iterator it2 = constructors().begin(); it2 != end2; ++it2) { - if (!it2->second->marked()) - it2->second->mark(); - } + for (JSDOMConstructorMap::iterator it2 = constructors().begin(); it2 != end2; ++it2) + markStack.append(it2->second); } JSEventListener* JSDOMGlobalObject::findJSEventListener(JSValue val) @@ -116,10 +114,15 @@ Event* JSDOMGlobalObject::currentEvent() const return d()->evt; } +JSDOMGlobalObject* toJSDOMGlobalObject(Document* document) +{ + return toJSDOMWindow(document->frame()); +} + JSDOMGlobalObject* toJSDOMGlobalObject(ScriptExecutionContext* scriptExecutionContext) { if (scriptExecutionContext->isDocument()) - return toJSDOMWindow(static_cast<Document*>(scriptExecutionContext)->frame()); + return toJSDOMGlobalObject(static_cast<Document*>(scriptExecutionContext)); #if ENABLE(WORKERS) if (scriptExecutionContext->isWorkerContext()) diff --git a/WebCore/bindings/js/JSDOMGlobalObject.h b/WebCore/bindings/js/JSDOMGlobalObject.h index 8e4e820..855691c 100644 --- a/WebCore/bindings/js/JSDOMGlobalObject.h +++ b/WebCore/bindings/js/JSDOMGlobalObject.h @@ -31,6 +31,7 @@ namespace WebCore { + class Document; class Event; class JSLazyEventListener; class JSEventListener; @@ -67,10 +68,13 @@ namespace WebCore { JSListenersMap& jsEventListeners(); + // Make binding code generation easier. + JSDOMGlobalObject* globalObject() { return this; } + void setCurrentEvent(Event*); Event* currentEvent() const; - virtual void mark(); + virtual void markChildren(JSC::MarkStack&); protected: struct JSDOMGlobalObjectData : public JSC::JSGlobalObject::JSGlobalObjectData { @@ -89,16 +93,6 @@ namespace WebCore { }; template<class ConstructorClass> - inline JSC::JSObject* getDOMConstructor(JSC::ExecState* exec) - { - if (JSC::JSObject* constructor = getCachedDOMConstructor(exec, &ConstructorClass::s_info)) - return constructor; - JSC::JSObject* constructor = new (exec) ConstructorClass(exec); - cacheDOMConstructor(exec, &ConstructorClass::s_info, constructor); - return constructor; - } - - template<class ConstructorClass> inline JSC::JSObject* getDOMConstructor(JSC::ExecState* exec, const JSDOMGlobalObject* globalObject) { if (JSC::JSObject* constructor = globalObject->constructors().get(&ConstructorClass::s_info)) @@ -109,6 +103,7 @@ namespace WebCore { return constructor; } + JSDOMGlobalObject* toJSDOMGlobalObject(Document*); JSDOMGlobalObject* toJSDOMGlobalObject(ScriptExecutionContext*); } // namespace WebCore diff --git a/WebCore/bindings/js/JSDOMWindowBase.cpp b/WebCore/bindings/js/JSDOMWindowBase.cpp index 4fd1139..df6068a 100644 --- a/WebCore/bindings/js/JSDOMWindowBase.cpp +++ b/WebCore/bindings/js/JSDOMWindowBase.cpp @@ -26,13 +26,9 @@ #include "CString.h" #include "Console.h" #include "DOMWindow.h" -#include "Element.h" #include "Frame.h" -#include "HTMLCollection.h" -#include "HTMLDocument.h" #include "InspectorController.h" #include "JSDOMWindowCustom.h" -#include "JSHTMLCollection.h" #include "JSNode.h" #include "Logging.h" #include "Page.h" @@ -67,7 +63,7 @@ void JSDOMWindowBase::updateDocument() { ASSERT(d()->impl->document()); ExecState* exec = globalExec(); - symbolTablePutWithAttributes(Identifier(exec, "document"), toJS(exec, d()->impl->document()), DontDelete | ReadOnly); + symbolTablePutWithAttributes(Identifier(exec, "document"), toJS(exec, this, d()->impl->document()), DontDelete | ReadOnly); } ScriptExecutionContext* JSDOMWindowBase::scriptExecutionContext() const @@ -75,88 +71,6 @@ ScriptExecutionContext* JSDOMWindowBase::scriptExecutionContext() const return d()->impl->document(); } -JSValue JSDOMWindowBase::childFrameGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot) -{ - return toJS(exec, static_cast<JSDOMWindowBase*>(asObject(slot.slotBase()))->impl()->frame()->tree()->child(AtomicString(propertyName))->domWindow()); -} - -JSValue JSDOMWindowBase::indexGetter(ExecState* exec, const Identifier&, const PropertySlot& slot) -{ - return toJS(exec, static_cast<JSDOMWindowBase*>(asObject(slot.slotBase()))->impl()->frame()->tree()->child(slot.index())->domWindow()); -} - -JSValue JSDOMWindowBase::namedItemGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot) -{ - JSDOMWindowBase* thisObj = static_cast<JSDOMWindowBase*>(asObject(slot.slotBase())); - Document* doc = thisObj->impl()->frame()->document(); - ASSERT(thisObj->allowsAccessFrom(exec)); - ASSERT(doc); - ASSERT(doc->isHTMLDocument()); - - RefPtr<HTMLCollection> collection = doc->windowNamedItems(propertyName); - if (collection->length() == 1) - return toJS(exec, collection->firstItem()); - return toJS(exec, collection.get()); -} - -bool JSDOMWindowBase::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot) -{ - // Check for child frames by name before built-in properties to - // match Mozilla. This does not match IE, but some sites end up - // naming frames things that conflict with window properties that - // are in Moz but not IE. Since we have some of these, we have to do - // it the Moz way. - if (impl()->frame()->tree()->child(propertyName)) { - slot.setCustom(this, childFrameGetter); - 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)->getPropertySlot(exec, propertyName, slot)) { - if (!allowsAccessFrom(exec)) - slot.setUndefined(); - return true; - } - } - - // FIXME: Search the whole frame hierachy somewhere around here. - // We need to test the correct priority order. - - // allow window[1] or parent[1] etc. (#56983) - bool ok; - unsigned i = propertyName.toArrayIndex(&ok); - if (ok && i < impl()->frame()->tree()->childCount()) { - slot.setCustomIndex(this, i, indexGetter); - return true; - } - - if (!allowsAccessFrom(exec)) { - slot.setUndefined(); - return true; - } - - // Allow shortcuts like 'Image1' instead of document.images.Image1 - Document* document = impl()->frame()->document(); - if (document->isHTMLDocument()) { - AtomicStringImpl* atomicPropertyName = AtomicString::find(propertyName); - if (atomicPropertyName && (static_cast<HTMLDocument*>(document)->hasNamedItem(atomicPropertyName) || document->hasElementWithId(atomicPropertyName))) { - slot.setCustom(this, namedItemGetter); - return true; - } - } - - return Base::getOwnPropertySlot(exec, propertyName, slot); -} - -void JSDOMWindowBase::put(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot) -{ - if (allowsAccessFrom(exec)) - Base::put(exec, propertyName, value, slot); -} - String JSDOMWindowBase::crossDomainAccessErrorMessage(const JSGlobalObject* other) const { KURL originURL = asJSDOMWindow(other)->impl()->url(); @@ -185,7 +99,7 @@ void JSDOMWindowBase::printErrorMessage(const String& message) const if (settings->privateBrowsingEnabled()) return; - impl()->console()->addMessage(JSMessageSource, ErrorMessageLevel, message, 1, String()); // FIXME: provide a real line number and source URL. + impl()->console()->addMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, message, 1, String()); // FIXME: provide a real line number and source URL. } ExecState* JSDOMWindowBase::globalExec() @@ -258,6 +172,13 @@ JSGlobalData* JSDOMWindowBase::commonJSGlobalData() return globalData; } +// JSDOMGlobalObject* is ignored, accesing a window in any context will +// use that DOMWindow's prototype chain. +JSValue toJS(ExecState* exec, JSDOMGlobalObject*, DOMWindow* domWindow) +{ + return toJS(exec, domWindow); +} + JSValue toJS(ExecState*, DOMWindow* domWindow) { if (!domWindow) diff --git a/WebCore/bindings/js/JSDOMWindowBase.h b/WebCore/bindings/js/JSDOMWindowBase.h index 6d93196..84cc81f 100644 --- a/WebCore/bindings/js/JSDOMWindowBase.h +++ b/WebCore/bindings/js/JSDOMWindowBase.h @@ -40,7 +40,6 @@ namespace WebCore { class JSDOMWindowBasePrivate; - // This is the only WebCore JS binding which does not inherit from DOMObject class JSDOMWindowBase : public JSDOMGlobalObject { typedef JSDOMGlobalObject Base; protected: @@ -52,9 +51,6 @@ namespace WebCore { DOMWindow* impl() const { return d()->impl.get(); } virtual ScriptExecutionContext* scriptExecutionContext() const; - virtual bool getOwnPropertySlot(JSC::ExecState*, const JSC::Identifier&, JSC::PropertySlot&); - virtual void put(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::JSValue, JSC::PutPropertySlot&); - // Called just before removing this window from the JSDOMWindowShell. void willRemoveFromWindowShell(); @@ -62,15 +58,12 @@ namespace WebCore { static const JSC::ClassInfo s_info; virtual JSC::ExecState* globalExec(); - virtual bool supportsProfiling() const; - virtual bool shouldInterruptScript() const; bool allowsAccessFrom(JSC::ExecState*) const; bool allowsAccessFromNoErrorMessage(JSC::ExecState*) const; bool allowsAccessFrom(JSC::ExecState*, String& message) const; - void printErrorMessage(const String&) const; // Don't call this version of allowsAccessFrom -- it's a slightly incorrect implementation used only by WebScriptObject @@ -89,10 +82,6 @@ namespace WebCore { JSDOMWindowShell* shell; }; - static JSC::JSValue childFrameGetter(JSC::ExecState*, const JSC::Identifier&, const JSC::PropertySlot&); - static JSC::JSValue indexGetter(JSC::ExecState*, const JSC::Identifier&, const JSC::PropertySlot&); - static JSC::JSValue namedItemGetter(JSC::ExecState*, const JSC::Identifier&, const JSC::PropertySlot&); - bool allowsAccessFromPrivate(const JSC::JSGlobalObject*) const; String crossDomainAccessErrorMessage(const JSC::JSGlobalObject*) const; @@ -100,6 +89,9 @@ namespace WebCore { }; // Returns a JSDOMWindow or jsNull() + // JSDOMGlobalObject* is ignored, accesing 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*); // Returns JSDOMWindow or 0 diff --git a/WebCore/bindings/js/JSDOMWindowCustom.cpp b/WebCore/bindings/js/JSDOMWindowCustom.cpp index b8c30c7..9798972 100644 --- a/WebCore/bindings/js/JSDOMWindowCustom.cpp +++ b/WebCore/bindings/js/JSDOMWindowCustom.cpp @@ -31,17 +31,21 @@ #include "FrameLoader.h" #include "FrameTree.h" #include "FrameView.h" +#include "HTMLCollection.h" +#include "HTMLDocument.h" #include "History.h" #include "JSAudioConstructor.h" #include "JSDOMWindowShell.h" #include "JSEvent.h" #include "JSEventListener.h" +#include "JSHTMLCollection.h" #include "JSHistory.h" #include "JSImageConstructor.h" #include "JSLocation.h" #include "JSMessageChannelConstructor.h" #include "JSMessagePort.h" #include "JSOptionConstructor.h" +#include "JSSharedWorkerConstructor.h" #include "JSWebKitCSSMatrixConstructor.h" #include "JSWebKitPointConstructor.h" #include "JSWorkerConstructor.h" @@ -58,40 +62,234 @@ #include "Settings.h" #include "WindowFeatures.h" #include <runtime/JSObject.h> +#include <runtime/PrototypeFunction.h> using namespace JSC; namespace WebCore { -void JSDOMWindow::mark() +void JSDOMWindow::markChildren(MarkStack& markStack) { - Base::mark(); + Base::markChildren(markStack); - markEventListeners(impl()->eventListeners()); + markEventListeners(markStack, impl()->eventListeners()); JSGlobalData& globalData = *Heap::heap(this)->globalData(); - markDOMObjectWrapper(globalData, impl()->optionalConsole()); - markDOMObjectWrapper(globalData, impl()->optionalHistory()); - markDOMObjectWrapper(globalData, impl()->optionalLocationbar()); - markDOMObjectWrapper(globalData, impl()->optionalMenubar()); - markDOMObjectWrapper(globalData, impl()->optionalNavigator()); - markDOMObjectWrapper(globalData, impl()->optionalPersonalbar()); - markDOMObjectWrapper(globalData, impl()->optionalScreen()); - markDOMObjectWrapper(globalData, impl()->optionalScrollbars()); - markDOMObjectWrapper(globalData, impl()->optionalSelection()); - markDOMObjectWrapper(globalData, impl()->optionalStatusbar()); - markDOMObjectWrapper(globalData, impl()->optionalToolbar()); - markDOMObjectWrapper(globalData, impl()->optionalLocation()); + markDOMObjectWrapper(markStack, globalData, impl()->optionalConsole()); + markDOMObjectWrapper(markStack, globalData, impl()->optionalHistory()); + markDOMObjectWrapper(markStack, globalData, impl()->optionalLocationbar()); + markDOMObjectWrapper(markStack, globalData, impl()->optionalMenubar()); + markDOMObjectWrapper(markStack, globalData, impl()->optionalNavigator()); + markDOMObjectWrapper(markStack, globalData, impl()->optionalPersonalbar()); + markDOMObjectWrapper(markStack, globalData, impl()->optionalScreen()); + markDOMObjectWrapper(markStack, globalData, impl()->optionalScrollbars()); + markDOMObjectWrapper(markStack, globalData, impl()->optionalSelection()); + markDOMObjectWrapper(markStack, globalData, impl()->optionalStatusbar()); + markDOMObjectWrapper(markStack, globalData, impl()->optionalToolbar()); + markDOMObjectWrapper(markStack, globalData, impl()->optionalLocation()); #if ENABLE(DOM_STORAGE) - markDOMObjectWrapper(globalData, impl()->optionalSessionStorage()); - markDOMObjectWrapper(globalData, impl()->optionalLocalStorage()); + markDOMObjectWrapper(markStack, globalData, impl()->optionalSessionStorage()); + markDOMObjectWrapper(markStack, globalData, impl()->optionalLocalStorage()); #endif #if ENABLE(OFFLINE_WEB_APPLICATIONS) - markDOMObjectWrapper(globalData, impl()->optionalApplicationCache()); + markDOMObjectWrapper(markStack, globalData, impl()->optionalApplicationCache()); #endif } +template<NativeFunction nativeFunction, int length> +JSValue nonCachingStaticFunctionGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot&) +{ + return new (exec) NativeFunctionWrapper(exec, exec->lexicalGlobalObject()->prototypeFunctionStructure(), length, propertyName, nativeFunction); +} + +static JSValue childFrameGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot) +{ + return toJS(exec, static_cast<JSDOMWindow*>(asObject(slot.slotBase()))->impl()->frame()->tree()->child(AtomicString(propertyName))->domWindow()); +} + +static JSValue indexGetter(ExecState* exec, const Identifier&, const PropertySlot& slot) +{ + return toJS(exec, static_cast<JSDOMWindow*>(asObject(slot.slotBase()))->impl()->frame()->tree()->child(slot.index())->domWindow()); +} + +static JSValue namedItemGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot) +{ + JSDOMWindowBase* thisObj = static_cast<JSDOMWindow*>(asObject(slot.slotBase())); + Document* document = thisObj->impl()->frame()->document(); + + ASSERT(thisObj->allowsAccessFrom(exec)); + ASSERT(document); + ASSERT(document->isHTMLDocument()); + + RefPtr<HTMLCollection> collection = document->windowNamedItems(propertyName); + if (collection->length() == 1) + return toJS(exec, collection->firstItem()); + return toJS(exec, collection.get()); +} + +bool JSDOMWindow::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot) +{ + // 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. + + const HashEntry* entry; + + // We don't want any properties other than "close" and "closed" on a closed window. + if (!impl()->frame()) { + // The following code is safe for cross-domain and same domain use. + // It ignores any custom properties that might be set on the DOMWindow (including a custom prototype). + entry = s_info.propHashTable(exec)->entry(exec, propertyName); + if (entry && !(entry->attributes() & Function) && entry->propertyGetter() == jsDOMWindowClosed) { + slot.setCustom(this, entry->propertyGetter()); + return true; + } + entry = JSDOMWindowPrototype::s_info.propHashTable(exec)->entry(exec, propertyName); + if (entry && (entry->attributes() & Function) && entry->function() == jsDOMWindowPrototypeFunctionClose) { + slot.setCustom(this, nonCachingStaticFunctionGetter<jsDOMWindowPrototypeFunctionClose, 0>); + return true; + } + + // FIXME: We should have a message here that explains why the property access/function call was + // not allowed. + slot.setUndefined(); + return true; + } + + // We need to check for cross-domain access here without printing the generic warning message + // because we always allow access to some function, just different ones depending whether access + // is allowed. + String errorMessage; + bool allowsAccess = allowsAccessFrom(exec, errorMessage); + + // Look for overrides before looking at any of our own properties, but ignore overrides completely + // if this is cross-domain access. + if (allowsAccess && JSGlobalObject::getOwnPropertySlot(exec, propertyName, slot)) + 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) { + slot.setCustom(this, nonCachingStaticFunctionGetter<jsDOMWindowPrototypeFunctionBlur, 0>); + return true; + } + } else if (entry->function() == jsDOMWindowPrototypeFunctionClose) { + if (!allowsAccess) { + slot.setCustom(this, nonCachingStaticFunctionGetter<jsDOMWindowPrototypeFunctionClose, 0>); + return true; + } + } else if (entry->function() == jsDOMWindowPrototypeFunctionFocus) { + if (!allowsAccess) { + slot.setCustom(this, nonCachingStaticFunctionGetter<jsDOMWindowPrototypeFunctionFocus, 0>); + return true; + } + } else if (entry->function() == jsDOMWindowPrototypeFunctionPostMessage) { + if (!allowsAccess) { + slot.setCustom(this, nonCachingStaticFunctionGetter<jsDOMWindowPrototypeFunctionPostMessage, 2>); + return true; + } + } else if (entry->function() == jsDOMWindowPrototypeFunctionShowModalDialog) { + if (!DOMWindow::canShowModalDialog(impl()->frame())) { + slot.setUndefined(); + return true; + } + } + } + } else { + // Allow access to toString() cross-domain, but always Object.prototype.toString. + if (propertyName == exec->propertyNames().toString) { + if (!allowsAccess) { + slot.setCustom(this, objectToStringFunctionGetter); + return true; + } + } + } + + entry = JSDOMWindow::s_info.propHashTable(exec)->entry(exec, propertyName); + if (entry) { + slot.setCustom(this, entry->propertyGetter()); + return true; + } + + // Check for child frames by name before built-in properties to + // match Mozilla. This does not match IE, but some sites end up + // naming frames things that conflict with window properties that + // are in Moz but not IE. Since we have some of these, we have to do + // it the Moz way. + if (impl()->frame()->tree()->child(propertyName)) { + slot.setCustom(this, childFrameGetter); + 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)->getPropertySlot(exec, propertyName, slot)) { + if (!allowsAccess) { + printErrorMessage(errorMessage); + slot.setUndefined(); + } + return true; + } + } + + // FIXME: Search the whole frame hierachy somewhere around here. + // We need to test the correct priority order. + + // allow window[1] or parent[1] etc. (#56983) + bool ok; + unsigned i = propertyName.toArrayIndex(&ok); + if (ok && i < impl()->frame()->tree()->childCount()) { + slot.setCustomIndex(this, i, indexGetter); + return true; + } + + if (!allowsAccess) { + printErrorMessage(errorMessage); + slot.setUndefined(); + return true; + } + + // Allow shortcuts like 'Image1' instead of document.images.Image1 + Document* document = impl()->frame()->document(); + if (document->isHTMLDocument()) { + AtomicStringImpl* atomicPropertyName = AtomicString::find(propertyName); + if (atomicPropertyName && (static_cast<HTMLDocument*>(document)->hasNamedItem(atomicPropertyName) || document->hasElementWithId(atomicPropertyName))) { + slot.setCustom(this, namedItemGetter); + return true; + } + } + + return Base::getOwnPropertySlot(exec, propertyName, slot); +} + +void JSDOMWindow::put(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot) +{ + if (!impl()->frame()) + return; + + // Optimization: access JavaScript global variables directly before involving the DOM. + if (JSGlobalObject::hasOwnPropertyForWrite(exec, propertyName)) { + if (allowsAccessFrom(exec)) + JSGlobalObject::put(exec, propertyName, value, slot); + return; + } + + if (lookupPut<JSDOMWindow>(exec, propertyName, value, s_info.propHashTable(exec), this)) + return; + + if (allowsAccessFrom(exec)) + Base::put(exec, propertyName, value, slot); +} + bool JSDOMWindow::deleteProperty(ExecState* exec, const Identifier& propertyName) { // Only allow deleting properties by frames in the same origin. @@ -100,15 +298,15 @@ bool JSDOMWindow::deleteProperty(ExecState* exec, const Identifier& propertyName return Base::deleteProperty(exec, propertyName); } -bool JSDOMWindow::customGetPropertyNames(ExecState* exec, PropertyNameArray&) +void JSDOMWindow::getPropertyNames(ExecState* exec, PropertyNameArray& propertyNames) { // Only allow the window to enumerated by frames in the same origin. if (!allowsAccessFrom(exec)) - return true; - return false; + return; + Base::getPropertyNames(exec, propertyNames); } -bool JSDOMWindow::getPropertyAttributes(JSC::ExecState* exec, const Identifier& propertyName, unsigned& attributes) const +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)) @@ -161,7 +359,8 @@ JSValue JSDOMWindow::history(ExecState* exec) const if (DOMObject* wrapper = getCachedDOMObjectWrapper(exec->globalData(), history)) return wrapper; - JSHistory* jsHistory = new (exec) JSHistory(getDOMStructure<JSHistory>(exec, const_cast<JSDOMWindow*>(this)), history); + JSDOMWindow* window = const_cast<JSDOMWindow*>(this); + JSHistory* jsHistory = new (exec) JSHistory(getDOMStructure<JSHistory>(exec, window), window, history); cacheDOMObjectWrapper(exec->globalData(), history, jsHistory); return jsHistory; } @@ -172,7 +371,8 @@ JSValue JSDOMWindow::location(ExecState* exec) const if (DOMObject* wrapper = getCachedDOMObjectWrapper(exec->globalData(), location)) return wrapper; - JSLocation* jsLocation = new (exec) JSLocation(getDOMStructure<JSLocation>(exec, const_cast<JSDOMWindow*>(this)), location); + JSDOMWindow* window = const_cast<JSDOMWindow*>(this); + JSLocation* jsLocation = new (exec) JSLocation(getDOMStructure<JSLocation>(exec, window), window, location); cacheDOMObjectWrapper(exec->globalData(), location, jsLocation); return jsLocation; } @@ -245,12 +445,12 @@ JSValue JSDOMWindow::audio(ExecState* exec) const JSValue JSDOMWindow::webKitPoint(ExecState* exec) const { - return getDOMConstructor<JSWebKitPointConstructor>(exec); + return getDOMConstructor<JSWebKitPointConstructor>(exec, this); } JSValue JSDOMWindow::webKitCSSMatrix(ExecState* exec) const { - return getDOMConstructor<JSWebKitCSSMatrixConstructor>(exec); + return getDOMConstructor<JSWebKitCSSMatrixConstructor>(exec, this); } JSValue JSDOMWindow::xmlHttpRequest(ExecState* exec) const @@ -261,7 +461,7 @@ JSValue JSDOMWindow::xmlHttpRequest(ExecState* exec) const #if ENABLE(XSLT) JSValue JSDOMWindow::xsltProcessor(ExecState* exec) const { - return getDOMConstructor<JSXSLTProcessorConstructor>(exec); + return getDOMConstructor<JSXSLTProcessorConstructor>(exec, this); } #endif @@ -275,7 +475,14 @@ JSValue JSDOMWindow::messageChannel(ExecState* exec) const #if ENABLE(WORKERS) JSValue JSDOMWindow::worker(ExecState* exec) const { - return getDOMConstructor<JSWorkerConstructor>(exec); + return getDOMConstructor<JSWorkerConstructor>(exec, this); +} +#endif + +#if ENABLE(SHARED_WORKERS) +JSValue JSDOMWindow::sharedWorker(ExecState* exec) const +{ + return getDOMConstructor<JSSharedWorkerConstructor>(exec, this); } #endif diff --git a/WebCore/bindings/js/JSDOMWindowCustom.h b/WebCore/bindings/js/JSDOMWindowCustom.h index 52ef4a0..a0e1b8f 100644 --- a/WebCore/bindings/js/JSDOMWindowCustom.h +++ b/WebCore/bindings/js/JSDOMWindowCustom.h @@ -21,7 +21,6 @@ #include "JSDOMWindow.h" #include "JSDOMWindowShell.h" -#include <runtime/PrototypeFunction.h> #include <wtf/AlwaysInline.h> namespace WebCore { @@ -36,121 +35,6 @@ inline const JSDOMWindow* asJSDOMWindow(const JSC::JSGlobalObject* globalObject) return static_cast<const JSDOMWindow*>(globalObject); } -template<JSC::NativeFunction nativeFunction, int length> -JSC::JSValue nonCachingStaticFunctionGetter(JSC::ExecState* exec, const JSC::Identifier& propertyName, const JSC::PropertySlot&) -{ - return new (exec) JSC::PrototypeFunction(exec, length, propertyName, nativeFunction); -} - -ALWAYS_INLINE bool JSDOMWindow::customGetOwnPropertySlot(JSC::ExecState* exec, const JSC::Identifier& propertyName, JSC::PropertySlot& slot) -{ - // 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. - - const JSC::HashEntry* entry; - - // We don't want any properties other than "close" and "closed" on a closed window. - if (!impl()->frame()) { - // The following code is safe for cross-domain and same domain use. - // It ignores any custom properties that might be set on the DOMWindow (including a custom prototype). - entry = s_info.propHashTable(exec)->entry(exec, propertyName); - if (entry && !(entry->attributes() & JSC::Function) && entry->propertyGetter() == jsDOMWindowClosed) { - slot.setCustom(this, entry->propertyGetter()); - return true; - } - entry = JSDOMWindowPrototype::s_info.propHashTable(exec)->entry(exec, propertyName); - if (entry && (entry->attributes() & JSC::Function) && entry->function() == jsDOMWindowPrototypeFunctionClose) { - slot.setCustom(this, nonCachingStaticFunctionGetter<jsDOMWindowPrototypeFunctionClose, 0>); - return true; - } - - // FIXME: We should have a message here that explains why the property access/function call was - // not allowed. - slot.setUndefined(); - return true; - } - - // We need to check for cross-domain access here without printing the generic warning message - // because we always allow access to some function, just different ones depending whether access - // is allowed. - bool allowsAccess = allowsAccessFromNoErrorMessage(exec); - - // Look for overrides before looking at any of our own properties, but ignore overrides completely - // if this is cross-domain access. - if (allowsAccess && JSGlobalObject::getOwnPropertySlot(exec, propertyName, slot)) - return true; - - // We need this code here because otherwise JSC::Window 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() & JSC::Function) { - if (entry->function() == jsDOMWindowPrototypeFunctionBlur) { - if (!allowsAccess) { - slot.setCustom(this, nonCachingStaticFunctionGetter<jsDOMWindowPrototypeFunctionBlur, 0>); - return true; - } - } else if (entry->function() == jsDOMWindowPrototypeFunctionClose) { - if (!allowsAccess) { - slot.setCustom(this, nonCachingStaticFunctionGetter<jsDOMWindowPrototypeFunctionClose, 0>); - return true; - } - } else if (entry->function() == jsDOMWindowPrototypeFunctionFocus) { - if (!allowsAccess) { - slot.setCustom(this, nonCachingStaticFunctionGetter<jsDOMWindowPrototypeFunctionFocus, 0>); - return true; - } - } else if (entry->function() == jsDOMWindowPrototypeFunctionPostMessage) { - if (!allowsAccess) { - slot.setCustom(this, nonCachingStaticFunctionGetter<jsDOMWindowPrototypeFunctionPostMessage, 2>); - return true; - } - } else if (entry->function() == jsDOMWindowPrototypeFunctionShowModalDialog) { - if (!DOMWindow::canShowModalDialog(impl()->frame())) { - slot.setUndefined(); - return true; - } - } - } - } else { - // Allow access to toString() cross-domain, but always Object.prototype.toString. - if (propertyName == exec->propertyNames().toString) { - if (!allowsAccess) { - slot.setCustom(this, objectToStringFunctionGetter); - return true; - } - } - } - - return false; -} - -inline bool JSDOMWindow::customPut(JSC::ExecState* exec, const JSC::Identifier& propertyName, JSC::JSValue value, JSC::PutPropertySlot& slot) -{ - if (!impl()->frame()) - return true; - - // Optimization: access JavaScript global variables directly before involving the DOM. - JSC::PropertySlot getSlot; - bool slotIsWriteable; - if (JSGlobalObject::getOwnPropertySlot(exec, propertyName, getSlot, slotIsWriteable)) { - if (allowsAccessFrom(exec)) { - if (slotIsWriteable) { - getSlot.putValue(value); - if (getSlot.isCacheable()) - slot.setExistingProperty(this, getSlot.cachedOffset()); - } else - JSGlobalObject::put(exec, propertyName, value, slot); - } - return true; - } - - return false; -} - inline bool JSDOMWindowBase::allowsAccessFrom(const JSGlobalObject* other) const { if (allowsAccessFromPrivate(other)) diff --git a/WebCore/bindings/js/JSDOMWindowShell.cpp b/WebCore/bindings/js/JSDOMWindowShell.cpp index 1bf478b..efffd42 100644 --- a/WebCore/bindings/js/JSDOMWindowShell.cpp +++ b/WebCore/bindings/js/JSDOMWindowShell.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008 Apple Inc. All rights reserved. + * 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 @@ -71,11 +71,11 @@ void JSDOMWindowShell::setWindow(PassRefPtr<DOMWindow> domWindow) // JSObject methods // ---- -void JSDOMWindowShell::mark() +void JSDOMWindowShell::markChildren(MarkStack& markStack) { - Base::mark(); - if (m_window && !m_window->marked()) - m_window->mark(); + Base::markChildren(markStack); + if (m_window) + markStack.append(m_window); } UString JSDOMWindowShell::className() const diff --git a/WebCore/bindings/js/JSDOMWindowShell.h b/WebCore/bindings/js/JSDOMWindowShell.h index 6f21892..0506283 100644 --- a/WebCore/bindings/js/JSDOMWindowShell.h +++ b/WebCore/bindings/js/JSDOMWindowShell.h @@ -64,7 +64,7 @@ namespace WebCore { } private: - virtual void mark(); + virtual void markChildren(JSC::MarkStack&); virtual JSC::UString className() const; virtual bool getOwnPropertySlot(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::PropertySlot&); virtual void put(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::JSValue, JSC::PutPropertySlot&); diff --git a/WebCore/bindings/js/JSDataGridColumnListCustom.cpp b/WebCore/bindings/js/JSDataGridColumnListCustom.cpp new file mode 100644 index 0000000..91b3d15 --- /dev/null +++ b/WebCore/bindings/js/JSDataGridColumnListCustom.cpp @@ -0,0 +1,54 @@ +/* + * 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" + +#if ENABLE(DATAGRID) + +#include "JSDataGridColumnList.h" + +#include "AtomicString.h" +#include "DataGridColumn.h" +#include "DataGridColumnList.h" +#include "JSDataGridColumn.h" + +using namespace JSC; + +namespace WebCore { + +bool JSDataGridColumnList::canGetItemsForName(ExecState*, DataGridColumnList* impl, const Identifier& propertyName) +{ + return impl->itemWithName(propertyName); +} + +JSValue JSDataGridColumnList::nameGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot) +{ + JSDataGridColumnList* thisObj = static_cast<JSDataGridColumnList*>(asObject(slot.slotBase())); + return toJS(exec, thisObj->globalObject(), thisObj->impl()->itemWithName(propertyName)); +} + +} // namespace WebCore + +#endif diff --git a/WebCore/bindings/js/JSDOMStringListCustom.cpp b/WebCore/bindings/js/JSDataGridDataSource.cpp index ac088af..02b4214 100644 --- a/WebCore/bindings/js/JSDOMStringListCustom.cpp +++ b/WebCore/bindings/js/JSDataGridDataSource.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009 Apple Inc. All Rights Reserved. + * 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 @@ -24,26 +24,32 @@ */ #include "config.h" -#include "JSDOMStringList.h" -#include "DOMStringList.h" +#if ENABLE(DATAGRID) + +#include "JSDataGridDataSource.h" + +#include "Document.h" +#include "Frame.h" +#include "HTMLDataGridElement.h" +#include "JSHTMLDataGridElement.h" +#include "JSDOMWindowBase.h" +#include <runtime/JSLock.h> using namespace JSC; namespace WebCore { -JSValue JSDOMStringList::getByIndex(ExecState* exec, unsigned index) +JSDataGridDataSource::JSDataGridDataSource(JSC::JSValue dataSource, Frame* frame) + : m_dataSource(dataSource) + , m_frame(frame) { - return jsString(exec, impl()->item(index)); } -JSValue JSDOMStringList::item(ExecState* exec, const ArgList& args) +JSDataGridDataSource::~JSDataGridDataSource() { - unsigned index = args.at(0).toUInt32(exec); - if (index >= impl()->length()) - return jsNull(); - - return jsString(exec, impl()->item(index)); } } // namespace WebCore + +#endif // ENABLE(DATAGRID) diff --git a/WebCore/bindings/js/JSDataGridDataSource.h b/WebCore/bindings/js/JSDataGridDataSource.h new file mode 100644 index 0000000..077ef8f --- /dev/null +++ b/WebCore/bindings/js/JSDataGridDataSource.h @@ -0,0 +1,76 @@ +/* + * 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 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 JSDataGridDataSource_h +#define JSDataGridDataSource_h + +#if ENABLE(DATAGRID) + +#include "DataGridDataSource.h" +#include <runtime/JSValue.h> +#include <runtime/Protect.h> +#include <wtf/PassRefPtr.h> +#include <wtf/RefPtr.h> + +namespace WebCore { + +class Frame; +class HTMLDataGridElement; + +class JSDataGridDataSource : public DataGridDataSource { +public: + static PassRefPtr<JSDataGridDataSource> create(JSC::JSValue dataSource, Frame* frame) + { + return adoptRef(new JSDataGridDataSource(dataSource, frame)); + } + + virtual ~JSDataGridDataSource(); + + virtual bool isJSDataGridDataSource() const { return true; } + JSC::JSValue jsDataSource() const { return m_dataSource.get(); } + +private: + JSDataGridDataSource(JSC::JSValue, Frame*); + + JSC::ProtectedJSValue m_dataSource; + RefPtr<Frame> m_frame; +}; + +inline JSDataGridDataSource* asJSDataGridDataSource(DataGridDataSource* dataSource) +{ + ASSERT(dataSource->isJSDataGridDataSource()); + return static_cast<JSDataGridDataSource*>(dataSource); +} + +inline const JSDataGridDataSource* asJSDataGridDataSource(const DataGridDataSource* dataSource) +{ + ASSERT(dataSource->isJSDataGridDataSource()); + return static_cast<const JSDataGridDataSource*>(dataSource); +} + +} // namespace WebCore + +#endif // ENABLE(DATAGRID) +#endif // JSDataGridDataSource_h diff --git a/WebCore/bindings/js/JSDedicatedWorkerContextCustom.cpp b/WebCore/bindings/js/JSDedicatedWorkerContextCustom.cpp new file mode 100644 index 0000000..657f9b3 --- /dev/null +++ b/WebCore/bindings/js/JSDedicatedWorkerContextCustom.cpp @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2009 Google Inc. All rights reserved. + * 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: + * + * * 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" + +#if ENABLE(WORKERS) + +#include "JSDedicatedWorkerContext.h" + +using namespace JSC; + +namespace WebCore { + +void JSDedicatedWorkerContext::markChildren(MarkStack& markStack) +{ + Base::markChildren(markStack); + + markIfNotNull(markStack, impl()->onmessage()); +} + +} // namespace WebCore + +#endif // ENABLE(WORKERS) diff --git a/WebCore/bindings/js/JSDocumentCustom.cpp b/WebCore/bindings/js/JSDocumentCustom.cpp index 956327a..39a1fc5 100644 --- a/WebCore/bindings/js/JSDocumentCustom.cpp +++ b/WebCore/bindings/js/JSDocumentCustom.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2007, 2008, 2009 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 @@ -39,11 +39,11 @@ using namespace JSC; namespace WebCore { -void JSDocument::mark() +void JSDocument::markChildren(MarkStack& markStack) { - JSNode::mark(); - markDOMNodesForDocument(impl()); - markActiveObjectsForContext(*Heap::heap(this)->globalData(), impl()); + JSNode::markChildren(markStack); + markDOMNodesForDocument(markStack, impl()); + markActiveObjectsForContext(markStack, *Heap::heap(this)->globalData(), impl()); } JSValue JSDocument::location(ExecState* exec) const @@ -56,8 +56,7 @@ JSValue JSDocument::location(ExecState* exec) const if (DOMObject* wrapper = getCachedDOMObjectWrapper(exec->globalData(), location)) return wrapper; - JSDOMWindow* window = static_cast<JSDOMWindow*>(exec->lexicalGlobalObject()); - JSLocation* jsLocation = new (exec) JSLocation(getDOMStructure<JSLocation>(exec, window), location); + JSLocation* jsLocation = new (exec) JSLocation(getDOMStructure<JSLocation>(exec, globalObject()), globalObject(), location); cacheDOMObjectWrapper(exec->globalData(), location, jsLocation); return jsLocation; } @@ -80,7 +79,7 @@ void JSDocument::setLocation(ExecState* exec, JSValue value) frame->loader()->scheduleLocationChange(str, activeFrame->loader()->outgoingReferrer(), !activeFrame->script()->anyPageIsProcessingUserGesture(), false, userGesture); } -JSValue toJS(ExecState* exec, Document* document) +JSValue toJS(ExecState* exec, JSDOMGlobalObject* globalObject, Document* document) { if (!document) return jsNull(); @@ -90,13 +89,13 @@ JSValue toJS(ExecState* exec, Document* document) return wrapper; if (document->isHTMLDocument()) - wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, HTMLDocument, document); + wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, globalObject, HTMLDocument, document); #if ENABLE(SVG) else if (document->isSVGDocument()) - wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, SVGDocument, document); + wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, globalObject, SVGDocument, document); #endif else - wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, Document, document); + wrapper = CREATE_DOM_OBJECT_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/WebCore/bindings/js/JSElementCustom.cpp b/WebCore/bindings/js/JSElementCustom.cpp index b12c185..47793d0 100644 --- a/WebCore/bindings/js/JSElementCustom.cpp +++ b/WebCore/bindings/js/JSElementCustom.cpp @@ -53,7 +53,7 @@ using namespace HTMLNames; static inline bool allowSettingSrcToJavascriptURL(ExecState* exec, Element* element, const String& name, const String& value) { - if ((element->hasTagName(iframeTag) || element->hasTagName(frameTag)) && equalIgnoringCase(name, "src") && protocolIsJavaScript(parseURL(value))) { + if ((element->hasTagName(iframeTag) || element->hasTagName(frameTag)) && equalIgnoringCase(name, "src") && protocolIsJavaScript(deprecatedParseURL(value))) { HTMLFrameElementBase* frame = static_cast<HTMLFrameElementBase*>(element); if (!checkNodeSecurity(exec, frame->contentDocument())) return false; @@ -89,7 +89,7 @@ JSValue JSElement::setAttributeNode(ExecState* exec, const ArgList& args) if (!allowSettingSrcToJavascriptURL(exec, imp, newAttr->name(), newAttr->value())) return jsUndefined(); - JSValue result = toJS(exec, WTF::getPtr(imp->setAttributeNode(newAttr, ec))); + JSValue result = toJS(exec, globalObject(), WTF::getPtr(imp->setAttributeNode(newAttr, ec))); setDOMException(exec, ec); return result; } @@ -123,12 +123,12 @@ JSValue JSElement::setAttributeNodeNS(ExecState* exec, const ArgList& args) if (!allowSettingSrcToJavascriptURL(exec, imp, newAttr->name(), newAttr->value())) return jsUndefined(); - JSValue result = toJS(exec, WTF::getPtr(imp->setAttributeNodeNS(newAttr, ec))); + JSValue result = toJS(exec, globalObject(), WTF::getPtr(imp->setAttributeNodeNS(newAttr, ec))); setDOMException(exec, ec); return result; } -JSValue toJSNewlyCreated(ExecState* exec, Element* element) +JSValue toJSNewlyCreated(ExecState* exec, JSDOMGlobalObject* globalObject, Element* element) { if (!element) return jsNull(); @@ -137,15 +137,15 @@ JSValue toJSNewlyCreated(ExecState* exec, Element* element) JSNode* wrapper; if (element->isHTMLElement()) - wrapper = createJSHTMLWrapper(exec, static_cast<HTMLElement*>(element)); + wrapper = createJSHTMLWrapper(exec, globalObject, static_cast<HTMLElement*>(element)); #if ENABLE(SVG) else if (element->isSVGElement()) - wrapper = createJSSVGWrapper(exec, static_cast<SVGElement*>(element)); + wrapper = createJSSVGWrapper(exec, globalObject, static_cast<SVGElement*>(element)); #endif else - wrapper = CREATE_DOM_NODE_WRAPPER(exec, Element, element); + wrapper = CREATE_DOM_NODE_WRAPPER(exec, globalObject, Element, element); return wrapper; } - + } // namespace WebCore diff --git a/WebCore/bindings/js/JSEventCustom.cpp b/WebCore/bindings/js/JSEventCustom.cpp index a020d74..7f9030e 100644 --- a/WebCore/bindings/js/JSEventCustom.cpp +++ b/WebCore/bindings/js/JSEventCustom.cpp @@ -32,6 +32,7 @@ #include "Clipboard.h" #include "Event.h" #include "JSClipboard.h" +#include "JSErrorEvent.h" #include "JSKeyboardEvent.h" #include "JSMessageEvent.h" #include "JSMouseEvent.h" @@ -44,6 +45,7 @@ #include "JSWebKitTransitionEvent.h" #include "JSWheelEvent.h" #include "JSXMLHttpRequestProgressEvent.h" +#include "ErrorEvent.h" #include "KeyboardEvent.h" #include "MessageEvent.h" #include "MouseEvent.h" @@ -79,12 +81,12 @@ namespace WebCore { JSValue JSEvent::clipboardData(ExecState* exec) const { - return impl()->isClipboardEvent() ? toJS(exec, impl()->clipboardData()) : jsUndefined(); + return impl()->isClipboardEvent() ? toJS(exec, globalObject(), impl()->clipboardData()) : jsUndefined(); } -JSValue toJS(ExecState* exec, Event* event) +JSValue toJS(ExecState* exec, JSDOMGlobalObject* globalObject, Event* event) { - JSLock lock(false); + JSLock lock(SilenceAssertionsOnly); if (!event) return jsNull(); @@ -95,45 +97,49 @@ JSValue toJS(ExecState* exec, Event* event) if (event->isUIEvent()) { if (event->isKeyboardEvent()) - wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, KeyboardEvent, event); + wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, globalObject, KeyboardEvent, event); else if (event->isTextEvent()) - wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, TextEvent, event); + wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, globalObject, TextEvent, event); else if (event->isMouseEvent()) - wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, MouseEvent, event); + wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, globalObject, MouseEvent, event); else if (event->isWheelEvent()) - wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, WheelEvent, event); + wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, globalObject, WheelEvent, event); #if ENABLE(SVG) else if (event->isSVGZoomEvent()) - wrapper = CREATE_SVG_OBJECT_WRAPPER(exec, SVGZoomEvent, event, 0); + wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, globalObject, SVGZoomEvent, event); #endif #if ENABLE(TOUCH_EVENTS) // Android else if (event->isTouchEvent()) wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, TouchEvent, event); #endif else - wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, UIEvent, event); + wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, globalObject, UIEvent, event); } else if (event->isMutationEvent()) - wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, MutationEvent, event); + wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, globalObject, MutationEvent, event); else if (event->isOverflowEvent()) - wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, OverflowEvent, event); + wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, globalObject, OverflowEvent, event); else if (event->isMessageEvent()) - wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, MessageEvent, event); + wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, globalObject, MessageEvent, event); else if (event->isProgressEvent()) { if (event->isXMLHttpRequestProgressEvent()) - wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, XMLHttpRequestProgressEvent, event); + wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, globalObject, XMLHttpRequestProgressEvent, event); else - wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, ProgressEvent, event); + wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, globalObject, ProgressEvent, event); } #if ENABLE(DOM_STORAGE) else if (event->isStorageEvent()) - wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, StorageEvent, event); + wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, globalObject, StorageEvent, event); #endif else if (event->isWebKitAnimationEvent()) - wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, WebKitAnimationEvent, event); + wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, globalObject, WebKitAnimationEvent, event); else if (event->isWebKitTransitionEvent()) - wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, WebKitTransitionEvent, event); + wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, globalObject, WebKitTransitionEvent, event); +#if ENABLE(WORKERS) + else if (event->isErrorEvent()) + wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, globalObject, ErrorEvent, event); +#endif else - wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, Event, event); + wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, globalObject, Event, event); return wrapper; } diff --git a/WebCore/bindings/js/JSEventListener.cpp b/WebCore/bindings/js/JSEventListener.cpp index b9ed685..42e0281 100644 --- a/WebCore/bindings/js/JSEventListener.cpp +++ b/WebCore/bindings/js/JSEventListener.cpp @@ -51,17 +51,17 @@ JSObject* JSEventListener::jsFunction() const return m_jsFunction; } -void JSEventListener::markJSFunction() +void JSEventListener::markJSFunction(MarkStack& markStack) { - if (m_jsFunction && !m_jsFunction->marked()) - m_jsFunction->mark(); - if (m_globalObject && !m_globalObject->marked()) - m_globalObject->mark(); + if (m_jsFunction) + markStack.append(m_jsFunction); + if (m_globalObject) + markStack.append(m_globalObject); } void JSEventListener::handleEvent(Event* event, bool isWindowEvent) { - JSLock lock(false); + JSLock lock(SilenceAssertionsOnly); JSObject* jsFunction = this->jsFunction(); if (!jsFunction) @@ -71,6 +71,7 @@ void JSEventListener::handleEvent(Event* event, bool isWindowEvent) // Null check as clearGlobalObject() can clear this and we still get called back by // xmlhttprequest objects. See http://bugs.webkit.org/show_bug.cgi?id=13275 // FIXME: Is this check still necessary? Requests are supposed to be stopped before clearGlobalObject() is called. + ASSERT(globalObject); if (!globalObject) return; @@ -107,7 +108,7 @@ void JSEventListener::handleEvent(Event* event, bool isWindowEvent) ref(); MarkedArgumentBuffer args; - args.append(toJS(exec, event)); + args.append(toJS(exec, globalObject, event)); Event* savedEvent = globalObject->currentEvent(); globalObject->setCurrentEvent(event); @@ -127,7 +128,7 @@ void JSEventListener::handleEvent(Event* event, bool isWindowEvent) if (isWindowEvent) thisValue = globalObject->toThisObject(exec); else - thisValue = toJS(exec, event->currentTarget()); + thisValue = toJS(exec, globalObject, event->currentTarget()); globalObject->globalData()->timeoutChecker.start(); retval = call(exec, jsFunction, callType, callData, thisValue, args); } @@ -153,6 +154,53 @@ void JSEventListener::handleEvent(Event* event, bool isWindowEvent) } } +bool JSEventListener::reportError(const String& message, const String& url, int lineNumber) +{ + JSLock lock(SilenceAssertionsOnly); + + JSObject* jsFunction = this->jsFunction(); + if (!jsFunction) + return false; + + JSDOMGlobalObject* globalObject = m_globalObject; + if (!globalObject) + return false; + + ExecState* exec = globalObject->globalExec(); + + CallData callData; + CallType callType = jsFunction->getCallData(callData); + + if (callType == CallTypeNone) + return false; + + MarkedArgumentBuffer args; + args.append(jsString(exec, message)); + args.append(jsString(exec, url)); + args.append(jsNumber(exec, lineNumber)); + + // If this event handler is the first JavaScript to execute, then the + // dynamic global object should be set to the global object of the + // window in which the event occurred. + JSGlobalData* globalData = globalObject->globalData(); + DynamicGlobalObjectScope globalObjectScope(exec, globalData->dynamicGlobalObject ? globalData->dynamicGlobalObject : globalObject); + + JSValue thisValue = globalObject->toThisObject(exec); + + globalObject->globalData()->timeoutChecker.start(); + JSValue returnValue = call(exec, jsFunction, callType, callData, thisValue, args); + globalObject->globalData()->timeoutChecker.stop(); + + // If an error occurs while handling the script error, it should be bubbled up. + if (exec->hadException()) { + exec->clearException(); + return false; + } + + bool bubbleEvent; + return returnValue.getBoolean(bubbleEvent) && !bubbleEvent; +} + bool JSEventListener::virtualisAttribute() const { return m_isAttribute; diff --git a/WebCore/bindings/js/JSEventListener.h b/WebCore/bindings/js/JSEventListener.h index ce34832..7929169 100644 --- a/WebCore/bindings/js/JSEventListener.h +++ b/WebCore/bindings/js/JSEventListener.h @@ -43,8 +43,9 @@ namespace WebCore { virtual JSC::JSObject* jsFunction() const; private: - virtual void markJSFunction(); + virtual void markJSFunction(JSC::MarkStack&); virtual void handleEvent(Event*, bool isWindowEvent); + virtual bool reportError(const String& message, const String& url, int lineNumber); virtual bool virtualisAttribute() const; void clearJSFunctionInline(); diff --git a/WebCore/bindings/js/JSEventTarget.cpp b/WebCore/bindings/js/JSEventTarget.cpp index 2058098..c34e10e 100644 --- a/WebCore/bindings/js/JSEventTarget.cpp +++ b/WebCore/bindings/js/JSEventTarget.cpp @@ -33,9 +33,13 @@ #include "JSEventListener.h" #include "JSMessagePort.h" #include "JSNode.h" +#include "JSSharedWorker.h" +#include "JSSharedWorkerContext.h" #include "JSXMLHttpRequest.h" #include "JSXMLHttpRequestUpload.h" #include "MessagePort.h" +#include "SharedWorker.h" +#include "SharedWorkerContext.h" #include "XMLHttpRequest.h" #include "XMLHttpRequestUpload.h" @@ -50,17 +54,17 @@ #endif #if ENABLE(WORKERS) +#include "DedicatedWorkerContext.h" +#include "JSDedicatedWorkerContext.h" #include "JSWorker.h" -#include "JSWorkerContext.h" #include "Worker.h" -#include "WorkerContext.h" #endif using namespace JSC; namespace WebCore { -JSValue toJS(ExecState* exec, EventTarget* target) +JSValue toJS(ExecState* exec, JSDOMGlobalObject* globalObject, EventTarget* target) { if (!target) return jsNull(); @@ -68,36 +72,42 @@ JSValue toJS(ExecState* exec, EventTarget* target) #if ENABLE(SVG) // SVGElementInstance supports both toSVGElementInstance and toNode since so much mouse handling code depends on toNode returning a valid node. if (SVGElementInstance* instance = target->toSVGElementInstance()) - return toJS(exec, instance); + return toJS(exec, globalObject, instance); #endif if (Node* node = target->toNode()) - return toJS(exec, node); + return toJS(exec, globalObject, node); if (DOMWindow* domWindow = target->toDOMWindow()) - return toJS(exec, domWindow); + return toJS(exec, globalObject, domWindow); if (XMLHttpRequest* xhr = target->toXMLHttpRequest()) - // XMLHttpRequest is always created via JS, so we don't need to use cacheDOMObject() here. - return getCachedDOMObjectWrapper(exec->globalData(), xhr); + return toJS(exec, globalObject, xhr); if (XMLHttpRequestUpload* upload = target->toXMLHttpRequestUpload()) - return toJS(exec, upload); + return toJS(exec, globalObject, upload); #if ENABLE(OFFLINE_WEB_APPLICATIONS) if (DOMApplicationCache* cache = target->toDOMApplicationCache()) - // DOMApplicationCache is always created via JS, so we don't need to use cacheDOMObject() here. - return getCachedDOMObjectWrapper(exec->globalData(), cache); + return toJS(exec, globalObject, cache); #endif if (MessagePort* messagePort = target->toMessagePort()) - return toJS(exec, messagePort); + return toJS(exec, globalObject, messagePort); #if ENABLE(WORKERS) if (Worker* worker = target->toWorker()) - return toJS(exec, worker); + return toJS(exec, globalObject, worker); - if (WorkerContext* workerContext = target->toWorkerContext()) + if (DedicatedWorkerContext* workerContext = target->toDedicatedWorkerContext()) + return toJSDOMGlobalObject(workerContext); +#endif + +#if ENABLE(SHARED_WORKERS) + if (SharedWorker* sharedWorker = target->toSharedWorker()) + return toJS(exec, globalObject, sharedWorker); + + if (SharedWorkerContext* workerContext = target->toSharedWorkerContext()) return toJSDOMGlobalObject(workerContext); #endif @@ -129,7 +139,12 @@ EventTarget* toEventTarget(JSC::JSValue value) #if ENABLE(WORKERS) CONVERT_TO_EVENT_TARGET(Worker) - CONVERT_TO_EVENT_TARGET(WorkerContext) + CONVERT_TO_EVENT_TARGET(DedicatedWorkerContext) +#endif + +#if ENABLE(SHARED_WORKERS) + CONVERT_TO_EVENT_TARGET(SharedWorker) + CONVERT_TO_EVENT_TARGET(SharedWorkerContext) #endif return 0; diff --git a/WebCore/bindings/js/JSEventTarget.h b/WebCore/bindings/js/JSEventTarget.h index 05df056..ddd8232 100644 --- a/WebCore/bindings/js/JSEventTarget.h +++ b/WebCore/bindings/js/JSEventTarget.h @@ -35,8 +35,9 @@ namespace JSC { namespace WebCore { class EventTarget; + class JSDOMGlobalObject; - JSC::JSValue toJS(JSC::ExecState*, EventTarget*); + JSC::JSValue toJS(JSC::ExecState*, JSDOMGlobalObject*, EventTarget*); EventTarget* toEventTarget(JSC::JSValue); } // namespace WebCore diff --git a/WebCore/bindings/js/JSHTMLAllCollection.h b/WebCore/bindings/js/JSHTMLAllCollection.h index d559d3b..7363e5c 100644 --- a/WebCore/bindings/js/JSHTMLAllCollection.h +++ b/WebCore/bindings/js/JSHTMLAllCollection.h @@ -35,8 +35,8 @@ namespace WebCore { class JSHTMLAllCollection : public JSHTMLCollection { public: - JSHTMLAllCollection(PassRefPtr<JSC::Structure> structure, PassRefPtr<HTMLCollection> collection) - : JSHTMLCollection(structure, collection) + JSHTMLAllCollection(PassRefPtr<JSC::Structure> structure, JSDOMGlobalObject* globalObject, PassRefPtr<HTMLCollection> collection) + : JSHTMLCollection(structure, globalObject, collection) { } diff --git a/WebCore/bindings/js/JSHTMLAppletElementCustom.cpp b/WebCore/bindings/js/JSHTMLAppletElementCustom.cpp index de6565d..37561af 100644 --- a/WebCore/bindings/js/JSHTMLAppletElementCustom.cpp +++ b/WebCore/bindings/js/JSHTMLAppletElementCustom.cpp @@ -33,12 +33,12 @@ namespace WebCore { using namespace JSC; -bool JSHTMLAppletElement::customGetOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot) +bool JSHTMLAppletElement::getOwnPropertySlotDelegate(ExecState* exec, const Identifier& propertyName, PropertySlot& slot) { return runtimeObjectCustomGetOwnPropertySlot(exec, propertyName, slot, this); } -bool JSHTMLAppletElement::customPut(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot) +bool JSHTMLAppletElement::putDelegate(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot) { return runtimeObjectCustomPut(exec, propertyName, value, impl(), slot); } diff --git a/WebCore/bindings/js/JSHTMLCollectionCustom.cpp b/WebCore/bindings/js/JSHTMLCollectionCustom.cpp index 4100468..dd9af74 100644 --- a/WebCore/bindings/js/JSHTMLCollectionCustom.cpp +++ b/WebCore/bindings/js/JSHTMLCollectionCustom.cpp @@ -35,18 +35,18 @@ using namespace JSC; namespace WebCore { -static JSValue getNamedItems(ExecState* exec, HTMLCollection* impl, const Identifier& propertyName) +static JSValue getNamedItems(ExecState* exec, JSHTMLCollection* collection, const Identifier& propertyName) { Vector<RefPtr<Node> > namedItems; - impl->namedItems(propertyName, namedItems); + collection->impl()->namedItems(propertyName, namedItems); if (namedItems.isEmpty()) return jsUndefined(); if (namedItems.size() == 1) - return toJS(exec, namedItems[0].get()); + return toJS(exec, collection->globalObject(), namedItems[0].get()); - return new (exec) JSNamedNodesCollection(exec, namedItems); + return new (exec) JSNamedNodesCollection(exec, collection->globalObject(), namedItems); } // HTMLCollections are strange objects, they support both get and call, @@ -57,7 +57,8 @@ static JSValue JSC_HOST_CALL callHTMLCollection(ExecState* exec, JSObject* funct return jsUndefined(); // Do not use thisObj here. It can be the JSHTMLDocument, in the document.forms(i) case. - HTMLCollection* collection = static_cast<JSHTMLCollection*>(function)->impl(); + JSHTMLCollection* jsCollection = static_cast<JSHTMLCollection*>(function); + HTMLCollection* collection = jsCollection->impl(); // Also, do we need the TypeError test here ? @@ -67,10 +68,10 @@ static JSValue JSC_HOST_CALL callHTMLCollection(ExecState* exec, JSObject* funct UString string = args.at(0).toString(exec); unsigned index = string.toUInt32(&ok, false); if (ok) - return toJS(exec, collection->item(index)); + return toJS(exec, jsCollection->globalObject(), collection->item(index)); // Support for document.images('<name>') etc. - return getNamedItems(exec, collection, Identifier(exec, string)); + return getNamedItems(exec, jsCollection, Identifier(exec, string)); } // The second arg, if set, is the index of the item we want @@ -82,7 +83,7 @@ static JSValue JSC_HOST_CALL callHTMLCollection(ExecState* exec, JSObject* funct Node* node = collection->namedItem(pstr); while (node) { if (!index) - return toJS(exec, node); + return toJS(exec, jsCollection->globalObject(), node); node = collection->nextNamedItem(pstr); --index; } @@ -97,15 +98,17 @@ CallType JSHTMLCollection::getCallData(CallData& callData) return CallTypeHost; } -bool JSHTMLCollection::canGetItemsForName(ExecState* exec, HTMLCollection* thisObj, const Identifier& propertyName) +bool JSHTMLCollection::canGetItemsForName(ExecState*, HTMLCollection* collection, const Identifier& propertyName) { - return !getNamedItems(exec, thisObj, propertyName).isUndefined(); + Vector<RefPtr<Node> > namedItems; + collection->namedItems(propertyName, namedItems); + return !namedItems.isEmpty(); } JSValue JSHTMLCollection::nameGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot) { JSHTMLCollection* thisObj = static_cast<JSHTMLCollection*>(asObject(slot.slotBase())); - return getNamedItems(exec, thisObj->impl(), propertyName); + return getNamedItems(exec, thisObj, propertyName); } JSValue JSHTMLCollection::item(ExecState* exec, const ArgList& args) @@ -113,16 +116,16 @@ JSValue JSHTMLCollection::item(ExecState* exec, const ArgList& args) bool ok; uint32_t index = args.at(0).toString(exec).toUInt32(&ok, false); if (ok) - return toJS(exec, impl()->item(index)); - return getNamedItems(exec, impl(), Identifier(exec, args.at(0).toString(exec))); + return toJS(exec, globalObject(), impl()->item(index)); + return getNamedItems(exec, this, Identifier(exec, args.at(0).toString(exec))); } JSValue JSHTMLCollection::namedItem(ExecState* exec, const ArgList& args) { - return getNamedItems(exec, impl(), Identifier(exec, args.at(0).toString(exec))); + return getNamedItems(exec, this, Identifier(exec, args.at(0).toString(exec))); } -JSValue toJS(ExecState* exec, HTMLCollection* collection) +JSValue toJS(ExecState* exec, JSDOMGlobalObject* globalObject, HTMLCollection* collection) { if (!collection) return jsNull(); @@ -134,14 +137,14 @@ JSValue toJS(ExecState* exec, HTMLCollection* collection) switch (collection->type()) { case SelectOptions: - wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, HTMLOptionsCollection, collection); + wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, globalObject, HTMLOptionsCollection, collection); break; case DocAll: typedef HTMLCollection HTMLAllCollection; - wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, HTMLAllCollection, collection); + wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, globalObject, HTMLAllCollection, collection); break; default: - wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, HTMLCollection, collection); + wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, globalObject, HTMLCollection, collection); break; } diff --git a/WebCore/bindings/js/JSHTMLDataGridElementCustom.cpp b/WebCore/bindings/js/JSHTMLDataGridElementCustom.cpp new file mode 100644 index 0000000..a30f5e4 --- /dev/null +++ b/WebCore/bindings/js/JSHTMLDataGridElementCustom.cpp @@ -0,0 +1,60 @@ +/* + * 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 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(DATAGRID) + +#include "JSHTMLDataGridElement.h" + +#include "Document.h" +#include "HTMLDataGridElement.h" +#include "JSDataGridDataSource.h" + +using namespace JSC; + +namespace WebCore { + +JSValue JSHTMLDataGridElement::dataSource(ExecState*) const +{ + DataGridDataSource* dataSource = static_cast<HTMLDataGridElement*>(impl())->dataSource(); + if (dataSource && dataSource->isJSDataGridDataSource()) + return asJSDataGridDataSource(dataSource)->jsDataSource(); + return jsNull(); +} + +void JSHTMLDataGridElement::setDataSource(ExecState*, JSValue value) +{ + if (value.isNull()) { + static_cast<HTMLDataGridElement*>(impl())->setDataSource(0); + return; + } + + static_cast<HTMLDataGridElement*>(impl())->setDataSource(JSDataGridDataSource::create(value, impl()->document()->frame())); +} + +} // namespace WebCore + +#endif // ENABLE(DATAGRID) diff --git a/WebCore/bindings/js/JSHTMLElementCustom.cpp b/WebCore/bindings/js/JSHTMLElementCustom.cpp index 3345764..4194657 100644 --- a/WebCore/bindings/js/JSHTMLElementCustom.cpp +++ b/WebCore/bindings/js/JSHTMLElementCustom.cpp @@ -38,14 +38,14 @@ void JSHTMLElement::pushEventHandlerScope(ExecState* exec, ScopeChain& scope) co HTMLElement* element = impl(); // The document is put on first, fall back to searching it only after the element and form. - scope.push(asObject(toJS(exec, element->ownerDocument()))); + scope.push(asObject(toJS(exec, globalObject(), element->ownerDocument()))); // The form is next, searched before the document, but after the element itself. if (HTMLFormElement* form = element->form()) - scope.push(asObject(toJS(exec, form))); + scope.push(asObject(toJS(exec, globalObject(), form))); // The element is on top, searched first. - scope.push(asObject(toJS(exec, element))); + scope.push(asObject(toJS(exec, globalObject(), element))); } } // namespace WebCore diff --git a/WebCore/bindings/js/JSHTMLEmbedElementCustom.cpp b/WebCore/bindings/js/JSHTMLEmbedElementCustom.cpp index 19aae86..2570bc6 100644 --- a/WebCore/bindings/js/JSHTMLEmbedElementCustom.cpp +++ b/WebCore/bindings/js/JSHTMLEmbedElementCustom.cpp @@ -33,12 +33,12 @@ namespace WebCore { using namespace JSC; -bool JSHTMLEmbedElement::customGetOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot) +bool JSHTMLEmbedElement::getOwnPropertySlotDelegate(ExecState* exec, const Identifier& propertyName, PropertySlot& slot) { return runtimeObjectCustomGetOwnPropertySlot(exec, propertyName, slot, this); } -bool JSHTMLEmbedElement::customPut(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot) +bool JSHTMLEmbedElement::putDelegate(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot) { return runtimeObjectCustomPut(exec, propertyName, value, impl(), slot); } diff --git a/WebCore/bindings/js/JSHTMLFormElementCustom.cpp b/WebCore/bindings/js/JSHTMLFormElementCustom.cpp index 8bf543c..ffa2d57 100644 --- a/WebCore/bindings/js/JSHTMLFormElementCustom.cpp +++ b/WebCore/bindings/js/JSHTMLFormElementCustom.cpp @@ -45,7 +45,8 @@ bool JSHTMLFormElement::canGetItemsForName(ExecState*, HTMLFormElement* form, co JSValue JSHTMLFormElement::nameGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot) { - HTMLFormElement* form = static_cast<HTMLFormElement*>(static_cast<JSHTMLElement*>(asObject(slot.slotBase()))->impl()); + JSHTMLElement* jsForm = static_cast<JSHTMLFormElement*>(asObject(slot.slotBase())); + HTMLFormElement* form = static_cast<HTMLFormElement*>(jsForm->impl()); Vector<RefPtr<Node> > namedItems; form->getNamedElements(propertyName, namedItems); @@ -53,7 +54,7 @@ JSValue JSHTMLFormElement::nameGetter(ExecState* exec, const Identifier& propert if (namedItems.size() == 1) return toJS(exec, namedItems[0].get()); if (namedItems.size() > 1) - return new (exec) JSNamedNodesCollection(exec, namedItems); + return new (exec) JSNamedNodesCollection(exec, jsForm->globalObject(), namedItems); return jsUndefined(); } @@ -62,7 +63,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(), false); + static_cast<HTMLFormElement*>(impl())->submit(0, false, !activeFrame->script()->anyPageIsProcessingUserGesture()); return jsUndefined(); } diff --git a/WebCore/bindings/js/JSHTMLFrameElementCustom.cpp b/WebCore/bindings/js/JSHTMLFrameElementCustom.cpp index 0a5d1f1..c8aea9f 100644 --- a/WebCore/bindings/js/JSHTMLFrameElementCustom.cpp +++ b/WebCore/bindings/js/JSHTMLFrameElementCustom.cpp @@ -40,7 +40,7 @@ namespace WebCore { static inline bool allowSettingJavascriptURL(ExecState* exec, HTMLFrameElement* imp, const String& value) { - if (protocolIsJavaScript(parseURL(value))) { + if (protocolIsJavaScript(deprecatedParseURL(value))) { if (!checkNodeSecurity(exec, imp->contentDocument())) return false; } diff --git a/WebCore/bindings/js/JSHTMLIFrameElementCustom.cpp b/WebCore/bindings/js/JSHTMLIFrameElementCustom.cpp index afff977..8e32381 100644 --- a/WebCore/bindings/js/JSHTMLIFrameElementCustom.cpp +++ b/WebCore/bindings/js/JSHTMLIFrameElementCustom.cpp @@ -44,7 +44,7 @@ void JSHTMLIFrameElement::setSrc(ExecState* exec, JSValue value) String srcValue = valueToStringWithNullCheck(exec, value); - if (protocolIsJavaScript(parseURL(srcValue))) { + if (protocolIsJavaScript(deprecatedParseURL(srcValue))) { if (!checkNodeSecurity(exec, imp->contentDocument())) return; } diff --git a/WebCore/bindings/js/JSHTMLObjectElementCustom.cpp b/WebCore/bindings/js/JSHTMLObjectElementCustom.cpp index f7f12b9..a99e46c 100644 --- a/WebCore/bindings/js/JSHTMLObjectElementCustom.cpp +++ b/WebCore/bindings/js/JSHTMLObjectElementCustom.cpp @@ -33,12 +33,12 @@ namespace WebCore { using namespace JSC; -bool JSHTMLObjectElement::customGetOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot) +bool JSHTMLObjectElement::getOwnPropertySlotDelegate(ExecState* exec, const Identifier& propertyName, PropertySlot& slot) { return runtimeObjectCustomGetOwnPropertySlot(exec, propertyName, slot, this); } -bool JSHTMLObjectElement::customPut(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot) +bool JSHTMLObjectElement::putDelegate(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot) { return runtimeObjectCustomPut(exec, propertyName, value, impl(), slot); } diff --git a/WebCore/bindings/js/JSHTMLOptionsCollectionCustom.cpp b/WebCore/bindings/js/JSHTMLOptionsCollectionCustom.cpp index 460ba08..7bca2db 100644 --- a/WebCore/bindings/js/JSHTMLOptionsCollectionCustom.cpp +++ b/WebCore/bindings/js/JSHTMLOptionsCollectionCustom.cpp @@ -91,7 +91,7 @@ JSValue JSHTMLOptionsCollection::add(ExecState* exec, const ArgList& args) JSValue JSHTMLOptionsCollection::remove(ExecState* exec, const ArgList& args) { HTMLOptionsCollection* imp = static_cast<HTMLOptionsCollection*>(impl()); - JSHTMLSelectElement* base = static_cast<JSHTMLSelectElement*>(asObject(toJS(exec, imp->base()))); + JSHTMLSelectElement* base = static_cast<JSHTMLSelectElement*>(asObject(toJS(exec, globalObject(), imp->base()))); return base->remove(exec, args); } diff --git a/WebCore/bindings/js/JSHistoryCustom.cpp b/WebCore/bindings/js/JSHistoryCustom.cpp index 998a364..a3b15e1 100644 --- a/WebCore/bindings/js/JSHistoryCustom.cpp +++ b/WebCore/bindings/js/JSHistoryCustom.cpp @@ -39,23 +39,23 @@ namespace WebCore { static JSValue nonCachingStaticBackFunctionGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot&) { - return new (exec) PrototypeFunction(exec, 0, propertyName, jsHistoryPrototypeFunctionBack); + return new (exec) NativeFunctionWrapper(exec, exec->lexicalGlobalObject()->prototypeFunctionStructure(), 0, propertyName, jsHistoryPrototypeFunctionBack); } static JSValue nonCachingStaticForwardFunctionGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot&) { - return new (exec) PrototypeFunction(exec, 0, propertyName, jsHistoryPrototypeFunctionForward); + return new (exec) NativeFunctionWrapper(exec, exec->lexicalGlobalObject()->prototypeFunctionStructure(), 0, propertyName, jsHistoryPrototypeFunctionForward); } static JSValue nonCachingStaticGoFunctionGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot&) { - return new (exec) PrototypeFunction(exec, 1, propertyName, jsHistoryPrototypeFunctionGo); + return new (exec) NativeFunctionWrapper(exec, exec->lexicalGlobalObject()->prototypeFunctionStructure(), 1, propertyName, jsHistoryPrototypeFunctionGo); } -bool JSHistory::customGetOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot) +bool JSHistory::getOwnPropertySlotDelegate(ExecState* exec, const Identifier& propertyName, PropertySlot& slot) { // When accessing History cross-domain, functions are always the native built-in ones. - // See JSDOMWindow::customGetOwnPropertySlot for additional details. + // 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. @@ -92,7 +92,7 @@ bool JSHistory::customGetOwnPropertySlot(ExecState* exec, const Identifier& prop return true; } -bool JSHistory::customPut(ExecState* exec, const Identifier&, JSValue, PutPropertySlot&) +bool JSHistory::putDelegate(ExecState* exec, const Identifier&, JSValue, PutPropertySlot&) { // Only allow putting by frames in the same origin. if (!allowsAccessFromFrame(exec, impl()->frame())) @@ -108,12 +108,12 @@ bool JSHistory::deleteProperty(ExecState* exec, const Identifier& propertyName) return Base::deleteProperty(exec, propertyName); } -bool JSHistory::customGetPropertyNames(ExecState* exec, PropertyNameArray&) +void JSHistory::getPropertyNames(ExecState* exec, PropertyNameArray& propertyNames) { // Only allow the history object to enumerated by frames in the same origin. if (!allowsAccessFromFrame(exec, impl()->frame())) - return true; - return false; + return; + Base::getPropertyNames(exec, propertyNames); } } // namespace WebCore diff --git a/WebCore/bindings/js/JSImageConstructor.cpp b/WebCore/bindings/js/JSImageConstructor.cpp index 4a27bb4..faaaf41 100644 --- a/WebCore/bindings/js/JSImageConstructor.cpp +++ b/WebCore/bindings/js/JSImageConstructor.cpp @@ -35,18 +35,9 @@ ASSERT_CLASS_FITS_IN_CELL(JSImageConstructor); const ClassInfo JSImageConstructor::s_info = { "ImageConstructor", 0, 0, 0 }; JSImageConstructor::JSImageConstructor(ExecState* exec, JSDOMGlobalObject* globalObject) - : DOMObject(JSImageConstructor::createStructure(exec->lexicalGlobalObject()->objectPrototype())) - , m_globalObject(globalObject) + : DOMConstructorWithDocument(JSImageConstructor::createStructure(globalObject->objectPrototype()), globalObject) { - ASSERT(globalObject->scriptExecutionContext()); - ASSERT(globalObject->scriptExecutionContext()->isDocument()); - - putDirect(exec->propertyNames().prototype, JSHTMLImageElementPrototype::self(exec, exec->lexicalGlobalObject()), None); -} - -Document* JSImageConstructor::document() const -{ - return static_cast<Document*>(m_globalObject->scriptExecutionContext()); + putDirect(exec->propertyNames().prototype, JSHTMLImageElementPrototype::self(exec, globalObject), None); } static JSObject* constructImage(ExecState* exec, JSObject* constructor, const ArgList& args) @@ -64,21 +55,22 @@ static JSObject* constructImage(ExecState* exec, JSObject* constructor, const Ar height = args.at(1).toInt32(exec); } - Document* document = static_cast<JSImageConstructor*>(constructor)->document(); + 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). - toJS(exec, document); + toJS(exec, jsConstructor->globalObject(), document); RefPtr<HTMLImageElement> image = new HTMLImageElement(HTMLNames::imgTag, document); if (widthSet) image->setWidth(width); if (heightSet) image->setHeight(height); - return asObject(toJS(exec, image.release())); + return asObject(toJS(exec, jsConstructor->globalObject(), image.release())); } ConstructType JSImageConstructor::getConstructData(ConstructData& constructData) @@ -87,11 +79,4 @@ ConstructType JSImageConstructor::getConstructData(ConstructData& constructData) return ConstructTypeHost; } -void JSImageConstructor::mark() -{ - DOMObject::mark(); - if (!m_globalObject->marked()) - m_globalObject->mark(); -} - } // namespace WebCore diff --git a/WebCore/bindings/js/JSImageConstructor.h b/WebCore/bindings/js/JSImageConstructor.h index 8dc7add..0525f5e 100644 --- a/WebCore/bindings/js/JSImageConstructor.h +++ b/WebCore/bindings/js/JSImageConstructor.h @@ -25,19 +25,14 @@ namespace WebCore { - class JSImageConstructor : public DOMObject { + class JSImageConstructor : public DOMConstructorWithDocument { public: JSImageConstructor(JSC::ExecState*, JSDOMGlobalObject*); - Document* document() const; static const JSC::ClassInfo s_info; - - virtual void mark(); private: virtual JSC::ConstructType getConstructData(JSC::ConstructData&); virtual const JSC::ClassInfo* classInfo() const { return &s_info; } - - JSDOMGlobalObject* m_globalObject; }; } // namespace WebCore diff --git a/WebCore/bindings/js/JSImageDataCustom.cpp b/WebCore/bindings/js/JSImageDataCustom.cpp index 32fe58b..fa3b1d5 100644 --- a/WebCore/bindings/js/JSImageDataCustom.cpp +++ b/WebCore/bindings/js/JSImageDataCustom.cpp @@ -36,7 +36,7 @@ using namespace JSC; namespace WebCore { -JSValue toJS(ExecState* exec, ImageData* imageData) +JSValue toJS(ExecState* exec, JSDOMGlobalObject* globalObject, ImageData* imageData) { if (!imageData) return jsNull(); @@ -45,7 +45,7 @@ JSValue toJS(ExecState* exec, ImageData* imageData) if (wrapper) return wrapper; - wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, ImageData, imageData); + wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, globalObject, ImageData, imageData); Identifier dataName(exec, "data"); DEFINE_STATIC_LOCAL(RefPtr<Structure>, cpaStructure, (JSByteArray::createStructure(jsNull()))); static const ClassInfo cpaClassInfo = { "CanvasPixelArray", 0, 0, 0 }; diff --git a/WebCore/bindings/js/JSInspectorControllerCustom.cpp b/WebCore/bindings/js/JSInspectorBackendCustom.cpp index b06c9e9..b2eb2d1 100644 --- a/WebCore/bindings/js/JSInspectorControllerCustom.cpp +++ b/WebCore/bindings/js/JSInspectorBackendCustom.cpp @@ -31,7 +31,7 @@ */ #include "config.h" -#include "JSInspectorController.h" +#include "JSInspectorBackend.h" #include "Console.h" #if ENABLE(DATABASE) @@ -41,6 +41,7 @@ #include "ExceptionCode.h" #include "Frame.h" #include "FrameLoader.h" +#include "InspectorBackend.h" #include "InspectorController.h" #include "InspectorResource.h" #include "JSDOMWindow.h" @@ -69,7 +70,7 @@ using namespace JSC; namespace WebCore { -JSValue JSInspectorController::highlightDOMNode(JSC::ExecState*, const JSC::ArgList& args) +JSValue JSInspectorBackend::highlightDOMNode(JSC::ExecState*, const JSC::ArgList& args) { if (args.size() < 1) return jsUndefined(); @@ -87,34 +88,7 @@ JSValue JSInspectorController::highlightDOMNode(JSC::ExecState*, const JSC::ArgL return jsUndefined(); } -JSValue JSInspectorController::getResourceDocumentNode(ExecState* exec, const ArgList& args) -{ - if (args.size() < 1) - return jsUndefined(); - - bool ok = false; - unsigned identifier = args.at(0).toUInt32(exec, ok); - if (!ok) - return jsUndefined(); - - RefPtr<InspectorResource> resource = impl()->resources().get(identifier); - ASSERT(resource); - if (!resource) - return jsUndefined(); - - Frame* frame = resource->frame(); - Document* document = frame->document(); - - if (document->isPluginDocument() || document->isImageDocument() || document->isMediaDocument()) - return jsUndefined(); - - ExecState* resourceExec = toJSDOMWindowShell(frame)->window()->globalExec(); - - JSLock lock(false); - return JSInspectedObjectWrapper::wrap(resourceExec, toJS(resourceExec, document)); -} - -JSValue JSInspectorController::search(ExecState* exec, const ArgList& args) +JSValue JSInspectorBackend::search(ExecState* exec, const ArgList& args) { if (args.size() < 2) return jsUndefined(); @@ -151,7 +125,7 @@ JSValue JSInspectorController::search(ExecState* exec, const ArgList& args) } #if ENABLE(DATABASE) -JSValue JSInspectorController::databaseTableNames(ExecState* exec, const ArgList& args) +JSValue JSInspectorBackend::databaseTableNames(ExecState* exec, const ArgList& args) { if (args.size() < 1) return jsUndefined(); @@ -175,13 +149,16 @@ JSValue JSInspectorController::databaseTableNames(ExecState* exec, const ArgList } #endif -JSValue JSInspectorController::inspectedWindow(ExecState*, const ArgList&) +JSValue JSInspectorBackend::inspectedWindow(ExecState*, const ArgList&) { - JSDOMWindow* inspectedWindow = toJSDOMWindow(impl()->inspectedPage()->mainFrame()); + InspectorController* ic = impl()->inspectorController(); + if (!ic) + return jsUndefined(); + JSDOMWindow* inspectedWindow = toJSDOMWindow(ic->inspectedPage()->mainFrame()); return JSInspectedObjectWrapper::wrap(inspectedWindow->globalExec(), inspectedWindow); } -JSValue JSInspectorController::setting(ExecState* exec, const ArgList& args) +JSValue JSInspectorBackend::setting(ExecState* exec, const ArgList& args) { if (args.size() < 1) return jsUndefined(); @@ -190,7 +167,10 @@ JSValue JSInspectorController::setting(ExecState* exec, const ArgList& args) if (exec->hadException()) return jsUndefined(); - const InspectorController::Setting& setting = impl()->setting(key); + InspectorController* ic = impl()->inspectorController(); + if (!ic) + return jsUndefined(); + const InspectorController::Setting& setting = ic->setting(key); switch (setting.type()) { default: @@ -215,7 +195,7 @@ JSValue JSInspectorController::setting(ExecState* exec, const ArgList& args) } } -JSValue JSInspectorController::setSetting(ExecState* exec, const ArgList& args) +JSValue JSInspectorBackend::setSetting(ExecState* exec, const ArgList& args) { if (args.size() < 2) return jsUndefined(); @@ -253,12 +233,14 @@ JSValue JSInspectorController::setSetting(ExecState* exec, const ArgList& args) if (exec->hadException()) return jsUndefined(); - impl()->setSetting(key, setting); + InspectorController* ic = impl()->inspectorController(); + if (ic) + ic->setSetting(key, setting); return jsUndefined(); } -JSValue JSInspectorController::wrapCallback(ExecState* exec, const ArgList& args) +JSValue JSInspectorBackend::wrapCallback(ExecState* exec, const ArgList& args) { if (args.size() < 1) return jsUndefined(); @@ -268,7 +250,7 @@ JSValue JSInspectorController::wrapCallback(ExecState* exec, const ArgList& args #if ENABLE(JAVASCRIPT_DEBUGGER) -JSValue JSInspectorController::currentCallFrame(ExecState* exec, const ArgList&) +JSValue JSInspectorBackend::currentCallFrame(ExecState* exec, const ArgList&) { JavaScriptCallFrame* callFrame = impl()->currentCallFrame(); if (!callFrame || !callFrame->isValid()) @@ -277,15 +259,18 @@ JSValue JSInspectorController::currentCallFrame(ExecState* exec, const ArgList&) // FIXME: I am not sure if this is actually needed. Can we just use exec? ExecState* globalExec = callFrame->scopeChain()->globalObject()->globalExec(); - JSLock lock(false); + JSLock lock(SilenceAssertionsOnly); return JSInspectedObjectWrapper::wrap(globalExec, toJS(exec, callFrame)); } -JSValue JSInspectorController::profiles(JSC::ExecState* exec, const JSC::ArgList&) +JSValue JSInspectorBackend::profiles(JSC::ExecState* exec, const JSC::ArgList&) { - JSLock lock(false); + JSLock lock(SilenceAssertionsOnly); MarkedArgumentBuffer result; - const Vector<RefPtr<Profile> >& profiles = impl()->profiles(); + InspectorController* ic = impl()->inspectorController(); + if (!ic) + return jsUndefined(); + const Vector<RefPtr<Profile> >& profiles = ic->profiles(); for (size_t i = 0; i < profiles.size(); ++i) result.append(toJS(exec, profiles[i].get())); diff --git a/WebCore/bindings/js/JSLazyEventListener.cpp b/WebCore/bindings/js/JSLazyEventListener.cpp index f7c74ae..7caff2b 100644 --- a/WebCore/bindings/js/JSLazyEventListener.cpp +++ b/WebCore/bindings/js/JSLazyEventListener.cpp @@ -77,7 +77,11 @@ void JSLazyEventListener::parseCode() const if (m_parsed) return; - if (m_globalObject->scriptExecutionContext()->isDocument()) { + ScriptExecutionContext* executionContext = m_globalObject->scriptExecutionContext(); + ASSERT(executionContext); + if (!executionContext) + return; + if (executionContext->isDocument()) { JSDOMWindow* window = static_cast<JSDOMWindow*>(m_globalObject); Frame* frame = window->impl()->frame(); if (!frame) @@ -93,7 +97,7 @@ void JSLazyEventListener::parseCode() const ExecState* exec = m_globalObject->globalExec(); MarkedArgumentBuffer args; - UString sourceURL(m_globalObject->scriptExecutionContext()->url().string()); + UString sourceURL(executionContext->url().string()); args.append(jsNontrivialString(exec, m_eventParameterName)); args.append(jsString(exec, m_code)); @@ -113,7 +117,7 @@ void JSLazyEventListener::parseCode() const // (and the document, and the form - see JSHTMLElement::eventHandlerScope) ScopeChain scope = listenerAsFunction->scope(); - JSValue thisObj = toJS(exec, m_originalNode); + JSValue thisObj = toJS(exec, m_globalObject, m_originalNode); if (thisObj.isObject()) { static_cast<JSNode*>(asObject(thisObj))->pushEventHandlerScope(exec, scope); listenerAsFunction->setScope(scope); diff --git a/WebCore/bindings/js/JSLocationCustom.cpp b/WebCore/bindings/js/JSLocationCustom.cpp index 9c5a834..d7d32f4 100644 --- a/WebCore/bindings/js/JSLocationCustom.cpp +++ b/WebCore/bindings/js/JSLocationCustom.cpp @@ -39,20 +39,20 @@ namespace WebCore { static JSValue nonCachingStaticReplaceFunctionGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot&) { - return new (exec) PrototypeFunction(exec, 1, propertyName, jsLocationPrototypeFunctionReplace); + return new (exec) NativeFunctionWrapper(exec, exec->lexicalGlobalObject()->prototypeFunctionStructure(), 1, propertyName, jsLocationPrototypeFunctionReplace); } static JSValue nonCachingStaticReloadFunctionGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot&) { - return new (exec) PrototypeFunction(exec, 0, propertyName, jsLocationPrototypeFunctionReload); + return new (exec) NativeFunctionWrapper(exec, exec->lexicalGlobalObject()->prototypeFunctionStructure(), 0, propertyName, jsLocationPrototypeFunctionReload); } static JSValue nonCachingStaticAssignFunctionGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot&) { - return new (exec) PrototypeFunction(exec, 1, propertyName, jsLocationPrototypeFunctionAssign); + return new (exec) NativeFunctionWrapper(exec, exec->lexicalGlobalObject()->prototypeFunctionStructure(), 1, propertyName, jsLocationPrototypeFunctionAssign); } -bool JSLocation::customGetOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot) +bool JSLocation::getOwnPropertySlotDelegate(ExecState* exec, const Identifier& propertyName, PropertySlot& slot) { Frame* frame = impl()->frame(); if (!frame) { @@ -61,7 +61,7 @@ bool JSLocation::customGetOwnPropertySlot(ExecState* exec, const Identifier& pro } // When accessing Location cross-domain, functions are always the native built-in ones. - // See JSDOMWindow::customGetOwnPropertySlot for additional details. + // 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. @@ -93,7 +93,7 @@ bool JSLocation::customGetOwnPropertySlot(ExecState* exec, const Identifier& pro return true; } -bool JSLocation::customPut(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot) +bool JSLocation::putDelegate(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot) { Frame* frame = impl()->frame(); if (!frame) @@ -128,12 +128,12 @@ bool JSLocation::deleteProperty(ExecState* exec, const Identifier& propertyName) return Base::deleteProperty(exec, propertyName); } -bool JSLocation::customGetPropertyNames(ExecState* exec, PropertyNameArray&) +void JSLocation::getPropertyNames(ExecState* exec, PropertyNameArray& propertyNames) { // Only allow the location object to enumerated by frames in the same origin. if (!allowsAccessFromFrame(exec, impl()->frame())) - return true; - return false; + return; + Base::getPropertyNames(exec, propertyNames); } void JSLocation::defineGetter(ExecState* exec, const Identifier& propertyName, JSObject* getterFunction) @@ -245,13 +245,13 @@ void JSLocation::setHash(ExecState* exec, JSValue value) ASSERT(frame); KURL url = frame->loader()->url(); - String oldRef = url.ref(); + String oldFragmentIdentifier = url.fragmentIdentifier(); String str = value.toString(exec); if (str.startsWith("#")) str = str.substring(1); - if (oldRef == str || (oldRef.isNull() && str.isEmpty())) + if (equalIgnoringNullity(oldFragmentIdentifier, str)) return; - url.setRef(str); + url.setFragmentIdentifier(str); navigateIfAllowed(exec, frame, url, !frame->script()->anyPageIsProcessingUserGesture(), false); } @@ -311,7 +311,7 @@ JSValue JSLocation::toString(ExecState* exec, const ArgList&) return jsString(exec, impl()->toString()); } -bool JSLocationPrototype::customPut(ExecState* exec, const Identifier& propertyName, JSValue, PutPropertySlot&) +bool JSLocationPrototype::putDelegate(ExecState* exec, const Identifier& propertyName, JSValue, PutPropertySlot&) { return (propertyName == exec->propertyNames().toString || propertyName == exec->propertyNames().valueOf); } diff --git a/WebCore/bindings/js/JSMessageChannelConstructor.cpp b/WebCore/bindings/js/JSMessageChannelConstructor.cpp index 495bd53..25a5cb2 100644 --- a/WebCore/bindings/js/JSMessageChannelConstructor.cpp +++ b/WebCore/bindings/js/JSMessageChannelConstructor.cpp @@ -38,21 +38,15 @@ namespace WebCore { const ClassInfo JSMessageChannelConstructor::s_info = { "MessageChannelConstructor", 0, 0, 0 }; JSMessageChannelConstructor::JSMessageChannelConstructor(ExecState* exec, JSDOMGlobalObject* globalObject) - : DOMObject(JSMessageChannelConstructor::createStructure(exec->lexicalGlobalObject()->objectPrototype())) - , m_globalObject(globalObject) + : DOMConstructorObject(JSMessageChannelConstructor::createStructure(globalObject->objectPrototype()), globalObject) { - putDirect(exec->propertyNames().prototype, JSMessageChannelPrototype::self(exec, exec->lexicalGlobalObject()), None); + putDirect(exec->propertyNames().prototype, JSMessageChannelPrototype::self(exec, globalObject), None); } JSMessageChannelConstructor::~JSMessageChannelConstructor() { } -ScriptExecutionContext* JSMessageChannelConstructor::scriptExecutionContext() const -{ - return m_globalObject->scriptExecutionContext(); -} - ConstructType JSMessageChannelConstructor::getConstructData(ConstructData& constructData) { constructData.native.function = construct; @@ -61,18 +55,12 @@ ConstructType JSMessageChannelConstructor::getConstructData(ConstructData& const JSObject* JSMessageChannelConstructor::construct(ExecState* exec, JSObject* constructor, const ArgList&) { - ScriptExecutionContext* context = static_cast<JSMessageChannelConstructor*>(constructor)->scriptExecutionContext(); + JSMessageChannelConstructor* jsConstructor = static_cast<JSMessageChannelConstructor*>(constructor); + ScriptExecutionContext* context = jsConstructor->scriptExecutionContext(); if (!context) return throwError(exec, ReferenceError, "MessageChannel constructor associated document is unavailable"); - return asObject(toJS(exec, MessageChannel::create(context))); -} - -void JSMessageChannelConstructor::mark() -{ - DOMObject::mark(); - if (!m_globalObject->marked()) - m_globalObject->mark(); + return asObject(toJS(exec, jsConstructor->globalObject(), MessageChannel::create(context))); } } // namespace WebCore diff --git a/WebCore/bindings/js/JSMessageChannelConstructor.h b/WebCore/bindings/js/JSMessageChannelConstructor.h index 90c29a3..d958760 100644 --- a/WebCore/bindings/js/JSMessageChannelConstructor.h +++ b/WebCore/bindings/js/JSMessageChannelConstructor.h @@ -30,23 +30,16 @@ namespace WebCore { - class JSMessageChannelConstructor : public DOMObject { + class JSMessageChannelConstructor : public DOMConstructorObject { public: JSMessageChannelConstructor(JSC::ExecState*, JSDOMGlobalObject*); virtual ~JSMessageChannelConstructor(); virtual const JSC::ClassInfo* classInfo() const { return &s_info; } static const JSC::ClassInfo s_info; - ScriptExecutionContext* scriptExecutionContext() const; - virtual bool implementsHasInstance() const { return true; } static JSC::JSObject* construct(JSC::ExecState*, JSC::JSObject*, const JSC::ArgList&); virtual JSC::ConstructType getConstructData(JSC::ConstructData&); - - virtual void mark(); - - private: - JSDOMGlobalObject* m_globalObject; }; } // namespace WebCore diff --git a/WebCore/bindings/js/JSMessageChannelCustom.cpp b/WebCore/bindings/js/JSMessageChannelCustom.cpp index 70329e2..574e28a 100644 --- a/WebCore/bindings/js/JSMessageChannelCustom.cpp +++ b/WebCore/bindings/js/JSMessageChannelCustom.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008 Apple Inc. All Rights Reserved. + * 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 @@ -32,20 +32,20 @@ using namespace JSC; namespace WebCore { -void JSMessageChannel::mark() +void JSMessageChannel::markChildren(MarkStack& markStack) { - DOMObject::mark(); + Base::markChildren(markStack); if (MessagePort* port = m_impl->port1()) { DOMObject* wrapper = getCachedDOMObjectWrapper(*Heap::heap(this)->globalData(), port); - if (wrapper && !wrapper->marked()) - wrapper->mark(); + if (wrapper) + markStack.append(wrapper); } if (MessagePort* port = m_impl->port2()) { DOMObject* wrapper = getCachedDOMObjectWrapper(*Heap::heap(this)->globalData(), port); - if (wrapper && !wrapper->marked()) - wrapper->mark(); + if (wrapper) + markStack.append(wrapper); } } diff --git a/WebCore/bindings/js/JSMessagePortCustom.cpp b/WebCore/bindings/js/JSMessagePortCustom.cpp index f4809ae..c3316c5 100644 --- a/WebCore/bindings/js/JSMessagePortCustom.cpp +++ b/WebCore/bindings/js/JSMessagePortCustom.cpp @@ -38,17 +38,17 @@ using namespace JSC; namespace WebCore { -void JSMessagePort::mark() +void JSMessagePort::markChildren(MarkStack& markStack) { - DOMObject::mark(); + Base::markChildren(markStack); - markIfNotNull(m_impl->onmessage()); - markIfNotNull(m_impl->onclose()); + markIfNotNull(markStack, m_impl->onmessage()); - if (MessagePortProxy* entangledPort = m_impl->entangledPort()) { + // If we have a locally entangled port, we can directly mark it as reachable. Ports that are remotely entangled are marked in-use by markActiveObjectsForContext(). + if (MessagePort* entangledPort = m_impl->locallyEntangledPort()) { DOMObject* wrapper = getCachedDOMObjectWrapper(*Heap::heap(this)->globalData(), entangledPort); - if (wrapper && !wrapper->marked()) - wrapper->mark(); + if (wrapper) + markStack.append(wrapper); } typedef MessagePort::EventListenersMap EventListenersMap; @@ -56,18 +56,10 @@ void JSMessagePort::mark() EventListenersMap& eventListeners = m_impl->eventListeners(); for (EventListenersMap::iterator mapIter = eventListeners.begin(); mapIter != eventListeners.end(); ++mapIter) { for (ListenerVector::iterator vecIter = mapIter->second.begin(); vecIter != mapIter->second.end(); ++vecIter) - (*vecIter)->markJSFunction(); + (*vecIter)->markJSFunction(markStack); } } -JSValue JSMessagePort::startConversation(ExecState* exec, const ArgList& args) -{ - JSDOMGlobalObject* globalObject = static_cast<JSDOMGlobalObject*>(exec->lexicalGlobalObject()); - const UString& message = args.at(0).toString(exec); - - return toJS(exec, impl()->startConversation(globalObject->scriptExecutionContext(), message).get()); -} - JSValue JSMessagePort::addEventListener(ExecState* exec, const ArgList& args) { JSDOMGlobalObject* globalObject = toJSDOMGlobalObject(impl()->scriptExecutionContext()); diff --git a/WebCore/bindings/js/JSNamedNodesCollection.cpp b/WebCore/bindings/js/JSNamedNodesCollection.cpp index 93a8937..f36a7d6 100644 --- a/WebCore/bindings/js/JSNamedNodesCollection.cpp +++ b/WebCore/bindings/js/JSNamedNodesCollection.cpp @@ -42,8 +42,8 @@ const ClassInfo JSNamedNodesCollection::s_info = { "Collection", 0, 0, 0 }; // Such a collection is usually very short-lived, it only exists // for constructs like document.forms.<name>[1], // so it shouldn't be a problem that it's storing all the nodes (with the same name). (David) -JSNamedNodesCollection::JSNamedNodesCollection(ExecState* exec, const Vector<RefPtr<Node> >& nodes) - : DOMObject(getDOMStructure<JSNamedNodesCollection>(exec)) +JSNamedNodesCollection::JSNamedNodesCollection(ExecState* exec, JSDOMGlobalObject* globalObject, const Vector<RefPtr<Node> >& nodes) + : DOMObjectWithGlobalPointer(getDOMStructure<JSNamedNodesCollection>(exec, globalObject), globalObject) , m_nodes(new Vector<RefPtr<Node> >(nodes)) { } @@ -86,7 +86,7 @@ bool JSNamedNodesCollection::getOwnPropertySlot(ExecState* exec, const Identifie } } - return DOMObject::getOwnPropertySlot(exec, propertyName, slot); + return DOMObjectWithGlobalPointer::getOwnPropertySlot(exec, propertyName, slot); } } // namespace WebCore diff --git a/WebCore/bindings/js/JSNamedNodesCollection.h b/WebCore/bindings/js/JSNamedNodesCollection.h index 3bbc102..cd6c2cb 100644 --- a/WebCore/bindings/js/JSNamedNodesCollection.h +++ b/WebCore/bindings/js/JSNamedNodesCollection.h @@ -35,9 +35,9 @@ namespace WebCore { // Internal class, used for the collection return by e.g. document.forms.myinput // when multiple nodes have the same name. - class JSNamedNodesCollection : public DOMObject { + class JSNamedNodesCollection : public DOMObjectWithGlobalPointer { public: - JSNamedNodesCollection(JSC::ExecState*, const Vector<RefPtr<Node> >&); + JSNamedNodesCollection(JSC::ExecState*, JSDOMGlobalObject*, const Vector<RefPtr<Node> >&); virtual bool getOwnPropertySlot(JSC::ExecState*, const JSC::Identifier&, JSC::PropertySlot&); diff --git a/WebCore/bindings/js/JSNavigatorCustom.cpp b/WebCore/bindings/js/JSNavigatorCustom.cpp index ea6cceb..c023931 100644 --- a/WebCore/bindings/js/JSNavigatorCustom.cpp +++ b/WebCore/bindings/js/JSNavigatorCustom.cpp @@ -29,13 +29,13 @@ namespace WebCore { using namespace JSC; -void JSNavigator::mark() +void JSNavigator::markChildren(MarkStack& markStack) { - Base::mark(); + Base::markChildren(markStack); JSGlobalData& globalData = *Heap::heap(this)->globalData(); - markDOMObjectWrapper(globalData, impl()->optionalGeolocation()); + markDOMObjectWrapper(markStack, globalData, impl()->optionalGeolocation()); } } diff --git a/WebCore/bindings/js/JSNodeCustom.cpp b/WebCore/bindings/js/JSNodeCustom.cpp index 79ac6b7..cf884b9 100644 --- a/WebCore/bindings/js/JSNodeCustom.cpp +++ b/WebCore/bindings/js/JSNodeCustom.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007 Apple Inc. All rights reserved. + * Copyright (C) 2007, 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 @@ -110,7 +110,7 @@ JSValue JSNode::appendChild(ExecState* exec, const ArgList& args) JSValue JSNode::addEventListener(ExecState* exec, const ArgList& args) { - JSDOMGlobalObject* globalObject = toJSDOMGlobalObject(impl()->scriptExecutionContext()); + JSDOMGlobalObject* globalObject = toJSDOMGlobalObject(impl()->document()); if (!globalObject) return jsUndefined(); @@ -122,7 +122,7 @@ JSValue JSNode::addEventListener(ExecState* exec, const ArgList& args) JSValue JSNode::removeEventListener(ExecState* exec, const ArgList& args) { - JSDOMGlobalObject* globalObject = toJSDOMGlobalObject(impl()->scriptExecutionContext()); + JSDOMGlobalObject* globalObject = toJSDOMGlobalObject(impl()->document()); if (!globalObject) return jsUndefined(); @@ -136,22 +136,21 @@ void JSNode::pushEventHandlerScope(ExecState*, ScopeChain&) const { } -void JSNode::mark() +void JSNode::markChildren(MarkStack& markStack) { - ASSERT(!marked()); - Node* node = m_impl.get(); + Base::markChildren(markStack); + markEventListeners(markStack, node->eventListeners()); + // 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()) { - DOMObject::mark(); - markEventListeners(node->eventListeners()); - if (Document* doc = node->ownerDocument()) + if (Document* doc = node->ownerDocument()) { if (DOMObject* docWrapper = getCachedDOMObjectWrapper(*Heap::heap(this)->globalData(), doc)) - if (!docWrapper->marked()) - docWrapper->mark(); + markStack.append(docWrapper); + } return; } @@ -163,36 +162,20 @@ void JSNode::mark() // 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()) { - DOMObject::mark(); - markEventListeners(node->eventListeners()); + if (root->inSubtreeMark()) 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) { - if (!wrapper->marked()) - wrapper->mark(); - } else if (nodeToMark == node) { - // This is the case where the map from the document to wrappers has - // been cleared out, but a wrapper is being marked. For now, we'll - // let the rest of the tree of wrappers get collected, because we have - // no good way of finding them. Later we should test behavior of other - // browsers and see if we need to preserve other wrappers in this case. - if (!marked()) - mark(); - } + if (wrapper) + markStack.append(wrapper); } root->setInSubtreeMark(false); - - // Double check that we actually ended up marked. This assert caught problems in the past. - ASSERT(marked()); } -static ALWAYS_INLINE JSValue createWrapper(ExecState* exec, Node* node) +static ALWAYS_INLINE JSValue createWrapper(ExecState* exec, JSDOMGlobalObject* globalObject, Node* node) { ASSERT(node); ASSERT(!getCachedDOMNodeWrapper(node->document(), node)); @@ -201,63 +184,63 @@ static ALWAYS_INLINE JSValue createWrapper(ExecState* exec, Node* node) switch (node->nodeType()) { case Node::ELEMENT_NODE: if (node->isHTMLElement()) - wrapper = createJSHTMLWrapper(exec, static_cast<HTMLElement*>(node)); + wrapper = createJSHTMLWrapper(exec, globalObject, static_cast<HTMLElement*>(node)); #if ENABLE(SVG) else if (node->isSVGElement()) - wrapper = createJSSVGWrapper(exec, static_cast<SVGElement*>(node)); + wrapper = createJSSVGWrapper(exec, globalObject, static_cast<SVGElement*>(node)); #endif else - wrapper = CREATE_DOM_NODE_WRAPPER(exec, Element, node); + wrapper = CREATE_DOM_NODE_WRAPPER(exec, globalObject, Element, node); break; case Node::ATTRIBUTE_NODE: - wrapper = CREATE_DOM_NODE_WRAPPER(exec, Attr, node); + wrapper = CREATE_DOM_NODE_WRAPPER(exec, globalObject, Attr, node); break; case Node::TEXT_NODE: - wrapper = CREATE_DOM_NODE_WRAPPER(exec, Text, node); + wrapper = CREATE_DOM_NODE_WRAPPER(exec, globalObject, Text, node); break; case Node::CDATA_SECTION_NODE: - wrapper = CREATE_DOM_NODE_WRAPPER(exec, CDATASection, node); + wrapper = CREATE_DOM_NODE_WRAPPER(exec, globalObject, CDATASection, node); break; case Node::ENTITY_NODE: - wrapper = CREATE_DOM_NODE_WRAPPER(exec, Entity, node); + wrapper = CREATE_DOM_NODE_WRAPPER(exec, globalObject, Entity, node); break; case Node::PROCESSING_INSTRUCTION_NODE: - wrapper = CREATE_DOM_NODE_WRAPPER(exec, ProcessingInstruction, node); + wrapper = CREATE_DOM_NODE_WRAPPER(exec, globalObject, ProcessingInstruction, node); break; case Node::COMMENT_NODE: - wrapper = CREATE_DOM_NODE_WRAPPER(exec, Comment, node); + wrapper = CREATE_DOM_NODE_WRAPPER(exec, globalObject, Comment, node); break; case Node::DOCUMENT_NODE: // we don't want to cache the document itself in the per-document dictionary - return toJS(exec, static_cast<Document*>(node)); + return toJS(exec, globalObject, static_cast<Document*>(node)); case Node::DOCUMENT_TYPE_NODE: - wrapper = CREATE_DOM_NODE_WRAPPER(exec, DocumentType, node); + wrapper = CREATE_DOM_NODE_WRAPPER(exec, globalObject, DocumentType, node); break; case Node::NOTATION_NODE: - wrapper = CREATE_DOM_NODE_WRAPPER(exec, Notation, node); + wrapper = CREATE_DOM_NODE_WRAPPER(exec, globalObject, Notation, node); break; case Node::DOCUMENT_FRAGMENT_NODE: - wrapper = CREATE_DOM_NODE_WRAPPER(exec, DocumentFragment, node); + wrapper = CREATE_DOM_NODE_WRAPPER(exec, globalObject, DocumentFragment, node); break; case Node::ENTITY_REFERENCE_NODE: - wrapper = CREATE_DOM_NODE_WRAPPER(exec, EntityReference, node); + wrapper = CREATE_DOM_NODE_WRAPPER(exec, globalObject, EntityReference, node); break; default: - wrapper = CREATE_DOM_NODE_WRAPPER(exec, Node, node); + wrapper = CREATE_DOM_NODE_WRAPPER(exec, globalObject, Node, node); } return wrapper; } -JSValue toJSNewlyCreated(ExecState* exec, Node* node) +JSValue toJSNewlyCreated(ExecState* exec, JSDOMGlobalObject* globalObject, Node* node) { if (!node) return jsNull(); - return createWrapper(exec, node); + return createWrapper(exec, globalObject, node); } -JSValue toJS(ExecState* exec, Node* node) +JSValue toJS(ExecState* exec, JSDOMGlobalObject* globalObject, Node* node) { if (!node) return jsNull(); @@ -266,7 +249,7 @@ JSValue toJS(ExecState* exec, Node* node) if (wrapper) return wrapper; - return createWrapper(exec, node); + return createWrapper(exec, globalObject, node); } } // namespace WebCore diff --git a/WebCore/bindings/js/JSNodeFilterCondition.cpp b/WebCore/bindings/js/JSNodeFilterCondition.cpp index f5d4d5c..a199417 100644 --- a/WebCore/bindings/js/JSNodeFilterCondition.cpp +++ b/WebCore/bindings/js/JSNodeFilterCondition.cpp @@ -1,6 +1,6 @@ /* * Copyright (C) 2001 Peter Kelly (pmk@post.com) - * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2007, 2008, 2009 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 @@ -36,15 +36,14 @@ JSNodeFilterCondition::JSNodeFilterCondition(JSValue filter) { } -void JSNodeFilterCondition::mark() +void JSNodeFilterCondition::markAggregate(MarkStack& markStack) { - if (!m_filter.marked()) - m_filter.mark(); + markStack.append(m_filter); } short JSNodeFilterCondition::acceptNode(JSC::ExecState* exec, Node* filterNode) const { - JSLock lock(false); + JSLock lock(SilenceAssertionsOnly); CallData callData; CallType callType = m_filter.getCallData(callData); @@ -61,7 +60,9 @@ short JSNodeFilterCondition::acceptNode(JSC::ExecState* exec, Node* filterNode) return NodeFilter::FILTER_REJECT; MarkedArgumentBuffer args; - args.append(toJS(exec, filterNode)); + // FIXME: The node should have the prototype chain that came from its document, not + // whatever prototype chain might be on the window this filter came from. Bug 27662 + args.append(toJS(exec, deprecatedGlobalObjectForPrototype(exec), filterNode)); if (exec->hadException()) return NodeFilter::FILTER_REJECT; diff --git a/WebCore/bindings/js/JSNodeFilterCondition.h b/WebCore/bindings/js/JSNodeFilterCondition.h index 3d591c6..b96534a 100644 --- a/WebCore/bindings/js/JSNodeFilterCondition.h +++ b/WebCore/bindings/js/JSNodeFilterCondition.h @@ -1,6 +1,6 @@ /* * Copyright (C) 2001 Peter Kelly (pmk@post.com) - * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2007, 2008, 2009 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 @@ -39,7 +39,7 @@ namespace WebCore { JSNodeFilterCondition(JSC::JSValue filter); virtual short acceptNode(ScriptState*, Node*) const; - virtual void mark(); + virtual void markAggregate(JSC::MarkStack&); mutable JSC::JSValue m_filter; }; diff --git a/WebCore/bindings/js/JSNodeFilterCustom.cpp b/WebCore/bindings/js/JSNodeFilterCustom.cpp index ecc12d5..09fd110 100644 --- a/WebCore/bindings/js/JSNodeFilterCustom.cpp +++ b/WebCore/bindings/js/JSNodeFilterCustom.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2007, 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 @@ -35,10 +35,10 @@ using namespace JSC; namespace WebCore { -void JSNodeFilter::mark() +void JSNodeFilter::markChildren(MarkStack& markStack) { - impl()->mark(); - DOMObject::mark(); + Base::markChildren(markStack); + impl()->markAggregate(markStack); } JSValue JSNodeFilter::acceptNode(ExecState* exec, const ArgList& args) diff --git a/WebCore/bindings/js/JSNodeIteratorCustom.cpp b/WebCore/bindings/js/JSNodeIteratorCustom.cpp index 8fff82e..6a09abf 100644 --- a/WebCore/bindings/js/JSNodeIteratorCustom.cpp +++ b/WebCore/bindings/js/JSNodeIteratorCustom.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2006, 2008, 2009 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 @@ -29,12 +29,12 @@ using namespace JSC; namespace WebCore { -void JSNodeIterator::mark() +void JSNodeIterator::markChildren(MarkStack& markStack) { + Base::markChildren(markStack); + if (NodeFilter* filter = m_impl->filter()) - filter->mark(); - - DOMObject::mark(); + filter->markAggregate(markStack); } JSValue JSNodeIterator::nextNode(ExecState* exec, const ArgList&) diff --git a/WebCore/bindings/js/JSOptionConstructor.cpp b/WebCore/bindings/js/JSOptionConstructor.cpp index 9e818ff..2b8bd5d 100644 --- a/WebCore/bindings/js/JSOptionConstructor.cpp +++ b/WebCore/bindings/js/JSOptionConstructor.cpp @@ -35,24 +35,16 @@ ASSERT_CLASS_FITS_IN_CELL(JSOptionConstructor); const ClassInfo JSOptionConstructor::s_info = { "OptionConstructor", 0, 0, 0 }; JSOptionConstructor::JSOptionConstructor(ExecState* exec, JSDOMGlobalObject* globalObject) - : DOMObject(JSOptionConstructor::createStructure(exec->lexicalGlobalObject()->objectPrototype())) - , m_globalObject(globalObject) + : DOMConstructorWithDocument(JSOptionConstructor::createStructure(globalObject->objectPrototype()), globalObject) { - ASSERT(globalObject->scriptExecutionContext()); - ASSERT(globalObject->scriptExecutionContext()->isDocument()); - - putDirect(exec->propertyNames().prototype, JSHTMLOptionElementPrototype::self(exec, exec->lexicalGlobalObject()), None); + putDirect(exec->propertyNames().prototype, JSHTMLOptionElementPrototype::self(exec, globalObject), None); putDirect(exec->propertyNames().length, jsNumber(exec, 4), ReadOnly|DontDelete|DontEnum); } -Document* JSOptionConstructor::document() const -{ - return static_cast<Document*>(m_globalObject->scriptExecutionContext()); -} - static JSObject* constructHTMLOptionElement(ExecState* exec, JSObject* constructor, const ArgList& args) { - Document* document = static_cast<JSOptionConstructor*>(constructor)->document(); + JSOptionConstructor* jsConstructor = static_cast<JSOptionConstructor*>(constructor); + Document* document = jsConstructor->document(); if (!document) return throwError(exec, ReferenceError, "Option constructor associated document is unavailable"); @@ -76,7 +68,7 @@ static JSObject* constructHTMLOptionElement(ExecState* exec, JSObject* construct return 0; } - return asObject(toJS(exec, element.release())); + return asObject(toJS(exec, jsConstructor->globalObject(), element.release())); } ConstructType JSOptionConstructor::getConstructData(ConstructData& constructData) @@ -85,11 +77,5 @@ ConstructType JSOptionConstructor::getConstructData(ConstructData& constructData return ConstructTypeHost; } -void JSOptionConstructor::mark() -{ - DOMObject::mark(); - if (!m_globalObject->marked()) - m_globalObject->mark(); -} } // namespace WebCore diff --git a/WebCore/bindings/js/JSOptionConstructor.h b/WebCore/bindings/js/JSOptionConstructor.h index 3c87c28..246e7fa 100644 --- a/WebCore/bindings/js/JSOptionConstructor.h +++ b/WebCore/bindings/js/JSOptionConstructor.h @@ -26,19 +26,14 @@ namespace WebCore { - class JSOptionConstructor : public DOMObject { + class JSOptionConstructor : public DOMConstructorWithDocument { public: JSOptionConstructor(JSC::ExecState*, JSDOMGlobalObject*); - Document* document() const; static const JSC::ClassInfo s_info; - - virtual void mark(); private: virtual JSC::ConstructType getConstructData(JSC::ConstructData&); virtual const JSC::ClassInfo* classInfo() const { return &s_info; } - - JSDOMGlobalObject* m_globalObject; }; } // namespace WebCore diff --git a/WebCore/bindings/js/JSQuarantinedObjectWrapper.cpp b/WebCore/bindings/js/JSQuarantinedObjectWrapper.cpp index ad1e556..5f4dfd4 100644 --- a/WebCore/bindings/js/JSQuarantinedObjectWrapper.cpp +++ b/WebCore/bindings/js/JSQuarantinedObjectWrapper.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008 Apple Inc. All Rights Reserved. + * 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 @@ -92,14 +92,12 @@ void JSQuarantinedObjectWrapper::transferExceptionToExecState(ExecState* exec) c exec->setException(wrapOutgoingValue(unwrappedExecState(), exception)); } -void JSQuarantinedObjectWrapper::mark() +void JSQuarantinedObjectWrapper::markChildren(MarkStack& markStack) { - JSObject::mark(); + JSObject::markChildren(markStack); - if (!m_unwrappedObject->marked()) - m_unwrappedObject->mark(); - if (!m_unwrappedGlobalObject->marked()) - m_unwrappedGlobalObject->mark(); + markStack.append(m_unwrappedObject); + markStack.append(m_unwrappedGlobalObject); } bool JSQuarantinedObjectWrapper::getOwnPropertySlot(ExecState* exec, const Identifier& identifier, PropertySlot& slot) diff --git a/WebCore/bindings/js/JSQuarantinedObjectWrapper.h b/WebCore/bindings/js/JSQuarantinedObjectWrapper.h index bf8fddb..08935e7 100644 --- a/WebCore/bindings/js/JSQuarantinedObjectWrapper.h +++ b/WebCore/bindings/js/JSQuarantinedObjectWrapper.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008 Apple Inc. All rights reserved. + * 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 @@ -53,7 +53,7 @@ namespace WebCore { protected: JSQuarantinedObjectWrapper(JSC::ExecState* unwrappedExec, JSC::JSObject* unwrappedObject, PassRefPtr<JSC::Structure>); - virtual void mark(); + virtual void markChildren(JSC::MarkStack&); private: virtual bool getOwnPropertySlot(JSC::ExecState*, const JSC::Identifier&, JSC::PropertySlot&); diff --git a/WebCore/bindings/js/JSRGBColor.cpp b/WebCore/bindings/js/JSRGBColor.cpp deleted file mode 100644 index f7c87e2..0000000 --- a/WebCore/bindings/js/JSRGBColor.cpp +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (C) 2000 Harri Porten (porten@kde.org) - * Copyright (C) 2001 Peter Kelly (pmk@post.com) - * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. - * Copyright (C) 2006 James G. Speth (speth@end.com) - * Copyright (C) 2006 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 "JSRGBColor.h" - -#include "CSSPrimitiveValue.h" -#include "JSCSSPrimitiveValue.h" - -using namespace JSC; - -static JSValue jsRGBColorRed(ExecState*, const Identifier&, const PropertySlot&); -static JSValue jsRGBColorGreen(ExecState*, const Identifier&, const PropertySlot&); -static JSValue jsRGBColorBlue(ExecState*, const Identifier&, const PropertySlot&); - -/* -@begin JSRGBColorTable - red jsRGBColorRed DontDelete|ReadOnly - green jsRGBColorGreen DontDelete|ReadOnly - blue jsRGBColorBlue DontDelete|ReadOnly -@end -*/ - -#include "JSRGBColor.lut.h" - -namespace WebCore { - -ASSERT_CLASS_FITS_IN_CELL(JSRGBColor); - -const ClassInfo JSRGBColor::s_info = { "RGBColor", 0, &JSRGBColorTable, 0 }; - -JSRGBColor::JSRGBColor(ExecState* exec, unsigned color) - : DOMObject(getDOMStructure<JSRGBColor>(exec)) - , m_color(color) -{ -} - -bool JSRGBColor::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot) -{ - return getStaticValueSlot<JSRGBColor, DOMObject>(exec, &JSRGBColorTable, this, propertyName, slot); -} - -JSValue getJSRGBColor(ExecState* exec, unsigned color) -{ - return new (exec) JSRGBColor(exec, color); -} - -} // namespace WebCore - -using namespace WebCore; - -JSValue jsRGBColorRed(ExecState* exec, const Identifier&, const PropertySlot& slot) -{ - return toJS(exec, CSSPrimitiveValue::create((static_cast<JSRGBColor*>(asObject(slot.slotBase()))->impl() >> 16) & 0xFF, CSSPrimitiveValue::CSS_NUMBER)); -} - -JSValue jsRGBColorGreen(ExecState* exec, const Identifier&, const PropertySlot& slot) -{ - return toJS(exec, CSSPrimitiveValue::create((static_cast<JSRGBColor*>(asObject(slot.slotBase()))->impl() >> 8) & 0xFF, CSSPrimitiveValue::CSS_NUMBER)); -} - -JSValue jsRGBColorBlue(ExecState* exec, const Identifier&, const PropertySlot& slot) -{ - return toJS(exec, CSSPrimitiveValue::create(static_cast<JSRGBColor*>(asObject(slot.slotBase()))->impl() & 0xFF, CSSPrimitiveValue::CSS_NUMBER)); -} - diff --git a/WebCore/bindings/js/JSRGBColor.h b/WebCore/bindings/js/JSRGBColor.h deleted file mode 100644 index cc2870f..0000000 --- a/WebCore/bindings/js/JSRGBColor.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (C) 2000 Harri Porten (porten@kde.org) - * Copyright (C) 2001 Peter Kelly (pmk@post.com) - * Copyright (C) 2004, 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 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 JSRGBColor_h -#define JSRGBColor_h - -#include "Color.h" -#include "JSDOMBinding.h" - -namespace WebCore { - - // FIXME: JSRGBColor should have a proper prototype and a constructor. - class JSRGBColor : public DOMObject { - public: - JSRGBColor(JSC::ExecState*, unsigned color); - - virtual bool getOwnPropertySlot(JSC::ExecState*, const JSC::Identifier&, JSC::PropertySlot&); - - virtual const JSC::ClassInfo* classInfo() const { return &s_info; } - static const JSC::ClassInfo s_info; - - unsigned impl() const { return m_color; } - - static JSC::ObjectPrototype* createPrototype(JSC::ExecState*, JSC::JSGlobalObject* globalObject) - { - return globalObject->objectPrototype(); - } - - static PassRefPtr<JSC::Structure> createStructure(JSC::JSValue prototype) - { - return JSC::Structure::create(prototype, JSC::TypeInfo(JSC::ObjectType)); - } - - private: - unsigned m_color; - }; - - JSC::JSValue getJSRGBColor(JSC::ExecState*, unsigned color); - -} // namespace WebCore - -#endif // JSRGBColor_h diff --git a/WebCore/bindings/js/JSSVGElementInstanceCustom.cpp b/WebCore/bindings/js/JSSVGElementInstanceCustom.cpp index 2922740..6e77f9b 100644 --- a/WebCore/bindings/js/JSSVGElementInstanceCustom.cpp +++ b/WebCore/bindings/js/JSSVGElementInstanceCustom.cpp @@ -1,5 +1,6 @@ /* * Copyright (C) 2008 Nikolas Zimmermann <zimmermann@kde.org> + * 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 @@ -37,14 +38,14 @@ using namespace JSC; namespace WebCore { -void JSSVGElementInstance::mark() +void JSSVGElementInstance::markChildren(MarkStack& markStack) { - DOMObject::mark(); + 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 && !correspondingWrapper->marked()) - correspondingWrapper->mark(); + if (correspondingWrapper) + markStack.append(correspondingWrapper); } JSValue JSSVGElementInstance::addEventListener(ExecState* exec, const ArgList& args) @@ -75,9 +76,9 @@ void JSSVGElementInstance::pushEventHandlerScope(ExecState*, ScopeChain&) const { } -JSC::JSValue toJS(JSC::ExecState* exec, SVGElementInstance* object) +JSC::JSValue toJS(JSC::ExecState* exec, JSDOMGlobalObject* globalObject, SVGElementInstance* object) { - JSValue result = getDOMObjectWrapper<JSSVGElementInstance>(exec, object); + JSValue result = getDOMObjectWrapper<JSSVGElementInstance>(exec, globalObject, object); // Ensure that our corresponding element has a JavaScript wrapper to keep its event handlers alive. if (object) diff --git a/WebCore/bindings/js/JSSVGMatrixCustom.cpp b/WebCore/bindings/js/JSSVGMatrixCustom.cpp index fc1e266..35390b2 100644 --- a/WebCore/bindings/js/JSSVGMatrixCustom.cpp +++ b/WebCore/bindings/js/JSSVGMatrixCustom.cpp @@ -32,7 +32,7 @@ namespace WebCore { JSValue JSSVGMatrix::inverse(ExecState* exec, const ArgList&) { TransformationMatrix imp(*impl()); - JSC::JSValue result = toJS(exec, JSSVGStaticPODTypeWrapper<TransformationMatrix>::create(imp.inverse()).get(), m_context.get()); + JSC::JSValue result = toJS(exec, deprecatedGlobalObjectForPrototype(exec), JSSVGStaticPODTypeWrapper<TransformationMatrix>::create(imp.inverse()).get(), m_context.get()); if (!imp.isInvertible()) setDOMException(exec, SVGException::SVG_MATRIX_NOT_INVERTABLE); @@ -47,7 +47,7 @@ JSValue JSSVGMatrix::rotateFromVector(ExecState* exec, const ArgList& args) float x = args.at(0).toFloat(exec); float y = args.at(1).toFloat(exec); - JSC::JSValue result = toJS(exec, JSSVGStaticPODTypeWrapper<TransformationMatrix>::create(imp.rotateFromVector(x, y)).get(), m_context.get()); + JSC::JSValue result = toJS(exec, deprecatedGlobalObjectForPrototype(exec), JSSVGStaticPODTypeWrapper<TransformationMatrix>::create(imp.rotateFromVector(x, y)).get(), m_context.get()); if (x == 0.0 || y == 0.0) setDOMException(exec, SVGException::SVG_INVALID_VALUE_ERR); diff --git a/WebCore/bindings/js/JSSVGPathSegCustom.cpp b/WebCore/bindings/js/JSSVGPathSegCustom.cpp index cb4687c..42fa878 100644 --- a/WebCore/bindings/js/JSSVGPathSegCustom.cpp +++ b/WebCore/bindings/js/JSSVGPathSegCustom.cpp @@ -59,7 +59,7 @@ using namespace JSC; namespace WebCore { -JSValue toJS(ExecState* exec, SVGPathSeg* object, SVGElement* context) +JSValue toJS(ExecState* exec, JSDOMGlobalObject* globalObject, SVGPathSeg* object, SVGElement* context) { if (!object) return jsNull(); @@ -69,46 +69,46 @@ JSValue toJS(ExecState* exec, SVGPathSeg* object, SVGElement* context) switch (object->pathSegType()) { case SVGPathSeg::PATHSEG_CLOSEPATH: - return CREATE_SVG_OBJECT_WRAPPER(exec, SVGPathSegClosePath, object, context); + return CREATE_SVG_OBJECT_WRAPPER(exec, globalObject, SVGPathSegClosePath, object, context); case SVGPathSeg::PATHSEG_MOVETO_ABS: - return CREATE_SVG_OBJECT_WRAPPER(exec, SVGPathSegMovetoAbs, object, context); + return CREATE_SVG_OBJECT_WRAPPER(exec, globalObject, SVGPathSegMovetoAbs, object, context); case SVGPathSeg::PATHSEG_MOVETO_REL: - return CREATE_SVG_OBJECT_WRAPPER(exec, SVGPathSegMovetoRel, object, context); + return CREATE_SVG_OBJECT_WRAPPER(exec, globalObject, SVGPathSegMovetoRel, object, context); case SVGPathSeg::PATHSEG_LINETO_ABS: - return CREATE_SVG_OBJECT_WRAPPER(exec, SVGPathSegLinetoAbs, object, context); + return CREATE_SVG_OBJECT_WRAPPER(exec, globalObject, SVGPathSegLinetoAbs, object, context); case SVGPathSeg::PATHSEG_LINETO_REL: - return CREATE_SVG_OBJECT_WRAPPER(exec, SVGPathSegLinetoRel, object, context); + return CREATE_SVG_OBJECT_WRAPPER(exec, globalObject, SVGPathSegLinetoRel, object, context); case SVGPathSeg::PATHSEG_CURVETO_CUBIC_ABS: - return CREATE_SVG_OBJECT_WRAPPER(exec, SVGPathSegCurvetoCubicAbs, object, context); + return CREATE_SVG_OBJECT_WRAPPER(exec, globalObject, SVGPathSegCurvetoCubicAbs, object, context); case SVGPathSeg::PATHSEG_CURVETO_CUBIC_REL: - return CREATE_SVG_OBJECT_WRAPPER(exec, SVGPathSegCurvetoCubicRel, object, context); + return CREATE_SVG_OBJECT_WRAPPER(exec, globalObject, SVGPathSegCurvetoCubicRel, object, context); case SVGPathSeg::PATHSEG_CURVETO_QUADRATIC_ABS: - return CREATE_SVG_OBJECT_WRAPPER(exec, SVGPathSegCurvetoQuadraticAbs, object, context); + return CREATE_SVG_OBJECT_WRAPPER(exec, globalObject, SVGPathSegCurvetoQuadraticAbs, object, context); case SVGPathSeg::PATHSEG_CURVETO_QUADRATIC_REL: - return CREATE_SVG_OBJECT_WRAPPER(exec, SVGPathSegCurvetoQuadraticRel, object, context); + return CREATE_SVG_OBJECT_WRAPPER(exec, globalObject, SVGPathSegCurvetoQuadraticRel, object, context); case SVGPathSeg::PATHSEG_ARC_ABS: - return CREATE_SVG_OBJECT_WRAPPER(exec, SVGPathSegArcAbs, object, context); + return CREATE_SVG_OBJECT_WRAPPER(exec, globalObject, SVGPathSegArcAbs, object, context); case SVGPathSeg::PATHSEG_ARC_REL: - return CREATE_SVG_OBJECT_WRAPPER(exec, SVGPathSegArcRel, object, context); + return CREATE_SVG_OBJECT_WRAPPER(exec, globalObject, SVGPathSegArcRel, object, context); case SVGPathSeg::PATHSEG_LINETO_HORIZONTAL_ABS: - return CREATE_SVG_OBJECT_WRAPPER(exec, SVGPathSegLinetoHorizontalAbs, object, context); + return CREATE_SVG_OBJECT_WRAPPER(exec, globalObject, SVGPathSegLinetoHorizontalAbs, object, context); case SVGPathSeg::PATHSEG_LINETO_HORIZONTAL_REL: - return CREATE_SVG_OBJECT_WRAPPER(exec, SVGPathSegLinetoHorizontalRel, object, context); + return CREATE_SVG_OBJECT_WRAPPER(exec, globalObject, SVGPathSegLinetoHorizontalRel, object, context); case SVGPathSeg::PATHSEG_LINETO_VERTICAL_ABS: - return CREATE_SVG_OBJECT_WRAPPER(exec, SVGPathSegLinetoVerticalAbs, object, context); + return CREATE_SVG_OBJECT_WRAPPER(exec, globalObject, SVGPathSegLinetoVerticalAbs, object, context); case SVGPathSeg::PATHSEG_LINETO_VERTICAL_REL: - return CREATE_SVG_OBJECT_WRAPPER(exec, SVGPathSegLinetoVerticalRel, object, context); + return CREATE_SVG_OBJECT_WRAPPER(exec, globalObject, SVGPathSegLinetoVerticalRel, object, context); case SVGPathSeg::PATHSEG_CURVETO_CUBIC_SMOOTH_ABS: - return CREATE_SVG_OBJECT_WRAPPER(exec, SVGPathSegCurvetoCubicSmoothAbs, object, context); + return CREATE_SVG_OBJECT_WRAPPER(exec, globalObject, SVGPathSegCurvetoCubicSmoothAbs, object, context); case SVGPathSeg::PATHSEG_CURVETO_CUBIC_SMOOTH_REL: - return CREATE_SVG_OBJECT_WRAPPER(exec, SVGPathSegCurvetoCubicSmoothRel, object, context); + return CREATE_SVG_OBJECT_WRAPPER(exec, globalObject, SVGPathSegCurvetoCubicSmoothRel, object, context); case SVGPathSeg::PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS: - return CREATE_SVG_OBJECT_WRAPPER(exec, SVGPathSegCurvetoQuadraticSmoothAbs, object, context); + return CREATE_SVG_OBJECT_WRAPPER(exec, globalObject, SVGPathSegCurvetoQuadraticSmoothAbs, object, context); case SVGPathSeg::PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL: - return CREATE_SVG_OBJECT_WRAPPER(exec, SVGPathSegCurvetoQuadraticSmoothRel, object, context); + return CREATE_SVG_OBJECT_WRAPPER(exec, globalObject, SVGPathSegCurvetoQuadraticSmoothRel, object, context); case SVGPathSeg::PATHSEG_UNKNOWN: default: - return CREATE_SVG_OBJECT_WRAPPER(exec, SVGPathSeg, object, context); + return CREATE_SVG_OBJECT_WRAPPER(exec, globalObject, SVGPathSeg, object, context); } } diff --git a/WebCore/bindings/js/JSSVGPathSegListCustom.cpp b/WebCore/bindings/js/JSSVGPathSegListCustom.cpp index b6fc116..b71f3a6 100644 --- a/WebCore/bindings/js/JSSVGPathSegListCustom.cpp +++ b/WebCore/bindings/js/JSSVGPathSegListCustom.cpp @@ -57,7 +57,7 @@ JSValue JSSVGPathSegList::initialize(ExecState* exec, const ArgList& args) SVGPathSeg* obj = WTF::getPtr(imp->initialize(newItem, ec)); - JSC::JSValue result = toJS(exec, obj, m_context.get()); + JSC::JSValue result = toJS(exec, deprecatedGlobalObjectForPrototype(exec), obj, m_context.get()); setDOMException(exec, ec); m_context->svgAttributeChanged(imp->associatedAttributeName()); @@ -78,7 +78,7 @@ JSValue JSSVGPathSegList::getItem(ExecState* exec, const ArgList& args) SVGPathSegList* imp = static_cast<SVGPathSegList*>(impl()); SVGPathSeg* obj = WTF::getPtr(imp->getItem(index, ec)); - JSC::JSValue result = toJS(exec, obj, m_context.get()); + JSC::JSValue result = toJS(exec, deprecatedGlobalObjectForPrototype(exec), obj, m_context.get()); setDOMException(exec, ec); return result; } @@ -97,7 +97,7 @@ JSValue JSSVGPathSegList::insertItemBefore(ExecState* exec, const ArgList& args) SVGPathSegList* imp = static_cast<SVGPathSegList*>(impl()); - JSC::JSValue result = toJS(exec, WTF::getPtr(imp->insertItemBefore(newItem, index, ec)), m_context.get()); + JSC::JSValue result = toJS(exec, deprecatedGlobalObjectForPrototype(exec), WTF::getPtr(imp->insertItemBefore(newItem, index, ec)), m_context.get()); setDOMException(exec, ec); m_context->svgAttributeChanged(imp->associatedAttributeName()); @@ -118,7 +118,7 @@ JSValue JSSVGPathSegList::replaceItem(ExecState* exec, const ArgList& args) SVGPathSegList* imp = static_cast<SVGPathSegList*>(impl()); - JSC::JSValue result = toJS(exec, WTF::getPtr(imp->replaceItem(newItem, index, ec)), m_context.get()); + JSC::JSValue result = toJS(exec, deprecatedGlobalObjectForPrototype(exec), WTF::getPtr(imp->replaceItem(newItem, index, ec)), m_context.get()); setDOMException(exec, ec); m_context->svgAttributeChanged(imp->associatedAttributeName()); @@ -140,7 +140,7 @@ JSValue JSSVGPathSegList::removeItem(ExecState* exec, const ArgList& args) RefPtr<SVGPathSeg> obj(imp->removeItem(index, ec)); - JSC::JSValue result = toJS(exec, obj.get(), m_context.get()); + JSC::JSValue result = toJS(exec, deprecatedGlobalObjectForPrototype(exec), obj.get(), m_context.get()); setDOMException(exec, ec); m_context->svgAttributeChanged(imp->associatedAttributeName()); @@ -154,7 +154,7 @@ JSValue JSSVGPathSegList::appendItem(ExecState* exec, const ArgList& args) SVGPathSegList* imp = static_cast<SVGPathSegList*>(impl()); - JSC::JSValue result = toJS(exec, WTF::getPtr(imp->appendItem(newItem, ec)), m_context.get()); + JSC::JSValue result = toJS(exec, deprecatedGlobalObjectForPrototype(exec), WTF::getPtr(imp->appendItem(newItem, ec)), m_context.get()); setDOMException(exec, ec); m_context->svgAttributeChanged(imp->associatedAttributeName()); diff --git a/WebCore/bindings/js/JSSVGPointListCustom.cpp b/WebCore/bindings/js/JSSVGPointListCustom.cpp index a18c2a2..1969fe2 100644 --- a/WebCore/bindings/js/JSSVGPointListCustom.cpp +++ b/WebCore/bindings/js/JSSVGPointListCustom.cpp @@ -39,7 +39,7 @@ static JSValue finishGetter(ExecState* exec, ExceptionCode& ec, SVGElement* cont setDOMException(exec, ec); return jsUndefined(); } - return toJS(exec, JSSVGPODTypeWrapperCreatorForList<FloatPoint>::create(item.get(), list->associatedAttributeName()).get(), context); + 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) @@ -50,7 +50,7 @@ static JSValue finishSetter(ExecState* exec, ExceptionCode& ec, SVGElement* cont } const QualifiedName& attributeName = list->associatedAttributeName(); context->svgAttributeChanged(attributeName); - return toJS(exec, JSSVGPODTypeWrapperCreatorForList<FloatPoint>::create(item.get(), attributeName).get(), context); + 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) @@ -60,7 +60,7 @@ static JSValue finishSetterReadOnlyResult(ExecState* exec, ExceptionCode& ec, SV return jsUndefined(); } context->svgAttributeChanged(list->associatedAttributeName()); - return toJS(exec, JSSVGStaticPODTypeWrapper<FloatPoint>::create(*item).get(), context); + return toJS(exec, deprecatedGlobalObjectForPrototype(exec), JSSVGStaticPODTypeWrapper<FloatPoint>::create(*item).get(), context); } JSValue JSSVGPointList::clear(ExecState* exec, const ArgList&) diff --git a/WebCore/bindings/js/JSSVGTransformListCustom.cpp b/WebCore/bindings/js/JSSVGTransformListCustom.cpp index 58b25ad..1a9110a 100644 --- a/WebCore/bindings/js/JSSVGTransformListCustom.cpp +++ b/WebCore/bindings/js/JSSVGTransformListCustom.cpp @@ -39,7 +39,7 @@ static JSValue finishGetter(ExecState* exec, ExceptionCode& ec, SVGElement* cont setDOMException(exec, ec); return jsUndefined(); } - return toJS(exec, JSSVGPODTypeWrapperCreatorForList<SVGTransform>::create(item.get(), list->associatedAttributeName()).get(), context); + 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) @@ -50,7 +50,7 @@ static JSValue finishSetter(ExecState* exec, ExceptionCode& ec, SVGElement* cont } const QualifiedName& attributeName = list->associatedAttributeName(); context->svgAttributeChanged(attributeName); - return toJS(exec, JSSVGPODTypeWrapperCreatorForList<SVGTransform>::create(item.get(), attributeName).get(), context); + 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) @@ -60,7 +60,7 @@ static JSValue finishSetterReadOnlyResult(ExecState* exec, ExceptionCode& ec, SV return jsUndefined(); } context->svgAttributeChanged(list->associatedAttributeName()); - return toJS(exec, JSSVGStaticPODTypeWrapper<SVGTransform>::create(*item).get(), context); + return toJS(exec, deprecatedGlobalObjectForPrototype(exec), JSSVGStaticPODTypeWrapper<SVGTransform>::create(*item).get(), context); } JSValue JSSVGTransformList::clear(ExecState* exec, const ArgList&) diff --git a/WebCore/bindings/js/JSSharedWorkerConstructor.cpp b/WebCore/bindings/js/JSSharedWorkerConstructor.cpp new file mode 100644 index 0000000..e2f1136 --- /dev/null +++ b/WebCore/bindings/js/JSSharedWorkerConstructor.cpp @@ -0,0 +1,85 @@ +/* + * 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" + +#if ENABLE(SHARED_WORKERS) + +#include "JSSharedWorkerConstructor.h" + +#include "JSDOMWindowCustom.h" +#include "JSSharedWorker.h" +#include "SharedWorker.h" + +using namespace JSC; + +namespace WebCore { + +const ClassInfo JSSharedWorkerConstructor::s_info = { "SharedWorkerConstructor", 0, 0, 0 }; + +JSSharedWorkerConstructor::JSSharedWorkerConstructor(ExecState* exec, JSDOMGlobalObject* globalObject) + : DOMConstructorObject(JSSharedWorkerConstructor::createStructure(globalObject->objectPrototype()), globalObject) +{ + putDirect(exec->propertyNames().prototype, JSSharedWorkerPrototype::self(exec, globalObject), None); + // Host functions have a length property describing the number of expected arguments. + putDirect(exec->propertyNames().length, jsNumber(exec, 2), ReadOnly|DontDelete|DontEnum); +} + +static JSObject* constructSharedWorker(ExecState* exec, JSObject* constructor, const ArgList& args) +{ + JSSharedWorkerConstructor* jsConstructor = static_cast<JSSharedWorkerConstructor*>(constructor); + + if (args.size() < 2) + return throwError(exec, SyntaxError, "Not enough arguments"); + + UString scriptURL = args.at(0).toString(exec); + UString name = args.at(1).toString(exec); + if (exec->hadException()) + return 0; + + // FIXME: We need to use both the dynamic scope and the lexical scope (dynamic scope for resolving the worker URL) + DOMWindow* window = asJSDOMWindow(exec->lexicalGlobalObject())->impl(); + ExceptionCode ec = 0; + RefPtr<SharedWorker> worker = SharedWorker::create(scriptURL, name, window->document(), ec); + setDOMException(exec, ec); + + return asObject(toJS(exec, jsConstructor->globalObject(), worker.release())); +} + +ConstructType JSSharedWorkerConstructor::getConstructData(ConstructData& constructData) +{ + constructData.native.function = constructSharedWorker; + return ConstructTypeHost; +} + + +} // namespace WebCore + +#endif // ENABLE(SHARED_WORKERS) diff --git a/WebCore/bindings/js/JSSharedWorkerConstructor.h b/WebCore/bindings/js/JSSharedWorkerConstructor.h new file mode 100644 index 0000000..87baa38 --- /dev/null +++ b/WebCore/bindings/js/JSSharedWorkerConstructor.h @@ -0,0 +1,56 @@ +/* + * 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 JSSharedWorkerConstructor_h +#define JSSharedWorkerConstructor_h + +#if ENABLE(SHARED_WORKERS) + +#include "JSDOMBinding.h" + +namespace WebCore { + + class JSSharedWorkerConstructor : public DOMConstructorObject { + public: + JSSharedWorkerConstructor(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; } + }; + +} // namespace WebCore + +#endif // ENABLE(SHARED_WORKERS) + +#endif // JSSharedWorkerConstructor_h diff --git a/WebCore/bindings/js/JSSharedWorkerContextCustom.cpp b/WebCore/bindings/js/JSSharedWorkerContextCustom.cpp new file mode 100644 index 0000000..dca3536 --- /dev/null +++ b/WebCore/bindings/js/JSSharedWorkerContextCustom.cpp @@ -0,0 +1,50 @@ +/* + * 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" + +#if ENABLE(SHARED_WORKERS) + +#include "JSSharedWorkerContext.h" + +using namespace JSC; + +namespace WebCore { + +void JSSharedWorkerContext::markChildren(MarkStack& markStack) +{ + Base::markChildren(markStack); + + markIfNotNull(markStack, impl()->onconnect()); +} + +} // namespace WebCore + +#endif // ENABLE(SHARED_WORKERS) diff --git a/WebCore/bindings/js/JSSharedWorkerCustom.cpp b/WebCore/bindings/js/JSSharedWorkerCustom.cpp new file mode 100644 index 0000000..f21f50c --- /dev/null +++ b/WebCore/bindings/js/JSSharedWorkerCustom.cpp @@ -0,0 +1,57 @@ +/* + * 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" + +#if ENABLE(SHARED_WORKERS) + +#include "JSSharedWorker.h" + +#include "JSDOMGlobalObject.h" +#include "SharedWorker.h" + +using namespace JSC; + +namespace WebCore { + +void JSSharedWorker::markChildren(MarkStack& markStack) +{ + Base::markChildren(markStack); + + if (MessagePort* port = impl()->port()) { + DOMObject* wrapper = getCachedDOMObjectWrapper(*Heap::heap(this)->globalData(), port); + if (wrapper) + markStack.append(wrapper); + } +} + +} // namespace WebCore + +#endif // ENABLE(SHARED_WORKERS) diff --git a/WebCore/bindings/js/JSStorageCustom.cpp b/WebCore/bindings/js/JSStorageCustom.cpp index bc43d79..07cf2f8 100644 --- a/WebCore/bindings/js/JSStorageCustom.cpp +++ b/WebCore/bindings/js/JSStorageCustom.cpp @@ -64,17 +64,16 @@ bool JSStorage::deleteProperty(ExecState* exec, const Identifier& propertyName) return true; } -bool JSStorage::customGetPropertyNames(ExecState* exec, PropertyNameArray& propertyNames) +void JSStorage::getPropertyNames(ExecState* exec, PropertyNameArray& propertyNames) { - ExceptionCode ec; unsigned length = m_impl->length(); for (unsigned i = 0; i < length; ++i) - propertyNames.add(Identifier(exec, m_impl->key(i, ec))); + propertyNames.add(Identifier(exec, m_impl->key(i))); - return false; + Base::getPropertyNames(exec, propertyNames); } -bool JSStorage::customPut(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot&) +bool JSStorage::putDelegate(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot&) { // Only perform the custom put if the object doesn't have a native property by this name. // Since hasProperty() would end up calling canGetItemsForName() and be fooled, we need to check diff --git a/WebCore/bindings/js/JSStyleSheetCustom.cpp b/WebCore/bindings/js/JSStyleSheetCustom.cpp index f8146bd..43249dc 100644 --- a/WebCore/bindings/js/JSStyleSheetCustom.cpp +++ b/WebCore/bindings/js/JSStyleSheetCustom.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2007, 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 @@ -35,7 +35,7 @@ using namespace JSC; namespace WebCore { -JSValue toJS(ExecState* exec, StyleSheet* styleSheet) +JSValue toJS(ExecState* exec, JSDOMGlobalObject* globalObject, StyleSheet* styleSheet) { if (!styleSheet) return jsNull(); @@ -45,16 +45,16 @@ JSValue toJS(ExecState* exec, StyleSheet* styleSheet) return wrapper; if (styleSheet->isCSSStyleSheet()) - wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, CSSStyleSheet, styleSheet); + wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, globalObject, CSSStyleSheet, styleSheet); else - wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, StyleSheet, styleSheet); + wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, globalObject, StyleSheet, styleSheet); return wrapper; } -void JSStyleSheet::mark() +void JSStyleSheet::markChildren(MarkStack& markStack) { - Base::mark(); + Base::markChildren(markStack); // This prevents us from having a style sheet with a dangling ownerNode pointer. // A better solution would be to handle this on the DOM side -- if the style sheet @@ -62,10 +62,8 @@ void JSStyleSheet::mark() // 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 = impl()->ownerNode()) { - if (JSNode* ownerNodeWrapper = getCachedDOMNodeWrapper(ownerNode->document(), ownerNode)) { - if (!ownerNodeWrapper->marked()) - ownerNodeWrapper->mark(); - } + if (JSNode* ownerNodeWrapper = getCachedDOMNodeWrapper(ownerNode->document(), ownerNode)) + markStack.append(ownerNodeWrapper); } } diff --git a/WebCore/bindings/js/JSTextCustom.cpp b/WebCore/bindings/js/JSTextCustom.cpp index 9e66826..2dc886d 100644 --- a/WebCore/bindings/js/JSTextCustom.cpp +++ b/WebCore/bindings/js/JSTextCustom.cpp @@ -32,12 +32,12 @@ using namespace JSC; namespace WebCore { -JSValue toJSNewlyCreated(ExecState* exec, Text* text) +JSValue toJSNewlyCreated(ExecState* exec, JSDOMGlobalObject* globalObject, Text* text) { if (!text) return jsNull(); - return CREATE_DOM_NODE_WRAPPER(exec, Text, text); + return CREATE_DOM_NODE_WRAPPER(exec, globalObject, Text, text); } } // namespace WebCore diff --git a/WebCore/bindings/js/JSTreeWalkerCustom.cpp b/WebCore/bindings/js/JSTreeWalkerCustom.cpp index 6369017..f879cf4 100644 --- a/WebCore/bindings/js/JSTreeWalkerCustom.cpp +++ b/WebCore/bindings/js/JSTreeWalkerCustom.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2006, 2008, 2009 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 @@ -29,12 +29,12 @@ using namespace JSC; namespace WebCore { -void JSTreeWalker::mark() +void JSTreeWalker::markChildren(MarkStack& markStack) { + Base::markChildren(markStack); + if (NodeFilter* filter = m_impl->filter()) - filter->mark(); - - DOMObject::mark(); + filter->markAggregate(markStack); } JSValue JSTreeWalker::parentNode(ExecState* exec, const ArgList&) diff --git a/WebCore/bindings/js/JSWebKitCSSMatrixConstructor.cpp b/WebCore/bindings/js/JSWebKitCSSMatrixConstructor.cpp index c7fe4a5..bc05250 100644 --- a/WebCore/bindings/js/JSWebKitCSSMatrixConstructor.cpp +++ b/WebCore/bindings/js/JSWebKitCSSMatrixConstructor.cpp @@ -35,15 +35,16 @@ namespace WebCore { const ClassInfo JSWebKitCSSMatrixConstructor::s_info = { "WebKitCSSMatrixConstructor", 0, 0, 0 }; -JSWebKitCSSMatrixConstructor::JSWebKitCSSMatrixConstructor(ExecState* exec) - : DOMObject(JSWebKitCSSMatrixConstructor::createStructure(exec->lexicalGlobalObject()->objectPrototype())) +JSWebKitCSSMatrixConstructor::JSWebKitCSSMatrixConstructor(ExecState* exec, JSDOMGlobalObject* globalObject) + : DOMConstructorObject(JSWebKitCSSMatrixConstructor::createStructure(globalObject->objectPrototype()), globalObject) { - putDirect(exec->propertyNames().prototype, JSWebKitCSSMatrixPrototype::self(exec, exec->lexicalGlobalObject()), None); + putDirect(exec->propertyNames().prototype, JSWebKitCSSMatrixPrototype::self(exec, globalObject), None); putDirect(exec->propertyNames().length, jsNumber(exec, 1), ReadOnly|DontDelete|DontEnum); } -static JSObject* constructWebKitCSSMatrix(ExecState* exec, JSObject*, const ArgList& args) +static JSObject* constructWebKitCSSMatrix(ExecState* exec, JSObject* constructor, const ArgList& args) { + JSWebKitCSSMatrixConstructor* jsConstructor = static_cast<JSWebKitCSSMatrixConstructor*>(constructor); String s; if (args.size() >= 1) s = args.at(0).toString(exec); @@ -51,7 +52,7 @@ static JSObject* constructWebKitCSSMatrix(ExecState* exec, JSObject*, const ArgL ExceptionCode ec = 0; RefPtr<WebKitCSSMatrix> matrix = WebKitCSSMatrix::create(s, ec); setDOMException(exec, ec); - return CREATE_DOM_OBJECT_WRAPPER(exec, WebKitCSSMatrix, matrix.get()); + return CREATE_DOM_OBJECT_WRAPPER(exec, jsConstructor->globalObject(), WebKitCSSMatrix, matrix.get()); } ConstructType JSWebKitCSSMatrixConstructor::getConstructData(ConstructData& constructData) diff --git a/WebCore/bindings/js/JSWebKitCSSMatrixConstructor.h b/WebCore/bindings/js/JSWebKitCSSMatrixConstructor.h index d0e0bd1..65b9050 100644 --- a/WebCore/bindings/js/JSWebKitCSSMatrixConstructor.h +++ b/WebCore/bindings/js/JSWebKitCSSMatrixConstructor.h @@ -31,9 +31,9 @@ namespace WebCore { -class JSWebKitCSSMatrixConstructor : public DOMObject { +class JSWebKitCSSMatrixConstructor : public DOMConstructorObject { public: - JSWebKitCSSMatrixConstructor(JSC::ExecState*); + JSWebKitCSSMatrixConstructor(JSC::ExecState*, JSDOMGlobalObject*); static const JSC::ClassInfo s_info; private: diff --git a/WebCore/bindings/js/JSWebKitPointConstructor.cpp b/WebCore/bindings/js/JSWebKitPointConstructor.cpp index c7d4e36..27cc1db 100644 --- a/WebCore/bindings/js/JSWebKitPointConstructor.cpp +++ b/WebCore/bindings/js/JSWebKitPointConstructor.cpp @@ -36,15 +36,17 @@ using namespace JSC; const ClassInfo JSWebKitPointConstructor::s_info = { "WebKitPointConstructor", 0, 0, 0 }; -JSWebKitPointConstructor::JSWebKitPointConstructor(ExecState* exec) - : DOMObject(JSWebKitPointConstructor::createStructure(exec->lexicalGlobalObject()->objectPrototype())) +JSWebKitPointConstructor::JSWebKitPointConstructor(ExecState* exec, JSDOMGlobalObject* globalObject) + : DOMConstructorObject(JSWebKitPointConstructor::createStructure(globalObject->objectPrototype()), globalObject) { - putDirect(exec->propertyNames().prototype, JSWebKitPointPrototype::self(exec, exec->lexicalGlobalObject()), None); + putDirect(exec->propertyNames().prototype, JSWebKitPointPrototype::self(exec, globalObject), None); putDirect(exec->propertyNames().length, jsNumber(exec, 2), ReadOnly|DontDelete|DontEnum); } -static JSObject* constructWebKitPoint(ExecState* exec, JSObject*, const ArgList& args) +static JSObject* constructWebKitPoint(ExecState* exec, JSObject* constructor, const ArgList& args) { + JSWebKitPointConstructor* jsConstructor = static_cast<JSWebKitPointConstructor*>(constructor); + float x = 0; float y = 0; if (args.size() >= 2) { @@ -55,7 +57,7 @@ static JSObject* constructWebKitPoint(ExecState* exec, JSObject*, const ArgList& if (isnan(y)) y = 0; } - return asObject(toJS(exec, WebKitPoint::create(x, y))); + return asObject(toJS(exec, jsConstructor->globalObject(), WebKitPoint::create(x, y))); } JSC::ConstructType JSWebKitPointConstructor::getConstructData(JSC::ConstructData& constructData) diff --git a/WebCore/bindings/js/JSWebKitPointConstructor.h b/WebCore/bindings/js/JSWebKitPointConstructor.h index a5bb5c1..44c253d 100644 --- a/WebCore/bindings/js/JSWebKitPointConstructor.h +++ b/WebCore/bindings/js/JSWebKitPointConstructor.h @@ -31,9 +31,9 @@ namespace WebCore { -class JSWebKitPointConstructor : public DOMObject { +class JSWebKitPointConstructor : public DOMConstructorObject { public: - JSWebKitPointConstructor(JSC::ExecState*); + JSWebKitPointConstructor(JSC::ExecState*, JSDOMGlobalObject*); static const JSC::ClassInfo s_info; private: diff --git a/WebCore/bindings/js/JSWebSocketConstructor.cpp b/WebCore/bindings/js/JSWebSocketConstructor.cpp new file mode 100644 index 0000000..ca2e104 --- /dev/null +++ b/WebCore/bindings/js/JSWebSocketConstructor.cpp @@ -0,0 +1,92 @@ +/* + * 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" + +#if ENABLE(WEB_SOCKETS) + +#include "JSWebSocketConstructor.h" + +#include "JSWebSocket.h" +#include "ScriptExecutionContext.h" +#include "WebSocket.h" + +using namespace JSC; + +namespace WebCore { + +ASSERT_CLASS_FITS_IN_CELL(JSWebSocketConstructor); + +const ClassInfo JSWebSocketConstructor::s_info = { "WebSocketConstructor", 0, 0, 0 }; + +JSWebSocketConstructor::JSWebSocketConstructor(ExecState* exec, JSDOMGlobalObject* globalObject) + : DOMConstructorObject(JSWebSocketConstructor::createStructure(globalObject->objectPrototype()), globalObject) +{ + putDirect(exec->propertyNames().prototype, JSWebSocketPrototype::self(exec, globalObject), None); + putDirect(exec->propertyNames().length, jsNumber(exec, 1), ReadOnly | DontDelete | DontEnum); +} + +static JSObject* constructWebSocket(ExecState* exec, JSObject* constructor, const ArgList& args) +{ + JSWebSocketConstructor* jsConstructor = static_cast<JSWebSocketConstructor*>(constructor); + ScriptExecutionContext* context = jsConstructor->scriptExecutionContext(); + if (!context) + return throwError(exec, ReferenceError, "WebSocket constructor associated document is unavailable"); + + if (args.size() == 0) + return throwError(exec, SyntaxError, "Not enough arguments"); + + const String& urlString = args.at(0).toString(exec); + if (exec->hadException()) + return throwError(exec, SyntaxError, "wrong URL"); + const KURL& url = context->completeURL(urlString); + RefPtr<WebSocket> webSocket = WebSocket::create(context); + ExceptionCode ec = 0; + if (args.size() < 2) + webSocket->connect(url, ec); + else { + const String& protocol = args.at(1).toString(exec); + if (exec->hadException()) + return 0; + webSocket->connect(url, protocol, ec); + } + setDOMException(exec, ec); + return CREATE_DOM_OBJECT_WRAPPER(exec, jsConstructor->globalObject(), WebSocket, webSocket.get()); +} + +ConstructType JSWebSocketConstructor::getConstructData(ConstructData& constructData) +{ + constructData.native.function = constructWebSocket; + return ConstructTypeHost; +} + +} // namespace WebCore + +#endif diff --git a/WebCore/bindings/js/JSWebSocketConstructor.h b/WebCore/bindings/js/JSWebSocketConstructor.h new file mode 100644 index 0000000..069647a --- /dev/null +++ b/WebCore/bindings/js/JSWebSocketConstructor.h @@ -0,0 +1,50 @@ +/* + * 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 JSWebSocketConstructor_h +#define JSWebSocketConstructor_h + +#include "JSDOMBinding.h" + +namespace WebCore { + +class JSWebSocketConstructor : public DOMConstructorObject { + public: + JSWebSocketConstructor(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; } +}; + +} // namespace WebCore + +#endif // JSWebSocketConstructor_h diff --git a/WebCore/bindings/js/JSWebSocketCustom.cpp b/WebCore/bindings/js/JSWebSocketCustom.cpp new file mode 100644 index 0000000..3aa4b8b --- /dev/null +++ b/WebCore/bindings/js/JSWebSocketCustom.cpp @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2009 Google Inc. All rights reserved. + * 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: + * + * * 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" + +#if ENABLE(WEB_SOCKETS) + +#include "JSWebSocket.h" + +#include "KURL.h" +#include "WebSocket.h" +#include "NotImplemented.h" + +using namespace JSC; + +namespace WebCore { + +void JSWebSocket::markChildren(MarkStack& markStack) +{ + Base::markChildren(markStack); + if (m_impl->readyState() != WebSocket::CLOSED) + markIfNotNull(markStack, m_impl->onmessage()); + // FIXME: mark if EventListeners is registered. +} + +// Custom functions +JSValue JSWebSocket::send(ExecState* exec, const ArgList& args) +{ + if (args.size() < 1) + return throwError(exec, SyntaxError, "Not enough arguments"); + + const String& msg = args.at(0).toString(exec); + if (exec->hadException()) + return throwError(exec, SyntaxError, "bad message data."); + ExceptionCode ec = 0; + JSValue ret = jsBoolean(impl()->send(msg, ec)); + setDOMException(exec, ec); + return ret; +} + +// FIXME: implement addEventListener/removeEventListener. + +} // namespace WebCore + +#endif diff --git a/WebCore/bindings/js/JSWorkerConstructor.cpp b/WebCore/bindings/js/JSWorkerConstructor.cpp index 8ea6718..9943cfb 100644 --- a/WebCore/bindings/js/JSWorkerConstructor.cpp +++ b/WebCore/bindings/js/JSWorkerConstructor.cpp @@ -41,15 +41,17 @@ namespace WebCore { const ClassInfo JSWorkerConstructor::s_info = { "WorkerConstructor", 0, 0, 0 }; -JSWorkerConstructor::JSWorkerConstructor(ExecState* exec) - : DOMObject(JSWorkerConstructor::createStructure(exec->lexicalGlobalObject()->objectPrototype())) +JSWorkerConstructor::JSWorkerConstructor(ExecState* exec, JSDOMGlobalObject* globalObject) + : DOMConstructorObject(JSWorkerConstructor::createStructure(globalObject->objectPrototype()), globalObject) { - putDirect(exec->propertyNames().prototype, JSWorkerPrototype::self(exec, exec->lexicalGlobalObject()), None); + putDirect(exec->propertyNames().prototype, JSWorkerPrototype::self(exec, globalObject), None); putDirect(exec->propertyNames().length, jsNumber(exec, 1), ReadOnly|DontDelete|DontEnum); } -static JSObject* constructWorker(ExecState* exec, JSObject*, const ArgList& args) +static JSObject* constructWorker(ExecState* exec, JSObject* constructor, const ArgList& args) { + JSWorkerConstructor* jsConstructor = static_cast<JSWorkerConstructor*>(constructor); + if (args.size() == 0) return throwError(exec, SyntaxError, "Not enough arguments"); @@ -57,13 +59,17 @@ static JSObject* constructWorker(ExecState* exec, JSObject*, const ArgList& args if (exec->hadException()) return 0; + // See section 4.8.2 step 14 of WebWorkers for why this is the lexicalGlobalObject. DOMWindow* window = asJSDOMWindow(exec->lexicalGlobalObject())->impl(); - + ExceptionCode ec = 0; RefPtr<Worker> worker = Worker::create(scriptURL, window->document(), ec); - setDOMException(exec, ec); + if (ec) { + setDOMException(exec, ec); + return 0; + } - return asObject(toJS(exec, worker.release())); + return asObject(toJS(exec, jsConstructor->globalObject(), worker.release())); } ConstructType JSWorkerConstructor::getConstructData(ConstructData& constructData) diff --git a/WebCore/bindings/js/JSWorkerConstructor.h b/WebCore/bindings/js/JSWorkerConstructor.h index d1df7eb..c845fa6 100644 --- a/WebCore/bindings/js/JSWorkerConstructor.h +++ b/WebCore/bindings/js/JSWorkerConstructor.h @@ -32,9 +32,9 @@ namespace WebCore { - class JSWorkerConstructor : public DOMObject { + class JSWorkerConstructor : public DOMConstructorObject { public: - JSWorkerConstructor(JSC::ExecState*); + JSWorkerConstructor(JSC::ExecState*, JSDOMGlobalObject*); static const JSC::ClassInfo s_info; diff --git a/WebCore/bindings/js/JSWorkerContextBase.cpp b/WebCore/bindings/js/JSWorkerContextBase.cpp index c71f45b..1e4df42 100644 --- a/WebCore/bindings/js/JSWorkerContextBase.cpp +++ b/WebCore/bindings/js/JSWorkerContextBase.cpp @@ -31,6 +31,8 @@ #include "JSWorkerContextBase.h" +#include "JSDedicatedWorkerContext.h" +#include "JSSharedWorkerContext.h" #include "JSWorkerContext.h" #include "WorkerContext.h" @@ -57,6 +59,11 @@ ScriptExecutionContext* JSWorkerContextBase::scriptExecutionContext() const return m_impl.get(); } +JSValue toJS(ExecState* exec, JSDOMGlobalObject*, WorkerContext* workerContext) +{ + return toJS(exec, workerContext); +} + JSValue toJS(ExecState*, WorkerContext* workerContext) { if (!workerContext) @@ -67,6 +74,38 @@ JSValue toJS(ExecState*, WorkerContext* workerContext) return script->workerContextWrapper(); } +JSDedicatedWorkerContext* toJSDedicatedWorkerContext(JSValue value) +{ + if (!value.isObject()) + return 0; + const ClassInfo* classInfo = asObject(value)->classInfo(); + if (classInfo == &JSDedicatedWorkerContext::s_info) + return static_cast<JSDedicatedWorkerContext*>(asObject(value)); + return 0; +} + +#if ENABLE(SHARED_WORKERS) +JSSharedWorkerContext* toJSSharedWorkerContext(JSValue value) +{ + if (!value.isObject()) + return 0; + const ClassInfo* classInfo = asObject(value)->classInfo(); + if (classInfo == &JSSharedWorkerContext::s_info) + return static_cast<JSSharedWorkerContext*>(asObject(value)); + return 0; +} +#endif + +JSWorkerContext* toJSWorkerContext(JSValue value) +{ + JSWorkerContext* context = toJSDedicatedWorkerContext(value); +#if ENABLE(SHARED_WORKERS) + if (!context) + context = toJSSharedWorkerContext(value); +#endif + return context; +} + } // namespace WebCore #endif // ENABLE(WORKERS) diff --git a/WebCore/bindings/js/JSWorkerContextBase.h b/WebCore/bindings/js/JSWorkerContextBase.h index dcbc5c3..a9a6e63 100644 --- a/WebCore/bindings/js/JSWorkerContextBase.h +++ b/WebCore/bindings/js/JSWorkerContextBase.h @@ -33,6 +33,9 @@ namespace WebCore { + class JSDedicatedWorkerContext; + class JSSharedWorkerContext; + class JSWorkerContext; class WorkerContext; class JSWorkerContextBase : public JSDOMGlobalObject { @@ -52,8 +55,17 @@ namespace WebCore { }; // Returns a JSWorkerContext or jsNull() + // Always ignores the execState and passed globalObject, WorkerContext is itself a globalObject and will always use its own prototype chain. + JSC::JSValue toJS(JSC::ExecState*, JSDOMGlobalObject*, WorkerContext*); JSC::JSValue toJS(JSC::ExecState*, WorkerContext*); + JSDedicatedWorkerContext* toJSDedicatedWorkerContext(JSC::JSValue); + JSWorkerContext* toJSWorkerContext(JSC::JSValue); + +#if ENABLE(SHARED_WORKERS) + JSSharedWorkerContext* toJSSharedWorkerContext(JSC::JSValue); +#endif + } // namespace WebCore #endif // ENABLE(WORKERS) diff --git a/WebCore/bindings/js/JSWorkerContextCustom.cpp b/WebCore/bindings/js/JSWorkerContextCustom.cpp index 6824914..919c81f 100644 --- a/WebCore/bindings/js/JSWorkerContextCustom.cpp +++ b/WebCore/bindings/js/JSWorkerContextCustom.cpp @@ -30,7 +30,10 @@ #include "JSWorkerContext.h" #include "JSDOMBinding.h" +#include "JSDOMGlobalObject.h" #include "JSEventListener.h" +#include "JSMessageChannelConstructor.h" +#include "JSMessagePort.h" #include "JSWorkerLocation.h" #include "JSWorkerNavigator.h" #include "JSXMLHttpRequestConstructor.h" @@ -44,29 +47,29 @@ using namespace JSC; namespace WebCore { -void JSWorkerContext::mark() +void JSWorkerContext::markChildren(MarkStack& markStack) { - Base::mark(); + Base::markChildren(markStack); JSGlobalData& globalData = *this->globalData(); - markActiveObjectsForContext(globalData, scriptExecutionContext()); + markActiveObjectsForContext(markStack, globalData, scriptExecutionContext()); - markDOMObjectWrapper(globalData, impl()->optionalLocation()); - markDOMObjectWrapper(globalData, impl()->optionalNavigator()); + markDOMObjectWrapper(markStack, globalData, impl()->optionalLocation()); + markDOMObjectWrapper(markStack, globalData, impl()->optionalNavigator()); - markIfNotNull(impl()->onmessage()); + markIfNotNull(markStack, impl()->onerror()); typedef WorkerContext::EventListenersMap EventListenersMap; typedef WorkerContext::ListenerVector ListenerVector; EventListenersMap& eventListeners = impl()->eventListeners(); for (EventListenersMap::iterator mapIter = eventListeners.begin(); mapIter != eventListeners.end(); ++mapIter) { for (ListenerVector::iterator vecIter = mapIter->second.begin(); vecIter != mapIter->second.end(); ++vecIter) - (*vecIter)->markJSFunction(); + (*vecIter)->markJSFunction(markStack); } } -bool JSWorkerContext::customGetOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot) +bool JSWorkerContext::getOwnPropertySlotDelegate(ExecState* exec, const Identifier& propertyName, PropertySlot& slot) { // Look for overrides before looking at any of our own properties. if (JSGlobalObject::getOwnPropertySlot(exec, propertyName, slot)) @@ -138,6 +141,14 @@ JSValue JSWorkerContext::setInterval(ExecState* exec, const ArgList& args) return jsNumber(exec, impl()->setInterval(action, delay)); } + +#if ENABLE(CHANNEL_MESSAGING) +JSValue JSWorkerContext::messageChannel(ExecState* exec) const +{ + return getDOMConstructor<JSMessageChannelConstructor>(exec, this); +} +#endif + } // namespace WebCore #endif // ENABLE(WORKERS) diff --git a/WebCore/bindings/js/JSWorkerCustom.cpp b/WebCore/bindings/js/JSWorkerCustom.cpp index f4d3033..f5c394b 100644 --- a/WebCore/bindings/js/JSWorkerCustom.cpp +++ b/WebCore/bindings/js/JSWorkerCustom.cpp @@ -30,51 +30,17 @@ #include "JSWorker.h" #include "JSDOMGlobalObject.h" -#include "JSEventListener.h" #include "Worker.h" using namespace JSC; namespace WebCore { -void JSWorker::mark() +void JSWorker::markChildren(MarkStack& markStack) { - DOMObject::mark(); + Base::markChildren(markStack); - markIfNotNull(m_impl->onmessage()); - markIfNotNull(m_impl->onerror()); - - typedef Worker::EventListenersMap EventListenersMap; - typedef Worker::ListenerVector ListenerVector; - EventListenersMap& eventListeners = m_impl->eventListeners(); - for (EventListenersMap::iterator mapIter = eventListeners.begin(); mapIter != eventListeners.end(); ++mapIter) { - for (ListenerVector::iterator vecIter = mapIter->second.begin(); vecIter != mapIter->second.end(); ++vecIter) - (*vecIter)->markJSFunction(); - } -} - -JSValue JSWorker::addEventListener(ExecState* exec, const ArgList& args) -{ - JSDOMGlobalObject* globalObject = toJSDOMGlobalObject(impl()->scriptExecutionContext()); - if (!globalObject) - return jsUndefined(); - RefPtr<JSEventListener> listener = globalObject->findOrCreateJSEventListener(args.at(1)); - if (!listener) - return jsUndefined(); - impl()->addEventListener(args.at(0).toString(exec), listener.release(), args.at(2).toBoolean(exec)); - return jsUndefined(); -} - -JSValue JSWorker::removeEventListener(ExecState* exec, const ArgList& args) -{ - JSDOMGlobalObject* globalObject = toJSDOMGlobalObject(impl()->scriptExecutionContext()); - if (!globalObject) - return jsUndefined(); - JSEventListener* listener = globalObject->findJSEventListener(args.at(1)); - if (!listener) - return jsUndefined(); - impl()->removeEventListener(args.at(0).toString(exec), listener, args.at(2).toBoolean(exec)); - return jsUndefined(); + markIfNotNull(markStack, static_cast<Worker*>(impl())->onmessage()); } } // namespace WebCore diff --git a/WebCore/bindings/js/JSXMLHttpRequestConstructor.cpp b/WebCore/bindings/js/JSXMLHttpRequestConstructor.cpp index 65cdfc2..a644c9e 100644 --- a/WebCore/bindings/js/JSXMLHttpRequestConstructor.cpp +++ b/WebCore/bindings/js/JSXMLHttpRequestConstructor.cpp @@ -33,25 +33,20 @@ ASSERT_CLASS_FITS_IN_CELL(JSXMLHttpRequestConstructor); const ClassInfo JSXMLHttpRequestConstructor::s_info = { "XMLHttpRequestConstructor", 0, 0, 0 }; JSXMLHttpRequestConstructor::JSXMLHttpRequestConstructor(ExecState* exec, JSDOMGlobalObject* globalObject) - : DOMObject(JSXMLHttpRequestConstructor::createStructure(exec->lexicalGlobalObject()->objectPrototype())) - , m_globalObject(globalObject) + : DOMConstructorObject(JSXMLHttpRequestConstructor::createStructure(globalObject->objectPrototype()), globalObject) { - putDirect(exec->propertyNames().prototype, JSXMLHttpRequestPrototype::self(exec, exec->lexicalGlobalObject()), None); -} - -ScriptExecutionContext* JSXMLHttpRequestConstructor::scriptExecutionContext() const -{ - return m_globalObject->scriptExecutionContext(); + putDirect(exec->propertyNames().prototype, JSXMLHttpRequestPrototype::self(exec, globalObject), None); } static JSObject* constructXMLHttpRequest(ExecState* exec, JSObject* constructor, const ArgList&) { - ScriptExecutionContext* context = static_cast<JSXMLHttpRequestConstructor*>(constructor)->scriptExecutionContext(); + JSXMLHttpRequestConstructor* jsConstructor = static_cast<JSXMLHttpRequestConstructor*>(constructor); + ScriptExecutionContext* context = jsConstructor->scriptExecutionContext(); if (!context) return throwError(exec, ReferenceError, "XMLHttpRequest constructor associated document is unavailable"); RefPtr<XMLHttpRequest> xmlHttpRequest = XMLHttpRequest::create(context); - return CREATE_DOM_OBJECT_WRAPPER(exec, XMLHttpRequest, xmlHttpRequest.get()); + return CREATE_DOM_OBJECT_WRAPPER(exec, jsConstructor->globalObject(), XMLHttpRequest, xmlHttpRequest.get()); } ConstructType JSXMLHttpRequestConstructor::getConstructData(ConstructData& constructData) @@ -60,11 +55,4 @@ ConstructType JSXMLHttpRequestConstructor::getConstructData(ConstructData& const return ConstructTypeHost; } -void JSXMLHttpRequestConstructor::mark() -{ - DOMObject::mark(); - if (!m_globalObject->marked()) - m_globalObject->mark(); -} - } // namespace WebCore diff --git a/WebCore/bindings/js/JSXMLHttpRequestConstructor.h b/WebCore/bindings/js/JSXMLHttpRequestConstructor.h index 978a9f0..2cc4fcf 100644 --- a/WebCore/bindings/js/JSXMLHttpRequestConstructor.h +++ b/WebCore/bindings/js/JSXMLHttpRequestConstructor.h @@ -24,18 +24,13 @@ namespace WebCore { -class JSXMLHttpRequestConstructor : public DOMObject { +class JSXMLHttpRequestConstructor : public DOMConstructorObject { public: JSXMLHttpRequestConstructor(JSC::ExecState*, JSDOMGlobalObject*); - ScriptExecutionContext* scriptExecutionContext() const; static const JSC::ClassInfo s_info; - - virtual void mark(); private: virtual JSC::ConstructType getConstructData(JSC::ConstructData&); virtual const JSC::ClassInfo* classInfo() const { return &s_info; } - - JSDOMGlobalObject* m_globalObject; }; } // namespace WebCore diff --git a/WebCore/bindings/js/JSXMLHttpRequestCustom.cpp b/WebCore/bindings/js/JSXMLHttpRequestCustom.cpp index 06a5817..a591fae 100644 --- a/WebCore/bindings/js/JSXMLHttpRequestCustom.cpp +++ b/WebCore/bindings/js/JSXMLHttpRequestCustom.cpp @@ -49,29 +49,29 @@ using namespace JSC; namespace WebCore { -void JSXMLHttpRequest::mark() +void JSXMLHttpRequest::markChildren(MarkStack& markStack) { - Base::mark(); + Base::markChildren(markStack); if (XMLHttpRequestUpload* upload = m_impl->optionalUpload()) { DOMObject* wrapper = getCachedDOMObjectWrapper(*Heap::heap(this)->globalData(), upload); - if (wrapper && !wrapper->marked()) - wrapper->mark(); + if (wrapper) + markStack.append(wrapper); } - markIfNotNull(m_impl->onreadystatechange()); - markIfNotNull(m_impl->onabort()); - markIfNotNull(m_impl->onerror()); - markIfNotNull(m_impl->onload()); - markIfNotNull(m_impl->onloadstart()); - markIfNotNull(m_impl->onprogress()); + markIfNotNull(markStack, m_impl->onreadystatechange()); + markIfNotNull(markStack, m_impl->onabort()); + markIfNotNull(markStack, m_impl->onerror()); + markIfNotNull(markStack, m_impl->onload()); + markIfNotNull(markStack, m_impl->onloadstart()); + markIfNotNull(markStack, m_impl->onprogress()); typedef XMLHttpRequest::EventListenersMap EventListenersMap; typedef XMLHttpRequest::ListenerVector ListenerVector; EventListenersMap& eventListeners = m_impl->eventListeners(); for (EventListenersMap::iterator mapIter = eventListeners.begin(); mapIter != eventListeners.end(); ++mapIter) { for (ListenerVector::iterator vecIter = mapIter->second.begin(); vecIter != mapIter->second.end(); ++vecIter) - (*vecIter)->markJSFunction(); + (*vecIter)->markJSFunction(markStack); } } diff --git a/WebCore/bindings/js/JSXMLHttpRequestUploadCustom.cpp b/WebCore/bindings/js/JSXMLHttpRequestUploadCustom.cpp index 597010c..cb6d5f2 100644 --- a/WebCore/bindings/js/JSXMLHttpRequestUploadCustom.cpp +++ b/WebCore/bindings/js/JSXMLHttpRequestUploadCustom.cpp @@ -41,28 +41,28 @@ using namespace JSC; namespace WebCore { -void JSXMLHttpRequestUpload::mark() +void JSXMLHttpRequestUpload::markChildren(MarkStack& markStack) { - Base::mark(); + Base::markChildren(markStack); if (XMLHttpRequest* xmlHttpRequest = m_impl->associatedXMLHttpRequest()) { DOMObject* wrapper = getCachedDOMObjectWrapper(*Heap::heap(this)->globalData(), xmlHttpRequest); - if (wrapper && !wrapper->marked()) - wrapper->mark(); + if (wrapper) + markStack.append(wrapper); } - markIfNotNull(m_impl->onabort()); - markIfNotNull(m_impl->onerror()); - markIfNotNull(m_impl->onload()); - markIfNotNull(m_impl->onloadstart()); - markIfNotNull(m_impl->onprogress()); + markIfNotNull(markStack, m_impl->onabort()); + markIfNotNull(markStack, m_impl->onerror()); + markIfNotNull(markStack, m_impl->onload()); + markIfNotNull(markStack, m_impl->onloadstart()); + markIfNotNull(markStack, m_impl->onprogress()); typedef XMLHttpRequestUpload::EventListenersMap EventListenersMap; typedef XMLHttpRequestUpload::ListenerVector ListenerVector; EventListenersMap& eventListeners = m_impl->eventListeners(); for (EventListenersMap::iterator mapIter = eventListeners.begin(); mapIter != eventListeners.end(); ++mapIter) { for (ListenerVector::iterator vecIter = mapIter->second.begin(); vecIter != mapIter->second.end(); ++vecIter) - (*vecIter)->markJSFunction(); + (*vecIter)->markJSFunction(markStack); } } diff --git a/WebCore/bindings/js/JSXSLTProcessorConstructor.cpp b/WebCore/bindings/js/JSXSLTProcessorConstructor.cpp index 807b017..07fec72 100644 --- a/WebCore/bindings/js/JSXSLTProcessorConstructor.cpp +++ b/WebCore/bindings/js/JSXSLTProcessorConstructor.cpp @@ -41,15 +41,16 @@ ASSERT_CLASS_FITS_IN_CELL(JSXSLTProcessorConstructor); const ClassInfo JSXSLTProcessorConstructor::s_info = { "XSLTProcessorConsructor", 0, 0, 0 }; -JSXSLTProcessorConstructor::JSXSLTProcessorConstructor(ExecState* exec) - : DOMObject(JSXSLTProcessorConstructor::createStructure(exec->lexicalGlobalObject()->objectPrototype())) +JSXSLTProcessorConstructor::JSXSLTProcessorConstructor(ExecState* exec, JSDOMGlobalObject* globalObject) + : DOMConstructorObject(JSXSLTProcessorConstructor::createStructure(globalObject->objectPrototype()), globalObject) { - putDirect(exec->propertyNames().prototype, JSXSLTProcessorPrototype::self(exec, exec->lexicalGlobalObject()), None); + putDirect(exec->propertyNames().prototype, JSXSLTProcessorPrototype::self(exec, globalObject), None); } -static JSObject* constructXSLTProcessor(ExecState* exec, JSObject*, const ArgList&) +static JSObject* constructXSLTProcessor(ExecState* exec, JSObject* constructor, const ArgList&) { - return CREATE_DOM_OBJECT_WRAPPER(exec, XSLTProcessor, XSLTProcessor::create().get()); + JSXSLTProcessorConstructor* jsConstructor = static_cast<JSXSLTProcessorConstructor*>(constructor); + return CREATE_DOM_OBJECT_WRAPPER(exec, jsConstructor->globalObject(), XSLTProcessor, XSLTProcessor::create().get()); } ConstructType JSXSLTProcessorConstructor::getConstructData(ConstructData& constructData) diff --git a/WebCore/bindings/js/JSXSLTProcessorConstructor.h b/WebCore/bindings/js/JSXSLTProcessorConstructor.h index 64ef944..96fa607 100644 --- a/WebCore/bindings/js/JSXSLTProcessorConstructor.h +++ b/WebCore/bindings/js/JSXSLTProcessorConstructor.h @@ -32,9 +32,9 @@ namespace WebCore { - class JSXSLTProcessorConstructor : public DOMObject { + class JSXSLTProcessorConstructor : public DOMConstructorObject { public: - JSXSLTProcessorConstructor(JSC::ExecState*); + JSXSLTProcessorConstructor(JSC::ExecState*, JSDOMGlobalObject*); static const JSC::ClassInfo s_info; private: diff --git a/WebCore/bindings/js/ScheduledAction.cpp b/WebCore/bindings/js/ScheduledAction.cpp index 91bece7..9e64bce 100644 --- a/WebCore/bindings/js/ScheduledAction.cpp +++ b/WebCore/bindings/js/ScheduledAction.cpp @@ -87,7 +87,7 @@ void ScheduledAction::execute(ScriptExecutionContext* context) void ScheduledAction::executeFunctionInContext(JSGlobalObject* globalObject, JSValue thisValue) { ASSERT(m_function); - JSLock lock(false); + JSLock lock(SilenceAssertionsOnly); CallData callData; CallType callType = m_function.get().getCallData(callData); diff --git a/WebCore/bindings/js/ScriptArray.cpp b/WebCore/bindings/js/ScriptArray.cpp new file mode 100644 index 0000000..2c4075a --- /dev/null +++ b/WebCore/bindings/js/ScriptArray.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 "ScriptArray.h" + +#include <runtime/JSLock.h> + +using namespace JSC; + +namespace WebCore { + +ScriptArray::ScriptArray(ScriptState* scriptState, JSArray* object) + : ScriptObject(scriptState, object) +{ +} + +static bool handleException(ScriptState* scriptState) +{ + if (!scriptState->hadException()) + return true; + + reportException(scriptState, scriptState->exception()); + return false; +} + +bool ScriptArray::set(unsigned index, const ScriptObject& value) +{ + JSLock lock(SilenceAssertionsOnly); + jsArray()->put(m_scriptState, index, value.jsObject()); + return handleException(m_scriptState); +} + +bool ScriptArray::set(unsigned index, const String& value) +{ + JSLock lock(SilenceAssertionsOnly); + jsArray()->put(m_scriptState, index, jsString(m_scriptState, value)); + return handleException(m_scriptState); +} + +bool ScriptArray::set(unsigned index, double value) +{ + JSLock lock(SilenceAssertionsOnly); + jsArray()->put(m_scriptState, index, jsNumber(m_scriptState, value)); + return handleException(m_scriptState); +} + +bool ScriptArray::set(unsigned index, long long value) +{ + JSLock lock(SilenceAssertionsOnly); + jsArray()->put(m_scriptState, index, jsNumber(m_scriptState, value)); + return handleException(m_scriptState); +} + +bool ScriptArray::set(unsigned index, int value) +{ + JSLock lock(SilenceAssertionsOnly); + jsArray()->put(m_scriptState, index, jsNumber(m_scriptState, value)); + return handleException(m_scriptState); +} + +bool ScriptArray::set(unsigned index, bool value) +{ + JSLock lock(SilenceAssertionsOnly); + jsArray()->put(m_scriptState, index, jsBoolean(value)); + return handleException(m_scriptState); +} + +unsigned ScriptArray::length() +{ + JSLock lock(SilenceAssertionsOnly); + return jsArray()->length(); +} + +ScriptArray ScriptArray::createNew(ScriptState* scriptState) +{ + JSLock lock(SilenceAssertionsOnly); + return ScriptArray(scriptState, constructEmptyArray(scriptState)); +} + +} // namespace WebCore diff --git a/WebCore/bindings/js/ScriptArray.h b/WebCore/bindings/js/ScriptArray.h new file mode 100644 index 0000000..9240368 --- /dev/null +++ b/WebCore/bindings/js/ScriptArray.h @@ -0,0 +1,59 @@ +/* + * 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 ScriptArray_h +#define ScriptArray_h + +#include "ScriptObject.h" +#include "ScriptState.h" + +#include <runtime/JSArray.h> + +namespace WebCore { + + class ScriptArray : public ScriptObject { + public: + ScriptArray(ScriptState*, JSC::JSArray*); + ScriptArray() {} + JSC::JSArray* jsArray() const { return asArray(jsValue()); } + + bool set(unsigned index, const ScriptObject&); + bool set(unsigned index, const String&); + bool set(unsigned index, double); + bool set(unsigned index, long long); + bool set(unsigned index, int); + bool set(unsigned index, bool); + unsigned length(); + + static ScriptArray createNew(ScriptState*); + }; +} + +#endif // ScriptArray_h diff --git a/WebCore/bindings/js/ScriptCachedFrameData.cpp b/WebCore/bindings/js/ScriptCachedFrameData.cpp index 213c708..8852611 100644 --- a/WebCore/bindings/js/ScriptCachedFrameData.cpp +++ b/WebCore/bindings/js/ScriptCachedFrameData.cpp @@ -45,7 +45,7 @@ namespace WebCore { ScriptCachedFrameData::ScriptCachedFrameData(Frame* frame) { - JSLock lock(false); + JSLock lock(SilenceAssertionsOnly); ScriptController* scriptController = frame->script(); if (scriptController->haveWindowShell()) { @@ -67,7 +67,7 @@ void ScriptCachedFrameData::restore(Frame* frame) { Page* page = frame->page(); - JSLock lock(false); + JSLock lock(SilenceAssertionsOnly); ScriptController* scriptController = frame->script(); if (scriptController->haveWindowShell()) { @@ -84,7 +84,7 @@ void ScriptCachedFrameData::restore(Frame* frame) void ScriptCachedFrameData::clear() { - JSLock lock(false); + JSLock lock(SilenceAssertionsOnly); if (!m_window) { m_window = 0; diff --git a/WebCore/bindings/js/ScriptController.cpp b/WebCore/bindings/js/ScriptController.cpp index 2f676c0..8908155 100644 --- a/WebCore/bindings/js/ScriptController.cpp +++ b/WebCore/bindings/js/ScriptController.cpp @@ -33,6 +33,7 @@ #include "ScriptSourceCode.h" #include "ScriptValue.h" #include "Settings.h" +#include "XSSAuditor.h" #include "npruntime_impl.h" #include "runtime_root.h" #include <debugger/Debugger.h> @@ -55,6 +56,7 @@ ScriptController::ScriptController(Frame* frame) #if PLATFORM(MAC) , m_windowScriptObject(0) #endif + , m_XSSAuditor(new XSSAuditor(frame)) { #if PLATFORM(MAC) && ENABLE(MAC_JAVA_BRIDGE) static bool initializedJavaJSBindings; @@ -79,10 +81,21 @@ ScriptController::~ScriptController() ScriptValue ScriptController::evaluate(const ScriptSourceCode& sourceCode) { + const SourceCode& jsSourceCode = sourceCode.jsSourceCode(); + String sourceURL = jsSourceCode.provider()->url(); + + if (sourceURL.isNull() && !m_XSSAuditor->canEvaluateJavaScriptURL(sourceCode.source())) { + // This JavaScript URL is not safe to be evaluated. + return JSValue(); + } + + if (!sourceURL.isNull() && !m_XSSAuditor->canEvaluate(sourceCode.source())) { + // This script is not safe to be evaluated. + return JSValue(); + } + // evaluate code. Returns the JS return value or 0 // if there was none, an error occured or the type couldn't be converted. - - const SourceCode& jsSourceCode = sourceCode.jsSourceCode(); initScriptIfNeeded(); // inlineCode is true for <a href="javascript:doSomething()"> @@ -91,10 +104,9 @@ ScriptValue ScriptController::evaluate(const ScriptSourceCode& sourceCode) // See smart window.open policy for where this is used. ExecState* exec = m_windowShell->window()->globalExec(); const String* savedSourceURL = m_sourceURL; - String sourceURL = jsSourceCode.provider()->url(); m_sourceURL = &sourceURL; - JSLock lock(false); + JSLock lock(SilenceAssertionsOnly); RefPtr<Frame> protect = m_frame; @@ -123,7 +135,7 @@ void ScriptController::clearWindowShell() if (!m_windowShell) return; - JSLock lock(false); + JSLock lock(SilenceAssertionsOnly); // Clear the debugger from the current window before setting the new window. attachDebugger(0); @@ -145,7 +157,7 @@ void ScriptController::initScript() if (m_windowShell) return; - JSLock lock(false); + JSLock lock(SilenceAssertionsOnly); m_windowShell = new JSDOMWindowShell(m_frame->domWindow()); m_windowShell->window()->updateDocument(); @@ -242,7 +254,7 @@ void ScriptController::updateDocument() if (!m_frame->document()) return; - JSLock lock(false); + JSLock lock(SilenceAssertionsOnly); if (m_windowShell) m_windowShell->window()->updateDocument(); } @@ -258,7 +270,7 @@ Bindings::RootObject* ScriptController::bindingRootObject() return 0; if (!m_bindingRootObject) { - JSLock lock(false); + JSLock lock(SilenceAssertionsOnly); m_bindingRootObject = Bindings::RootObject::create(0, globalObject()); } return m_bindingRootObject.get(); @@ -284,7 +296,7 @@ NPObject* ScriptController::windowScriptNPObject() if (isEnabled()) { // JavaScript is enabled, so there is a JavaScript window object. // Return an NPObject bound to the window object. - JSC::JSLock lock(false); + JSC::JSLock lock(SilenceAssertionsOnly); JSObject* win = windowShell()->window(); ASSERT(win); Bindings::RootObject* root = bindingRootObject(); @@ -318,9 +330,9 @@ JSObject* ScriptController::jsObjectForPluginElement(HTMLPlugInElement* plugin) return 0; // Create a JSObject bound to this element - JSLock lock(false); + JSLock lock(SilenceAssertionsOnly); ExecState* exec = globalObject()->globalExec(); - JSValue jsElementValue = toJS(exec, plugin); + JSValue jsElementValue = toJS(exec, globalObject(), plugin); if (!jsElementValue || !jsElementValue.isObject()) return 0; @@ -352,7 +364,7 @@ void ScriptController::cleanupScriptObjectsForPlugin(void* nativeHandle) void ScriptController::clearScriptObjects() { - JSLock lock(false); + JSLock lock(SilenceAssertionsOnly); RootObjectMap::const_iterator end = m_rootObjects.end(); for (RootObjectMap::const_iterator it = m_rootObjects.begin(); it != end; ++it) diff --git a/WebCore/bindings/js/ScriptController.h b/WebCore/bindings/js/ScriptController.h index f700cd9..4528495 100644 --- a/WebCore/bindings/js/ScriptController.h +++ b/WebCore/bindings/js/ScriptController.h @@ -58,6 +58,7 @@ class ScriptSourceCode; class ScriptValue; class String; class Widget; +class XSSAuditor; typedef HashMap<void*, RefPtr<JSC::Bindings::RootObject> > RootObjectMap; @@ -132,6 +133,8 @@ public: NPObject* createScriptObjectForPluginElement(HTMLPlugInElement*); NPObject* windowScriptNPObject(); #endif + + XSSAuditor* xssAuditor() { return m_XSSAuditor.get(); } private: void initScriptIfNeeded() @@ -164,6 +167,9 @@ private: #if PLATFORM(MAC) RetainPtr<WebScriptObject> m_windowScriptObject; #endif + + // The XSSAuditor associated with this ScriptController. + OwnPtr<XSSAuditor> m_XSSAuditor; }; } // namespace WebCore diff --git a/WebCore/bindings/js/ScriptControllerHaiku.cpp b/WebCore/bindings/js/ScriptControllerHaiku.cpp new file mode 100644 index 0000000..b573b97 --- /dev/null +++ b/WebCore/bindings/js/ScriptControllerHaiku.cpp @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2008 Apple Computer, Inc. All rights reserved. + * 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" +#include "ScriptController.h" + +#include "PluginView.h" +#include "runtime_root.h" +#include "runtime.h" + + +namespace WebCore { + +PassRefPtr<JSC::Bindings::Instance> ScriptController::createScriptInstanceForWidget(Widget* widget) +{ + if (!widget->isPluginView()) + return 0; + + return static_cast<PluginView*>(widget)->bindingInstance(); +} + +} // namespace WebCore + diff --git a/WebCore/bindings/js/ScriptControllerMac.mm b/WebCore/bindings/js/ScriptControllerMac.mm index 502a504..e6a654f 100644 --- a/WebCore/bindings/js/ScriptControllerMac.mm +++ b/WebCore/bindings/js/ScriptControllerMac.mm @@ -112,7 +112,7 @@ WebScriptObject* ScriptController::windowScriptObject() return 0; if (!m_windowScriptObject) { - JSC::JSLock lock(false); + JSC::JSLock lock(JSC::SilenceAssertionsOnly); JSC::Bindings::RootObject* root = bindingRootObject(); m_windowScriptObject = [WebScriptObject scriptObjectForJSObject:toRef(windowShell()) originRootObject:root rootObject:root]; } diff --git a/WebCore/bindings/js/ScriptEventListener.cpp b/WebCore/bindings/js/ScriptEventListener.cpp index 0ce7bca..878c535 100644 --- a/WebCore/bindings/js/ScriptEventListener.cpp +++ b/WebCore/bindings/js/ScriptEventListener.cpp @@ -35,6 +35,7 @@ #include "Document.h" #include "JSNode.h" #include "Frame.h" +#include "XSSAuditor.h" #include <runtime/JSLock.h> @@ -61,12 +62,18 @@ PassRefPtr<JSLazyEventListener> createAttributeEventListener(Node* node, Attribu if (!scriptController->isEnabled()) return 0; + if (!scriptController->xssAuditor()->canCreateInlineEventListener(attr->localName().string(), attr->value())) { + // This script is not safe to execute. + return 0; + } + JSDOMWindow* globalObject = scriptController->globalObject(); // Ensure that 'node' has a JavaScript wrapper to mark the event listener we're creating. { - JSLock lock(false); - toJS(globalObject->globalExec(), node); + JSLock lock(SilenceAssertionsOnly); + // FIXME: Should pass the global object associated with the node + toJS(globalObject->globalExec(), globalObject, node); } return JSLazyEventListener::create(attr->localName().string(), eventParameterName(node->isSVGElement()), attr->value(), globalObject, node, scriptController->eventHandlerLineNumber()); @@ -80,6 +87,11 @@ PassRefPtr<JSLazyEventListener> createAttributeEventListener(Frame* frame, Attri ScriptController* scriptController = frame->script(); if (!scriptController->isEnabled()) return 0; + + if (!scriptController->xssAuditor()->canCreateInlineEventListener(attr->localName().string(), attr->value())) { + // This script is not safe to execute. + return 0; + } // 'globalObject' is the JavaScript wrapper that will mark the event listener we're creating. JSDOMWindow* globalObject = scriptController->globalObject(); diff --git a/WebCore/bindings/js/ScriptFunctionCall.cpp b/WebCore/bindings/js/ScriptFunctionCall.cpp index 1122931..46e80ac 100644 --- a/WebCore/bindings/js/ScriptFunctionCall.cpp +++ b/WebCore/bindings/js/ScriptFunctionCall.cpp @@ -66,7 +66,7 @@ void ScriptFunctionCall::appendArgument(const ScriptValue& argument) void ScriptFunctionCall::appendArgument(const String& argument) { - JSLock lock(false); + JSLock lock(SilenceAssertionsOnly); m_arguments.append(jsString(m_exec, argument)); } @@ -82,19 +82,19 @@ void ScriptFunctionCall::appendArgument(JSC::JSValue argument) void ScriptFunctionCall::appendArgument(long long argument) { - JSLock lock(false); + JSLock lock(SilenceAssertionsOnly); m_arguments.append(jsNumber(m_exec, argument)); } void ScriptFunctionCall::appendArgument(unsigned int argument) { - JSLock lock(false); + JSLock lock(SilenceAssertionsOnly); m_arguments.append(jsNumber(m_exec, argument)); } void ScriptFunctionCall::appendArgument(int argument) { - JSLock lock(false); + JSLock lock(SilenceAssertionsOnly); m_arguments.append(jsNumber(m_exec, argument)); } @@ -107,7 +107,7 @@ ScriptValue ScriptFunctionCall::call(bool& hadException, bool reportExceptions) { JSObject* thisObject = m_thisObject.jsObject(); - JSLock lock(false); + JSLock lock(SilenceAssertionsOnly); JSValue function = thisObject->get(m_exec, Identifier(m_exec, m_name)); if (m_exec->hadException()) { @@ -145,7 +145,7 @@ ScriptObject ScriptFunctionCall::construct(bool& hadException, bool reportExcept { JSObject* thisObject = m_thisObject.jsObject(); - JSLock lock(false); + JSLock lock(SilenceAssertionsOnly); JSObject* constructor = asObject(thisObject->get(m_exec, Identifier(m_exec, m_name))); if (m_exec->hadException()) { @@ -170,7 +170,7 @@ ScriptObject ScriptFunctionCall::construct(bool& hadException, bool reportExcept return ScriptObject(); } - return ScriptObject(asObject(result)); + return ScriptObject(m_exec, asObject(result)); } } // namespace WebCore diff --git a/WebCore/bindings/js/ScriptObject.cpp b/WebCore/bindings/js/ScriptObject.cpp index 44337bd..c5fa399 100644 --- a/WebCore/bindings/js/ScriptObject.cpp +++ b/WebCore/bindings/js/ScriptObject.cpp @@ -32,10 +32,14 @@ #include "ScriptObject.h" #include "JSDOMBinding.h" +#ifdef MANUAL_MERGE_REQUIRED #if ENABLE(JAVASCRIPT_DEBUGGER) #include "JSInspectorController.h" #endif +#else // MANUAL_MERGE_REQUIRED +#include "JSInspectorBackend.h" +#endif // MANUAL_MERGE_REQUIRED #include <runtime/JSLock.h> @@ -43,8 +47,9 @@ using namespace JSC; namespace WebCore { -ScriptObject::ScriptObject(JSObject* object) +ScriptObject::ScriptObject(ScriptState* scriptState, JSObject* object) : ScriptValue(object) + , m_scriptState(scriptState) { } @@ -57,87 +62,92 @@ static bool handleException(ScriptState* scriptState) return false; } -bool ScriptObject::set(ScriptState* scriptState, const String& name, const String& value) +bool ScriptObject::set(const String& name, const String& value) { - JSLock lock(false); + JSLock lock(SilenceAssertionsOnly); PutPropertySlot slot; - jsObject()->put(scriptState, Identifier(scriptState, name), jsString(scriptState, value), slot); - return handleException(scriptState); + jsObject()->put(m_scriptState, Identifier(m_scriptState, name), jsString(m_scriptState, value), slot); + return handleException(m_scriptState); } -bool ScriptObject::set(ScriptState* scriptState, const char* name, const ScriptObject& value) +bool ScriptObject::set(const char* name, const ScriptObject& value) { - JSLock lock(false); + JSLock lock(SilenceAssertionsOnly); PutPropertySlot slot; - jsObject()->put(scriptState, Identifier(scriptState, name), value.jsObject(), slot); - return handleException(scriptState); + jsObject()->put(m_scriptState, Identifier(m_scriptState, name), value.jsObject(), slot); + return handleException(m_scriptState); } -bool ScriptObject::set(ScriptState* scriptState, const char* name, const String& value) +bool ScriptObject::set(const char* name, const String& value) { - JSLock lock(false); + JSLock lock(SilenceAssertionsOnly); PutPropertySlot slot; - jsObject()->put(scriptState, Identifier(scriptState, name), jsString(scriptState, value), slot); - return handleException(scriptState); + jsObject()->put(m_scriptState, Identifier(m_scriptState, name), jsString(m_scriptState, value), slot); + return handleException(m_scriptState); } -bool ScriptObject::set(ScriptState* scriptState, const char* name, double value) +bool ScriptObject::set(const char* name, double value) { - JSLock lock(false); + JSLock lock(SilenceAssertionsOnly); PutPropertySlot slot; - jsObject()->put(scriptState, Identifier(scriptState, name), jsNumber(scriptState, value), slot); - return handleException(scriptState); + jsObject()->put(m_scriptState, Identifier(m_scriptState, name), jsNumber(m_scriptState, value), slot); + return handleException(m_scriptState); } -bool ScriptObject::set(ScriptState* scriptState, const char* name, long long value) +bool ScriptObject::set(const char* name, long long value) { - JSLock lock(false); + JSLock lock(SilenceAssertionsOnly); PutPropertySlot slot; - jsObject()->put(scriptState, Identifier(scriptState, name), jsNumber(scriptState, value), slot); - return handleException(scriptState); + jsObject()->put(m_scriptState, Identifier(m_scriptState, name), jsNumber(m_scriptState, value), slot); + return handleException(m_scriptState); } -bool ScriptObject::set(ScriptState* scriptState, const char* name, int value) +bool ScriptObject::set(const char* name, int value) { - JSLock lock(false); + JSLock lock(SilenceAssertionsOnly); PutPropertySlot slot; - jsObject()->put(scriptState, Identifier(scriptState, name), jsNumber(scriptState, value), slot); - return handleException(scriptState); + jsObject()->put(m_scriptState, Identifier(m_scriptState, name), jsNumber(m_scriptState, value), slot); + return handleException(m_scriptState); } -bool ScriptObject::set(ScriptState* scriptState, const char* name, bool value) +bool ScriptObject::set(const char* name, bool value) { - JSLock lock(false); + JSLock lock(SilenceAssertionsOnly); PutPropertySlot slot; - jsObject()->put(scriptState, Identifier(scriptState, name), jsBoolean(value), slot); - return handleException(scriptState); + jsObject()->put(m_scriptState, Identifier(m_scriptState, name), jsBoolean(value), slot); + return handleException(m_scriptState); } ScriptObject ScriptObject::createNew(ScriptState* scriptState) { - JSLock lock(false); - return ScriptObject(constructEmptyObject(scriptState)); + JSLock lock(SilenceAssertionsOnly); + return ScriptObject(scriptState, constructEmptyObject(scriptState)); } bool ScriptGlobalObject::set(ScriptState* scriptState, const char* name, const ScriptObject& value) { - JSLock lock(false); + JSLock lock(SilenceAssertionsOnly); scriptState->lexicalGlobalObject()->putDirect(Identifier(scriptState, name), value.jsObject()); return handleException(scriptState); } +#ifdef MANUAL_MERGE_REQUIRED #if ENABLE(JAVASCRIPT_DEBUGGER) bool ScriptGlobalObject::set(ScriptState* scriptState, const char* name, InspectorController* value) +#else // MANUAL_MERGE_REQUIRED +bool ScriptGlobalObject::set(ScriptState* scriptState, const char* name, InspectorBackend* value) +#endif // MANUAL_MERGE_REQUIRED { - JSLock lock(false); - scriptState->lexicalGlobalObject()->putDirect(Identifier(scriptState, name), toJS(scriptState, value)); + JSLock lock(SilenceAssertionsOnly); + JSDOMGlobalObject* globalObject = static_cast<JSDOMGlobalObject*>(scriptState->lexicalGlobalObject()); + globalObject->putDirect(Identifier(scriptState, name), toJS(scriptState, globalObject, value)); return handleException(scriptState); } #endif bool ScriptGlobalObject::get(ScriptState* scriptState, const char* name, ScriptObject& value) { - JSLock lock(false); + JSLock lock(SilenceAssertionsOnly); JSValue jsValue = scriptState->lexicalGlobalObject()->get(scriptState, Identifier(scriptState, name)); if (!jsValue) return false; @@ -145,13 +155,13 @@ bool ScriptGlobalObject::get(ScriptState* scriptState, const char* name, ScriptO if (!jsValue.isObject()) return false; - value = ScriptObject(asObject(jsValue)); + value = ScriptObject(scriptState, asObject(jsValue)); return true; } bool ScriptGlobalObject::remove(ScriptState* scriptState, const char* name) { - JSLock lock(false); + JSLock lock(SilenceAssertionsOnly); scriptState->lexicalGlobalObject()->deleteProperty(scriptState, Identifier(scriptState, name)); return handleException(scriptState); } diff --git a/WebCore/bindings/js/ScriptObject.h b/WebCore/bindings/js/ScriptObject.h index ed86659..50b63ad 100644 --- a/WebCore/bindings/js/ScriptObject.h +++ b/WebCore/bindings/js/ScriptObject.h @@ -38,29 +38,32 @@ #include <runtime/Protect.h> namespace WebCore { - class InspectorController; + class InspectorBackend; class ScriptObject : public ScriptValue { public: - ScriptObject(JSC::JSObject*); + ScriptObject(ScriptState*, JSC::JSObject*); ScriptObject() {} JSC::JSObject* jsObject() const { return asObject(jsValue()); } - bool set(ScriptState*, const String& name, const String&); - bool set(ScriptState*, const char* name, const ScriptObject&); - bool set(ScriptState*, const char* name, const String&); - bool set(ScriptState*, const char* name, double); - bool set(ScriptState*, const char* name, long long); - bool set(ScriptState*, const char* name, int); - bool set(ScriptState*, const char* name, bool); + 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 long); + bool set(const char* name, int); + bool set(const char* name, bool); static ScriptObject createNew(ScriptState*); + + protected: + ScriptState* m_scriptState; }; class ScriptGlobalObject { public: static bool set(ScriptState*, const char* name, const ScriptObject&); - static bool set(ScriptState*, const char* name, InspectorController*); + static bool set(ScriptState*, const char* name, InspectorBackend*); static bool get(ScriptState*, const char* name, ScriptObject&); static bool remove(ScriptState*, const char* name); private: diff --git a/WebCore/bindings/js/ScriptObjectQuarantine.cpp b/WebCore/bindings/js/ScriptObjectQuarantine.cpp index 13e180a..89553ef 100644 --- a/WebCore/bindings/js/ScriptObjectQuarantine.cpp +++ b/WebCore/bindings/js/ScriptObjectQuarantine.cpp @@ -31,7 +31,6 @@ #include "config.h" #include "ScriptObjectQuarantine.h" -#include "Database.h" #include "Document.h" #include "Frame.h" #include "JSDOMBinding.h" @@ -43,6 +42,7 @@ #include <runtime/JSLock.h> #if ENABLE(DATABASE) +#include "Database.h" #include "JSDatabase.h" #endif @@ -56,7 +56,7 @@ namespace WebCore { ScriptValue quarantineValue(ScriptState* scriptState, const ScriptValue& value) { - JSLock lock(false); + JSLock lock(SilenceAssertionsOnly); return ScriptValue(JSInspectedObjectWrapper::wrap(scriptState, value.jsValue())); } @@ -69,10 +69,11 @@ bool getQuarantinedScriptObject(Database* database, ScriptObject& quarantinedObj if (!frame) return false; - ExecState* exec = toJSDOMWindow(frame)->globalExec(); + JSDOMGlobalObject* globalObject = toJSDOMWindow(frame); + ExecState* exec = globalObject->globalExec(); - JSLock lock(false); - quarantinedObject = ScriptObject(asObject(JSInspectedObjectWrapper::wrap(exec, toJS(exec, database)))); + JSLock lock(SilenceAssertionsOnly); + quarantinedObject = ScriptObject(exec, asObject(JSInspectedObjectWrapper::wrap(exec, toJS(exec, globalObject, database)))); return true; } @@ -84,10 +85,11 @@ bool getQuarantinedScriptObject(Frame* frame, Storage* storage, ScriptObject& qu ASSERT(frame); ASSERT(storage); - ExecState* exec = toJSDOMWindow(frame)->globalExec(); + JSDOMGlobalObject* globalObject = toJSDOMWindow(frame); + ExecState* exec = globalObject->globalExec(); - JSLock lock(false); - quarantinedObject = ScriptObject(asObject(JSInspectedObjectWrapper::wrap(exec, toJS(exec, storage)))); + JSLock lock(SilenceAssertionsOnly); + quarantinedObject = ScriptObject(exec, asObject(JSInspectedObjectWrapper::wrap(exec, toJS(exec, globalObject, storage)))); return true; } @@ -99,8 +101,9 @@ bool getQuarantinedScriptObject(Node* node, ScriptObject& quarantinedObject) if (!exec) return false; - JSLock lock(false); - quarantinedObject = ScriptObject(asObject(JSInspectedObjectWrapper::wrap(exec, toJS(exec, node)))); + JSLock lock(SilenceAssertionsOnly); + // FIXME: Should use some sort of globalObjectFromNode() + quarantinedObject = ScriptObject(exec, asObject(JSInspectedObjectWrapper::wrap(exec, toJS(exec, deprecatedGlobalObjectForPrototype(exec), node)))); return true; } @@ -112,8 +115,8 @@ bool getQuarantinedScriptObject(DOMWindow* domWindow, ScriptObject& quarantinedO JSDOMWindow* window = toJSDOMWindow(domWindow->frame()); ExecState* exec = window->globalExec(); - JSLock lock(false); - quarantinedObject = ScriptObject(asObject(JSInspectedObjectWrapper::wrap(exec, window))); + JSLock lock(SilenceAssertionsOnly); + quarantinedObject = ScriptObject(exec, asObject(JSInspectedObjectWrapper::wrap(exec, window))); return true; } diff --git a/WebCore/bindings/js/ScriptSourceCode.h b/WebCore/bindings/js/ScriptSourceCode.h index 4a2403d..1b05ded 100644 --- a/WebCore/bindings/js/ScriptSourceCode.h +++ b/WebCore/bindings/js/ScriptSourceCode.h @@ -32,20 +32,24 @@ #define ScriptSourceCode_h #include "CachedScriptSourceProvider.h" +#include "ScriptSourceProvider.h" #include "StringSourceProvider.h" #include "KURL.h" +#include <wtf/RefPtr.h> namespace WebCore { class ScriptSourceCode { public: ScriptSourceCode(const String& source, const KURL& url = KURL(), int startLine = 1) - : m_code(makeSource(source, url.isNull() ? String() : url.string(), startLine)) + : m_provider(StringSourceProvider::create(source, url.isNull() ? String() : url.string())) + , m_code(m_provider, startLine) { } ScriptSourceCode(CachedScript* cs) - : m_code(makeSource(cs)) + : m_provider(CachedScriptSourceProvider::create(cs)) + , m_code(m_provider) { } @@ -53,7 +57,11 @@ public: const JSC::SourceCode& jsSourceCode() const { return m_code; } + const String& source() const { return m_provider->source(); } + private: + RefPtr<ScriptSourceProvider> m_provider; + JSC::SourceCode m_code; }; diff --git a/WebCore/bindings/js/ScriptSourceProvider.h b/WebCore/bindings/js/ScriptSourceProvider.h new file mode 100644 index 0000000..3fe3584 --- /dev/null +++ b/WebCore/bindings/js/ScriptSourceProvider.h @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2009 Daniel Bates (dbates@intudata.com) + * 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 ScriptSourceProvider_h +#define ScriptSourceProvider_h + +#include <parser/SourceProvider.h> + +namespace WebCore { + + class String; + + class ScriptSourceProvider : public JSC::SourceProvider { + public: + ScriptSourceProvider(const JSC::UString& url, JSC::SourceBOMPresence hasBOMs = JSC::SourceCouldHaveBOMs) + : SourceProvider(url, hasBOMs) + { + } + + virtual const String& source() const = 0; + }; + +} // namespace WebCore + +#endif // ScriptSourceProvider_h diff --git a/WebCore/bindings/js/ScriptValue.cpp b/WebCore/bindings/js/ScriptValue.cpp index dfb46da..d427cee 100644 --- a/WebCore/bindings/js/ScriptValue.cpp +++ b/WebCore/bindings/js/ScriptValue.cpp @@ -44,7 +44,7 @@ bool ScriptValue::getString(String& result) const { if (!m_value) return false; - JSLock lock(false); + JSLock lock(SilenceAssertionsOnly); UString ustring; if (!m_value.get().getString(ustring)) return false; diff --git a/WebCore/bindings/js/StringSourceProvider.h b/WebCore/bindings/js/StringSourceProvider.h index ab37a56..770c4fc 100644 --- a/WebCore/bindings/js/StringSourceProvider.h +++ b/WebCore/bindings/js/StringSourceProvider.h @@ -29,21 +29,23 @@ #ifndef StringSourceProvider_h #define StringSourceProvider_h +#include "ScriptSourceProvider.h" #include <parser/SourceCode.h> namespace WebCore { - class StringSourceProvider : public JSC::SourceProvider { + class StringSourceProvider : public ScriptSourceProvider { public: static PassRefPtr<StringSourceProvider> create(const String& source, const String& url) { return adoptRef(new StringSourceProvider(source, url)); } JSC::UString getRange(int start, int end) const { return JSC::UString(m_source.characters() + start, end - start); } const UChar* data() const { return m_source.characters(); } int length() const { return m_source.length(); } + const String& source() const { return m_source; } private: StringSourceProvider(const String& source, const String& url) - : SourceProvider(url) + : ScriptSourceProvider(url) , m_source(source) { } diff --git a/WebCore/bindings/js/WorkerScriptController.cpp b/WebCore/bindings/js/WorkerScriptController.cpp index bcf107b..3590dad 100644 --- a/WebCore/bindings/js/WorkerScriptController.cpp +++ b/WebCore/bindings/js/WorkerScriptController.cpp @@ -31,7 +31,8 @@ #include "WorkerScriptController.h" #include "JSDOMBinding.h" -#include "JSWorkerContext.h" +#include "JSDedicatedWorkerContext.h" +#include "JSSharedWorkerContext.h" #include "ScriptSourceCode.h" #include "ScriptValue.h" #include "WorkerContext.h" @@ -66,16 +67,30 @@ void WorkerScriptController::initScript() { ASSERT(!m_workerContextWrapper); - JSLock lock(false); + JSLock lock(SilenceAssertionsOnly); // Explicitly protect the global object's prototype so it isn't collected // when we allocate the global object. (Once the global object is fully // constructed, it can mark its own prototype.) - RefPtr<Structure> prototypeStructure = JSWorkerContextPrototype::createStructure(jsNull()); - ProtectedPtr<JSWorkerContextPrototype> prototype = new (m_globalData.get()) JSWorkerContextPrototype(prototypeStructure.release()); - - RefPtr<Structure> structure = JSWorkerContext::createStructure(prototype); - m_workerContextWrapper = new (m_globalData.get()) JSWorkerContext(structure.release(), m_workerContext); + RefPtr<Structure> workerContextPrototypeStructure = JSWorkerContextPrototype::createStructure(jsNull()); + ProtectedPtr<JSWorkerContextPrototype> workerContextPrototype = new (m_globalData.get()) JSWorkerContextPrototype(workerContextPrototypeStructure.release()); + + if (m_workerContext->isDedicatedWorkerContext()) { + RefPtr<Structure> dedicatedContextPrototypeStructure = JSDedicatedWorkerContextPrototype::createStructure(workerContextPrototype); + ProtectedPtr<JSDedicatedWorkerContextPrototype> dedicatedContextPrototype = new (m_globalData.get()) JSDedicatedWorkerContextPrototype(dedicatedContextPrototypeStructure.release()); + RefPtr<Structure> structure = JSDedicatedWorkerContext::createStructure(dedicatedContextPrototype); + + m_workerContextWrapper = new (m_globalData.get()) JSDedicatedWorkerContext(structure.release(), m_workerContext->toDedicatedWorkerContext()); +#if ENABLE(SHARED_WORKERS) + } else { + ASSERT(m_workerContext->isSharedWorkerContext()); + RefPtr<Structure> sharedContextPrototypeStructure = JSSharedWorkerContextPrototype::createStructure(workerContextPrototype); + ProtectedPtr<JSSharedWorkerContextPrototype> sharedContextPrototype = new (m_globalData.get()) JSSharedWorkerContextPrototype(sharedContextPrototypeStructure.release()); + RefPtr<Structure> structure = JSSharedWorkerContext::createStructure(sharedContextPrototype); + + m_workerContextWrapper = new (m_globalData.get()) JSSharedWorkerContext(structure.release(), m_workerContext->toSharedWorkerContext()); +#endif + } } ScriptValue WorkerScriptController::evaluate(const ScriptSourceCode& sourceCode) @@ -88,7 +103,7 @@ ScriptValue WorkerScriptController::evaluate(const ScriptSourceCode& sourceCode) ScriptValue exception; ScriptValue result = evaluate(sourceCode, &exception); if (exception.jsValue()) { - JSLock lock(false); + JSLock lock(SilenceAssertionsOnly); reportException(m_workerContextWrapper->globalExec(), exception.jsValue()); } return result; @@ -103,15 +118,13 @@ ScriptValue WorkerScriptController::evaluate(const ScriptSourceCode& sourceCode, } initScriptIfNeeded(); - JSLock lock(false); + JSLock lock(SilenceAssertionsOnly); ExecState* exec = m_workerContextWrapper->globalExec(); m_workerContextWrapper->globalData()->timeoutChecker.start(); Completion comp = JSC::evaluate(exec, exec->dynamicGlobalObject()->globalScopeChain(), sourceCode.jsSourceCode(), m_workerContextWrapper); m_workerContextWrapper->globalData()->timeoutChecker.stop(); - m_workerContext->thread()->workerObjectProxy().reportPendingActivity(m_workerContext->hasPendingActivity()); - if (comp.complType() == Normal || comp.complType() == ReturnValue) return comp.value(); diff --git a/WebCore/bindings/js/WorkerScriptController.h b/WebCore/bindings/js/WorkerScriptController.h index 0454721..bb33f60 100644 --- a/WebCore/bindings/js/WorkerScriptController.h +++ b/WebCore/bindings/js/WorkerScriptController.h @@ -45,7 +45,7 @@ namespace WebCore { class String; class WorkerContext; - class WorkerScriptController : Noncopyable { + class WorkerScriptController : public Noncopyable { public: WorkerScriptController(WorkerContext*); ~WorkerScriptController(); |