diff options
author | Steve Block <steveblock@google.com> | 2009-12-15 10:12:09 +0000 |
---|---|---|
committer | Steve Block <steveblock@google.com> | 2009-12-17 17:41:10 +0000 |
commit | 643ca7872b450ea4efacab6188849e5aac2ba161 (patch) | |
tree | 6982576c228bcd1a7efe98afed544d840751094c /WebCore/bindings | |
parent | d026980fde6eb3b01c1fe49441174e89cd1be298 (diff) | |
download | external_webkit-643ca7872b450ea4efacab6188849e5aac2ba161.zip external_webkit-643ca7872b450ea4efacab6188849e5aac2ba161.tar.gz external_webkit-643ca7872b450ea4efacab6188849e5aac2ba161.tar.bz2 |
Merge webkit.org at r51976 : Initial merge by git.
Change-Id: Ib0e7e2f0fb4bee5a186610272edf3186f0986b43
Diffstat (limited to 'WebCore/bindings')
181 files changed, 5760 insertions, 3582 deletions
diff --git a/WebCore/bindings/ScriptControllerBase.cpp b/WebCore/bindings/ScriptControllerBase.cpp index c232e84..72c9f45 100644 --- a/WebCore/bindings/ScriptControllerBase.cpp +++ b/WebCore/bindings/ScriptControllerBase.cpp @@ -62,6 +62,9 @@ bool ScriptController::executeIfJavaScriptURL(const KURL& url, bool userGesture, if (m_frame->page() && !m_frame->page()->javaScriptURLsAreAllowed()) return true; + if (m_frame->inViewSourceMode()) + return true; + const int javascriptSchemeLength = sizeof("javascript:") - 1; String script = decodeURLEscapeSequences(url.string().substring(javascriptSchemeLength)); @@ -70,8 +73,15 @@ bool ScriptController::executeIfJavaScriptURL(const KURL& url, bool userGesture, result = executeScript(script, userGesture); String scriptResult; +#if USE(JSC) + JSDOMWindowShell* shell = windowShell(mainThreadNormalWorld()); + JSC::ExecState* exec = shell->window()->globalExec(); + if (!result.getString(exec, scriptResult)) + return true; +#else if (!result.getString(scriptResult)) return true; +#endif // FIXME: We should always replace the document, but doing so // synchronously can cause crashes: diff --git a/WebCore/bindings/js/JSAttrCustom.cpp b/WebCore/bindings/js/JSAttrCustom.cpp index 14457c4..3c01535 100644 --- a/WebCore/bindings/js/JSAttrCustom.cpp +++ b/WebCore/bindings/js/JSAttrCustom.cpp @@ -65,10 +65,8 @@ void JSAttr::markChildren(MarkStack& markStack) // Mark the element so that this will work to access the attribute even if the last // other reference goes away. - if (Element* element = impl()->ownerElement()) { - if (JSNode* wrapper = getCachedDOMNodeWrapper(element->document(), element)) - markStack.append(wrapper); - } + if (Element* element = impl()->ownerElement()) + markDOMNodeWrapper(markStack, element->document(), element); } } // namespace WebCore diff --git a/WebCore/bindings/js/JSBindingsAllInOne.cpp b/WebCore/bindings/js/JSBindingsAllInOne.cpp new file mode 100644 index 0000000..cf1049a --- /dev/null +++ b/WebCore/bindings/js/JSBindingsAllInOne.cpp @@ -0,0 +1,150 @@ +/* + * 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. + */ + +// This all-in-one cpp file cuts down on template bloat to allow us to build our Windows release build. + +#include "GCController.cpp" +#include "JSAbstractWorkerCustom.cpp" +#include "JSAttrCustom.cpp" +#include "JSAudioConstructor.cpp" +#include "JSCDATASectionCustom.cpp" +#include "JSCSSRuleCustom.cpp" +#include "JSCSSRuleListCustom.cpp" +#include "JSCSSStyleDeclarationCustom.cpp" +#include "JSCSSValueCustom.cpp" +#include "JSCallbackData.cpp" +#include "JSCanvasRenderingContext2DCustom.cpp" +#include "JSCanvasRenderingContextCustom.cpp" +#include "JSClipboardCustom.cpp" +#include "JSConsoleCustom.cpp" +#include "JSCoordinatesCustom.cpp" +#include "JSCustomSQLStatementCallback.cpp" +#include "JSCustomSQLStatementErrorCallback.cpp" +#include "JSCustomSQLTransactionCallback.cpp" +#include "JSCustomSQLTransactionErrorCallback.cpp" +#include "JSCustomVoidCallback.cpp" +#include "JSCustomXPathNSResolver.cpp" +#include "JSDOMApplicationCacheCustom.cpp" +#include "JSDOMBinding.cpp" +#include "JSDOMGlobalObject.cpp" +#include "JSDOMWindowBase.cpp" +#include "JSDOMWindowCustom.cpp" +#include "JSDOMWindowShell.cpp" +#include "JSDataGridColumnListCustom.cpp" +#include "JSDataGridDataSource.cpp" +#include "JSDatabaseCustom.cpp" +#include "JSDedicatedWorkerContextCustom.cpp" +#include "JSDesktopNotificationsCustom.cpp" +#include "JSDocumentCustom.cpp" +#include "JSDocumentFragmentCustom.cpp" +#include "JSElementCustom.cpp" +#include "JSEventCustom.cpp" +#include "JSEventListener.cpp" +#include "JSEventSourceConstructor.cpp" +#include "JSEventSourceCustom.cpp" +#include "JSEventTarget.cpp" +#include "JSExceptionBase.cpp" +#include "JSHTMLAllCollectionCustom.cpp" +#include "JSHTMLAppletElementCustom.cpp" +#include "JSHTMLCanvasElementCustom.cpp" +#include "JSHTMLCollectionCustom.cpp" +#include "JSHTMLDataGridElementCustom.cpp" +#include "JSHTMLDocumentCustom.cpp" +#include "JSHTMLElementCustom.cpp" +#include "JSHTMLEmbedElementCustom.cpp" +#include "JSHTMLFormElementCustom.cpp" +#include "JSHTMLFrameElementCustom.cpp" +#include "JSHTMLFrameSetElementCustom.cpp" +#include "JSHTMLIFrameElementCustom.cpp" +#include "JSHTMLInputElementCustom.cpp" +#include "JSHTMLObjectElementCustom.cpp" +#include "JSHTMLOptionsCollectionCustom.cpp" +#include "JSHTMLSelectElementCustom.cpp" +#include "JSHistoryCustom.cpp" +#include "JSImageConstructor.cpp" +#include "JSImageDataCustom.cpp" +#include "JSInjectedScriptHostCustom.cpp" +#include "JSInspectedObjectWrapper.cpp" +#include "JSInspectorFrontendHostCustom.cpp" +#include "JSJavaScriptCallFrameCustom.cpp" +#include "JSLazyEventListener.cpp" +#include "JSLocationCustom.cpp" +#include "JSMessageChannelConstructor.cpp" +#include "JSMessageChannelCustom.cpp" +#include "JSMessageEventCustom.cpp" +#include "JSMessagePortCustom.cpp" +#include "JSMimeTypeArrayCustom.cpp" +#include "JSNamedNodeMapCustom.cpp" +#include "JSNavigatorCustom.cpp" +#include "JSNodeCustom.cpp" +#include "JSNodeFilterCondition.cpp" +#include "JSNodeFilterCustom.cpp" +#include "JSNodeIteratorCustom.cpp" +#include "JSNodeListCustom.cpp" +#include "JSOptionConstructor.cpp" +#include "JSPluginArrayCustom.cpp" +#include "JSPluginCustom.cpp" +#include "JSPluginElementFunctions.cpp" +#include "JSQuarantinedObjectWrapper.cpp" +#include "JSSQLResultSetRowListCustom.cpp" +#include "JSSQLTransactionCustom.cpp" +#include "JSSVGElementInstanceCustom.cpp" +#include "JSSVGLengthCustom.cpp" +#include "JSSVGMatrixCustom.cpp" +#include "JSSVGPathSegCustom.cpp" +#include "JSSVGPathSegListCustom.cpp" +#include "JSSVGPointListCustom.cpp" +#include "JSSharedWorkerConstructor.cpp" +#include "JSSharedWorkerCustom.cpp" +#include "JSStorageCustom.cpp" +#include "JSStyleSheetCustom.cpp" +#include "JSStyleSheetListCustom.cpp" +#include "JSTextCustom.cpp" +#include "JSTreeWalkerCustom.cpp" +#include "JSWebKitCSSMatrixConstructor.cpp" +#include "JSWebKitPointConstructor.cpp" +#include "JSWebSocketConstructor.cpp" +#include "JSWebSocketCustom.cpp" +#include "JSWorkerConstructor.cpp" +#include "JSWorkerContextBase.cpp" +#include "JSWorkerContextCustom.cpp" +#include "JSWorkerCustom.cpp" +#include "JSXMLHttpRequestConstructor.cpp" +#include "JSXMLHttpRequestCustom.cpp" +#include "JSXMLHttpRequestUploadCustom.cpp" +#include "JSXSLTProcessorConstructor.cpp" +#include "JSXSLTProcessorCustom.cpp" +#include "ScheduledAction.cpp" +#include "ScriptArray.cpp" +#include "ScriptCachedFrameData.cpp" +#include "ScriptCallFrame.cpp" +#include "ScriptCallStack.cpp" +#include "ScriptController.cpp" +#include "ScriptControllerWin.cpp" +#include "ScriptEventListener.cpp" +#include "ScriptFunctionCall.cpp" +#include "ScriptState.cpp" +#include "SerializedScriptValue.cpp" +#include "WorkerScriptController.cpp" diff --git a/WebCore/bindings/js/JSCSSRuleCustom.cpp b/WebCore/bindings/js/JSCSSRuleCustom.cpp index 1b96c06..b0adf15 100644 --- a/WebCore/bindings/js/JSCSSRuleCustom.cpp +++ b/WebCore/bindings/js/JSCSSRuleCustom.cpp @@ -54,7 +54,7 @@ JSValue toJS(ExecState* exec, JSDOMGlobalObject* globalObject, CSSRule* rule) if (!rule) return jsNull(); - DOMObject* wrapper = getCachedDOMObjectWrapper(exec->globalData(), rule); + DOMObject* wrapper = getCachedDOMObjectWrapper(exec, rule); if (wrapper) return wrapper; diff --git a/WebCore/bindings/js/JSCSSValueCustom.cpp b/WebCore/bindings/js/JSCSSValueCustom.cpp index 87a5760..83c1d3a 100644 --- a/WebCore/bindings/js/JSCSSValueCustom.cpp +++ b/WebCore/bindings/js/JSCSSValueCustom.cpp @@ -49,7 +49,7 @@ JSValue toJS(ExecState* exec, JSDOMGlobalObject* globalObject, CSSValue* value) if (!value) return jsNull(); - DOMObject* wrapper = getCachedDOMObjectWrapper(exec->globalData(), value); + DOMObject* wrapper = getCachedDOMObjectWrapper(exec, value); if (wrapper) return wrapper; diff --git a/WebCore/bindings/js/JSCallbackData.cpp b/WebCore/bindings/js/JSCallbackData.cpp index 38292c7..e128f27 100644 --- a/WebCore/bindings/js/JSCallbackData.cpp +++ b/WebCore/bindings/js/JSCallbackData.cpp @@ -47,13 +47,8 @@ JSValue JSCallbackData::invokeCallback(MarkedArgumentBuffer& args, bool* raisedE ASSERT(globalObject()); ExecState* exec = globalObject()->globalExec(); - - JSValue function; - { - // Switch worlds, just in case handleEvent is a getter and causes JS execution! - EnterDOMWrapperWorld worldEntry(exec, m_isolatedWorld.get()); - function = callback()->get(exec, Identifier(exec, "handleEvent")); - } + JSValue function = callback()->get(exec, Identifier(exec, "handleEvent")); + CallData callData; CallType callType = function.getCallData(callData); if (callType == CallTypeNone) { @@ -64,7 +59,7 @@ JSValue JSCallbackData::invokeCallback(MarkedArgumentBuffer& args, bool* raisedE } globalObject()->globalData()->timeoutChecker.start(); - JSValue result = callInWorld(exec, function, callType, callData, callback(), args, m_isolatedWorld.get()); + JSValue result = JSC::call(exec, function, callType, callData, callback(), args); globalObject()->globalData()->timeoutChecker.stop(); Document::updateStyleForAllDocuments(); diff --git a/WebCore/bindings/js/JSCallbackData.h b/WebCore/bindings/js/JSCallbackData.h index 5c86701..b939c01 100644 --- a/WebCore/bindings/js/JSCallbackData.h +++ b/WebCore/bindings/js/JSCallbackData.h @@ -48,7 +48,6 @@ public: JSCallbackData(JSC::JSObject* callback, JSDOMGlobalObject* globalObject) : m_callback(callback) , m_globalObject(globalObject) - , m_isolatedWorld(currentWorld(globalObject->globalExec())) { } @@ -65,7 +64,6 @@ public: private: JSC::ProtectedPtr<JSC::JSObject> m_callback; JSC::ProtectedPtr<JSDOMGlobalObject> m_globalObject; - RefPtr<DOMWrapperWorld> m_isolatedWorld; }; } // namespace WebCore diff --git a/WebCore/bindings/js/JSCanvasRenderingContext2DCustom.cpp b/WebCore/bindings/js/JSCanvasRenderingContext2DCustom.cpp index bb3500b..a271923 100644 --- a/WebCore/bindings/js/JSCanvasRenderingContext2DCustom.cpp +++ b/WebCore/bindings/js/JSCanvasRenderingContext2DCustom.cpp @@ -51,10 +51,10 @@ static JSValue toJS(ExecState* exec, CanvasStyle* style) return jsString(exec, style->color()); } -static PassRefPtr<CanvasStyle> toHTMLCanvasStyle(ExecState*, JSValue value) +static PassRefPtr<CanvasStyle> toHTMLCanvasStyle(ExecState* exec, JSValue value) { if (value.isString()) - return CanvasStyle::create(asString(value)->value()); + return CanvasStyle::create(asString(value)->value(exec)); if (!value.isObject()) return 0; JSObject* object = asObject(value); @@ -102,13 +102,13 @@ JSValue JSCanvasRenderingContext2D::setFillColor(ExecState* exec, const ArgList& switch (args.size()) { case 1: if (args.at(0).isString()) - context->setFillColor(asString(args.at(0))->value()); + context->setFillColor(asString(args.at(0))->value(exec)); else context->setFillColor(args.at(0).toFloat(exec)); break; case 2: if (args.at(0).isString()) - context->setFillColor(asString(args.at(0))->value(), args.at(1).toFloat(exec)); + context->setFillColor(asString(args.at(0))->value(exec), args.at(1).toFloat(exec)); else context->setFillColor(args.at(0).toFloat(exec), args.at(1).toFloat(exec)); break; @@ -139,13 +139,13 @@ JSValue JSCanvasRenderingContext2D::setStrokeColor(ExecState* exec, const ArgLis switch (args.size()) { case 1: if (args.at(0).isString()) - context->setStrokeColor(asString(args.at(0))->value()); + context->setStrokeColor(asString(args.at(0))->value(exec)); else context->setStrokeColor(args.at(0).toFloat(exec)); break; case 2: if (args.at(0).isString()) - context->setStrokeColor(asString(args.at(0))->value(), args.at(1).toFloat(exec)); + context->setStrokeColor(asString(args.at(0))->value(exec), args.at(1).toFloat(exec)); else context->setStrokeColor(args.at(0).toFloat(exec), args.at(1).toFloat(exec)); break; @@ -298,7 +298,7 @@ JSValue JSCanvasRenderingContext2D::setShadow(ExecState* exec, const ArgList& ar case 4: if (args.at(3).isString()) context->setShadow(args.at(0).toFloat(exec), args.at(1).toFloat(exec), - args.at(2).toFloat(exec), asString(args.at(3))->value()); + args.at(2).toFloat(exec), asString(args.at(3))->value(exec)); else context->setShadow(args.at(0).toFloat(exec), args.at(1).toFloat(exec), args.at(2).toFloat(exec), args.at(3).toFloat(exec)); @@ -306,7 +306,7 @@ JSValue JSCanvasRenderingContext2D::setShadow(ExecState* exec, const ArgList& ar case 5: if (args.at(3).isString()) context->setShadow(args.at(0).toFloat(exec), args.at(1).toFloat(exec), - args.at(2).toFloat(exec), asString(args.at(3))->value(), + args.at(2).toFloat(exec), asString(args.at(3))->value(exec), args.at(4).toFloat(exec)); else context->setShadow(args.at(0).toFloat(exec), args.at(1).toFloat(exec), diff --git a/WebCore/bindings/js/JSCanvasRenderingContext3DCustom.cpp b/WebCore/bindings/js/JSCanvasRenderingContext3DCustom.cpp deleted file mode 100644 index 3938ba1..0000000 --- a/WebCore/bindings/js/JSCanvasRenderingContext3DCustom.cpp +++ /dev/null @@ -1,443 +0,0 @@ -/* - * Copyright (C) 2009 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" - -#if ENABLE(3D_CANVAS) - -#include "JSCanvasRenderingContext3D.h" - -#include "CanvasRenderingContext3D.h" -#include "ExceptionCode.h" -#include "HTMLCanvasElement.h" -#include "HTMLImageElement.h" -#include "JSCanvasFloatArray.h" -#include "JSCanvasIntArray.h" -#include "JSHTMLCanvasElement.h" -#include "JSHTMLImageElement.h" -#include "JSWebKitCSSMatrix.h" -#include <runtime/Error.h> -#include <wtf/FastMalloc.h> -#include <wtf/OwnFastMallocPtr.h> - -using namespace JSC; - -namespace WebCore { - -JSValue JSCanvasRenderingContext3D::bufferData(JSC::ExecState* exec, JSC::ArgList const& args) -{ - if (args.size() != 3) - return throwError(exec, SyntaxError); - - unsigned target = args.at(0).toInt32(exec); - unsigned usage = args.at(2).toInt32(exec); - - // If argument 1 is a number, we are initializing this buffer to that size - if (!args.at(1).isObject()) { - unsigned int count = args.at(1).toInt32(exec); - static_cast<CanvasRenderingContext3D*>(impl())->bufferData(target, count, usage); - return jsUndefined(); - } - - CanvasArray* array = toCanvasArray(args.at(1)); - - static_cast<CanvasRenderingContext3D*>(impl())->bufferData(target, array, usage); - return jsUndefined(); -} - -JSValue JSCanvasRenderingContext3D::bufferSubData(JSC::ExecState* exec, JSC::ArgList const& args) -{ - if (args.size() != 3) - return throwError(exec, SyntaxError); - - unsigned target = args.at(0).toInt32(exec); - unsigned offset = args.at(1).toInt32(exec); - - CanvasArray* array = toCanvasArray(args.at(2)); - - static_cast<CanvasRenderingContext3D*>(impl())->bufferSubData(target, offset, array); - return jsUndefined(); -} - -// void texImage2DHTML(in unsigned long target, in unsigned long level, in HTMLImageElement image); -JSValue JSCanvasRenderingContext3D::texImage2D(ExecState* exec, const ArgList& args) -{ - if (args.size() < 3) - return throwError(exec, SyntaxError); - - ExceptionCode ec = 0; - CanvasRenderingContext3D* context = static_cast<CanvasRenderingContext3D*>(impl()); - unsigned target = args.at(0).toInt32(exec); - if (exec->hadException()) - return jsUndefined(); - - unsigned level = args.at(1).toInt32(exec); - if (exec->hadException()) - return jsUndefined(); - - if (args.size() > 5) { - // This must be the bare array case. - if (args.size() != 9) - return throwError(exec, SyntaxError); - - unsigned internalformat = args.at(2).toInt32(exec); - if (exec->hadException()) - return jsUndefined(); - - unsigned width = args.at(3).toInt32(exec); - if (exec->hadException()) - return jsUndefined(); - - unsigned height = args.at(4).toInt32(exec); - if (exec->hadException()) - return jsUndefined(); - - unsigned border = args.at(5).toInt32(exec); - if (exec->hadException()) - return jsUndefined(); - - unsigned format = args.at(6).toInt32(exec); - if (exec->hadException()) - return jsUndefined(); - - unsigned type = args.at(7).toInt32(exec); - if (exec->hadException()) - return jsUndefined(); - - CanvasArray* array = toCanvasArray(args.at(8)); - if (exec->hadException()) - return jsUndefined(); - - if (!array) - return throwError(exec, TypeError); - - // FIXME: Need to check to make sure CanvasArray is a CanvasByteArray or CanvasShortArray, - // depending on the passed type parameter. - - context->texImage2D(target, level, internalformat, width, height, border, format, type, array, ec); - return jsUndefined(); - } - - // The image parameter can be a <img> or <canvas> element. - JSValue value = args.at(2); - if (!value.isObject()) - return throwError(exec, TypeError); - JSObject* o = asObject(value); - - bool flipY = (args.size() > 3) ? args.at(3).toBoolean(exec) : false; - bool premultiplyAlpha = (args.size() > 4) ? args.at(3).toBoolean(exec) : false; - - if (o->inherits(&JSHTMLImageElement::s_info)) { - HTMLImageElement* imgElt = static_cast<HTMLImageElement*>(static_cast<JSHTMLElement*>(o)->impl()); - context->texImage2D(target, level, imgElt, flipY, premultiplyAlpha, ec); - } else if (o->inherits(&JSHTMLCanvasElement::s_info)) { - HTMLCanvasElement* canvas = static_cast<HTMLCanvasElement*>(static_cast<JSHTMLElement*>(o)->impl()); - context->texImage2D(target, level, canvas, flipY, premultiplyAlpha, ec); - } else { - setDOMException(exec, TYPE_MISMATCH_ERR); - } - - return jsUndefined(); -} - -// void texSubImage2DHTML(in unsigned long target, in unsigned long level, in unsigned long xoff, in unsigned long yoff, in unsigned long width, in unsigned long height, in HTMLImageElement image); -JSValue JSCanvasRenderingContext3D::texSubImage2D(ExecState* exec, const ArgList& args) -{ - if (args.size() < 7 || args.size() > 9) - return throwError(exec, SyntaxError); - - CanvasRenderingContext3D* context = static_cast<CanvasRenderingContext3D*>(impl()); - unsigned target = args.at(0).toInt32(exec); - unsigned level = args.at(1).toInt32(exec); - unsigned xoff = args.at(2).toInt32(exec); - unsigned yoff = args.at(3).toInt32(exec); - unsigned width = args.at(4).toInt32(exec); - unsigned height = args.at(5).toInt32(exec); - - // The image parameter can be a <img> or <canvas> element. - JSValue value = args.at(6); - if (!value.isObject()) - return throwError(exec, TypeError); - JSObject* o = asObject(value); - - bool flipY = (args.size() > 3) ? args.at(3).toBoolean(exec) : false; - bool premultiplyAlpha = (args.size() > 4) ? args.at(3).toBoolean(exec) : false; - - ExceptionCode ec = 0; - if (o->inherits(&JSHTMLImageElement::s_info)) { - HTMLImageElement* imgElt = static_cast<HTMLImageElement*>(static_cast<JSHTMLElement*>(o)->impl()); - context->texSubImage2D(target, level, xoff, yoff, width, height, imgElt, flipY, premultiplyAlpha, ec); - } else if (o->inherits(&JSHTMLCanvasElement::s_info)) { - HTMLCanvasElement* canvas = static_cast<HTMLCanvasElement*>(static_cast<JSHTMLElement*>(o)->impl()); - context->texSubImage2D(target, level, xoff, yoff, width, height, canvas, flipY, premultiplyAlpha, ec); - } else { - setDOMException(exec, TYPE_MISMATCH_ERR); - } - - return jsUndefined(); -} - -template<typename T> -void toArray(JSC::ExecState* exec, JSC::JSValue value, T*& array, int& size) -{ - array = 0; - - if (!value.isObject()) - return; - - JSC::JSObject* object = asObject(value); - int length = object->get(exec, JSC::Identifier(exec, "length")).toInt32(exec); - void* tempValues; - if (!tryFastMalloc(length * sizeof(T)).getValue(tempValues)) - return; - - T* values = static_cast<T*>(tempValues); - for (int i = 0; i < length; ++i) { - JSC::JSValue v = object->get(exec, i); - if (exec->hadException()) - return; - values[i] = static_cast<T>(v.toNumber(exec)); - } - - array = values; - size = length; -} - -enum DataFunctionToCall { - f_uniform1v, f_uniform2v, f_uniform3v, f_uniform4v, - f_vertexAttrib1v, f_vertexAttrib2v, f_vertexAttrib3v, f_vertexAttrib4v -}; - -enum DataFunctionMatrixToCall { - f_uniformMatrix2fv, f_uniformMatrix3fv, f_uniformMatrix4fv -}; - -static JSC::JSValue dataFunctionf(DataFunctionToCall f, JSC::ExecState* exec, const JSC::ArgList& args, CanvasRenderingContext3D* context) -{ - if (args.size() != 2) - return throwError(exec, SyntaxError); - - long location = args.at(0).toInt32(exec); - if (exec->hadException()) - return jsUndefined(); - - RefPtr<CanvasFloatArray> canvasArray = toCanvasFloatArray(args.at(1)); - if (exec->hadException()) - return jsUndefined(); - - if (canvasArray) { - switch(f) { - case f_uniform1v: context->uniform1fv(location, canvasArray.get()); break; - case f_uniform2v: context->uniform2fv(location, canvasArray.get()); break; - case f_uniform3v: context->uniform3fv(location, canvasArray.get()); break; - case f_uniform4v: context->uniform4fv(location, canvasArray.get()); break; - case f_vertexAttrib1v: context->vertexAttrib1fv(location, canvasArray.get()); break; - case f_vertexAttrib2v: context->vertexAttrib2fv(location, canvasArray.get()); break; - case f_vertexAttrib3v: context->vertexAttrib3fv(location, canvasArray.get()); break; - case f_vertexAttrib4v: context->vertexAttrib4fv(location, canvasArray.get()); break; - } - return jsUndefined(); - } - - float* array; - int size; - toArray<float>(exec, args.at(1), array, size); - - if (!array) - return throwError(exec, TypeError); - - switch(f) { - case f_uniform1v: context->uniform1fv(location, array, size); break; - case f_uniform2v: context->uniform2fv(location, array, size); break; - case f_uniform3v: context->uniform3fv(location, array, size); break; - case f_uniform4v: context->uniform4fv(location, array, size); break; - case f_vertexAttrib1v: context->vertexAttrib1fv(location, array, size); break; - case f_vertexAttrib2v: context->vertexAttrib2fv(location, array, size); break; - case f_vertexAttrib3v: context->vertexAttrib3fv(location, array, size); break; - case f_vertexAttrib4v: context->vertexAttrib4fv(location, array, size); break; - } - return jsUndefined(); -} - -static JSC::JSValue dataFunctioni(DataFunctionToCall f, JSC::ExecState* exec, const JSC::ArgList& args, CanvasRenderingContext3D* context) -{ - if (args.size() != 2) - return throwError(exec, SyntaxError); - - long location = args.at(0).toInt32(exec); - if (exec->hadException()) - return jsUndefined(); - - RefPtr<CanvasIntArray> canvasArray = toCanvasIntArray(args.at(1)); - if (exec->hadException()) - return jsUndefined(); - - if (canvasArray) { - switch(f) { - case f_uniform1v: context->uniform1iv(location, canvasArray.get()); break; - case f_uniform2v: context->uniform2iv(location, canvasArray.get()); break; - case f_uniform3v: context->uniform3iv(location, canvasArray.get()); break; - case f_uniform4v: context->uniform4iv(location, canvasArray.get()); break; - default: break; - } - return jsUndefined(); - } - - int* array; - int size; - toArray<int>(exec, args.at(1), array, size); - - if (!array) - return throwError(exec, TypeError); - - switch(f) { - case f_uniform1v: context->uniform1iv(location, array, size); break; - case f_uniform2v: context->uniform2iv(location, array, size); break; - case f_uniform3v: context->uniform3iv(location, array, size); break; - case f_uniform4v: context->uniform4iv(location, array, size); break; - default: break; - } - return jsUndefined(); -} - -static JSC::JSValue dataFunctionMatrix(DataFunctionMatrixToCall f, JSC::ExecState* exec, const JSC::ArgList& args, CanvasRenderingContext3D* context) -{ - if (args.size() != 3) - return throwError(exec, SyntaxError); - - long location = args.at(0).toInt32(exec); - if (exec->hadException()) - return jsUndefined(); - - bool transpose = args.at(1).toBoolean(exec); - if (exec->hadException()) - return jsUndefined(); - - RefPtr<CanvasFloatArray> canvasArray = toCanvasFloatArray(args.at(2)); - if (exec->hadException()) - return jsUndefined(); - - if (canvasArray) { - switch(f) { - case f_uniformMatrix2fv: context->uniformMatrix2fv(location, transpose, canvasArray.get()); break; - case f_uniformMatrix3fv: context->uniformMatrix3fv(location, transpose, canvasArray.get()); break; - case f_uniformMatrix4fv: context->uniformMatrix4fv(location, transpose, canvasArray.get()); break; - } - return jsUndefined(); - } - - float* array; - int size; - toArray<float>(exec, args.at(2), array, size); - - if (!array) - return throwError(exec, TypeError); - - switch(f) { - case f_uniformMatrix2fv: context->uniformMatrix2fv(location, transpose, array, size); break; - case f_uniformMatrix3fv: context->uniformMatrix3fv(location, transpose, array, size); break; - case f_uniformMatrix4fv: context->uniformMatrix4fv(location, transpose, array, size); break; - } - return jsUndefined(); -} - -JSC::JSValue JSCanvasRenderingContext3D::uniform1fv(JSC::ExecState* exec, const JSC::ArgList& args) -{ - return dataFunctionf(f_uniform1v, exec, args, static_cast<CanvasRenderingContext3D*>(impl())); -} - -JSC::JSValue JSCanvasRenderingContext3D::uniform1iv(JSC::ExecState* exec, const JSC::ArgList& args) -{ - return dataFunctioni(f_uniform1v, exec, args, static_cast<CanvasRenderingContext3D*>(impl())); -} - -JSC::JSValue JSCanvasRenderingContext3D::uniform2fv(JSC::ExecState* exec, const JSC::ArgList& args) -{ - return dataFunctionf(f_uniform2v, exec, args, static_cast<CanvasRenderingContext3D*>(impl())); -} - -JSC::JSValue JSCanvasRenderingContext3D::uniform2iv(JSC::ExecState* exec, const JSC::ArgList& args) -{ - return dataFunctioni(f_uniform2v, exec, args, static_cast<CanvasRenderingContext3D*>(impl())); -} - -JSC::JSValue JSCanvasRenderingContext3D::uniform3fv(JSC::ExecState* exec, const JSC::ArgList& args) -{ - return dataFunctionf(f_uniform3v, exec, args, static_cast<CanvasRenderingContext3D*>(impl())); -} - -JSC::JSValue JSCanvasRenderingContext3D::uniform3iv(JSC::ExecState* exec, const JSC::ArgList& args) -{ - return dataFunctioni(f_uniform3v, exec, args, static_cast<CanvasRenderingContext3D*>(impl())); -} - -JSC::JSValue JSCanvasRenderingContext3D::uniform4fv(JSC::ExecState* exec, const JSC::ArgList& args) -{ - return dataFunctionf(f_uniform4v, exec, args, static_cast<CanvasRenderingContext3D*>(impl())); -} - -JSC::JSValue JSCanvasRenderingContext3D::uniform4iv(JSC::ExecState* exec, const JSC::ArgList& args) -{ - return dataFunctioni(f_uniform4v, exec, args, static_cast<CanvasRenderingContext3D*>(impl())); -} - -JSC::JSValue JSCanvasRenderingContext3D::uniformMatrix2fv(JSC::ExecState* exec, const JSC::ArgList& args) -{ - return dataFunctionMatrix(f_uniformMatrix2fv, exec, args, static_cast<CanvasRenderingContext3D*>(impl())); -} - -JSC::JSValue JSCanvasRenderingContext3D::uniformMatrix3fv(JSC::ExecState* exec, const JSC::ArgList& args) -{ - return dataFunctionMatrix(f_uniformMatrix3fv, exec, args, static_cast<CanvasRenderingContext3D*>(impl())); -} - -JSC::JSValue JSCanvasRenderingContext3D::uniformMatrix4fv(JSC::ExecState* exec, const JSC::ArgList& args) -{ - return dataFunctionMatrix(f_uniformMatrix4fv, exec, args, static_cast<CanvasRenderingContext3D*>(impl())); -} - -JSC::JSValue JSCanvasRenderingContext3D::vertexAttrib1fv(JSC::ExecState* exec, const JSC::ArgList& args) -{ - return dataFunctionf(f_vertexAttrib1v, exec, args, static_cast<CanvasRenderingContext3D*>(impl())); -} - -JSC::JSValue JSCanvasRenderingContext3D::vertexAttrib2fv(JSC::ExecState* exec, const JSC::ArgList& args) -{ - return dataFunctionf(f_vertexAttrib2v, exec, args, static_cast<CanvasRenderingContext3D*>(impl())); -} - -JSC::JSValue JSCanvasRenderingContext3D::vertexAttrib3fv(JSC::ExecState* exec, const JSC::ArgList& args) -{ - return dataFunctionf(f_vertexAttrib3v, exec, args, static_cast<CanvasRenderingContext3D*>(impl())); -} - -JSC::JSValue JSCanvasRenderingContext3D::vertexAttrib4fv(JSC::ExecState* exec, const JSC::ArgList& args) -{ - return dataFunctionf(f_vertexAttrib4v, exec, args, static_cast<CanvasRenderingContext3D*>(impl())); -} - -} // namespace WebCore - -#endif // ENABLE(3D_CANVAS) diff --git a/WebCore/bindings/js/JSCanvasRenderingContextCustom.cpp b/WebCore/bindings/js/JSCanvasRenderingContextCustom.cpp index 0cd2aa3..df24eb7 100644 --- a/WebCore/bindings/js/JSCanvasRenderingContextCustom.cpp +++ b/WebCore/bindings/js/JSCanvasRenderingContextCustom.cpp @@ -29,8 +29,8 @@ #include "CanvasRenderingContext2D.h" #include "JSCanvasRenderingContext2D.h" #if ENABLE(3D_CANVAS) -#include "CanvasRenderingContext3D.h" -#include "JSCanvasRenderingContext3D.h" +#include "WebGLRenderingContext.h" +#include "JSWebGLRenderingContext.h" #endif using namespace JSC; @@ -44,7 +44,7 @@ JSC::JSValue toJS(JSC::ExecState* exec, JSDOMGlobalObject* globalObject, CanvasR #if ENABLE(3D_CANVAS) if (object->is3d()) - return getDOMObjectWrapper<JSCanvasRenderingContext3D>(exec, globalObject, static_cast<CanvasRenderingContext3D*>(object)); + return getDOMObjectWrapper<JSWebGLRenderingContext>(exec, globalObject, static_cast<WebGLRenderingContext*>(object)); #endif ASSERT(object->is2d()); return getDOMObjectWrapper<JSCanvasRenderingContext2D>(exec, globalObject, static_cast<CanvasRenderingContext2D*>(object)); diff --git a/WebCore/bindings/js/JSCanvasUnsignedShortArrayConstructor.h b/WebCore/bindings/js/JSCanvasUnsignedShortArrayConstructor.h deleted file mode 100644 index 23c197f..0000000 --- a/WebCore/bindings/js/JSCanvasUnsignedShortArrayConstructor.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (C) 2009 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef JSCanvasUnsignedShortArrayConstructor_h -#define JSCanvasUnsignedShortArrayConstructor_h - -#include "JSDOMBinding.h" -#include "JSDocument.h" - -namespace WebCore { - - class JSCanvasUnsignedShortArrayConstructor : public DOMConstructorObject { - public: - JSCanvasUnsignedShortArrayConstructor(JSC::ExecState*, JSDOMGlobalObject*); - static const JSC::ClassInfo s_info; - - private: - virtual JSC::ConstructType getConstructData(JSC::ConstructData&); - virtual const JSC::ClassInfo* classInfo() const { return &s_info; } - }; - -} - -#endif // JSCanvasUnsignedShortArrayConstructor_h diff --git a/WebCore/bindings/js/JSConsoleCustom.cpp b/WebCore/bindings/js/JSConsoleCustom.cpp index 9c48467..8366b39 100644 --- a/WebCore/bindings/js/JSConsoleCustom.cpp +++ b/WebCore/bindings/js/JSConsoleCustom.cpp @@ -26,6 +26,7 @@ #include "config.h" #include "JSConsole.h" #include "JavaScriptProfile.h" +#include "ScriptCallStack.h" #include <runtime/JSArray.h> #include "Console.h" @@ -50,6 +51,22 @@ JSValue JSConsole::profiles(ExecState* exec) const return constructArray(exec, list); } +JSValue JSConsole::profile(ExecState* exec, const ArgList& args) +{ + ScriptCallStack callStack(exec, args, 1); + const UString title = valueToStringWithUndefinedOrNullCheck(exec, args.at(0)); + impl()->profile(title, &callStack); + return jsUndefined(); +} + +JSValue JSConsole::profileEnd(ExecState* exec, const ArgList& args) +{ + ScriptCallStack callStack(exec, args, 1); + const UString title = valueToStringWithUndefinedOrNullCheck(exec, args.at(0)); + impl()->profileEnd(title, &callStack); + return jsUndefined(); +} + #endif } // namespace WebCore diff --git a/WebCore/bindings/js/JSCustomXPathNSResolver.cpp b/WebCore/bindings/js/JSCustomXPathNSResolver.cpp index c2884d7..07cfc74 100644 --- a/WebCore/bindings/js/JSCustomXPathNSResolver.cpp +++ b/WebCore/bindings/js/JSCustomXPathNSResolver.cpp @@ -90,7 +90,7 @@ String JSCustomXPathNSResolver::lookupNamespaceURI(const String& prefix) args.append(jsString(exec, prefix)); m_globalObject->globalData()->timeoutChecker.start(); - JSValue retval = callInWorld(exec, function, callType, callData, m_customResolver, args, currentWorld(m_globalObject->globalExec())); + JSValue retval = JSC::call(exec, function, callType, callData, m_customResolver, args); m_globalObject->globalData()->timeoutChecker.stop(); String result; diff --git a/WebCore/bindings/js/JSDOMBinding.cpp b/WebCore/bindings/js/JSDOMBinding.cpp index ef69c7b..f12c779 100644 --- a/WebCore/bindings/js/JSDOMBinding.cpp +++ b/WebCore/bindings/js/JSDOMBinding.cpp @@ -45,6 +45,7 @@ #include "KURL.h" #include "MessagePort.h" #include "RangeException.h" +#include "ScriptCachedFrameData.h" #include "ScriptController.h" #include "Settings.h" #include "XMLHttpRequestException.h" @@ -167,29 +168,6 @@ DOMWrapperWorld::~DOMWrapperWorld() for (HashSet<Document*>::iterator iter = documentsWithWrappers.begin(); iter != documentsWithWrappers.end(); ++iter) forgetWorldOfDOMNodesForDocument(*iter, this); - for (HashSet<ScriptController*>::iterator iter = scriptControllersWithShells.begin(); iter != scriptControllersWithShells.end(); ++iter) - (*iter)->forgetWorld(this); -} - -EnterDOMWrapperWorld::EnterDOMWrapperWorld(JSC::JSGlobalData& globalData, DOMWrapperWorld* isolatedWorld) -{ - JSGlobalData::ClientData* clientData = globalData.clientData; - ASSERT(clientData); - m_clientData = static_cast<WebCoreJSClientData*>(clientData); - m_clientData->m_worldStack.append(isolatedWorld); -} - -EnterDOMWrapperWorld::EnterDOMWrapperWorld(JSC::ExecState* exec, DOMWrapperWorld* isolatedWorld) -{ - JSGlobalData::ClientData* clientData = exec->globalData().clientData; - ASSERT(clientData); - m_clientData = static_cast<WebCoreJSClientData*>(clientData); - m_clientData->m_worldStack.append(isolatedWorld); -} - -EnterDOMWrapperWorld::~EnterDOMWrapperWorld() -{ - m_clientData->m_worldStack.removeLast(); } class JSGlobalDataWorldIterator { @@ -228,16 +206,9 @@ private: HashSet<DOMWrapperWorld*>::iterator m_end; }; -static inline DOMWrapperWorld* currentWorld(JSC::JSGlobalData& globalData) -{ - JSGlobalData::ClientData* clientData = globalData.clientData; - ASSERT(clientData); - return static_cast<WebCoreJSClientData*>(clientData)->currentWorld(); -} - DOMWrapperWorld* currentWorld(JSC::ExecState* exec) { - return currentWorld(exec->globalData()); + return static_cast<JSDOMGlobalObject*>(exec->lexicalGlobalObject())->world(); } DOMWrapperWorld* normalWorld(JSC::JSGlobalData& globalData) @@ -250,16 +221,8 @@ DOMWrapperWorld* normalWorld(JSC::JSGlobalData& globalData) DOMWrapperWorld* mainThreadNormalWorld() { ASSERT(isMainThread()); - return normalWorld(*JSDOMWindow::commonJSGlobalData()); -} - -DOMWrapperWorld* mainThreadCurrentWorld() -{ - ASSERT(isMainThread()); - - JSGlobalData::ClientData* clientData = JSDOMWindowBase::commonJSGlobalData()->clientData; - ASSERT(clientData); - return static_cast<WebCoreJSClientData*>(clientData)->currentWorld(); + static DOMWrapperWorld* cachedNormalWorld = normalWorld(*JSDOMWindow::commonJSGlobalData()); + return cachedNormalWorld; } DOMObjectHashTableMap& DOMObjectHashTableMap::mapFor(JSGlobalData& globalData) @@ -274,28 +237,49 @@ const JSC::HashTable* getHashTableForGlobalData(JSGlobalData& globalData, const return DOMObjectHashTableMap::mapFor(globalData).get(staticTable); } -//inline DOMObjectWrapperMap& DOMObjectWrapperMap::mapFor(JSGlobalData& globalData) -inline DOMObjectWrapperMap& DOMObjectWrapperMapFor(JSGlobalData& globalData) +static inline DOMObjectWrapperMap& DOMObjectWrapperMapFor(JSC::ExecState* exec) { - return currentWorld(globalData)->m_wrappers; + return currentWorld(exec)->m_wrappers; } -DOMObject* getCachedDOMObjectWrapper(JSGlobalData& globalData, void* objectHandle) +bool hasCachedDOMObjectWrapper(JSGlobalData* globalData, void* objectHandle) { - return DOMObjectWrapperMapFor(globalData).get(objectHandle); + for (JSGlobalDataWorldIterator worldIter(globalData); worldIter; ++worldIter) { + if (worldIter->m_wrappers.contains(objectHandle)) + return true; + } + return false; } -void cacheDOMObjectWrapper(JSGlobalData& globalData, void* objectHandle, DOMObject* wrapper) +DOMObject* getCachedDOMObjectWrapper(JSC::ExecState* exec, void* objectHandle) +{ + return DOMObjectWrapperMapFor(exec).get(objectHandle); +} + +void cacheDOMObjectWrapper(JSC::ExecState* exec, void* objectHandle, DOMObject* wrapper) { addWrapper(wrapper); - DOMObjectWrapperMapFor(globalData).set(objectHandle, wrapper); + DOMObjectWrapperMapFor(exec).set(objectHandle, wrapper); +} + +bool hasCachedDOMNodeWrapper(Document* document, Node* node) +{ + if (!document) + return hasCachedDOMObjectWrapper(JSDOMWindow::commonJSGlobalData(), node); + + JSWrapperCacheMap& wrapperCacheMap = document->wrapperCacheMap(); + for (JSWrapperCacheMap::iterator iter = wrapperCacheMap.begin(); iter != wrapperCacheMap.end(); ++iter) { + if (iter->second->contains(node)) + return true; + } + return false; } -JSNode* getCachedDOMNodeWrapper(Document* document, Node* node) +JSNode* getCachedDOMNodeWrapper(JSC::ExecState* exec, Document* document, Node* node) { if (document) - return document->getWrapperCache(mainThreadCurrentWorld())->get(node); - return static_cast<JSNode*>(DOMObjectWrapperMapFor(*JSDOMWindow::commonJSGlobalData()).get(node)); + return document->getWrapperCache(currentWorld(exec))->get(node); + return static_cast<JSNode*>(DOMObjectWrapperMapFor(exec).get(node)); } void forgetDOMObject(DOMObject* wrapper, void* objectHandle) @@ -337,15 +321,15 @@ void forgetDOMNode(DOMObject* wrapper, Node* node, Document* document) ASSERT(!wrapperSet().contains(wrapper)); } -void cacheDOMNodeWrapper(Document* document, Node* node, JSNode* wrapper) +void cacheDOMNodeWrapper(JSC::ExecState* exec, Document* document, Node* node, JSNode* wrapper) { if (!document) { addWrapper(wrapper); - DOMObjectWrapperMapFor(*JSDOMWindow::commonJSGlobalData()).set(node, wrapper); + DOMObjectWrapperMapFor(exec).set(node, wrapper); return; } addWrapper(wrapper); - document->getWrapperCache(mainThreadCurrentWorld())->set(node, wrapper); + document->getWrapperCache(currentWorld(exec))->set(node, wrapper); } void forgetAllDOMNodesForDocument(Document* document) @@ -537,6 +521,23 @@ void markDOMObjectWrapper(MarkStack& markStack, JSGlobalData& globalData, void* } } +void markDOMNodeWrapper(MarkStack& markStack, Document* document, Node* node) +{ + if (document) { + JSWrapperCacheMap& wrapperCacheMap = document->wrapperCacheMap(); + for (JSWrapperCacheMap::iterator iter = wrapperCacheMap.begin(); iter != wrapperCacheMap.end(); ++iter) { + if (JSNode* wrapper = iter->second->get(node)) + markStack.append(wrapper); + } + return; + } + + for (JSGlobalDataWorldIterator worldIter(JSDOMWindow::commonJSGlobalData()); worldIter; ++worldIter) { + if (DOMObject* wrapper = worldIter->m_wrappers.get(node)) + markStack.append(wrapper); + } +} + JSValue jsStringOrNull(ExecState* exec, const String& s) { if (s.isNull()) @@ -810,28 +811,4 @@ bool DOMObject::defineOwnProperty(ExecState* exec, const Identifier&, PropertyDe return false; } -JSValue DebuggerCallFrame_evaluateInWorld(const JSC::DebuggerCallFrame& debuggerCallFrame, const UString& script, JSValue& exception) -{ - EnterDOMWrapperWorld worldEntry(debuggerCallFrame.dynamicGlobalObject()->globalExec(), debuggerWorld()); - return debuggerCallFrame.evaluate(script, exception); -} - -JSValue callInWorld(ExecState* exec, JSValue function, CallType callType, const CallData& callData, JSValue thisValue, const ArgList& args, DOMWrapperWorld* isolatedWorld) -{ - EnterDOMWrapperWorld worldEntry(exec, isolatedWorld); - return JSC::call(exec, function, callType, callData, thisValue, args); -} - -JSObject* constructInWorld(ExecState* exec, JSValue object, ConstructType constructType, const ConstructData& constructData, const ArgList& args, DOMWrapperWorld* isolatedWorld) -{ - EnterDOMWrapperWorld worldEntry(exec, isolatedWorld); - return JSC::construct(exec, object, constructType, constructData, args); -} - -Completion evaluateInWorld(ExecState* exec, ScopeChain& scopeChain, const SourceCode& sourceCode, JSValue thisValue, DOMWrapperWorld* isolatedWorld) -{ - EnterDOMWrapperWorld worldEntry(exec, isolatedWorld); - return JSC::evaluate(exec, scopeChain, sourceCode, thisValue); -} - } // namespace WebCore diff --git a/WebCore/bindings/js/JSDOMBinding.h b/WebCore/bindings/js/JSDOMBinding.h index ba41d85..3982dad 100644 --- a/WebCore/bindings/js/JSDOMBinding.h +++ b/WebCore/bindings/js/JSDOMBinding.h @@ -42,6 +42,7 @@ namespace WebCore { class Node; class String; class ScriptController; + class ScriptCachedFrameData; typedef int ExceptionCode; @@ -147,8 +148,6 @@ namespace WebCore { void rememberDocument(Document* document) { documentsWithWrappers.add(document); } void forgetDocument(Document* document) { documentsWithWrappers.remove(document); } - void rememberScriptController(ScriptController* scriptController) { scriptControllersWithShells.add(scriptController); } - void forgetScriptController(ScriptController* scriptController) { scriptControllersWithShells.remove(scriptController); } // FIXME: can we make this private? DOMObjectWrapperMap m_wrappers; @@ -156,7 +155,6 @@ namespace WebCore { private: JSC::JSGlobalData* m_globalData; HashSet<Document*> documentsWithWrappers; - HashSet<ScriptController*> scriptControllersWithShells; }; // Map from static HashTable instances to per-GlobalData ones. @@ -184,21 +182,23 @@ namespace WebCore { }; class WebCoreJSClientData : public JSC::JSGlobalData::ClientData { - friend class EnterDOMWrapperWorld; friend class JSGlobalDataWorldIterator; public: WebCoreJSClientData(JSC::JSGlobalData* globalData) : m_normalWorld(globalData) { - m_worldStack.append(&m_normalWorld); m_worldSet.add(&m_normalWorld); } // FIXME: add a destructor to assert m_worldSet only contains m_normalWorld? - DOMWrapperWorld* currentWorld() { return m_worldStack.last(); } DOMWrapperWorld* normalWorld() { return &m_normalWorld; } + void getAllWorlds(Vector<DOMWrapperWorld*>& worlds) + { + copyToVector(m_worldSet, worlds); + } + void rememberWorld(DOMWrapperWorld* world) { ASSERT(!m_worldSet.contains(world)); @@ -212,34 +212,26 @@ namespace WebCore { DOMObjectHashTableMap hashTableMap; private: - Vector<DOMWrapperWorld*> m_worldStack; HashSet<DOMWrapperWorld*> m_worldSet; DOMWrapperWorld m_normalWorld; }; - class EnterDOMWrapperWorld { - public: - EnterDOMWrapperWorld(JSC::JSGlobalData&, DOMWrapperWorld*); - EnterDOMWrapperWorld(JSC::ExecState*, DOMWrapperWorld*); - ~EnterDOMWrapperWorld(); - - private: - WebCoreJSClientData* m_clientData; - }; - - DOMObject* getCachedDOMObjectWrapper(JSC::JSGlobalData&, void* objectHandle); - void cacheDOMObjectWrapper(JSC::JSGlobalData&, void* objectHandle, DOMObject* wrapper); + bool hasCachedDOMObjectWrapper(JSC::JSGlobalData*, void* objectHandle); + DOMObject* getCachedDOMObjectWrapper(JSC::ExecState*, void* objectHandle); + void cacheDOMObjectWrapper(JSC::ExecState*, void* objectHandle, DOMObject* wrapper); void forgetDOMNode(DOMObject* wrapper, Node* node, Document* document); void forgetDOMObject(DOMObject* wrapper, void* objectHandle); - JSNode* getCachedDOMNodeWrapper(Document*, Node*); - void cacheDOMNodeWrapper(Document*, Node*, JSNode* wrapper); + bool hasCachedDOMNodeWrapper(Document*, Node*); + JSNode* getCachedDOMNodeWrapper(JSC::ExecState*, Document*, Node*); + void cacheDOMNodeWrapper(JSC::ExecState*, Document*, Node*, JSNode* wrapper); void forgetAllDOMNodesForDocument(Document*); void forgetWorldOfDOMNodesForDocument(Document*, DOMWrapperWorld*); void updateDOMNodeDocument(Node*, Document* oldDocument, Document* newDocument); void markDOMNodesForDocument(JSC::MarkStack&, Document*); void markActiveObjectsForContext(JSC::MarkStack&, JSC::JSGlobalData&, ScriptExecutionContext*); void markDOMObjectWrapper(JSC::MarkStack&, JSC::JSGlobalData& globalData, void* object); + void markDOMNodeWrapper(JSC::MarkStack& markStack, Document* document, Node* node); JSC::Structure* getCachedDOMStructure(JSDOMGlobalObject*, const JSC::ClassInfo*); JSC::Structure* cacheDOMStructure(JSDOMGlobalObject*, NonNullPassRefPtr<JSC::Structure>, const JSC::ClassInfo*); @@ -248,7 +240,6 @@ namespace WebCore { DOMWrapperWorld* currentWorld(JSC::ExecState*); DOMWrapperWorld* normalWorld(JSC::JSGlobalData&); - DOMWrapperWorld* mainThreadCurrentWorld(); DOMWrapperWorld* mainThreadNormalWorld(); inline DOMWrapperWorld* debuggerWorld() { return mainThreadNormalWorld(); } inline DOMWrapperWorld* pluginWorld() { return mainThreadNormalWorld(); } @@ -283,17 +274,17 @@ namespace WebCore { template<class WrapperClass, class DOMClass> inline DOMObject* createDOMObjectWrapper(JSC::ExecState* exec, JSDOMGlobalObject* globalObject, DOMClass* object) { ASSERT(object); - ASSERT(!getCachedDOMObjectWrapper(exec->globalData(), object)); + ASSERT(!getCachedDOMObjectWrapper(exec, object)); // FIXME: new (exec) could use a different globalData than the globalData this wrapper is cached on. WrapperClass* wrapper = new (exec) WrapperClass(getDOMStructure<WrapperClass>(exec, globalObject), globalObject, object); - cacheDOMObjectWrapper(exec->globalData(), object, wrapper); + cacheDOMObjectWrapper(exec, object, wrapper); return wrapper; } template<class WrapperClass, class DOMClass> inline JSC::JSValue getDOMObjectWrapper(JSC::ExecState* exec, JSDOMGlobalObject* globalObject, DOMClass* object) { if (!object) return JSC::jsNull(); - if (DOMObject* wrapper = getCachedDOMObjectWrapper(exec->globalData(), object)) + if (DOMObject* wrapper = getCachedDOMObjectWrapper(exec, object)) return wrapper; return createDOMObjectWrapper<WrapperClass>(exec, globalObject, object); } @@ -303,16 +294,16 @@ namespace WebCore { template<class WrapperClass, class DOMClass> inline DOMObject* createDOMObjectWrapper(JSC::ExecState* exec, JSDOMGlobalObject* globalObject, DOMClass* object, SVGElement* context) { ASSERT(object); - ASSERT(!getCachedDOMObjectWrapper(exec->globalData(), object)); + ASSERT(!getCachedDOMObjectWrapper(exec, object)); WrapperClass* wrapper = new (exec) WrapperClass(getDOMStructure<WrapperClass>(exec, globalObject), globalObject, object, context); - cacheDOMObjectWrapper(exec->globalData(), object, wrapper); + cacheDOMObjectWrapper(exec, object, wrapper); return wrapper; } template<class WrapperClass, class DOMClass> inline JSC::JSValue getDOMObjectWrapper(JSC::ExecState* exec, JSDOMGlobalObject* globalObject, DOMClass* object, SVGElement* context) { if (!object) return JSC::jsNull(); - if (DOMObject* wrapper = getCachedDOMObjectWrapper(exec->globalData(), object)) + if (DOMObject* wrapper = getCachedDOMObjectWrapper(exec, object)) return wrapper; return createDOMObjectWrapper<WrapperClass>(exec, globalObject, object, context); } @@ -322,18 +313,18 @@ namespace WebCore { template<class WrapperClass, class DOMClass> inline JSNode* createDOMNodeWrapper(JSC::ExecState* exec, JSDOMGlobalObject* globalObject, DOMClass* node) { ASSERT(node); - ASSERT(!getCachedDOMNodeWrapper(node->document(), node)); + ASSERT(!getCachedDOMNodeWrapper(exec, node->document(), node)); WrapperClass* wrapper = new (exec) WrapperClass(getDOMStructure<WrapperClass>(exec, globalObject), globalObject, node); // FIXME: The entire function can be removed, once we fix caching. // This function is a one-off hack to make Nodes cache in the right global object. - cacheDOMNodeWrapper(node->document(), node, wrapper); + cacheDOMNodeWrapper(exec, node->document(), node, wrapper); return wrapper; } template<class WrapperClass, class DOMClass> inline JSC::JSValue getDOMNodeWrapper(JSC::ExecState* exec, JSDOMGlobalObject* globalObject, DOMClass* node) { if (!node) return JSC::jsNull(); - if (JSNode* wrapper = getCachedDOMNodeWrapper(node->document(), node)) + if (JSNode* wrapper = getCachedDOMNodeWrapper(exec, node->document(), node)) return wrapper; return createDOMNodeWrapper<WrapperClass>(exec, globalObject, node); } @@ -404,11 +395,6 @@ namespace WebCore { bool processingUserGesture(JSC::ExecState*); KURL completeURL(JSC::ExecState*, const String& relativeURL); - JSC::JSValue DebuggerCallFrame_evaluateInWorld(const JSC::DebuggerCallFrame& debuggerCallFrame, const JSC::UString& script, JSC::JSValue& exception); - JSC::JSValue callInWorld(JSC::ExecState*, JSC::JSValue function, JSC::CallType, const JSC::CallData&, JSC::JSValue thisValue, const JSC::ArgList&, DOMWrapperWorld*); - JSC::JSObject* constructInWorld(JSC::ExecState* exec, JSC::JSValue object, JSC::ConstructType constructType, const JSC::ConstructData& constructData, const JSC::ArgList& args, DOMWrapperWorld*); - JSC::Completion evaluateInWorld(JSC::ExecState*, JSC::ScopeChain&, const JSC::SourceCode&, JSC::JSValue thisValue, DOMWrapperWorld*); - } // namespace WebCore #endif // JSDOMBinding_h diff --git a/WebCore/bindings/js/JSDOMGlobalObject.h b/WebCore/bindings/js/JSDOMGlobalObject.h index 6b75a6f..647730c 100644 --- a/WebCore/bindings/js/JSDOMGlobalObject.h +++ b/WebCore/bindings/js/JSDOMGlobalObject.h @@ -66,17 +66,14 @@ namespace WebCore { virtual void markChildren(JSC::MarkStack&); + DOMWrapperWorld* world() { return d()->m_world.get(); } + protected: struct JSDOMGlobalObjectData : public JSC::JSGlobalObject::JSGlobalObjectData { - JSDOMGlobalObjectData() - : JSGlobalObjectData(destroyJSDOMGlobalObjectData) - , evt(0) - { - } - - JSDOMGlobalObjectData(Destructor destructor) + JSDOMGlobalObjectData(DOMWrapperWorld* world, Destructor destructor = destroyJSDOMGlobalObjectData) : JSGlobalObjectData(destructor) , evt(0) + , m_world(world) { } @@ -84,6 +81,7 @@ namespace WebCore { JSDOMConstructorMap constructors; Event* evt; + RefPtr<DOMWrapperWorld> m_world; }; private: diff --git a/WebCore/bindings/js/JSDOMWindowBase.cpp b/WebCore/bindings/js/JSDOMWindowBase.cpp index 86ff149..e3af13f 100644 --- a/WebCore/bindings/js/JSDOMWindowBase.cpp +++ b/WebCore/bindings/js/JSDOMWindowBase.cpp @@ -42,6 +42,13 @@ namespace WebCore { const ClassInfo JSDOMWindowBase::s_info = { "Window", 0, 0, 0 }; +JSDOMWindowBase::JSDOMWindowBaseData::JSDOMWindowBaseData(PassRefPtr<DOMWindow> window, JSDOMWindowShell* shell) + : JSDOMGlobalObjectData(shell->world(), destroyJSDOMWindowBaseData) + , impl(window) + , shell(shell) +{ +} + JSDOMWindowBase::JSDOMWindowBase(NonNullPassRefPtr<Structure> structure, PassRefPtr<DOMWindow> window, JSDOMWindowShell* shell) : JSDOMGlobalObject(structure, new JSDOMWindowBaseData(window, shell), shell) { @@ -53,11 +60,10 @@ JSDOMWindowBase::JSDOMWindowBase(NonNullPassRefPtr<Structure> structure, PassRef addStaticGlobals(staticGlobals, sizeof(staticGlobals) / sizeof(GlobalPropertyInfo)); } -void JSDOMWindowBase::updateDocument(DOMWrapperWorld* world) +void JSDOMWindowBase::updateDocument() { ASSERT(d()->impl->document()); ExecState* exec = globalExec(); - EnterDOMWrapperWorld worldEntry(exec, world); symbolTablePutWithAttributes(Identifier(exec, "document"), toJS(exec, this, d()->impl->document()), DontDelete | ReadOnly); } diff --git a/WebCore/bindings/js/JSDOMWindowBase.h b/WebCore/bindings/js/JSDOMWindowBase.h index 31e2486..66af344 100644 --- a/WebCore/bindings/js/JSDOMWindowBase.h +++ b/WebCore/bindings/js/JSDOMWindowBase.h @@ -47,7 +47,7 @@ namespace WebCore { JSDOMWindowBase(NonNullPassRefPtr<JSC::Structure>, PassRefPtr<DOMWindow>, JSDOMWindowShell*); public: - void updateDocument(DOMWrapperWorld*); + void updateDocument(); DOMWindow* impl() const { return d()->impl.get(); } virtual ScriptExecutionContext* scriptExecutionContext() const; @@ -77,12 +77,7 @@ namespace WebCore { private: struct JSDOMWindowBaseData : public JSDOMGlobalObjectData { - JSDOMWindowBaseData(PassRefPtr<DOMWindow> window, JSDOMWindowShell* shell) - : JSDOMGlobalObjectData(destroyJSDOMWindowBaseData) - , impl(window) - , shell(shell) - { - } + JSDOMWindowBaseData(PassRefPtr<DOMWindow> window, JSDOMWindowShell* shell); RefPtr<DOMWindow> impl; JSDOMWindowShell* shell; diff --git a/WebCore/bindings/js/JSDOMWindowCustom.cpp b/WebCore/bindings/js/JSDOMWindowCustom.cpp index 2804b3c..66fe926 100644 --- a/WebCore/bindings/js/JSDOMWindowCustom.cpp +++ b/WebCore/bindings/js/JSDOMWindowCustom.cpp @@ -53,14 +53,14 @@ #endif #if ENABLE(3D_CANVAS) -#include "JSCanvasArrayBufferConstructor.h" -#include "JSCanvasByteArrayConstructor.h" -#include "JSCanvasUnsignedByteArrayConstructor.h" -#include "JSCanvasIntArrayConstructor.h" -#include "JSCanvasUnsignedIntArrayConstructor.h" -#include "JSCanvasShortArrayConstructor.h" -#include "JSCanvasUnsignedShortArrayConstructor.h" -#include "JSCanvasFloatArrayConstructor.h" +#include "JSWebGLArrayBufferConstructor.h" +#include "JSWebGLByteArrayConstructor.h" +#include "JSWebGLUnsignedByteArrayConstructor.h" +#include "JSWebGLIntArrayConstructor.h" +#include "JSWebGLUnsignedIntArrayConstructor.h" +#include "JSWebGLShortArrayConstructor.h" +#include "JSWebGLUnsignedShortArrayConstructor.h" +#include "JSWebGLFloatArrayConstructor.h" #endif #include "JSWebKitCSSMatrixConstructor.h" #include "JSWebKitPointConstructor.h" @@ -297,10 +297,10 @@ bool JSDOMWindow::getOwnPropertySlot(ExecState* exec, const Identifier& property bool JSDOMWindow::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor) { - // When accessing a Window cross-domain, functions are always the native built-in ones, and they - // are not affected by properties changed on the Window or anything in its prototype chain. - // This is consistent with the behavior of Firefox. - + // Never allow cross-domain getOwnPropertyDescriptor + if (!allowsAccessFrom(exec)) + return false; + const HashEntry* entry; // We don't want any properties other than "close" and "closed" on a closed window. @@ -323,11 +323,6 @@ bool JSDOMWindow::getOwnPropertyDescriptor(ExecState* exec, const Identifier& pr return true; } - String errorMessage; - bool allowsAccess = allowsAccessFrom(exec, errorMessage); - if (allowsAccess && JSGlobalObject::getOwnPropertyDescriptor(exec, propertyName, descriptor)) - return true; - // We need this code here because otherwise JSDOMWindowBase will stop the search before we even get to the // prototype due to the blanket same origin (allowsAccessFrom) check at the end of getOwnPropertySlot. // Also, it's important to get the implementation straight out of the DOMWindow prototype regardless of @@ -335,51 +330,13 @@ bool JSDOMWindow::getOwnPropertyDescriptor(ExecState* exec, const Identifier& pr entry = JSDOMWindowPrototype::s_info.propHashTable(exec)->entry(exec, propertyName); if (entry) { if (entry->attributes() & Function) { - if (entry->function() == jsDOMWindowPrototypeFunctionBlur) { - if (!allowsAccess) { - PropertySlot slot; - slot.setCustom(this, nonCachingStaticFunctionGetter<jsDOMWindowPrototypeFunctionBlur, 0>); - descriptor.setDescriptor(slot.getValue(exec, propertyName), ReadOnly | DontDelete | DontEnum); - return true; - } - } else if (entry->function() == jsDOMWindowPrototypeFunctionClose) { - if (!allowsAccess) { - PropertySlot slot; - slot.setCustom(this, nonCachingStaticFunctionGetter<jsDOMWindowPrototypeFunctionClose, 0>); - descriptor.setDescriptor(slot.getValue(exec, propertyName), ReadOnly | DontDelete | DontEnum); - return true; - } - } else if (entry->function() == jsDOMWindowPrototypeFunctionFocus) { - if (!allowsAccess) { - PropertySlot slot; - slot.setCustom(this, nonCachingStaticFunctionGetter<jsDOMWindowPrototypeFunctionFocus, 0>); - descriptor.setDescriptor(slot.getValue(exec, propertyName), ReadOnly | DontDelete | DontEnum); - return true; - } - } else if (entry->function() == jsDOMWindowPrototypeFunctionPostMessage) { - if (!allowsAccess) { - PropertySlot slot; - slot.setCustom(this, nonCachingStaticFunctionGetter<jsDOMWindowPrototypeFunctionPostMessage, 2>); - descriptor.setDescriptor(slot.getValue(exec, propertyName), ReadOnly | DontDelete | DontEnum); - return true; - } - } else if (entry->function() == jsDOMWindowPrototypeFunctionShowModalDialog) { + if (entry->function() == jsDOMWindowPrototypeFunctionShowModalDialog) { if (!DOMWindow::canShowModalDialog(impl()->frame())) { descriptor.setUndefined(); return true; } } } - } else { - // Allow access to toString() cross-domain, but always Object.prototype.toString. - if (propertyName == exec->propertyNames().toString) { - if (!allowsAccess) { - PropertySlot slot; - slot.setCustom(this, objectToStringFunctionGetter); - descriptor.setDescriptor(slot.getValue(exec, propertyName), ReadOnly | DontDelete | DontEnum); - return true; - } - } } entry = JSDOMWindow::s_info.propHashTable(exec)->entry(exec, propertyName); @@ -406,13 +363,8 @@ bool JSDOMWindow::getOwnPropertyDescriptor(ExecState* exec, const Identifier& pr // precedence over the index and name getters. JSValue proto = prototype(); if (proto.isObject()) { - if (asObject(proto)->getPropertyDescriptor(exec, propertyName, descriptor)) { - if (!allowsAccess) { - printErrorMessage(errorMessage); - descriptor.setUndefined(); - } + if (asObject(proto)->getPropertyDescriptor(exec, propertyName, descriptor)) return true; - } } bool ok; @@ -482,14 +434,6 @@ void JSDOMWindow::getOwnPropertyNames(ExecState* exec, PropertyNameArray& proper Base::getOwnPropertyNames(exec, propertyNames); } -bool JSDOMWindow::getPropertyAttributes(ExecState* exec, const Identifier& propertyName, unsigned& attributes) const -{ - // Only allow getting property attributes properties by frames in the same origin. - if (!allowsAccessFrom(exec)) - return false; - return Base::getPropertyAttributes(exec, propertyName, attributes); -} - void JSDOMWindow::defineGetter(ExecState* exec, const Identifier& propertyName, JSObject* getterFunction, unsigned attributes) { // Only allow defining getters by frames in the same origin. @@ -540,24 +484,24 @@ JSValue JSDOMWindow::lookupSetter(ExecState* exec, const Identifier& propertyNam JSValue JSDOMWindow::history(ExecState* exec) const { History* history = impl()->history(); - if (DOMObject* wrapper = getCachedDOMObjectWrapper(exec->globalData(), history)) + if (DOMObject* wrapper = getCachedDOMObjectWrapper(exec, history)) return wrapper; JSDOMWindow* window = const_cast<JSDOMWindow*>(this); JSHistory* jsHistory = new (exec) JSHistory(getDOMStructure<JSHistory>(exec, window), window, history); - cacheDOMObjectWrapper(exec->globalData(), history, jsHistory); + cacheDOMObjectWrapper(exec, history, jsHistory); return jsHistory; } JSValue JSDOMWindow::location(ExecState* exec) const { Location* location = impl()->location(); - if (DOMObject* wrapper = getCachedDOMObjectWrapper(exec->globalData(), location)) + if (DOMObject* wrapper = getCachedDOMObjectWrapper(exec, location)) return wrapper; JSDOMWindow* window = const_cast<JSDOMWindow*>(this); JSLocation* jsLocation = new (exec) JSLocation(getDOMStructure<JSLocation>(exec, window), window, location); - cacheDOMObjectWrapper(exec->globalData(), location, jsLocation); + cacheDOMObjectWrapper(exec, location, jsLocation); return jsLocation; } @@ -645,44 +589,44 @@ JSValue JSDOMWindow::webKitCSSMatrix(ExecState* exec) const } #if ENABLE(3D_CANVAS) -JSValue JSDOMWindow::canvasArrayBuffer(ExecState* exec) const +JSValue JSDOMWindow::webGLArrayBuffer(ExecState* exec) const { - return getDOMConstructor<JSCanvasArrayBufferConstructor>(exec, this); + return getDOMConstructor<JSWebGLArrayBufferConstructor>(exec, this); } -JSValue JSDOMWindow::canvasByteArray(ExecState* exec) const +JSValue JSDOMWindow::webGLByteArray(ExecState* exec) const { - return getDOMConstructor<JSCanvasByteArrayConstructor>(exec, this); + return getDOMConstructor<JSWebGLByteArrayConstructor>(exec, this); } -JSValue JSDOMWindow::canvasUnsignedByteArray(ExecState* exec) const +JSValue JSDOMWindow::webGLUnsignedByteArray(ExecState* exec) const { - return getDOMConstructor<JSCanvasUnsignedByteArrayConstructor>(exec, this); + return getDOMConstructor<JSWebGLUnsignedByteArrayConstructor>(exec, this); } -JSValue JSDOMWindow::canvasIntArray(ExecState* exec) const +JSValue JSDOMWindow::webGLIntArray(ExecState* exec) const { - return getDOMConstructor<JSCanvasIntArrayConstructor>(exec, this); + return getDOMConstructor<JSWebGLIntArrayConstructor>(exec, this); } -JSValue JSDOMWindow::canvasUnsignedIntArray(ExecState* exec) const +JSValue JSDOMWindow::webGLUnsignedIntArray(ExecState* exec) const { - return getDOMConstructor<JSCanvasUnsignedIntArrayConstructor>(exec, this); + return getDOMConstructor<JSWebGLUnsignedIntArrayConstructor>(exec, this); } -JSValue JSDOMWindow::canvasShortArray(ExecState* exec) const +JSValue JSDOMWindow::webGLShortArray(ExecState* exec) const { - return getDOMConstructor<JSCanvasShortArrayConstructor>(exec, this); + return getDOMConstructor<JSWebGLShortArrayConstructor>(exec, this); } -JSValue JSDOMWindow::canvasUnsignedShortArray(ExecState* exec) const +JSValue JSDOMWindow::webGLUnsignedShortArray(ExecState* exec) const { - return getDOMConstructor<JSCanvasUnsignedShortArrayConstructor>(exec, this); + return getDOMConstructor<JSWebGLUnsignedShortArrayConstructor>(exec, this); } -JSValue JSDOMWindow::canvasFloatArray(ExecState* exec) const +JSValue JSDOMWindow::webGLFloatArray(ExecState* exec) const { - return getDOMConstructor<JSCanvasFloatArrayConstructor>(exec, this); + return getDOMConstructor<JSWebGLFloatArrayConstructor>(exec, this); } #endif @@ -744,6 +688,10 @@ static Frame* createWindow(ExecState* exec, Frame* lexicalFrame, Frame* dynamicF ASSERT(lexicalFrame); ASSERT(dynamicFrame); + // Sandboxed iframes cannot open new auxiliary browsing contexts. + if (lexicalFrame && lexicalFrame->loader()->isSandboxed(SandboxNavigation)) + return 0; + ResourceRequest request; // For whatever reason, Firefox uses the dynamicGlobalObject to determine diff --git a/WebCore/bindings/js/JSDOMWindowShell.cpp b/WebCore/bindings/js/JSDOMWindowShell.cpp index 9072f91..09141ee 100644 --- a/WebCore/bindings/js/JSDOMWindowShell.cpp +++ b/WebCore/bindings/js/JSDOMWindowShell.cpp @@ -43,9 +43,10 @@ ASSERT_CLASS_FITS_IN_CELL(JSDOMWindowShell); const ClassInfo JSDOMWindowShell::s_info = { "JSDOMWindowShell", 0, 0, 0 }; -JSDOMWindowShell::JSDOMWindowShell(PassRefPtr<DOMWindow> window) +JSDOMWindowShell::JSDOMWindowShell(PassRefPtr<DOMWindow> window, DOMWrapperWorld* world) : Base(JSDOMWindowShell::createStructure(jsNull())) , m_window(0) + , m_world(world) { setWindow(window); } @@ -123,11 +124,6 @@ void JSDOMWindowShell::getOwnPropertyNames(ExecState* exec, PropertyNameArray& p m_window->getOwnPropertyNames(exec, propertyNames); } -bool JSDOMWindowShell::getPropertyAttributes(JSC::ExecState* exec, const Identifier& propertyName, unsigned& attributes) const -{ - return m_window->getPropertyAttributes(exec, propertyName, attributes); -} - void JSDOMWindowShell::defineGetter(ExecState* exec, const Identifier& propertyName, JSObject* getterFunction, unsigned attributes) { m_window->defineGetter(exec, propertyName, getterFunction, attributes); diff --git a/WebCore/bindings/js/JSDOMWindowShell.h b/WebCore/bindings/js/JSDOMWindowShell.h index 36cb8d6..27036d4 100644 --- a/WebCore/bindings/js/JSDOMWindowShell.h +++ b/WebCore/bindings/js/JSDOMWindowShell.h @@ -40,7 +40,7 @@ namespace WebCore { class JSDOMWindowShell : public DOMObject { typedef DOMObject Base; public: - JSDOMWindowShell(PassRefPtr<DOMWindow>); + JSDOMWindowShell(PassRefPtr<DOMWindow>, DOMWrapperWorld* world); virtual ~JSDOMWindowShell(); JSDOMWindow* window() const { return m_window; } @@ -63,6 +63,8 @@ namespace WebCore { return JSC::Structure::create(prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags)); } + DOMWrapperWorld* world() { return m_world.get(); } + private: static const unsigned StructureFlags = JSC::OverridesGetOwnPropertySlot | JSC::OverridesMarkChildren | JSC::OverridesGetPropertyNames | DOMObject::StructureFlags; @@ -75,7 +77,6 @@ namespace WebCore { virtual bool deleteProperty(JSC::ExecState*, const JSC::Identifier& propertyName); virtual void getPropertyNames(JSC::ExecState*, JSC::PropertyNameArray&); virtual void getOwnPropertyNames(JSC::ExecState*, JSC::PropertyNameArray&); - virtual bool getPropertyAttributes(JSC::ExecState*, const JSC::Identifier& propertyName, unsigned& attributes) const; virtual void defineGetter(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::JSObject* getterFunction, unsigned attributes); virtual void defineSetter(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::JSObject* setterFunction, unsigned attributes); virtual bool defineOwnProperty(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::PropertyDescriptor&, bool shouldThrow); @@ -85,6 +86,7 @@ namespace WebCore { virtual const JSC::ClassInfo* classInfo() const { return &s_info; } JSDOMWindow* m_window; + RefPtr<DOMWrapperWorld> m_world; }; JSC::JSValue toJS(JSC::ExecState*, Frame*); diff --git a/WebCore/bindings/js/JSDocumentCustom.cpp b/WebCore/bindings/js/JSDocumentCustom.cpp index d7f8725..4aa6583 100644 --- a/WebCore/bindings/js/JSDocumentCustom.cpp +++ b/WebCore/bindings/js/JSDocumentCustom.cpp @@ -26,7 +26,7 @@ #include "HTMLDocument.h" #include "JSCanvasRenderingContext2D.h" #if ENABLE(3D_CANVAS) -#include "JSCanvasRenderingContext3D.h" +#include "JSWebGLRenderingContext.h" #endif #include "JSDOMWindowCustom.h" #include "JSHTMLDocument.h" @@ -65,11 +65,11 @@ JSValue JSDocument::location(ExecState* exec) const return jsNull(); Location* location = frame->domWindow()->location(); - if (DOMObject* wrapper = getCachedDOMObjectWrapper(exec->globalData(), location)) + if (DOMObject* wrapper = getCachedDOMObjectWrapper(exec, location)) return wrapper; JSLocation* jsLocation = new (exec) JSLocation(getDOMStructure<JSLocation>(exec, globalObject()), globalObject(), location); - cacheDOMObjectWrapper(exec->globalData(), location, jsLocation); + cacheDOMObjectWrapper(exec, location, jsLocation); return jsLocation; } @@ -96,7 +96,7 @@ JSValue toJS(ExecState* exec, JSDOMGlobalObject* globalObject, Document* documen if (!document) return jsNull(); - DOMObject* wrapper = getCachedDOMObjectWrapper(exec->globalData(), document); + DOMObject* wrapper = getCachedDOMObjectWrapper(exec, document); if (wrapper) return wrapper; diff --git a/WebCore/bindings/js/JSElementCustom.cpp b/WebCore/bindings/js/JSElementCustom.cpp index fb64ff2..c725290 100644 --- a/WebCore/bindings/js/JSElementCustom.cpp +++ b/WebCore/bindings/js/JSElementCustom.cpp @@ -145,7 +145,7 @@ JSValue toJSNewlyCreated(ExecState* exec, JSDOMGlobalObject* globalObject, Eleme if (!element) return jsNull(); - ASSERT(!getCachedDOMNodeWrapper(element->document(), element)); + ASSERT(!getCachedDOMNodeWrapper(exec, element->document(), element)); JSNode* wrapper; if (element->isHTMLElement()) diff --git a/WebCore/bindings/js/JSEventCustom.cpp b/WebCore/bindings/js/JSEventCustom.cpp index 28e38ac..06b2fe5 100644 --- a/WebCore/bindings/js/JSEventCustom.cpp +++ b/WebCore/bindings/js/JSEventCustom.cpp @@ -30,9 +30,11 @@ #include "JSEvent.h" #include "Clipboard.h" +#include "CompositionEvent.h" #include "Event.h" #include "JSBeforeLoadEvent.h" #include "JSClipboard.h" +#include "JSCompositionEvent.h" #include "JSErrorEvent.h" #include "JSKeyboardEvent.h" #include "JSMessageEvent.h" @@ -40,6 +42,7 @@ #include "JSMutationEvent.h" #include "JSOverflowEvent.h" #include "JSPageTransitionEvent.h" +#include "JSPopStateEvent.h" #include "JSProgressEvent.h" #include "JSTextEvent.h" #include "JSUIEvent.h" @@ -55,6 +58,7 @@ #include "MutationEvent.h" #include "OverflowEvent.h" #include "PageTransitionEvent.h" +#include "PopStateEvent.h" #include "ProgressEvent.h" #include "TextEvent.h" #include "UIEvent.h" @@ -95,7 +99,7 @@ JSValue toJS(ExecState* exec, JSDOMGlobalObject* globalObject, Event* event) if (!event) return jsNull(); - DOMObject* wrapper = getCachedDOMObjectWrapper(exec->globalData(), event); + DOMObject* wrapper = getCachedDOMObjectWrapper(exec, event); if (wrapper) return wrapper; @@ -112,10 +116,15 @@ JSValue toJS(ExecState* exec, JSDOMGlobalObject* globalObject, Event* event) else if (event->isSVGZoomEvent()) wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, globalObject, SVGZoomEvent, event); #endif +<<<<<<< HEAD:WebCore/bindings/js/JSEventCustom.cpp #if ENABLE(TOUCH_EVENTS) // Android else if (event->isTouchEvent()) wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, globalObject, TouchEvent, event); #endif +======= + else if (event->isCompositionEvent()) + wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, globalObject, CompositionEvent, event); +>>>>>>> webkit.org at r51976:WebCore/bindings/js/JSEventCustom.cpp else wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, globalObject, UIEvent, event); } else if (event->isMutationEvent()) @@ -145,6 +154,8 @@ JSValue toJS(ExecState* exec, JSDOMGlobalObject* globalObject, Event* event) else if (event->isErrorEvent()) wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, globalObject, ErrorEvent, event); #endif + else if (event->isPopStateEvent()) + wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, globalObject, PopStateEvent, event); else wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, globalObject, Event, event); diff --git a/WebCore/bindings/js/JSEventListener.cpp b/WebCore/bindings/js/JSEventListener.cpp index 1a999a8..73060f1 100644 --- a/WebCore/bindings/js/JSEventListener.cpp +++ b/WebCore/bindings/js/JSEventListener.cpp @@ -86,13 +86,8 @@ void JSEventListener::handleEvent(ScriptExecutionContext* scriptExecutionContext } ExecState* exec = globalObject->globalExec(); + JSValue handleEventFunction = jsFunction->get(exec, Identifier(exec, "handleEvent")); - JSValue handleEventFunction; - { - // Switch worlds, just in case handleEvent is a getter and causes JS execution! - EnterDOMWrapperWorld worldEntry(exec, m_isolatedWorld.get()); - handleEventFunction = jsFunction->get(exec, Identifier(exec, "handleEvent")); - } CallData callData; CallType callType = handleEventFunction.getCallData(callData); if (callType == CallTypeNone) { @@ -114,8 +109,8 @@ void JSEventListener::handleEvent(ScriptExecutionContext* scriptExecutionContext globalData->timeoutChecker.start(); JSValue retval = handleEventFunction - ? callInWorld(exec, handleEventFunction, callType, callData, jsFunction, args, m_isolatedWorld.get()) - : callInWorld(exec, jsFunction, callType, callData, toJS(exec, globalObject, event->currentTarget()), args, m_isolatedWorld.get()); + ? JSC::call(exec, handleEventFunction, callType, callData, jsFunction, args) + : JSC::call(exec, jsFunction, callType, callData, toJS(exec, globalObject, event->currentTarget()), args); globalData->timeoutChecker.stop(); globalObject->setCurrentEvent(savedEvent); @@ -166,7 +161,7 @@ bool JSEventListener::reportError(ScriptExecutionContext* context, const String& JSValue thisValue = globalObject->toThisObject(exec); globalData->timeoutChecker.start(); - JSValue returnValue = callInWorld(exec, jsFunction, callType, callData, thisValue, args, m_isolatedWorld.get()); + JSValue returnValue = JSC::call(exec, jsFunction, callType, callData, thisValue, args); globalData->timeoutChecker.stop(); // If an error occurs while handling the script error, it should be bubbled up. diff --git a/WebCore/bindings/js/JSHTMLCanvasElementCustom.cpp b/WebCore/bindings/js/JSHTMLCanvasElementCustom.cpp index 8ecd287..751e7de 100644 --- a/WebCore/bindings/js/JSHTMLCanvasElementCustom.cpp +++ b/WebCore/bindings/js/JSHTMLCanvasElementCustom.cpp @@ -29,7 +29,7 @@ #include "HTMLCanvasElement.h" #include "JSCanvasRenderingContext2D.h" #if ENABLE(3D_CANVAS) -#include "JSCanvasRenderingContext3D.h" +#include "JSWebGLRenderingContext.h" #endif #include <wtf/GetPtr.h> diff --git a/WebCore/bindings/js/JSHTMLCollectionCustom.cpp b/WebCore/bindings/js/JSHTMLCollectionCustom.cpp index dd4ceaa..ba61922 100644 --- a/WebCore/bindings/js/JSHTMLCollectionCustom.cpp +++ b/WebCore/bindings/js/JSHTMLCollectionCustom.cpp @@ -134,7 +134,7 @@ JSValue toJS(ExecState* exec, JSDOMGlobalObject* globalObject, HTMLCollection* c if (!collection) return jsNull(); - DOMObject* wrapper = getCachedDOMObjectWrapper(exec->globalData(), collection); + DOMObject* wrapper = getCachedDOMObjectWrapper(exec, collection); if (wrapper) return wrapper; diff --git a/WebCore/bindings/js/JSHTMLDocumentCustom.cpp b/WebCore/bindings/js/JSHTMLDocumentCustom.cpp index a65ca7c..7fde002 100644 --- a/WebCore/bindings/js/JSHTMLDocumentCustom.cpp +++ b/WebCore/bindings/js/JSHTMLDocumentCustom.cpp @@ -113,7 +113,7 @@ JSValue JSHTMLDocument::open(ExecState* exec, const ArgList& args) CallType callType = function.getCallData(callData); if (callType == CallTypeNone) return throwError(exec, TypeError); - return callInWorld(exec, function, callType, callData, wrapper, args, currentWorld(exec)); + return JSC::call(exec, function, callType, callData, wrapper, args); } } return jsUndefined(); diff --git a/WebCore/bindings/js/JSHistoryCustom.cpp b/WebCore/bindings/js/JSHistoryCustom.cpp index b24b1ff..3076503 100644 --- a/WebCore/bindings/js/JSHistoryCustom.cpp +++ b/WebCore/bindings/js/JSHistoryCustom.cpp @@ -95,15 +95,15 @@ bool JSHistory::getOwnPropertySlotDelegate(ExecState* exec, const Identifier& pr bool JSHistory::getOwnPropertyDescriptorDelegate(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor) { - // When accessing History cross-domain, functions are always the native built-in ones. - // See JSDOMWindow::getOwnPropertySlotDelegate for additional details. - - // Our custom code is only needed to implement the Window cross-domain scheme, so if access is - // allowed, return false so the normal lookup will take place. - String message; - if (allowsAccessFromFrame(exec, impl()->frame(), message)) - return false; - + if (!impl()->frame()) { + descriptor.setUndefined(); + return true; + } + + // Throw out all cross domain access + if (!allowsAccessFromFrame(exec, impl()->frame())) + return true; + // Check for the few functions that we allow, even when called cross-domain. const HashEntry* entry = JSHistoryPrototype::s_info.propHashTable(exec)->entry(exec, propertyName); if (entry) { @@ -133,8 +133,7 @@ bool JSHistory::getOwnPropertyDescriptorDelegate(ExecState* exec, const Identifi return true; } } - - printErrorMessageForFrame(impl()->frame(), message); + descriptor.setUndefined(); return true; } @@ -163,4 +162,52 @@ void JSHistory::getOwnPropertyNames(ExecState* exec, PropertyNameArray& property Base::getOwnPropertyNames(exec, propertyNames); } +JSValue JSHistory::pushState(ExecState* exec, const ArgList& args) +{ + RefPtr<SerializedScriptValue> historyState = SerializedScriptValue::create(exec, args.at(0)); + if (exec->hadException()) + return jsUndefined(); + + String title = valueToStringWithUndefinedOrNullCheck(exec, args.at(1)); + if (exec->hadException()) + return jsUndefined(); + + String url; + if (args.size() > 2) { + url = valueToStringWithUndefinedOrNullCheck(exec, args.at(2)); + if (exec->hadException()) + return jsUndefined(); + } + + ExceptionCode ec = 0; + impl()->stateObjectAdded(historyState.release(), title, url, History::StateObjectPush, ec); + setDOMException(exec, ec); + + return jsUndefined(); +} + +JSValue JSHistory::replaceState(ExecState* exec, const ArgList& args) +{ + RefPtr<SerializedScriptValue> historyState = SerializedScriptValue::create(exec, args.at(0)); + if (exec->hadException()) + return jsUndefined(); + + String title = valueToStringWithUndefinedOrNullCheck(exec, args.at(1)); + if (exec->hadException()) + return jsUndefined(); + + String url; + if (args.size() > 2) { + url = valueToStringWithUndefinedOrNullCheck(exec, args.at(2)); + if (exec->hadException()) + return jsUndefined(); + } + + ExceptionCode ec = 0; + impl()->stateObjectAdded(historyState.release(), title, url, History::StateObjectReplace, ec); + setDOMException(exec, ec); + + return jsUndefined(); +} + } // namespace WebCore diff --git a/WebCore/bindings/js/JSImageDataCustom.cpp b/WebCore/bindings/js/JSImageDataCustom.cpp index fa3b1d5..61c5112 100644 --- a/WebCore/bindings/js/JSImageDataCustom.cpp +++ b/WebCore/bindings/js/JSImageDataCustom.cpp @@ -41,7 +41,7 @@ JSValue toJS(ExecState* exec, JSDOMGlobalObject* globalObject, ImageData* imageD if (!imageData) return jsNull(); - DOMObject* wrapper = getCachedDOMObjectWrapper(exec->globalData(), imageData); + DOMObject* wrapper = getCachedDOMObjectWrapper(exec, imageData); if (wrapper) return wrapper; diff --git a/WebCore/bindings/js/JSInspectorBackendCustom.cpp b/WebCore/bindings/js/JSInjectedScriptHostCustom.cpp index 439f532..fcc9e5e 100644 --- a/WebCore/bindings/js/JSInspectorBackendCustom.cpp +++ b/WebCore/bindings/js/JSInjectedScriptHostCustom.cpp @@ -31,7 +31,7 @@ */ #include "config.h" -#include "JSInspectorBackend.h" +#include "JSInjectedScriptHost.h" #if ENABLE(INSPECTOR) @@ -43,7 +43,7 @@ #include "ExceptionCode.h" #include "Frame.h" #include "FrameLoader.h" -#include "InspectorBackend.h" +#include "InjectedScriptHost.h" #include "InspectorController.h" #include "InspectorResource.h" #include "JSDOMWindow.h" @@ -73,53 +73,8 @@ using namespace JSC; namespace WebCore { -JSValue JSInspectorBackend::highlightDOMNode(JSC::ExecState* exec, const JSC::ArgList& args) -{ - if (args.size() < 1) - return jsUndefined(); - - impl()->highlight(args.at(0).toInt32(exec)); - return jsUndefined(); -} - -JSValue JSInspectorBackend::search(ExecState* exec, const ArgList& args) -{ - if (args.size() < 2) - return jsUndefined(); - - Node* node = toNode(args.at(0)); - if (!node) - return jsUndefined(); - - String target = args.at(1).toString(exec); - if (exec->hadException()) - return jsUndefined(); - - MarkedArgumentBuffer result; - RefPtr<Range> searchRange(rangeOfContents(node)); - - ExceptionCode ec = 0; - do { - RefPtr<Range> resultRange(findPlainText(searchRange.get(), target, true, false)); - if (resultRange->collapsed(ec)) - break; - - // A non-collapsed result range can in some funky whitespace cases still not - // advance the range's start position (4509328). Break to avoid infinite loop. - VisiblePosition newStart = endVisiblePosition(resultRange.get(), DOWNSTREAM); - if (newStart == startVisiblePosition(searchRange.get(), DOWNSTREAM)) - break; - - result.append(toJS(exec, resultRange.get())); - - setStart(searchRange.get(), newStart); - } while (true); - - return constructArray(exec, result); -} - #if ENABLE(DATABASE) -JSValue JSInspectorBackend::databaseForId(ExecState* exec, const ArgList& args) +JSValue JSInjectedScriptHost::databaseForId(ExecState* exec, const ArgList& args) { if (args.size() < 1) return jsUndefined(); @@ -137,7 +92,7 @@ JSValue JSInspectorBackend::databaseForId(ExecState* exec, const ArgList& args) } #endif -JSValue JSInspectorBackend::inspectedWindow(ExecState*, const ArgList&) +JSValue JSInjectedScriptHost::inspectedWindow(ExecState*, const ArgList&) { InspectorController* ic = impl()->inspectorController(); if (!ic) @@ -146,89 +101,7 @@ JSValue JSInspectorBackend::inspectedWindow(ExecState*, const ArgList&) return JSInspectedObjectWrapper::wrap(inspectedWindow->globalExec(), inspectedWindow); } -JSValue JSInspectorBackend::setting(ExecState* exec, const ArgList& args) -{ - if (args.size() < 1) - return jsUndefined(); - - String key = args.at(0).toString(exec); - if (exec->hadException()) - return jsUndefined(); - - InspectorController* ic = impl()->inspectorController(); - if (!ic) - return jsUndefined(); - const InspectorController::Setting& setting = ic->setting(key); - - switch (setting.type()) { - default: - case InspectorController::Setting::NoType: - return jsUndefined(); - case InspectorController::Setting::StringType: - return jsString(exec, setting.string()); - case InspectorController::Setting::DoubleType: - return jsNumber(exec, setting.doubleValue()); - case InspectorController::Setting::IntegerType: - return jsNumber(exec, setting.integerValue()); - case InspectorController::Setting::BooleanType: - return jsBoolean(setting.booleanValue()); - case InspectorController::Setting::StringVectorType: { - MarkedArgumentBuffer stringsArray; - const Vector<String>& strings = setting.stringVector(); - const unsigned length = strings.size(); - for (unsigned i = 0; i < length; ++i) - stringsArray.append(jsString(exec, strings[i])); - return constructArray(exec, stringsArray); - } - } -} - -JSValue JSInspectorBackend::setSetting(ExecState* exec, const ArgList& args) -{ - if (args.size() < 2) - return jsUndefined(); - - String key = args.at(0).toString(exec); - if (exec->hadException()) - return jsUndefined(); - - InspectorController::Setting setting; - - JSValue value = args.at(1); - if (value.isUndefined() || value.isNull()) { - // Do nothing. The setting is already NoType. - ASSERT(setting.type() == InspectorController::Setting::NoType); - } else if (value.isString()) - setting.set(value.toString(exec)); - else if (value.isNumber()) - setting.set(value.toNumber(exec)); - else if (value.isBoolean()) - setting.set(value.toBoolean(exec)); - else { - JSArray* jsArray = asArray(value); - if (!jsArray) - return jsUndefined(); - Vector<String> strings; - for (unsigned i = 0; i < jsArray->length(); ++i) { - String item = jsArray->get(exec, i).toString(exec); - if (exec->hadException()) - return jsUndefined(); - strings.append(item); - } - setting.set(strings); - } - - if (exec->hadException()) - return jsUndefined(); - - InspectorController* ic = impl()->inspectorController(); - if (ic) - ic->setSetting(key, setting); - - return jsUndefined(); -} - -JSValue JSInspectorBackend::wrapCallback(ExecState* exec, const ArgList& args) +JSValue JSInjectedScriptHost::wrapCallback(ExecState* exec, const ArgList& args) { if (args.size() < 1) return jsUndefined(); @@ -238,7 +111,7 @@ JSValue JSInspectorBackend::wrapCallback(ExecState* exec, const ArgList& args) #if ENABLE(JAVASCRIPT_DEBUGGER) -JSValue JSInspectorBackend::currentCallFrame(ExecState* exec, const ArgList&) +JSValue JSInjectedScriptHost::currentCallFrame(ExecState* exec, const ArgList&) { JavaScriptCallFrame* callFrame = impl()->currentCallFrame(); if (!callFrame || !callFrame->isValid()) @@ -253,7 +126,7 @@ JSValue JSInspectorBackend::currentCallFrame(ExecState* exec, const ArgList&) #endif -JSValue JSInspectorBackend::nodeForId(ExecState* exec, const ArgList& args) +JSValue JSInjectedScriptHost::nodeForId(ExecState* exec, const ArgList& args) { if (args.size() < 1) return jsUndefined(); @@ -271,7 +144,7 @@ JSValue JSInspectorBackend::nodeForId(ExecState* exec, const ArgList& args) return JSInspectedObjectWrapper::wrap(inspectedWindow->globalExec(), toJS(exec, deprecatedGlobalObjectForPrototype(inspectedWindow->globalExec()), node)); } -JSValue JSInspectorBackend::wrapObject(ExecState* exec, const ArgList& args) +JSValue JSInjectedScriptHost::wrapObject(ExecState* exec, const ArgList& args) { if (args.size() < 2) return jsUndefined(); @@ -279,7 +152,7 @@ JSValue JSInspectorBackend::wrapObject(ExecState* exec, const ArgList& args) return impl()->wrapObject(ScriptValue(args.at(0)), args.at(1).toString(exec)).jsValue(); } -JSValue JSInspectorBackend::unwrapObject(ExecState* exec, const ArgList& args) +JSValue JSInjectedScriptHost::unwrapObject(ExecState* exec, const ArgList& args) { if (args.size() < 1) return jsUndefined(); @@ -287,7 +160,7 @@ JSValue JSInspectorBackend::unwrapObject(ExecState* exec, const ArgList& args) return impl()->unwrapObject(args.at(0).toString(exec)).jsValue(); } -JSValue JSInspectorBackend::pushNodePathToFrontend(ExecState* exec, const ArgList& args) +JSValue JSInjectedScriptHost::pushNodePathToFrontend(ExecState* exec, const ArgList& args) { if (args.size() < 2) return jsUndefined(); @@ -305,7 +178,7 @@ JSValue JSInspectorBackend::pushNodePathToFrontend(ExecState* exec, const ArgLis } #if ENABLE(DATABASE) -JSValue JSInspectorBackend::selectDatabase(ExecState*, const ArgList& args) +JSValue JSInjectedScriptHost::selectDatabase(ExecState*, const ArgList& args) { if (args.size() < 1) return jsUndefined(); @@ -322,7 +195,7 @@ JSValue JSInspectorBackend::selectDatabase(ExecState*, const ArgList& args) #endif #if ENABLE(DOM_STORAGE) -JSValue JSInspectorBackend::selectDOMStorage(ExecState*, const ArgList& args) +JSValue JSInjectedScriptHost::selectDOMStorage(ExecState*, const ArgList& args) { if (args.size() < 1) return jsUndefined(); diff --git a/WebCore/bindings/js/JSInspectedObjectWrapper.cpp b/WebCore/bindings/js/JSInspectedObjectWrapper.cpp index ed79427..13f59b7 100644 --- a/WebCore/bindings/js/JSInspectedObjectWrapper.cpp +++ b/WebCore/bindings/js/JSInspectedObjectWrapper.cpp @@ -68,7 +68,8 @@ JSValue JSInspectedObjectWrapper::wrap(ExecState* unwrappedExec, JSValue unwrapp if (prototype.isNull()) return new (unwrappedExec) JSInspectedObjectWrapper(unwrappedExec, unwrappedObject, JSQuarantinedObjectWrapper::createStructure(jsNull())); - return new (unwrappedExec) JSInspectedObjectWrapper(unwrappedExec, unwrappedObject, JSQuarantinedObjectWrapper::createStructure(asObject(wrap(unwrappedExec, prototype)))); + ProtectedJSValue wrappedProto = wrap(unwrappedExec, prototype); + return new (unwrappedExec) JSInspectedObjectWrapper(unwrappedExec, unwrappedObject, JSQuarantinedObjectWrapper::createStructure(asObject(wrappedProto))); } JSInspectedObjectWrapper::JSInspectedObjectWrapper(ExecState* unwrappedExec, JSObject* unwrappedObject, NonNullPassRefPtr<Structure> structure) diff --git a/WebCore/bindings/js/JSInspectorCallbackWrapper.cpp b/WebCore/bindings/js/JSInspectorCallbackWrapper.cpp index 9c4330d..ff4fbb9 100644 --- a/WebCore/bindings/js/JSInspectorCallbackWrapper.cpp +++ b/WebCore/bindings/js/JSInspectorCallbackWrapper.cpp @@ -75,7 +75,8 @@ JSValue JSInspectorCallbackWrapper::wrap(ExecState* unwrappedExec, JSValue unwra static Structure* structure = leakInspectorCallbackWrapperStructure(); return new (unwrappedExec) JSInspectorCallbackWrapper(unwrappedExec, unwrappedObject, structure); } - return new (unwrappedExec) JSInspectorCallbackWrapper(unwrappedExec, unwrappedObject, createStructure(wrap(unwrappedExec, prototype))); + ProtectedJSValue wrappedProto = wrap(unwrappedExec, prototype); + return new (unwrappedExec) JSInspectorCallbackWrapper(unwrappedExec, unwrappedObject, createStructure(wrappedProto.get())); } JSInspectorCallbackWrapper::JSInspectorCallbackWrapper(ExecState* unwrappedExec, JSObject* unwrappedObject, NonNullPassRefPtr<Structure> structure) diff --git a/WebCore/bindings/js/JSInspectorFrontendHostCustom.cpp b/WebCore/bindings/js/JSInspectorFrontendHostCustom.cpp new file mode 100644 index 0000000..1970bf7 --- /dev/null +++ b/WebCore/bindings/js/JSInspectorFrontendHostCustom.cpp @@ -0,0 +1,124 @@ +/* + * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2008 Matt Lilek <webkit@mattlilek.com> + * Copyright (C) 2009 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "JSInspectorFrontendHost.h" + +#if ENABLE(INSPECTOR) + +#include "ContextMenuItem.h" +#include "ExceptionCode.h" +#include "Frame.h" +#include "InspectorController.h" +#include "InspectorFrontendHost.h" +#include "JSEvent.h" +#include "JSNode.h" +#include "JSRange.h" +#include "MouseEvent.h" +#include "Node.h" +#include "Page.h" +#include "TextIterator.h" +#include "VisiblePosition.h" +#include <runtime/JSArray.h> +#include <runtime/JSLock.h> +#include <runtime/JSObject.h> +#include <wtf/Vector.h> + +using namespace JSC; + +namespace WebCore { + +JSValue JSInspectorFrontendHost::search(ExecState* exec, const ArgList& args) +{ + if (args.size() < 2) + return jsUndefined(); + + Node* node = toNode(args.at(0)); + if (!node) + return jsUndefined(); + + String target = args.at(1).toString(exec); + if (exec->hadException()) + return jsUndefined(); + + MarkedArgumentBuffer result; + RefPtr<Range> searchRange(rangeOfContents(node)); + + ExceptionCode ec = 0; + do { + RefPtr<Range> resultRange(findPlainText(searchRange.get(), target, true, false)); + if (resultRange->collapsed(ec)) + break; + + // A non-collapsed result range can in some funky whitespace cases still not + // advance the range's start position (4509328). Break to avoid infinite loop. + VisiblePosition newStart = endVisiblePosition(resultRange.get(), DOWNSTREAM); + if (newStart == startVisiblePosition(searchRange.get(), DOWNSTREAM)) + break; + + result.append(toJS(exec, resultRange.get())); + + setStart(searchRange.get(), newStart); + } while (true); + + return constructArray(exec, result); +} + +JSValue JSInspectorFrontendHost::showContextMenu(ExecState* execState, const ArgList& args) +{ + if (args.size() < 2) + return jsUndefined(); + + Event* event = toEvent(args.at(0)); + + JSArray* array = asArray(args.at(1)); + Vector<ContextMenuItem> items; + + for (size_t i = 0; i < array->length(); ++i) { + JSObject* item = asObject(array->getIndex(i)); + JSValue label = item->get(execState, Identifier(execState, "label")); + JSValue id = item->get(execState, Identifier(execState, "id")); + if (label.isUndefined() || id.isUndefined()) + items.append(ContextMenuItem(SeparatorType, ContextMenuItemTagNoAction, String())); + else { + ContextMenuAction typedId = static_cast<ContextMenuAction>(ContextMenuItemBaseCustomTag + id.toInt32(execState)); + items.append(ContextMenuItem(ActionType, typedId, label.toString(execState))); + } + } + + impl()->showContextMenu(event, items); + return jsUndefined(); +} + +} // namespace WebCore + +#endif // ENABLE(INSPECTOR) diff --git a/WebCore/bindings/js/JSLocationCustom.cpp b/WebCore/bindings/js/JSLocationCustom.cpp index c76a2b1..6c8e032 100644 --- a/WebCore/bindings/js/JSLocationCustom.cpp +++ b/WebCore/bindings/js/JSLocationCustom.cpp @@ -102,14 +102,9 @@ bool JSLocation::getOwnPropertyDescriptorDelegate(ExecState* exec, const Identif return true; } - // When accessing Location cross-domain, functions are always the native built-in ones. - // See JSDOMWindow::getOwnPropertySlotDelegate for additional details. - - // Our custom code is only needed to implement the Window cross-domain scheme, so if access is - // allowed, return false so the normal lookup will take place. - String message; - if (allowsAccessFromFrame(exec, frame, message)) - return false; + // throw out all cross domain access + if (!allowsAccessFromFrame(exec, frame)) + return true; // Check for the few functions that we allow, even when called cross-domain. const HashEntry* entry = JSLocationPrototype::s_info.propHashTable(exec)->entry(exec, propertyName); @@ -133,8 +128,7 @@ bool JSLocation::getOwnPropertyDescriptorDelegate(ExecState* exec, const Identif // FIXME: Other implementers of the Window cross-domain scheme (Window, History) allow toString, // but for now we have decided not to, partly because it seems silly to return "[Object Location]" in // such cases when normally the string form of Location would be the URL. - - printErrorMessageForFrame(frame, message); + descriptor.setUndefined(); return true; } @@ -257,8 +251,9 @@ void JSLocation::setPort(ExecState* exec, JSValue value) const UString& portString = value.toString(exec); int port = charactersToInt(portString.data(), portString.size()); if (port < 0 || port > 0xFFFF) - port = 0; - url.setPort(port); + url.removePort(); + else + url.setPort(port); navigateIfAllowed(exec, frame, url, !frame->script()->anyPageIsProcessingUserGesture(), false); } diff --git a/WebCore/bindings/js/JSNamedNodeMapCustom.cpp b/WebCore/bindings/js/JSNamedNodeMapCustom.cpp index 1974ab0..d1bbeec 100644 --- a/WebCore/bindings/js/JSNamedNodeMapCustom.cpp +++ b/WebCore/bindings/js/JSNamedNodeMapCustom.cpp @@ -52,10 +52,8 @@ void JSNamedNodeMap::markChildren(MarkStack& markStack) // Mark the element so that this will work to access the attribute even if the last // other reference goes away. - if (Element* element = impl()->element()) { - if (JSNode* wrapper = getCachedDOMNodeWrapper(element->document(), element)) - markStack.append(wrapper); - } + if (Element* element = impl()->element()) + markDOMNodeWrapper(markStack, element->document(), element); } } // namespace WebCore diff --git a/WebCore/bindings/js/JSNodeCustom.cpp b/WebCore/bindings/js/JSNodeCustom.cpp index 2a4aa80..f375ae5 100644 --- a/WebCore/bindings/js/JSNodeCustom.cpp +++ b/WebCore/bindings/js/JSNodeCustom.cpp @@ -148,31 +148,34 @@ void JSNode::markChildren(MarkStack& markStack) return; } - // This is a node outside the document, so find the root of the tree it is in, - // and start marking from there. + // This is a node outside the document. + // Find the the root, and the highest ancestor with a wrapper. Node* root = node; - for (Node* current = m_impl.get(); current; current = current->parentNode()) + Node* outermostNodeWithWrapper = node; + for (Node* current = m_impl.get(); current; current = current->parentNode()) { root = current; + if (hasCachedDOMNodeWrapper(current->document(), current)) + outermostNodeWithWrapper = current; + } - // Nodes in a subtree are marked by the tree's root, so, if the root is already - // marking the tree, we don't need to explicitly mark any other nodes. - if (root->inSubtreeMark()) + // Only nodes that have no ancestors with wrappers mark the subtree. In the common + // case, the root of the detached subtree has a wrapper, so the tree will only + // get marked once. Nodes that aren't outermost need to mark the outermost + // in case it is otherwise unreachable. + if (node != outermostNodeWithWrapper) { + markDOMNodeWrapper(markStack, m_impl->document(), outermostNodeWithWrapper); return; + } // Mark the whole tree subtree. - root->setInSubtreeMark(true); - for (Node* nodeToMark = root; nodeToMark; nodeToMark = nodeToMark->traverseNextNode()) { - JSNode* wrapper = getCachedDOMNodeWrapper(m_impl->document(), nodeToMark); - if (wrapper) - markStack.append(wrapper); - } - root->setInSubtreeMark(false); + for (Node* nodeToMark = root; nodeToMark; nodeToMark = nodeToMark->traverseNextNode()) + markDOMNodeWrapper(markStack, m_impl->document(), nodeToMark); } static ALWAYS_INLINE JSValue createWrapper(ExecState* exec, JSDOMGlobalObject* globalObject, Node* node) { ASSERT(node); - ASSERT(!getCachedDOMNodeWrapper(node->document(), node)); + ASSERT(!getCachedDOMNodeWrapper(exec, node->document(), node)); JSNode* wrapper; switch (node->nodeType()) { @@ -239,7 +242,7 @@ JSValue toJS(ExecState* exec, JSDOMGlobalObject* globalObject, Node* node) if (!node) return jsNull(); - JSNode* wrapper = getCachedDOMNodeWrapper(node->document(), node); + JSNode* wrapper = getCachedDOMNodeWrapper(exec, node->document(), node); if (wrapper) return wrapper; diff --git a/WebCore/bindings/js/JSNodeFilterCondition.cpp b/WebCore/bindings/js/JSNodeFilterCondition.cpp index 54dc020..d34f5c1 100644 --- a/WebCore/bindings/js/JSNodeFilterCondition.cpp +++ b/WebCore/bindings/js/JSNodeFilterCondition.cpp @@ -66,7 +66,7 @@ short JSNodeFilterCondition::acceptNode(JSC::ExecState* exec, Node* filterNode) if (exec->hadException()) return NodeFilter::FILTER_REJECT; - JSValue result = callInWorld(exec, m_filter, callType, callData, m_filter, args, currentWorld(exec)); + JSValue result = JSC::call(exec, m_filter, callType, callData, m_filter, args); if (exec->hadException()) return NodeFilter::FILTER_REJECT; diff --git a/WebCore/bindings/js/JSCanvasFloatArrayCustom.cpp b/WebCore/bindings/js/JSPopStateEventCustom.cpp index 20cd805..ee86a09 100644 --- a/WebCore/bindings/js/JSCanvasFloatArrayCustom.cpp +++ b/WebCore/bindings/js/JSPopStateEventCustom.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 @@ -10,7 +10,7 @@ * 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 + * 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 @@ -21,30 +21,37 @@ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * */ #include "config.h" +#include "JSPopStateEvent.h" -#if ENABLE(3D_CANVAS) - -#include "JSCanvasFloatArray.h" - -#include "CanvasFloatArray.h" +#include "PopStateEvent.h" using namespace JSC; namespace WebCore { -void JSCanvasFloatArray::indexSetter(JSC::ExecState* exec, unsigned index, JSC::JSValue value) +JSValue JSPopStateEvent::initPopStateEvent(ExecState* exec, const ArgList& args) { - impl()->set(index, static_cast<float>(value.toInt32(exec))); + const UString& typeArg = args.at(0).toString(exec); + bool canBubbleArg = args.at(1).toBoolean(exec); + bool cancelableArg = args.at(2).toBoolean(exec); + RefPtr<SerializedScriptValue> stateObjectArg = SerializedScriptValue::create(exec, args.at(3)); + + PopStateEvent* event = static_cast<PopStateEvent*>(impl()); + event->initPopStateEvent(typeArg, canBubbleArg, cancelableArg, stateObjectArg.release()); + return jsUndefined(); } -JSC::JSValue toJS(JSC::ExecState* exec, JSDOMGlobalObject* globalObject, CanvasFloatArray* object) +JSC::JSValue JSPopStateEvent::state(JSC::ExecState* exec) const { - return getDOMObjectWrapper<JSCanvasFloatArray>(exec, globalObject, object); + SerializedScriptValue* object = static_cast<PopStateEvent*>(impl())->state(); + if (!object) + return JSC::jsNull(); + + return object->deserialize(exec); } } // namespace WebCore - -#endif // ENABLE(3D_CANVAS) diff --git a/WebCore/bindings/js/JSQuarantinedObjectWrapper.cpp b/WebCore/bindings/js/JSQuarantinedObjectWrapper.cpp index 2ab2c00..ea2f72f 100644 --- a/WebCore/bindings/js/JSQuarantinedObjectWrapper.cpp +++ b/WebCore/bindings/js/JSQuarantinedObjectWrapper.cpp @@ -245,9 +245,7 @@ JSObject* JSQuarantinedObjectWrapper::construct(ExecState* exec, JSObject* const ConstructType unwrappedConstructType = wrapper->m_unwrappedObject->getConstructData(unwrappedConstructData); ASSERT(unwrappedConstructType != ConstructTypeNone); - // FIXME: Quarantined objects are all in the debuggerWorld(), for now. Instead, we should remove the quarantined objects, & replace them with an isolated world? - JSValue unwrappedResult = constructInWorld(wrapper->unwrappedExecState(), wrapper->m_unwrappedObject, unwrappedConstructType, unwrappedConstructData, preparedArgs, debuggerWorld()); - + JSValue unwrappedResult = JSC::construct(wrapper->unwrappedExecState(), wrapper->m_unwrappedObject, unwrappedConstructType, unwrappedConstructData, preparedArgs); JSValue resultValue = wrapper->wrapOutgoingValue(wrapper->unwrappedExecState(), unwrappedResult); ASSERT(resultValue.isObject()); JSObject* result = asObject(resultValue); @@ -296,9 +294,7 @@ JSValue JSQuarantinedObjectWrapper::call(ExecState* exec, JSObject* function, JS CallType unwrappedCallType = wrapper->m_unwrappedObject->getCallData(unwrappedCallData); ASSERT(unwrappedCallType != CallTypeNone); - // FIXME: Quarantined objects are all in the debuggerWorld(), for now. Instead, we should remove the quarantined objects, & replace them with an isolated world? - JSValue unwrappedResult = callInWorld(wrapper->unwrappedExecState(), wrapper->m_unwrappedObject, unwrappedCallType, unwrappedCallData, preparedThisValue, preparedArgs, debuggerWorld()); - + JSValue unwrappedResult = JSC::call(wrapper->unwrappedExecState(), wrapper->m_unwrappedObject, unwrappedCallType, unwrappedCallData, preparedThisValue, preparedArgs); JSValue result = wrapper->wrapOutgoingValue(wrapper->unwrappedExecState(), unwrappedResult); wrapper->transferExceptionToExecState(exec); diff --git a/WebCore/bindings/js/JSSVGElementInstanceCustom.cpp b/WebCore/bindings/js/JSSVGElementInstanceCustom.cpp index ba1cf22..5f26df3 100644 --- a/WebCore/bindings/js/JSSVGElementInstanceCustom.cpp +++ b/WebCore/bindings/js/JSSVGElementInstanceCustom.cpp @@ -43,9 +43,7 @@ void JSSVGElementInstance::markChildren(MarkStack& markStack) Base::markChildren(markStack); // Mark the wrapper for our corresponding element, so it can mark its event handlers. - JSNode* correspondingWrapper = getCachedDOMNodeWrapper(impl()->correspondingElement()->document(), impl()->correspondingElement()); - if (correspondingWrapper) - markStack.append(correspondingWrapper); + markDOMNodeWrapper(markStack, impl()->correspondingElement()->document(), impl()->correspondingElement()); } JSValue JSSVGElementInstance::addEventListener(ExecState* exec, const ArgList& args) diff --git a/WebCore/bindings/js/JSSVGMatrixCustom.cpp b/WebCore/bindings/js/JSSVGMatrixCustom.cpp index 35390b2..a9d0e54 100644 --- a/WebCore/bindings/js/JSSVGMatrixCustom.cpp +++ b/WebCore/bindings/js/JSSVGMatrixCustom.cpp @@ -1,5 +1,6 @@ /* * Copyright (C) 2006, 2007, 2008 Nikolas Zimmermann <zimmermann@kde.org> + * Copyright (C) 2009 Jeff Schiller <codedread@gmail.com> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -24,11 +25,30 @@ #include "TransformationMatrix.h" #include "SVGException.h" +#include <runtime/Error.h> using namespace JSC; namespace WebCore { +JSValue JSSVGMatrix::multiply(ExecState* exec, const ArgList& args) +{ + if (args.size() < 1) + return throwError(exec, SyntaxError, "Not enough arguments"); + + if (!args.at(0).inherits(&JSSVGMatrix::s_info)) + return throwError(exec, TypeError, "secondMatrix argument was not a SVGMatrix"); + + JSSVGMatrix* matrixObj = static_cast<JSSVGMatrix*>(asObject(args.at(0))); + + TransformationMatrix m1(*impl()); + TransformationMatrix m2(*(matrixObj->impl())); + + JSC::JSValue result = toJS(exec, deprecatedGlobalObjectForPrototype(exec), JSSVGStaticPODTypeWrapper<TransformationMatrix>::create(m1.multLeft(m2)).get(), m_context.get()); + + return result; +} + JSValue JSSVGMatrix::inverse(ExecState* exec, const ArgList&) { TransformationMatrix imp(*impl()); diff --git a/WebCore/bindings/js/JSSVGPathSegCustom.cpp b/WebCore/bindings/js/JSSVGPathSegCustom.cpp index 42fa878..d5be3fd 100644 --- a/WebCore/bindings/js/JSSVGPathSegCustom.cpp +++ b/WebCore/bindings/js/JSSVGPathSegCustom.cpp @@ -64,7 +64,7 @@ JSValue toJS(ExecState* exec, JSDOMGlobalObject* globalObject, SVGPathSeg* objec if (!object) return jsNull(); - if (DOMObject* wrapper = getCachedDOMObjectWrapper(exec->globalData(), object)) + if (DOMObject* wrapper = getCachedDOMObjectWrapper(exec, object)) return wrapper; switch (object->pathSegType()) { diff --git a/WebCore/bindings/js/JSStyleSheetCustom.cpp b/WebCore/bindings/js/JSStyleSheetCustom.cpp index d711b6f..ecfc6a6 100644 --- a/WebCore/bindings/js/JSStyleSheetCustom.cpp +++ b/WebCore/bindings/js/JSStyleSheetCustom.cpp @@ -40,7 +40,7 @@ JSValue toJS(ExecState* exec, JSDOMGlobalObject* globalObject, StyleSheet* style if (!styleSheet) return jsNull(); - DOMObject* wrapper = getCachedDOMObjectWrapper(exec->globalData(), styleSheet); + DOMObject* wrapper = getCachedDOMObjectWrapper(exec, styleSheet); if (wrapper) return wrapper; @@ -68,10 +68,8 @@ void JSStyleSheet::markChildren(MarkStack& markStack) // is kept around, then we want the node to stay around too. One possibility would // be to make ref/deref on the style sheet ref/deref the node instead, but there's // a lot of disentangling of the CSS DOM objects that would need to happen first. - if (Node* ownerNode = sheet->ownerNode()) { - if (JSNode* ownerNodeWrapper = getCachedDOMNodeWrapper(ownerNode->document(), ownerNode)) - markStack.append(ownerNodeWrapper); - } + if (Node* ownerNode = sheet->ownerNode()) + markDOMNodeWrapper(markStack, ownerNode->document(), ownerNode); } } // namespace WebCore diff --git a/WebCore/bindings/js/JSCanvasArrayBufferConstructor.cpp b/WebCore/bindings/js/JSWebGLArrayBufferConstructor.cpp index 93d53ca..9742db7 100644 --- a/WebCore/bindings/js/JSCanvasArrayBufferConstructor.cpp +++ b/WebCore/bindings/js/JSWebGLArrayBufferConstructor.cpp @@ -27,28 +27,28 @@ #if ENABLE(3D_CANVAS) -#include "JSCanvasArrayBufferConstructor.h" +#include "JSWebGLArrayBufferConstructor.h" #include "Document.h" -#include "CanvasArrayBuffer.h" -#include "JSCanvasArrayBuffer.h" +#include "WebGLArrayBuffer.h" +#include "JSWebGLArrayBuffer.h" namespace WebCore { using namespace JSC; -const ClassInfo JSCanvasArrayBufferConstructor::s_info = { "CanvasArrayBufferConstructor", 0, 0, 0 }; +const ClassInfo JSWebGLArrayBufferConstructor::s_info = { "WebGLArrayBufferConstructor", 0, 0, 0 }; -JSCanvasArrayBufferConstructor::JSCanvasArrayBufferConstructor(ExecState* exec, JSDOMGlobalObject* globalObject) - : DOMConstructorObject(JSCanvasArrayBufferConstructor::createStructure(globalObject->objectPrototype()), globalObject) +JSWebGLArrayBufferConstructor::JSWebGLArrayBufferConstructor(ExecState* exec, JSDOMGlobalObject* globalObject) + : DOMConstructorObject(JSWebGLArrayBufferConstructor::createStructure(globalObject->objectPrototype()), globalObject) { - putDirect(exec->propertyNames().prototype, JSCanvasArrayBufferPrototype::self(exec, globalObject), None); + putDirect(exec->propertyNames().prototype, JSWebGLArrayBufferPrototype::self(exec, globalObject), None); putDirect(exec->propertyNames().length, jsNumber(exec, 2), ReadOnly|DontDelete|DontEnum); } static JSObject* constructCanvasArrayBuffer(ExecState* exec, JSObject* constructor, const ArgList& args) { - JSCanvasArrayBufferConstructor* jsConstructor = static_cast<JSCanvasArrayBufferConstructor*>(constructor); + JSWebGLArrayBufferConstructor* jsConstructor = static_cast<JSWebGLArrayBufferConstructor*>(constructor); unsigned int size = 0; if (args.size() == 1) { @@ -56,10 +56,10 @@ static JSObject* constructCanvasArrayBuffer(ExecState* exec, JSObject* construct if (isnan(size)) size = 0; } - return asObject(toJS(exec, jsConstructor->globalObject(), CanvasArrayBuffer::create(size))); + return asObject(toJS(exec, jsConstructor->globalObject(), WebGLArrayBuffer::create(size))); } -JSC::ConstructType JSCanvasArrayBufferConstructor::getConstructData(JSC::ConstructData& constructData) +JSC::ConstructType JSWebGLArrayBufferConstructor::getConstructData(JSC::ConstructData& constructData) { constructData.native.function = constructCanvasArrayBuffer; return ConstructTypeHost; diff --git a/WebCore/bindings/js/JSCanvasArrayBufferConstructor.h b/WebCore/bindings/js/JSWebGLArrayBufferConstructor.h index 5f1254e..98e364b 100644 --- a/WebCore/bindings/js/JSCanvasArrayBufferConstructor.h +++ b/WebCore/bindings/js/JSWebGLArrayBufferConstructor.h @@ -23,26 +23,26 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef JSCanvasArrayBufferConstructor_h -#define JSCanvasArrayBufferConstructor_h +#ifndef JSWebGLArrayBufferConstructor_h +#define JSWebGLArrayBufferConstructor_h #include "JSDOMBinding.h" #include "JSDocument.h" -#include "JSCanvasArrayBuffer.h" +#include "JSWebGLArrayBuffer.h" #include <runtime/Error.h> namespace WebCore { - class CanvasArray; + class WebGLArray; // Template function used by CanvasXXXArrayConstructors template<class C, typename T> - PassRefPtr<CanvasArray> construct(JSC::ExecState* exec, const JSC::ArgList& args) + PassRefPtr<WebGLArray> construct(JSC::ExecState* exec, const JSC::ArgList& args) { // There are 3 constructors: // // 1) (in int size) - // 2) (in CanvasArrayBuffer buffer, [Optional] in int offset, [Optional] in unsigned int length) + // 2) (in WebGLArrayBuffer buffer, [Optional] in int offset, [Optional] in unsigned int length) // 3) (in sequence<T>) - This ends up being a JS "array-like" object // RefPtr<C> arrayObject; @@ -52,7 +52,7 @@ namespace WebCore { return C::create(0, 0, 0); if (args.at(0).isObject()) { - RefPtr<CanvasArrayBuffer> buffer = toCanvasArrayBuffer(args.at(0)); + RefPtr<WebGLArrayBuffer> buffer = toWebGLArrayBuffer(args.at(0)); if (buffer) { int offset = (args.size() > 1) ? args.at(1).toInt32(exec) : 0; unsigned int length = (args.size() > 2) ? static_cast<unsigned int>(args.at(2).toInt32(exec)) : 0; @@ -82,9 +82,9 @@ namespace WebCore { return C::create(size); } - class JSCanvasArrayBufferConstructor : public DOMConstructorObject { + class JSWebGLArrayBufferConstructor : public DOMConstructorObject { public: - JSCanvasArrayBufferConstructor(JSC::ExecState*, JSDOMGlobalObject*); + JSWebGLArrayBufferConstructor(JSC::ExecState*, JSDOMGlobalObject*); static const JSC::ClassInfo s_info; private: @@ -94,4 +94,4 @@ namespace WebCore { } -#endif // JSCanvasArrayBufferConstructor_h +#endif // JSWebGLArrayBufferConstructor_h diff --git a/WebCore/bindings/js/JSWebGLArrayCustom.cpp b/WebCore/bindings/js/JSWebGLArrayCustom.cpp new file mode 100644 index 0000000..9018544 --- /dev/null +++ b/WebCore/bindings/js/JSWebGLArrayCustom.cpp @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2009 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" + +#if ENABLE(3D_CANVAS) + +#include "config.h" +#include "JSWebGLArray.h" +#include "JSWebGLByteArray.h" +#include "JSWebGLUnsignedByteArray.h" +#include "JSWebGLShortArray.h" +#include "JSWebGLUnsignedShortArray.h" +#include "JSWebGLIntArray.h" +#include "JSWebGLUnsignedIntArray.h" +#include "JSWebGLFloatArray.h" + +#include "WebGLArray.h" + +using namespace JSC; + +namespace WebCore { + +JSC::JSValue toJS(JSC::ExecState* exec, JSDOMGlobalObject* globalObject, WebGLArray* object) +{ + if (!object) + return jsUndefined(); + + if (object) { + if (object->isFloatArray()) + return getDOMObjectWrapper<JSWebGLFloatArray>(exec, globalObject, static_cast<WebGLFloatArray*>(object)); + if (object->isUnsignedByteArray()) + return getDOMObjectWrapper<JSWebGLUnsignedByteArray>(exec, globalObject, static_cast<WebGLUnsignedByteArray*>(object)); + if (object->isByteArray()) + return getDOMObjectWrapper<JSWebGLByteArray>(exec, globalObject, static_cast<WebGLByteArray*>(object)); + if (object->isIntArray()) + return getDOMObjectWrapper<JSWebGLIntArray>(exec, globalObject, static_cast<WebGLIntArray*>(object)); + if (object->isUnsignedIntArray()) + return getDOMObjectWrapper<JSWebGLUnsignedIntArray>(exec, globalObject, static_cast<WebGLUnsignedIntArray*>(object)); + if (object->isShortArray()) + return getDOMObjectWrapper<JSWebGLShortArray>(exec, globalObject, static_cast<WebGLShortArray*>(object)); + if (object->isUnsignedShortArray()) + return getDOMObjectWrapper<JSWebGLUnsignedShortArray>(exec, globalObject, static_cast<WebGLUnsignedShortArray*>(object)); + } + return jsUndefined(); +} + +} // namespace WebCore + +#endif // ENABLE(3D_CANVAS) diff --git a/WebCore/bindings/js/JSWebGLArrayHelper.h b/WebCore/bindings/js/JSWebGLArrayHelper.h new file mode 100644 index 0000000..f538cce --- /dev/null +++ b/WebCore/bindings/js/JSWebGLArrayHelper.h @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2009 Apple Inc. All rights reserved. + * Copyright (C) 2009 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef JSWebGLArrayHelper_h +#define JSWebGLArrayHelper_h + +#include <interpreter/CallFrame.h> +#include <runtime/ArgList.h> +#include <runtime/Error.h> +#include <runtime/JSObject.h> +#include <runtime/JSValue.h> + +namespace WebCore { + +template <class T> +JSC::JSValue setWebGLArrayFromArray(JSC::ExecState* exec, T* webGLArray, JSC::ArgList const& args) +{ + if (args.at(0).isObject()) { + // void set(in sequence<long> array, [Optional] in unsigned long offset); + JSC::JSObject* array = JSC::asObject(args.at(0)); + unsigned offset = 0; + if (args.size() == 2) + offset = args.at(1).toInt32(exec); + int length = array->get(exec, JSC::Identifier(exec, "length")).toInt32(exec); + for (int i = 0; i < length; i++) { + JSC::JSValue v = array->get(exec, i); + if (exec->hadException()) + return JSC::jsUndefined(); + webGLArray->set(i + offset, v.toNumber(exec)); + } + + return JSC::jsUndefined(); + } + + return JSC::throwError(exec, JSC::SyntaxError); +} + +} + +#endif // JSWebGLArrayHelper_h diff --git a/WebCore/bindings/js/JSCanvasIntArrayConstructor.cpp b/WebCore/bindings/js/JSWebGLByteArrayConstructor.cpp index 6d57912..7db710f 100644 --- a/WebCore/bindings/js/JSCanvasIntArrayConstructor.cpp +++ b/WebCore/bindings/js/JSWebGLByteArrayConstructor.cpp @@ -27,38 +27,38 @@ #if ENABLE(3D_CANVAS) -#include "JSCanvasIntArrayConstructor.h" +#include "JSWebGLByteArrayConstructor.h" #include "Document.h" -#include "CanvasIntArray.h" -#include "JSCanvasArrayBuffer.h" -#include "JSCanvasArrayBufferConstructor.h" -#include "JSCanvasIntArray.h" +#include "WebGLByteArray.h" +#include "JSWebGLArrayBuffer.h" +#include "JSWebGLArrayBufferConstructor.h" +#include "JSWebGLByteArray.h" #include <runtime/Error.h> namespace WebCore { using namespace JSC; -const ClassInfo JSCanvasIntArrayConstructor::s_info = { "CanvasIntArrayConstructor", &JSCanvasArray::s_info, 0, 0 }; +const ClassInfo JSWebGLByteArrayConstructor::s_info = { "WebGLByteArrayConstructor", &JSWebGLArray::s_info, 0, 0 }; -JSCanvasIntArrayConstructor::JSCanvasIntArrayConstructor(ExecState* exec, JSDOMGlobalObject* globalObject) - : DOMConstructorObject(JSCanvasIntArrayConstructor::createStructure(globalObject->objectPrototype()), globalObject) +JSWebGLByteArrayConstructor::JSWebGLByteArrayConstructor(ExecState* exec, JSDOMGlobalObject* globalObject) + : DOMConstructorObject(JSWebGLByteArrayConstructor::createStructure(globalObject->objectPrototype()), globalObject) { - putDirect(exec->propertyNames().prototype, JSCanvasIntArrayPrototype::self(exec, globalObject), None); + putDirect(exec->propertyNames().prototype, JSWebGLByteArrayPrototype::self(exec, globalObject), None); putDirect(exec->propertyNames().length, jsNumber(exec, 2), ReadOnly|DontDelete|DontEnum); } -static JSObject* constructCanvasIntArray(ExecState* exec, JSObject* constructor, const ArgList& args) +static JSObject* constructCanvasByteArray(ExecState* exec, JSObject* constructor, const ArgList& args) { - JSCanvasIntArrayConstructor* jsConstructor = static_cast<JSCanvasIntArrayConstructor*>(constructor); - RefPtr<CanvasIntArray> array = static_cast<CanvasIntArray*>(construct<CanvasIntArray, int>(exec, args).get()); + JSWebGLByteArrayConstructor* jsConstructor = static_cast<JSWebGLByteArrayConstructor*>(constructor); + RefPtr<WebGLByteArray> array = static_cast<WebGLByteArray*>(construct<WebGLByteArray, signed char>(exec, args).get()); return asObject(toJS(exec, jsConstructor->globalObject(), array.get())); } -JSC::ConstructType JSCanvasIntArrayConstructor::getConstructData(JSC::ConstructData& constructData) +JSC::ConstructType JSWebGLByteArrayConstructor::getConstructData(JSC::ConstructData& constructData) { - constructData.native.function = constructCanvasIntArray; + constructData.native.function = constructCanvasByteArray; return ConstructTypeHost; } diff --git a/WebCore/bindings/js/JSCanvasIntArrayConstructor.h b/WebCore/bindings/js/JSWebGLByteArrayConstructor.h index 5e19652..a201567 100644 --- a/WebCore/bindings/js/JSCanvasIntArrayConstructor.h +++ b/WebCore/bindings/js/JSWebGLByteArrayConstructor.h @@ -23,17 +23,17 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef JSCanvasIntArrayConstructor_h -#define JSCanvasIntArrayConstructor_h +#ifndef JSWebGLByteArrayConstructor_h +#define JSWebGLByteArrayConstructor_h #include "JSDOMBinding.h" #include "JSDocument.h" namespace WebCore { - class JSCanvasIntArrayConstructor : public DOMConstructorObject { + class JSWebGLByteArrayConstructor : public DOMConstructorObject { public: - JSCanvasIntArrayConstructor(JSC::ExecState*, JSDOMGlobalObject*); + JSWebGLByteArrayConstructor(JSC::ExecState*, JSDOMGlobalObject*); static const JSC::ClassInfo s_info; private: @@ -43,4 +43,4 @@ namespace WebCore { } -#endif // JSCanvasIntArrayConstructor_h +#endif // JSWebGLByteArrayConstructor_h diff --git a/WebCore/bindings/js/JSCanvasByteArrayCustom.cpp b/WebCore/bindings/js/JSWebGLByteArrayCustom.cpp index 04697ce..f7872a8 100644 --- a/WebCore/bindings/js/JSCanvasByteArrayCustom.cpp +++ b/WebCore/bindings/js/JSWebGLByteArrayCustom.cpp @@ -27,22 +27,52 @@ #if ENABLE(3D_CANVAS) -#include "JSCanvasByteArray.h" +#include "JSWebGLArrayHelper.h" +#include "JSWebGLByteArray.h" -#include "CanvasByteArray.h" +#include "WebGLByteArray.h" + +#include <runtime/Error.h> using namespace JSC; namespace WebCore { -void JSCanvasByteArray::indexSetter(JSC::ExecState* exec, unsigned index, JSC::JSValue value) +void JSWebGLByteArray::indexSetter(JSC::ExecState* exec, unsigned index, JSC::JSValue value) { impl()->set(index, static_cast<signed char>(value.toInt32(exec))); } -JSC::JSValue toJS(JSC::ExecState* exec, JSDOMGlobalObject* globalObject, CanvasByteArray* object) +JSC::JSValue toJS(JSC::ExecState* exec, JSDOMGlobalObject* globalObject, WebGLByteArray* object) +{ + return getDOMObjectWrapper<JSWebGLByteArray>(exec, globalObject, object); +} + +JSC::JSValue JSWebGLByteArray::set(JSC::ExecState* exec, JSC::ArgList const& args) { - return getDOMObjectWrapper<JSCanvasByteArray>(exec, globalObject, object); + if (args.size() < 1 || args.size() > 2) + return throwError(exec, SyntaxError); + + if (args.size() == 2 && args.at(0).isInt32()) { + // void set(in unsigned long index, in long value); + unsigned index = args.at(0).toUInt32(exec); + impl()->set(index, static_cast<signed char>(args.at(1).toInt32(exec))); + return jsUndefined(); + } + + WebGLByteArray* array = toWebGLByteArray(args.at(0)); + if (array) { + // void set(in WebGLByteArray array, [Optional] in unsigned long offset); + unsigned offset = 0; + if (args.size() == 2) + offset = args.at(1).toInt32(exec); + ExceptionCode ec = 0; + impl()->set(array, offset, ec); + setDOMException(exec, ec); + return jsUndefined(); + } + + return setWebGLArrayFromArray(exec, impl(), args); } } // namespace WebCore diff --git a/WebCore/bindings/js/JSCanvasByteArrayConstructor.cpp b/WebCore/bindings/js/JSWebGLFloatArrayConstructor.cpp index ec1d66d..707fe56 100644 --- a/WebCore/bindings/js/JSCanvasByteArrayConstructor.cpp +++ b/WebCore/bindings/js/JSWebGLFloatArrayConstructor.cpp @@ -27,38 +27,38 @@ #if ENABLE(3D_CANVAS) -#include "JSCanvasByteArrayConstructor.h" +#include "JSWebGLFloatArrayConstructor.h" #include "Document.h" -#include "CanvasByteArray.h" -#include "JSCanvasArrayBuffer.h" -#include "JSCanvasArrayBufferConstructor.h" -#include "JSCanvasByteArray.h" +#include "WebGLFloatArray.h" +#include "JSWebGLArrayBuffer.h" +#include "JSWebGLArrayBufferConstructor.h" +#include "JSWebGLFloatArray.h" #include <runtime/Error.h> namespace WebCore { using namespace JSC; -const ClassInfo JSCanvasByteArrayConstructor::s_info = { "CanvasByteArrayConstructor", &JSCanvasArray::s_info, 0, 0 }; +const ClassInfo JSWebGLFloatArrayConstructor::s_info = { "WebGLFloatArrayConstructor", &JSWebGLArray::s_info, 0, 0 }; -JSCanvasByteArrayConstructor::JSCanvasByteArrayConstructor(ExecState* exec, JSDOMGlobalObject* globalObject) - : DOMConstructorObject(JSCanvasByteArrayConstructor::createStructure(globalObject->objectPrototype()), globalObject) +JSWebGLFloatArrayConstructor::JSWebGLFloatArrayConstructor(ExecState* exec, JSDOMGlobalObject* globalObject) + : DOMConstructorObject(JSWebGLFloatArrayConstructor::createStructure(globalObject->objectPrototype()), globalObject) { - putDirect(exec->propertyNames().prototype, JSCanvasByteArrayPrototype::self(exec, globalObject), None); + putDirect(exec->propertyNames().prototype, JSWebGLFloatArrayPrototype::self(exec, globalObject), None); putDirect(exec->propertyNames().length, jsNumber(exec, 2), ReadOnly|DontDelete|DontEnum); } -static JSObject* constructCanvasByteArray(ExecState* exec, JSObject* constructor, const ArgList& args) +static JSObject* constructCanvasFloatArray(ExecState* exec, JSObject* constructor, const ArgList& args) { - JSCanvasByteArrayConstructor* jsConstructor = static_cast<JSCanvasByteArrayConstructor*>(constructor); - RefPtr<CanvasByteArray> array = static_cast<CanvasByteArray*>(construct<CanvasByteArray, signed char>(exec, args).get()); + JSWebGLFloatArrayConstructor* jsConstructor = static_cast<JSWebGLFloatArrayConstructor*>(constructor); + RefPtr<WebGLFloatArray> array = static_cast<WebGLFloatArray*>(construct<WebGLFloatArray, float>(exec, args).get()); return asObject(toJS(exec, jsConstructor->globalObject(), array.get())); } -JSC::ConstructType JSCanvasByteArrayConstructor::getConstructData(JSC::ConstructData& constructData) +JSC::ConstructType JSWebGLFloatArrayConstructor::getConstructData(JSC::ConstructData& constructData) { - constructData.native.function = constructCanvasByteArray; + constructData.native.function = constructCanvasFloatArray; return ConstructTypeHost; } diff --git a/WebCore/bindings/js/JSCanvasByteArrayConstructor.h b/WebCore/bindings/js/JSWebGLFloatArrayConstructor.h index 4d5dc11..faf90ff 100644 --- a/WebCore/bindings/js/JSCanvasByteArrayConstructor.h +++ b/WebCore/bindings/js/JSWebGLFloatArrayConstructor.h @@ -23,17 +23,17 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef JSCanvasByteArrayConstructor_h -#define JSCanvasByteArrayConstructor_h +#ifndef JSWebGLFloatArrayConstructor_h +#define JSWebGLFloatArrayConstructor_h #include "JSDOMBinding.h" #include "JSDocument.h" namespace WebCore { - class JSCanvasByteArrayConstructor : public DOMConstructorObject { + class JSWebGLFloatArrayConstructor : public DOMConstructorObject { public: - JSCanvasByteArrayConstructor(JSC::ExecState*, JSDOMGlobalObject*); + JSWebGLFloatArrayConstructor(JSC::ExecState*, JSDOMGlobalObject*); static const JSC::ClassInfo s_info; private: @@ -43,4 +43,4 @@ namespace WebCore { } -#endif // JSCanvasByteArrayConstructor_h +#endif // JSWebGLFloatArrayConstructor_h diff --git a/WebCore/bindings/js/JSWebGLFloatArrayCustom.cpp b/WebCore/bindings/js/JSWebGLFloatArrayCustom.cpp new file mode 100644 index 0000000..5f5b24f --- /dev/null +++ b/WebCore/bindings/js/JSWebGLFloatArrayCustom.cpp @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2009 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" + +#if ENABLE(3D_CANVAS) + +#include "JSWebGLArrayHelper.h" +#include "JSWebGLFloatArray.h" + +#include "WebGLFloatArray.h" + +using namespace JSC; + +namespace WebCore { + +void JSWebGLFloatArray::indexSetter(JSC::ExecState* exec, unsigned index, JSC::JSValue value) +{ + impl()->set(index, static_cast<float>(value.toInt32(exec))); +} + +JSC::JSValue toJS(JSC::ExecState* exec, JSDOMGlobalObject* globalObject, WebGLFloatArray* object) +{ + return getDOMObjectWrapper<JSWebGLFloatArray>(exec, globalObject, object); +} + +JSC::JSValue JSWebGLFloatArray::set(JSC::ExecState* exec, JSC::ArgList const& args) +{ + if (args.size() > 2) + return throwError(exec, SyntaxError); + + if (args.size() == 2 && args.at(0).isInt32()) { + // void set(in unsigned long index, in long value); + unsigned index = args.at(0).toUInt32(exec); + impl()->set(index, static_cast<signed char>(args.at(1).toInt32(exec))); + return jsUndefined(); + } + + WebGLFloatArray* array = toWebGLFloatArray(args.at(0)); + if (array) { + // void set(in WebGLFloatArray array, [Optional] in unsigned long offset); + unsigned offset = 0; + if (args.size() == 2) + offset = args.at(1).toInt32(exec); + ExceptionCode ec = 0; + impl()->set(array, offset, ec); + setDOMException(exec, ec); + return jsUndefined(); + } + + return setWebGLArrayFromArray(exec, impl(), args); +} + +} // namespace WebCore + +#endif // ENABLE(3D_CANVAS) diff --git a/WebCore/bindings/js/JSCanvasFloatArrayConstructor.cpp b/WebCore/bindings/js/JSWebGLIntArrayConstructor.cpp index 15e39c2..f2a0922 100644 --- a/WebCore/bindings/js/JSCanvasFloatArrayConstructor.cpp +++ b/WebCore/bindings/js/JSWebGLIntArrayConstructor.cpp @@ -27,38 +27,38 @@ #if ENABLE(3D_CANVAS) -#include "JSCanvasFloatArrayConstructor.h" +#include "JSWebGLIntArrayConstructor.h" #include "Document.h" -#include "CanvasFloatArray.h" -#include "JSCanvasArrayBuffer.h" -#include "JSCanvasArrayBufferConstructor.h" -#include "JSCanvasFloatArray.h" +#include "WebGLIntArray.h" +#include "JSWebGLArrayBuffer.h" +#include "JSWebGLArrayBufferConstructor.h" +#include "JSWebGLIntArray.h" #include <runtime/Error.h> namespace WebCore { using namespace JSC; -const ClassInfo JSCanvasFloatArrayConstructor::s_info = { "CanvasFloatArrayConstructor", &JSCanvasArray::s_info, 0, 0 }; +const ClassInfo JSWebGLIntArrayConstructor::s_info = { "WebGLIntArrayConstructor", &JSWebGLArray::s_info, 0, 0 }; -JSCanvasFloatArrayConstructor::JSCanvasFloatArrayConstructor(ExecState* exec, JSDOMGlobalObject* globalObject) - : DOMConstructorObject(JSCanvasFloatArrayConstructor::createStructure(globalObject->objectPrototype()), globalObject) +JSWebGLIntArrayConstructor::JSWebGLIntArrayConstructor(ExecState* exec, JSDOMGlobalObject* globalObject) + : DOMConstructorObject(JSWebGLIntArrayConstructor::createStructure(globalObject->objectPrototype()), globalObject) { - putDirect(exec->propertyNames().prototype, JSCanvasFloatArrayPrototype::self(exec, globalObject), None); + putDirect(exec->propertyNames().prototype, JSWebGLIntArrayPrototype::self(exec, globalObject), None); putDirect(exec->propertyNames().length, jsNumber(exec, 2), ReadOnly|DontDelete|DontEnum); } -static JSObject* constructCanvasFloatArray(ExecState* exec, JSObject* constructor, const ArgList& args) +static JSObject* constructCanvasIntArray(ExecState* exec, JSObject* constructor, const ArgList& args) { - JSCanvasFloatArrayConstructor* jsConstructor = static_cast<JSCanvasFloatArrayConstructor*>(constructor); - RefPtr<CanvasFloatArray> array = static_cast<CanvasFloatArray*>(construct<CanvasFloatArray, float>(exec, args).get()); + JSWebGLIntArrayConstructor* jsConstructor = static_cast<JSWebGLIntArrayConstructor*>(constructor); + RefPtr<WebGLIntArray> array = static_cast<WebGLIntArray*>(construct<WebGLIntArray, int>(exec, args).get()); return asObject(toJS(exec, jsConstructor->globalObject(), array.get())); } -JSC::ConstructType JSCanvasFloatArrayConstructor::getConstructData(JSC::ConstructData& constructData) +JSC::ConstructType JSWebGLIntArrayConstructor::getConstructData(JSC::ConstructData& constructData) { - constructData.native.function = constructCanvasFloatArray; + constructData.native.function = constructCanvasIntArray; return ConstructTypeHost; } diff --git a/WebCore/bindings/js/JSCanvasShortArrayConstructor.h b/WebCore/bindings/js/JSWebGLIntArrayConstructor.h index df21825..d42c046 100644 --- a/WebCore/bindings/js/JSCanvasShortArrayConstructor.h +++ b/WebCore/bindings/js/JSWebGLIntArrayConstructor.h @@ -23,17 +23,17 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef JSCanvasShortArrayConstructor_h -#define JSCanvasShortArrayConstructor_h +#ifndef JSWebGLIntArrayConstructor_h +#define JSWebGLIntArrayConstructor_h #include "JSDOMBinding.h" #include "JSDocument.h" namespace WebCore { - class JSCanvasShortArrayConstructor : public DOMConstructorObject { + class JSWebGLIntArrayConstructor : public DOMConstructorObject { public: - JSCanvasShortArrayConstructor(JSC::ExecState*, JSDOMGlobalObject*); + JSWebGLIntArrayConstructor(JSC::ExecState*, JSDOMGlobalObject*); static const JSC::ClassInfo s_info; private: @@ -43,4 +43,4 @@ namespace WebCore { } -#endif // JSCanvasShortArrayConstructor_h +#endif // JSWebGLIntArrayConstructor_h diff --git a/WebCore/bindings/js/JSCanvasIntArrayCustom.cpp b/WebCore/bindings/js/JSWebGLIntArrayCustom.cpp index 8442b87..9c384d8 100644 --- a/WebCore/bindings/js/JSCanvasIntArrayCustom.cpp +++ b/WebCore/bindings/js/JSWebGLIntArrayCustom.cpp @@ -27,22 +27,50 @@ #if ENABLE(3D_CANVAS) -#include "JSCanvasIntArray.h" +#include "JSWebGLArrayHelper.h" +#include "JSWebGLIntArray.h" -#include "CanvasIntArray.h" +#include "WebGLIntArray.h" using namespace JSC; namespace WebCore { -void JSCanvasIntArray::indexSetter(JSC::ExecState* exec, unsigned index, JSC::JSValue value) +void JSWebGLIntArray::indexSetter(JSC::ExecState* exec, unsigned index, JSC::JSValue value) { impl()->set(index, static_cast<signed int>(value.toInt32(exec))); } -JSC::JSValue toJS(JSC::ExecState* exec, JSDOMGlobalObject* globalObject, CanvasIntArray* object) +JSC::JSValue toJS(JSC::ExecState* exec, JSDOMGlobalObject* globalObject, WebGLIntArray* object) { - return getDOMObjectWrapper<JSCanvasIntArray>(exec, globalObject, object); + return getDOMObjectWrapper<JSWebGLIntArray>(exec, globalObject, object); +} + +JSC::JSValue JSWebGLIntArray::set(JSC::ExecState* exec, JSC::ArgList const& args) +{ + if (args.size() > 2) + return throwError(exec, SyntaxError); + + if (args.size() == 2 && args.at(0).isInt32()) { + // void set(in unsigned long index, in long value); + unsigned index = args.at(0).toUInt32(exec); + impl()->set(index, static_cast<signed char>(args.at(1).toInt32(exec))); + return jsUndefined(); + } + + WebGLIntArray* array = toWebGLIntArray(args.at(0)); + if (array) { + // void set(in WebGLIntArray array, [Optional] in unsigned long offset); + unsigned offset = 0; + if (args.size() == 2) + offset = args.at(1).toInt32(exec); + ExceptionCode ec = 0; + impl()->set(array, offset, ec); + setDOMException(exec, ec); + return jsUndefined(); + } + + return setWebGLArrayFromArray(exec, impl(), args); } } // namespace WebCore diff --git a/WebCore/bindings/js/JSWebGLRenderingContextCustom.cpp b/WebCore/bindings/js/JSWebGLRenderingContextCustom.cpp new file mode 100644 index 0000000..3de9606 --- /dev/null +++ b/WebCore/bindings/js/JSWebGLRenderingContextCustom.cpp @@ -0,0 +1,708 @@ +/* + * Copyright (C) 2009 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" + +#if ENABLE(3D_CANVAS) + +#include "JSWebGLRenderingContext.h" + +#include "WebGLRenderingContext.h" +#include "ExceptionCode.h" +#include "HTMLCanvasElement.h" +#include "HTMLImageElement.h" +#include "JSHTMLCanvasElement.h" +#include "JSHTMLImageElement.h" +#include "JSWebGLBuffer.h" +#include "JSWebGLFloatArray.h" +#include "JSWebGLFramebuffer.h" +#include "JSWebGLIntArray.h" +#include "JSWebGLProgram.h" +#include "JSWebGLRenderbuffer.h" +#include "JSWebGLShader.h" +#include "JSWebGLTexture.h" +#include "JSWebGLUniformLocation.h" +#include "JSWebGLUnsignedByteArray.h" +#include "JSWebKitCSSMatrix.h" +#include "NotImplemented.h" +#include "WebGLBuffer.h" +#include "WebGLGetInfo.h" +#include "WebGLFloatArray.h" +#include "WebGLFramebuffer.h" +#include "WebGLIntArray.h" +#include "WebGLProgram.h" +#include <runtime/Error.h> +#include <wtf/FastMalloc.h> +#include <wtf/OwnFastMallocPtr.h> + +using namespace JSC; + +namespace WebCore { + +JSValue JSWebGLRenderingContext::bufferData(JSC::ExecState* exec, JSC::ArgList const& args) +{ + if (args.size() != 3) + return throwError(exec, SyntaxError); + + unsigned target = args.at(0).toInt32(exec); + unsigned usage = args.at(2).toInt32(exec); + ExceptionCode ec = 0; + + // If argument 1 is a number, we are initializing this buffer to that size + if (!args.at(1).isObject()) { + unsigned int count = args.at(1).toInt32(exec); + static_cast<WebGLRenderingContext*>(impl())->bufferData(target, count, usage, ec); + } else { + WebGLArray* array = toWebGLArray(args.at(1)); + static_cast<WebGLRenderingContext*>(impl())->bufferData(target, array, usage, ec); + } + + if (ec != 0) + setDOMException(exec, ec); + return jsUndefined(); +} + +JSValue JSWebGLRenderingContext::bufferSubData(JSC::ExecState* exec, JSC::ArgList const& args) +{ + if (args.size() != 3) + return throwError(exec, SyntaxError); + + unsigned target = args.at(0).toInt32(exec); + unsigned offset = args.at(1).toInt32(exec); + ExceptionCode ec = 0; + + WebGLArray* array = toWebGLArray(args.at(2)); + + static_cast<WebGLRenderingContext*>(impl())->bufferSubData(target, offset, array, ec); + + if (ec != 0) + setDOMException(exec, ec); + return jsUndefined(); +} + +static JSValue toJS(ExecState* exec, JSDOMGlobalObject* globalObject, const WebGLGetInfo& info) +{ + switch (info.getType()) { + case WebGLGetInfo::kTypeBool: + return jsBoolean(info.getBool()); + case WebGLGetInfo::kTypeFloat: + return jsNumber(exec, info.getFloat()); + case WebGLGetInfo::kTypeLong: + return jsNumber(exec, info.getLong()); + case WebGLGetInfo::kTypeNull: + return jsNull(); + case WebGLGetInfo::kTypeString: + return jsString(exec, info.getString()); + case WebGLGetInfo::kTypeUnsignedLong: + return jsNumber(exec, info.getUnsignedLong()); + case WebGLGetInfo::kTypeWebGLBuffer: + return toJS(exec, globalObject, info.getWebGLBuffer()); + case WebGLGetInfo::kTypeWebGLFloatArray: + return toJS(exec, globalObject, info.getWebGLFloatArray()); + case WebGLGetInfo::kTypeWebGLFramebuffer: + return toJS(exec, globalObject, info.getWebGLFramebuffer()); + case WebGLGetInfo::kTypeWebGLIntArray: + return toJS(exec, globalObject, info.getWebGLIntArray()); + // FIXME: implement WebGLObjectArray + // case WebGLGetInfo::kTypeWebGLObjectArray: + case WebGLGetInfo::kTypeWebGLProgram: + return toJS(exec, globalObject, info.getWebGLProgram()); + case WebGLGetInfo::kTypeWebGLRenderbuffer: + return toJS(exec, globalObject, info.getWebGLRenderbuffer()); + case WebGLGetInfo::kTypeWebGLTexture: + return toJS(exec, globalObject, info.getWebGLTexture()); + case WebGLGetInfo::kTypeWebGLUnsignedByteArray: + return toJS(exec, globalObject, info.getWebGLUnsignedByteArray()); + default: + notImplemented(); + return jsUndefined(); + } +} + +enum ObjectType { + kBuffer, kRenderbuffer, kTexture, kVertexAttrib +}; + +static JSValue getObjectParameter(JSWebGLRenderingContext* obj, ExecState* exec, const ArgList& args, ObjectType objectType) +{ + if (args.size() != 2) + return throwError(exec, SyntaxError); + + ExceptionCode ec = 0; + WebGLRenderingContext* context = static_cast<WebGLRenderingContext*>(obj->impl()); + unsigned target = args.at(0).toInt32(exec); + if (exec->hadException()) + return jsUndefined(); + unsigned pname = args.at(1).toInt32(exec); + if (exec->hadException()) + return jsUndefined(); + WebGLGetInfo info; + switch (objectType) { + case kBuffer: + info = context->getBufferParameter(target, pname, ec); + break; + case kRenderbuffer: + info = context->getRenderbufferParameter(target, pname, ec); + break; + case kTexture: + info = context->getTexParameter(target, pname, ec); + break; + case kVertexAttrib: + // target => index + info = context->getVertexAttrib(target, pname, ec); + break; + default: + notImplemented(); + break; + } + if (ec) { + setDOMException(exec, ec); + return jsUndefined(); + } + return toJS(exec, obj->globalObject(), info); +} + +enum WhichProgramCall { + kProgramParameter, kUniform +}; + +JSValue JSWebGLRenderingContext::getBufferParameter(ExecState* exec, const ArgList& args) +{ + return getObjectParameter(this, exec, args, kBuffer); +} + +JSValue JSWebGLRenderingContext::getFramebufferAttachmentParameter(ExecState* exec, const ArgList& args) +{ + if (args.size() != 3) + return throwError(exec, SyntaxError); + + ExceptionCode ec = 0; + WebGLRenderingContext* context = static_cast<WebGLRenderingContext*>(impl()); + unsigned target = args.at(0).toInt32(exec); + if (exec->hadException()) + return jsUndefined(); + unsigned attachment = args.at(1).toInt32(exec); + if (exec->hadException()) + return jsUndefined(); + unsigned pname = args.at(2).toInt32(exec); + if (exec->hadException()) + return jsUndefined(); + WebGLGetInfo info = context->getFramebufferAttachmentParameter(target, attachment, pname, ec); + if (ec) { + setDOMException(exec, ec); + return jsUndefined(); + } + return toJS(exec, globalObject(), info); +} + +JSValue JSWebGLRenderingContext::getParameter(ExecState* exec, const ArgList& args) +{ + if (args.size() != 1) + return throwError(exec, SyntaxError); + + ExceptionCode ec = 0; + WebGLRenderingContext* context = static_cast<WebGLRenderingContext*>(impl()); + unsigned pname = args.at(0).toInt32(exec); + if (exec->hadException()) + return jsUndefined(); + WebGLGetInfo info = context->getParameter(pname, ec); + if (ec) { + setDOMException(exec, ec); + return jsUndefined(); + } + return toJS(exec, globalObject(), info); +} + +JSValue JSWebGLRenderingContext::getProgramParameter(ExecState* exec, const ArgList& args) +{ + if (args.size() != 2) + return throwError(exec, SyntaxError); + + ExceptionCode ec = 0; + WebGLRenderingContext* context = static_cast<WebGLRenderingContext*>(impl()); + WebGLProgram* program = toWebGLProgram(args.at(0)); + unsigned pname = args.at(1).toInt32(exec); + if (exec->hadException()) + return jsUndefined(); + WebGLGetInfo info = context->getProgramParameter(program, pname, ec); + if (ec) { + setDOMException(exec, ec); + return jsUndefined(); + } + return toJS(exec, globalObject(), info); +} + +JSValue JSWebGLRenderingContext::getRenderbufferParameter(ExecState* exec, const ArgList& args) +{ + return getObjectParameter(this, exec, args, kRenderbuffer); +} + +JSValue JSWebGLRenderingContext::getShaderParameter(ExecState* exec, const ArgList& args) +{ + if (args.size() != 2) + return throwError(exec, SyntaxError); + + ExceptionCode ec = 0; + WebGLRenderingContext* context = static_cast<WebGLRenderingContext*>(impl()); + WebGLShader* shader = toWebGLShader(args.at(0)); + unsigned pname = args.at(1).toInt32(exec); + if (exec->hadException()) + return jsUndefined(); + WebGLGetInfo info = context->getShaderParameter(shader, pname, ec); + if (ec) { + setDOMException(exec, ec); + return jsUndefined(); + } + return toJS(exec, globalObject(), info); +} + +JSValue JSWebGLRenderingContext::getTexParameter(ExecState* exec, const ArgList& args) +{ + return getObjectParameter(this, exec, args, kTexture); +} + +JSValue JSWebGLRenderingContext::getUniform(ExecState* exec, const ArgList& args) +{ + if (args.size() != 2) + return throwError(exec, SyntaxError); + + ExceptionCode ec = 0; + WebGLRenderingContext* context = static_cast<WebGLRenderingContext*>(impl()); + WebGLProgram* program = toWebGLProgram(args.at(0)); + WebGLUniformLocation* loc = toWebGLUniformLocation(args.at(1)); + if (exec->hadException()) + return jsUndefined(); + WebGLGetInfo info = context->getUniform(program, loc, ec); + if (ec) { + setDOMException(exec, ec); + return jsUndefined(); + } + return toJS(exec, globalObject(), info); +} + +JSValue JSWebGLRenderingContext::getVertexAttrib(ExecState* exec, const ArgList& args) +{ + return getObjectParameter(this, exec, args, kVertexAttrib); +} + +// void texImage2DHTML(in unsigned long target, in unsigned long level, in HTMLImageElement image); +JSValue JSWebGLRenderingContext::texImage2D(ExecState* exec, const ArgList& args) +{ + if (args.size() < 3) + return throwError(exec, SyntaxError); + + ExceptionCode ec = 0; + WebGLRenderingContext* context = static_cast<WebGLRenderingContext*>(impl()); + unsigned target = args.at(0).toInt32(exec); + if (exec->hadException()) + return jsUndefined(); + + unsigned level = args.at(1).toInt32(exec); + if (exec->hadException()) + return jsUndefined(); + + if (args.size() > 5) { + // This must be the bare array case. + if (args.size() != 9) + return throwError(exec, SyntaxError); + + unsigned internalformat = args.at(2).toInt32(exec); + if (exec->hadException()) + return jsUndefined(); + + unsigned width = args.at(3).toInt32(exec); + if (exec->hadException()) + return jsUndefined(); + + unsigned height = args.at(4).toInt32(exec); + if (exec->hadException()) + return jsUndefined(); + + unsigned border = args.at(5).toInt32(exec); + if (exec->hadException()) + return jsUndefined(); + + unsigned format = args.at(6).toInt32(exec); + if (exec->hadException()) + return jsUndefined(); + + unsigned type = args.at(7).toInt32(exec); + if (exec->hadException()) + return jsUndefined(); + + WebGLArray* array = toWebGLArray(args.at(8)); + if (exec->hadException()) + return jsUndefined(); + + if (!array) + return throwError(exec, TypeError); + + // FIXME: Need to check to make sure WebGLArray is a WebGLByteArray or WebGLShortArray, + // depending on the passed type parameter. + + context->texImage2D(target, level, internalformat, width, height, border, format, type, array, ec); + return jsUndefined(); + } + + // The image parameter can be a <img> or <canvas> element. + JSValue value = args.at(2); + if (!value.isObject()) + return throwError(exec, TypeError); + JSObject* o = asObject(value); + + bool flipY = (args.size() > 3) ? args.at(3).toBoolean(exec) : false; + bool premultiplyAlpha = (args.size() > 4) ? args.at(3).toBoolean(exec) : false; + + if (o->inherits(&JSHTMLImageElement::s_info)) { + HTMLImageElement* imgElt = static_cast<HTMLImageElement*>(static_cast<JSHTMLElement*>(o)->impl()); + context->texImage2D(target, level, imgElt, flipY, premultiplyAlpha, ec); + } else if (o->inherits(&JSHTMLCanvasElement::s_info)) { + HTMLCanvasElement* canvas = static_cast<HTMLCanvasElement*>(static_cast<JSHTMLElement*>(o)->impl()); + context->texImage2D(target, level, canvas, flipY, premultiplyAlpha, ec); + } else { + setDOMException(exec, TYPE_MISMATCH_ERR); + } + + return jsUndefined(); +} + +// void texSubImage2DHTML(in unsigned long target, in unsigned long level, in unsigned long xoff, in unsigned long yoff, in unsigned long width, in unsigned long height, in HTMLImageElement image); +JSValue JSWebGLRenderingContext::texSubImage2D(ExecState* exec, const ArgList& args) +{ + if (args.size() < 7 || args.size() > 9) + return throwError(exec, SyntaxError); + + WebGLRenderingContext* context = static_cast<WebGLRenderingContext*>(impl()); + unsigned target = args.at(0).toInt32(exec); + unsigned level = args.at(1).toInt32(exec); + unsigned xoff = args.at(2).toInt32(exec); + unsigned yoff = args.at(3).toInt32(exec); + unsigned width = args.at(4).toInt32(exec); + unsigned height = args.at(5).toInt32(exec); + + // The image parameter can be a <img> or <canvas> element. + JSValue value = args.at(6); + if (!value.isObject()) + return throwError(exec, TypeError); + JSObject* o = asObject(value); + + bool flipY = (args.size() > 3) ? args.at(3).toBoolean(exec) : false; + bool premultiplyAlpha = (args.size() > 4) ? args.at(3).toBoolean(exec) : false; + + ExceptionCode ec = 0; + if (o->inherits(&JSHTMLImageElement::s_info)) { + HTMLImageElement* imgElt = static_cast<HTMLImageElement*>(static_cast<JSHTMLElement*>(o)->impl()); + context->texSubImage2D(target, level, xoff, yoff, width, height, imgElt, flipY, premultiplyAlpha, ec); + } else if (o->inherits(&JSHTMLCanvasElement::s_info)) { + HTMLCanvasElement* canvas = static_cast<HTMLCanvasElement*>(static_cast<JSHTMLElement*>(o)->impl()); + context->texSubImage2D(target, level, xoff, yoff, width, height, canvas, flipY, premultiplyAlpha, ec); + } else + ec = TYPE_MISMATCH_ERR; + + if (ec != 0) + setDOMException(exec, ec); + return jsUndefined(); +} + +template<typename T> +void toArray(JSC::ExecState* exec, JSC::JSValue value, T*& array, int& size) +{ + array = 0; + + if (!value.isObject()) + return; + + JSC::JSObject* object = asObject(value); + int length = object->get(exec, JSC::Identifier(exec, "length")).toInt32(exec); + void* tempValues; + if (!tryFastMalloc(length * sizeof(T)).getValue(tempValues)) + return; + + T* values = static_cast<T*>(tempValues); + for (int i = 0; i < length; ++i) { + JSC::JSValue v = object->get(exec, i); + if (exec->hadException()) + return; + values[i] = static_cast<T>(v.toNumber(exec)); + } + + array = values; + size = length; +} + +enum DataFunctionToCall { + f_uniform1v, f_uniform2v, f_uniform3v, f_uniform4v, + f_vertexAttrib1v, f_vertexAttrib2v, f_vertexAttrib3v, f_vertexAttrib4v +}; + +enum DataFunctionMatrixToCall { + f_uniformMatrix2fv, f_uniformMatrix3fv, f_uniformMatrix4fv +}; + +static bool functionForUniform(DataFunctionToCall f) +{ + switch (f) { + case f_uniform1v: + case f_uniform2v: + case f_uniform3v: + case f_uniform4v: + return true; + break; + default: break; + } + return false; +} + +static JSC::JSValue dataFunctionf(DataFunctionToCall f, JSC::ExecState* exec, const JSC::ArgList& args, WebGLRenderingContext* context) +{ + if (args.size() != 2) + return throwError(exec, SyntaxError); + + WebGLUniformLocation* location = 0; + long index = -1; + + if (functionForUniform(f)) + location = toWebGLUniformLocation(args.at(0)); + else + index = args.at(0).toInt32(exec); + + if (exec->hadException()) + return jsUndefined(); + + RefPtr<WebGLFloatArray> webGLArray = toWebGLFloatArray(args.at(1)); + if (exec->hadException()) + return jsUndefined(); + + ExceptionCode ec = 0; + if (webGLArray) { + switch(f) { + case f_uniform1v: context->uniform1fv(location, webGLArray.get(), ec); break; + case f_uniform2v: context->uniform2fv(location, webGLArray.get(), ec); break; + case f_uniform3v: context->uniform3fv(location, webGLArray.get(), ec); break; + case f_uniform4v: context->uniform4fv(location, webGLArray.get(), ec); break; + case f_vertexAttrib1v: context->vertexAttrib1fv(index, webGLArray.get()); break; + case f_vertexAttrib2v: context->vertexAttrib2fv(index, webGLArray.get()); break; + case f_vertexAttrib3v: context->vertexAttrib3fv(index, webGLArray.get()); break; + case f_vertexAttrib4v: context->vertexAttrib4fv(index, webGLArray.get()); break; + } + if (ec != 0) + setDOMException(exec, ec); + return jsUndefined(); + } + + float* array; + int size; + toArray<float>(exec, args.at(1), array, size); + + if (!array) + return throwError(exec, TypeError); + + switch(f) { + case f_uniform1v: context->uniform1fv(location, array, size, ec); break; + case f_uniform2v: context->uniform2fv(location, array, size, ec); break; + case f_uniform3v: context->uniform3fv(location, array, size, ec); break; + case f_uniform4v: context->uniform4fv(location, array, size, ec); break; + case f_vertexAttrib1v: context->vertexAttrib1fv(index, array, size); break; + case f_vertexAttrib2v: context->vertexAttrib2fv(index, array, size); break; + case f_vertexAttrib3v: context->vertexAttrib3fv(index, array, size); break; + case f_vertexAttrib4v: context->vertexAttrib4fv(index, array, size); break; + } + if (ec != 0) + setDOMException(exec, ec); + return jsUndefined(); +} + +static JSC::JSValue dataFunctioni(DataFunctionToCall f, JSC::ExecState* exec, const JSC::ArgList& args, WebGLRenderingContext* context) +{ + if (args.size() != 2) + return throwError(exec, SyntaxError); + + WebGLUniformLocation* location = toWebGLUniformLocation(args.at(0)); + + if (exec->hadException()) + return jsUndefined(); + + RefPtr<WebGLIntArray> webGLArray = toWebGLIntArray(args.at(1)); + if (exec->hadException()) + return jsUndefined(); + + ExceptionCode ec = 0; + if (webGLArray) { + switch(f) { + case f_uniform1v: context->uniform1iv(location, webGLArray.get(), ec); break; + case f_uniform2v: context->uniform2iv(location, webGLArray.get(), ec); break; + case f_uniform3v: context->uniform3iv(location, webGLArray.get(), ec); break; + case f_uniform4v: context->uniform4iv(location, webGLArray.get(), ec); break; + default: break; + } + if (ec != 0) + setDOMException(exec, ec); + return jsUndefined(); + } + + int* array; + int size; + toArray<int>(exec, args.at(1), array, size); + + if (!array) + return throwError(exec, TypeError); + + switch(f) { + case f_uniform1v: context->uniform1iv(location, array, size, ec); break; + case f_uniform2v: context->uniform2iv(location, array, size, ec); break; + case f_uniform3v: context->uniform3iv(location, array, size, ec); break; + case f_uniform4v: context->uniform4iv(location, array, size, ec); break; + default: break; + } + if (ec != 0) + setDOMException(exec, ec); + return jsUndefined(); +} + +static JSC::JSValue dataFunctionMatrix(DataFunctionMatrixToCall f, JSC::ExecState* exec, const JSC::ArgList& args, WebGLRenderingContext* context) +{ + if (args.size() != 3) + return throwError(exec, SyntaxError); + + WebGLUniformLocation* location = toWebGLUniformLocation(args.at(0)); + + if (exec->hadException()) + return jsUndefined(); + + bool transpose = args.at(1).toBoolean(exec); + if (exec->hadException()) + return jsUndefined(); + + RefPtr<WebGLFloatArray> webGLArray = toWebGLFloatArray(args.at(2)); + if (exec->hadException()) + return jsUndefined(); + + ExceptionCode ec = 0; + if (webGLArray) { + switch(f) { + case f_uniformMatrix2fv: context->uniformMatrix2fv(location, transpose, webGLArray.get(), ec); break; + case f_uniformMatrix3fv: context->uniformMatrix3fv(location, transpose, webGLArray.get(), ec); break; + case f_uniformMatrix4fv: context->uniformMatrix4fv(location, transpose, webGLArray.get(), ec); break; + } + if (ec != 0) + setDOMException(exec, ec); + return jsUndefined(); + } + + float* array; + int size; + toArray<float>(exec, args.at(2), array, size); + + if (!array) + return throwError(exec, TypeError); + + switch(f) { + case f_uniformMatrix2fv: context->uniformMatrix2fv(location, transpose, array, size, ec); break; + case f_uniformMatrix3fv: context->uniformMatrix3fv(location, transpose, array, size, ec); break; + case f_uniformMatrix4fv: context->uniformMatrix4fv(location, transpose, array, size, ec); break; + } + if (ec != 0) + setDOMException(exec, ec); + return jsUndefined(); +} + +JSC::JSValue JSWebGLRenderingContext::uniform1fv(JSC::ExecState* exec, const JSC::ArgList& args) +{ + return dataFunctionf(f_uniform1v, exec, args, static_cast<WebGLRenderingContext*>(impl())); +} + +JSC::JSValue JSWebGLRenderingContext::uniform1iv(JSC::ExecState* exec, const JSC::ArgList& args) +{ + return dataFunctioni(f_uniform1v, exec, args, static_cast<WebGLRenderingContext*>(impl())); +} + +JSC::JSValue JSWebGLRenderingContext::uniform2fv(JSC::ExecState* exec, const JSC::ArgList& args) +{ + return dataFunctionf(f_uniform2v, exec, args, static_cast<WebGLRenderingContext*>(impl())); +} + +JSC::JSValue JSWebGLRenderingContext::uniform2iv(JSC::ExecState* exec, const JSC::ArgList& args) +{ + return dataFunctioni(f_uniform2v, exec, args, static_cast<WebGLRenderingContext*>(impl())); +} + +JSC::JSValue JSWebGLRenderingContext::uniform3fv(JSC::ExecState* exec, const JSC::ArgList& args) +{ + return dataFunctionf(f_uniform3v, exec, args, static_cast<WebGLRenderingContext*>(impl())); +} + +JSC::JSValue JSWebGLRenderingContext::uniform3iv(JSC::ExecState* exec, const JSC::ArgList& args) +{ + return dataFunctioni(f_uniform3v, exec, args, static_cast<WebGLRenderingContext*>(impl())); +} + +JSC::JSValue JSWebGLRenderingContext::uniform4fv(JSC::ExecState* exec, const JSC::ArgList& args) +{ + return dataFunctionf(f_uniform4v, exec, args, static_cast<WebGLRenderingContext*>(impl())); +} + +JSC::JSValue JSWebGLRenderingContext::uniform4iv(JSC::ExecState* exec, const JSC::ArgList& args) +{ + return dataFunctioni(f_uniform4v, exec, args, static_cast<WebGLRenderingContext*>(impl())); +} + +JSC::JSValue JSWebGLRenderingContext::uniformMatrix2fv(JSC::ExecState* exec, const JSC::ArgList& args) +{ + return dataFunctionMatrix(f_uniformMatrix2fv, exec, args, static_cast<WebGLRenderingContext*>(impl())); +} + +JSC::JSValue JSWebGLRenderingContext::uniformMatrix3fv(JSC::ExecState* exec, const JSC::ArgList& args) +{ + return dataFunctionMatrix(f_uniformMatrix3fv, exec, args, static_cast<WebGLRenderingContext*>(impl())); +} + +JSC::JSValue JSWebGLRenderingContext::uniformMatrix4fv(JSC::ExecState* exec, const JSC::ArgList& args) +{ + return dataFunctionMatrix(f_uniformMatrix4fv, exec, args, static_cast<WebGLRenderingContext*>(impl())); +} + +JSC::JSValue JSWebGLRenderingContext::vertexAttrib1fv(JSC::ExecState* exec, const JSC::ArgList& args) +{ + return dataFunctionf(f_vertexAttrib1v, exec, args, static_cast<WebGLRenderingContext*>(impl())); +} + +JSC::JSValue JSWebGLRenderingContext::vertexAttrib2fv(JSC::ExecState* exec, const JSC::ArgList& args) +{ + return dataFunctionf(f_vertexAttrib2v, exec, args, static_cast<WebGLRenderingContext*>(impl())); +} + +JSC::JSValue JSWebGLRenderingContext::vertexAttrib3fv(JSC::ExecState* exec, const JSC::ArgList& args) +{ + return dataFunctionf(f_vertexAttrib3v, exec, args, static_cast<WebGLRenderingContext*>(impl())); +} + +JSC::JSValue JSWebGLRenderingContext::vertexAttrib4fv(JSC::ExecState* exec, const JSC::ArgList& args) +{ + return dataFunctionf(f_vertexAttrib4v, exec, args, static_cast<WebGLRenderingContext*>(impl())); +} + +} // namespace WebCore + +#endif // ENABLE(3D_CANVAS) diff --git a/WebCore/bindings/js/JSCanvasShortArrayConstructor.cpp b/WebCore/bindings/js/JSWebGLShortArrayConstructor.cpp index a885b7b..74bfe5c 100644 --- a/WebCore/bindings/js/JSCanvasShortArrayConstructor.cpp +++ b/WebCore/bindings/js/JSWebGLShortArrayConstructor.cpp @@ -27,37 +27,37 @@ #if ENABLE(3D_CANVAS) -#include "JSCanvasShortArrayConstructor.h" +#include "JSWebGLShortArrayConstructor.h" #include "Document.h" -#include "CanvasShortArray.h" -#include "JSCanvasArray.h" -#include "JSCanvasArrayBuffer.h" -#include "JSCanvasArrayBufferConstructor.h" -#include "JSCanvasShortArray.h" +#include "WebGLShortArray.h" +#include "JSWebGLArray.h" +#include "JSWebGLArrayBuffer.h" +#include "JSWebGLArrayBufferConstructor.h" +#include "JSWebGLShortArray.h" #include <runtime/Error.h> namespace WebCore { using namespace JSC; -const ClassInfo JSCanvasShortArrayConstructor::s_info = { "CanvasShortArrayConstructor", &JSCanvasArray::s_info, 0, 0 }; +const ClassInfo JSWebGLShortArrayConstructor::s_info = { "WebGLShortArrayConstructor", &JSWebGLArray::s_info, 0, 0 }; -JSCanvasShortArrayConstructor::JSCanvasShortArrayConstructor(ExecState* exec, JSDOMGlobalObject* globalObject) - : DOMConstructorObject(JSCanvasShortArrayConstructor::createStructure(globalObject->objectPrototype()), globalObject) +JSWebGLShortArrayConstructor::JSWebGLShortArrayConstructor(ExecState* exec, JSDOMGlobalObject* globalObject) + : DOMConstructorObject(JSWebGLShortArrayConstructor::createStructure(globalObject->objectPrototype()), globalObject) { - putDirect(exec->propertyNames().prototype, JSCanvasShortArrayPrototype::self(exec, globalObject), None); + putDirect(exec->propertyNames().prototype, JSWebGLShortArrayPrototype::self(exec, globalObject), None); putDirect(exec->propertyNames().length, jsNumber(exec, 2), ReadOnly|DontDelete|DontEnum); } static JSObject* constructCanvasShortArray(ExecState* exec, JSObject* constructor, const ArgList& args) { - JSCanvasShortArrayConstructor* jsConstructor = static_cast<JSCanvasShortArrayConstructor*>(constructor); - RefPtr<CanvasShortArray> array = static_cast<CanvasShortArray*>(construct<CanvasShortArray, short>(exec, args).get()); + JSWebGLShortArrayConstructor* jsConstructor = static_cast<JSWebGLShortArrayConstructor*>(constructor); + RefPtr<WebGLShortArray> array = static_cast<WebGLShortArray*>(construct<WebGLShortArray, short>(exec, args).get()); return asObject(toJS(exec, jsConstructor->globalObject(), array.get())); } -JSC::ConstructType JSCanvasShortArrayConstructor::getConstructData(JSC::ConstructData& constructData) +JSC::ConstructType JSWebGLShortArrayConstructor::getConstructData(JSC::ConstructData& constructData) { constructData.native.function = constructCanvasShortArray; return ConstructTypeHost; diff --git a/WebCore/bindings/js/JSCanvasFloatArrayConstructor.h b/WebCore/bindings/js/JSWebGLShortArrayConstructor.h index efea250..7807a13 100644 --- a/WebCore/bindings/js/JSCanvasFloatArrayConstructor.h +++ b/WebCore/bindings/js/JSWebGLShortArrayConstructor.h @@ -23,17 +23,17 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef JSCanvasFloatArrayConstructor_h -#define JSCanvasFloatArrayConstructor_h +#ifndef JSWebGLShortArrayConstructor_h +#define JSWebGLShortArrayConstructor_h #include "JSDOMBinding.h" #include "JSDocument.h" namespace WebCore { - class JSCanvasFloatArrayConstructor : public DOMConstructorObject { + class JSWebGLShortArrayConstructor : public DOMConstructorObject { public: - JSCanvasFloatArrayConstructor(JSC::ExecState*, JSDOMGlobalObject*); + JSWebGLShortArrayConstructor(JSC::ExecState*, JSDOMGlobalObject*); static const JSC::ClassInfo s_info; private: @@ -43,4 +43,4 @@ namespace WebCore { } -#endif // JSCanvasFloatArrayConstructor_h +#endif // JSWebGLShortArrayConstructor_h diff --git a/WebCore/bindings/js/JSCanvasShortArrayCustom.cpp b/WebCore/bindings/js/JSWebGLShortArrayCustom.cpp index 21af0a6..462b09a 100644 --- a/WebCore/bindings/js/JSCanvasShortArrayCustom.cpp +++ b/WebCore/bindings/js/JSWebGLShortArrayCustom.cpp @@ -27,22 +27,50 @@ #if ENABLE(3D_CANVAS) -#include "JSCanvasShortArray.h" +#include "JSWebGLArrayHelper.h" +#include "JSWebGLShortArray.h" -#include "CanvasShortArray.h" +#include "WebGLShortArray.h" using namespace JSC; namespace WebCore { -void JSCanvasShortArray::indexSetter(JSC::ExecState* exec, unsigned index, JSC::JSValue value) +void JSWebGLShortArray::indexSetter(JSC::ExecState* exec, unsigned index, JSC::JSValue value) { impl()->set(index, static_cast<signed short>(value.toInt32(exec))); } -JSC::JSValue toJS(JSC::ExecState* exec, JSDOMGlobalObject* globalObject, CanvasShortArray* object) +JSC::JSValue toJS(JSC::ExecState* exec, JSDOMGlobalObject* globalObject, WebGLShortArray* object) { - return getDOMObjectWrapper<JSCanvasShortArray>(exec, globalObject, object); + return getDOMObjectWrapper<JSWebGLShortArray>(exec, globalObject, object); +} + +JSC::JSValue JSWebGLShortArray::set(JSC::ExecState* exec, JSC::ArgList const& args) +{ + if (args.size() > 2) + return throwError(exec, SyntaxError); + + if (args.size() == 2 && args.at(0).isInt32()) { + // void set(in unsigned long index, in long value); + unsigned index = args.at(0).toUInt32(exec); + impl()->set(index, static_cast<signed char>(args.at(1).toInt32(exec))); + return jsUndefined(); + } + + WebGLShortArray* shortArray = toWebGLShortArray(args.at(0)); + if (shortArray) { + // void set(in WebGLShortArray array, [Optional] in unsigned long offset); + unsigned offset = 0; + if (args.size() == 2) + offset = args.at(1).toInt32(exec); + ExceptionCode ec = 0; + impl()->set(shortArray, offset, ec); + setDOMException(exec, ec); + return jsUndefined(); + } + + return setWebGLArrayFromArray(exec, impl(), args); } } // namespace WebCore diff --git a/WebCore/bindings/js/JSCanvasUnsignedByteArrayConstructor.cpp b/WebCore/bindings/js/JSWebGLUnsignedByteArrayConstructor.cpp index 5d0800e..d5597ce 100644 --- a/WebCore/bindings/js/JSCanvasUnsignedByteArrayConstructor.cpp +++ b/WebCore/bindings/js/JSWebGLUnsignedByteArrayConstructor.cpp @@ -27,36 +27,36 @@ #if ENABLE(3D_CANVAS) -#include "JSCanvasUnsignedByteArrayConstructor.h" +#include "JSWebGLUnsignedByteArrayConstructor.h" #include "Document.h" -#include "CanvasUnsignedByteArray.h" -#include "JSCanvasArrayBuffer.h" -#include "JSCanvasArrayBufferConstructor.h" -#include "JSCanvasUnsignedByteArray.h" +#include "WebGLUnsignedByteArray.h" +#include "JSWebGLArrayBuffer.h" +#include "JSWebGLArrayBufferConstructor.h" +#include "JSWebGLUnsignedByteArray.h" #include <runtime/Error.h> namespace WebCore { using namespace JSC; -const ClassInfo JSCanvasUnsignedByteArrayConstructor::s_info = { "CanvasUnsignedByteArrayConstructor", &JSCanvasArray::s_info, 0, 0 }; +const ClassInfo JSWebGLUnsignedByteArrayConstructor::s_info = { "WebGLUnsignedByteArrayConstructor", &JSWebGLArray::s_info, 0, 0 }; -JSCanvasUnsignedByteArrayConstructor::JSCanvasUnsignedByteArrayConstructor(ExecState* exec, JSDOMGlobalObject* globalObject) - : DOMConstructorObject(JSCanvasUnsignedByteArrayConstructor::createStructure(globalObject->objectPrototype()), globalObject) +JSWebGLUnsignedByteArrayConstructor::JSWebGLUnsignedByteArrayConstructor(ExecState* exec, JSDOMGlobalObject* globalObject) + : DOMConstructorObject(JSWebGLUnsignedByteArrayConstructor::createStructure(globalObject->objectPrototype()), globalObject) { - putDirect(exec->propertyNames().prototype, JSCanvasUnsignedByteArrayPrototype::self(exec, globalObject), None); + putDirect(exec->propertyNames().prototype, JSWebGLUnsignedByteArrayPrototype::self(exec, globalObject), None); putDirect(exec->propertyNames().length, jsNumber(exec, 2), ReadOnly|DontDelete|DontEnum); } static JSObject* constructCanvasUnsignedByteArray(ExecState* exec, JSObject* constructor, const ArgList& args) { - JSCanvasUnsignedByteArrayConstructor* jsConstructor = static_cast<JSCanvasUnsignedByteArrayConstructor*>(constructor); - RefPtr<CanvasUnsignedByteArray> array = static_cast<CanvasUnsignedByteArray*>(construct<CanvasUnsignedByteArray, unsigned char>(exec, args).get()); + JSWebGLUnsignedByteArrayConstructor* jsConstructor = static_cast<JSWebGLUnsignedByteArrayConstructor*>(constructor); + RefPtr<WebGLUnsignedByteArray> array = static_cast<WebGLUnsignedByteArray*>(construct<WebGLUnsignedByteArray, unsigned char>(exec, args).get()); return asObject(toJS(exec, jsConstructor->globalObject(), array.get())); } -JSC::ConstructType JSCanvasUnsignedByteArrayConstructor::getConstructData(JSC::ConstructData& constructData) +JSC::ConstructType JSWebGLUnsignedByteArrayConstructor::getConstructData(JSC::ConstructData& constructData) { constructData.native.function = constructCanvasUnsignedByteArray; return ConstructTypeHost; diff --git a/WebCore/bindings/js/JSCanvasUnsignedIntArrayConstructor.h b/WebCore/bindings/js/JSWebGLUnsignedByteArrayConstructor.h index 6016159..d90ce96 100644 --- a/WebCore/bindings/js/JSCanvasUnsignedIntArrayConstructor.h +++ b/WebCore/bindings/js/JSWebGLUnsignedByteArrayConstructor.h @@ -23,17 +23,17 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef JSCanvasUnsignedIntArrayConstructor_h -#define JSCanvasUnsignedIntArrayConstructor_h +#ifndef JSWebGLUnsignedByteArrayConstructor_h +#define JSWebGLUnsignedByteArrayConstructor_h #include "JSDOMBinding.h" #include "JSDocument.h" namespace WebCore { - class JSCanvasUnsignedIntArrayConstructor : public DOMConstructorObject { + class JSWebGLUnsignedByteArrayConstructor : public DOMConstructorObject { public: - JSCanvasUnsignedIntArrayConstructor(JSC::ExecState*, JSDOMGlobalObject*); + JSWebGLUnsignedByteArrayConstructor(JSC::ExecState*, JSDOMGlobalObject*); static const JSC::ClassInfo s_info; private: @@ -43,4 +43,4 @@ namespace WebCore { } -#endif // JSCanvasUnsignedIntArrayConstructor_h +#endif // JSWebGLUnsignedByteArrayConstructor_h diff --git a/WebCore/bindings/js/JSCanvasUnsignedByteArrayCustom.cpp b/WebCore/bindings/js/JSWebGLUnsignedByteArrayCustom.cpp index f2b0c74..35a545d 100644 --- a/WebCore/bindings/js/JSCanvasUnsignedByteArrayCustom.cpp +++ b/WebCore/bindings/js/JSWebGLUnsignedByteArrayCustom.cpp @@ -27,22 +27,50 @@ #if ENABLE(3D_CANVAS) -#include "JSCanvasUnsignedByteArray.h" +#include "JSWebGLArrayHelper.h" +#include "JSWebGLUnsignedByteArray.h" -#include "CanvasUnsignedByteArray.h" +#include "WebGLUnsignedByteArray.h" using namespace JSC; namespace WebCore { -void JSCanvasUnsignedByteArray::indexSetter(JSC::ExecState* exec, unsigned index, JSC::JSValue value) +void JSWebGLUnsignedByteArray::indexSetter(JSC::ExecState* exec, unsigned index, JSC::JSValue value) { impl()->set(index, static_cast<unsigned char>(value.toInt32(exec))); } -JSC::JSValue toJS(JSC::ExecState* exec, JSDOMGlobalObject* globalObject, CanvasUnsignedByteArray* object) +JSC::JSValue toJS(JSC::ExecState* exec, JSDOMGlobalObject* globalObject, WebGLUnsignedByteArray* object) { - return getDOMObjectWrapper<JSCanvasUnsignedByteArray>(exec, globalObject, object); + return getDOMObjectWrapper<JSWebGLUnsignedByteArray>(exec, globalObject, object); +} + +JSC::JSValue JSWebGLUnsignedByteArray::set(JSC::ExecState* exec, JSC::ArgList const& args) +{ + if (args.size() > 2) + return throwError(exec, SyntaxError); + + if (args.size() == 2 && args.at(0).isInt32()) { + // void set(in unsigned long index, in long value); + unsigned index = args.at(0).toUInt32(exec); + impl()->set(index, static_cast<signed char>(args.at(1).toInt32(exec))); + return jsUndefined(); + } + + WebGLUnsignedByteArray* array = toWebGLUnsignedByteArray(args.at(0)); + if (array) { + // void set(in WebGLUnsignedByteArray array, [Optional] in unsigned long offset); + unsigned offset = 0; + if (args.size() == 2) + offset = args.at(1).toInt32(exec); + ExceptionCode ec = 0; + impl()->set(array, offset, ec); + setDOMException(exec, ec); + return jsUndefined(); + } + + return setWebGLArrayFromArray(exec, impl(), args); } } // namespace WebCore diff --git a/WebCore/bindings/js/JSCanvasUnsignedIntArrayConstructor.cpp b/WebCore/bindings/js/JSWebGLUnsignedIntArrayConstructor.cpp index 5f145a7..6fafa81 100644 --- a/WebCore/bindings/js/JSCanvasUnsignedIntArrayConstructor.cpp +++ b/WebCore/bindings/js/JSWebGLUnsignedIntArrayConstructor.cpp @@ -27,36 +27,36 @@ #if ENABLE(3D_CANVAS) -#include "JSCanvasUnsignedIntArrayConstructor.h" +#include "JSWebGLUnsignedIntArrayConstructor.h" #include "Document.h" -#include "CanvasUnsignedIntArray.h" -#include "JSCanvasArrayBuffer.h" -#include "JSCanvasArrayBufferConstructor.h" -#include "JSCanvasUnsignedIntArray.h" +#include "WebGLUnsignedIntArray.h" +#include "JSWebGLArrayBuffer.h" +#include "JSWebGLArrayBufferConstructor.h" +#include "JSWebGLUnsignedIntArray.h" #include <runtime/Error.h> namespace WebCore { using namespace JSC; -const ClassInfo JSCanvasUnsignedIntArrayConstructor::s_info = { "CanvasUnsignedIntArrayConstructor", &JSCanvasArray::s_info, 0, 0 }; +const ClassInfo JSWebGLUnsignedIntArrayConstructor::s_info = { "WebGLUnsignedIntArrayConstructor", &JSWebGLArray::s_info, 0, 0 }; -JSCanvasUnsignedIntArrayConstructor::JSCanvasUnsignedIntArrayConstructor(ExecState* exec, JSDOMGlobalObject* globalObject) - : DOMConstructorObject(JSCanvasUnsignedIntArrayConstructor::createStructure(globalObject->objectPrototype()), globalObject) +JSWebGLUnsignedIntArrayConstructor::JSWebGLUnsignedIntArrayConstructor(ExecState* exec, JSDOMGlobalObject* globalObject) + : DOMConstructorObject(JSWebGLUnsignedIntArrayConstructor::createStructure(globalObject->objectPrototype()), globalObject) { - putDirect(exec->propertyNames().prototype, JSCanvasUnsignedIntArrayPrototype::self(exec, globalObject), None); + putDirect(exec->propertyNames().prototype, JSWebGLUnsignedIntArrayPrototype::self(exec, globalObject), None); putDirect(exec->propertyNames().length, jsNumber(exec, 2), ReadOnly|DontDelete|DontEnum); } static JSObject* constructCanvasUnsignedIntArray(ExecState* exec, JSObject* constructor, const ArgList& args) { - JSCanvasUnsignedIntArrayConstructor* jsConstructor = static_cast<JSCanvasUnsignedIntArrayConstructor*>(constructor); - RefPtr<CanvasUnsignedIntArray> array = static_cast<CanvasUnsignedIntArray*>(construct<CanvasUnsignedIntArray, unsigned int>(exec, args).get()); + JSWebGLUnsignedIntArrayConstructor* jsConstructor = static_cast<JSWebGLUnsignedIntArrayConstructor*>(constructor); + RefPtr<WebGLUnsignedIntArray> array = static_cast<WebGLUnsignedIntArray*>(construct<WebGLUnsignedIntArray, unsigned int>(exec, args).get()); return asObject(toJS(exec, jsConstructor->globalObject(), array.get())); } -JSC::ConstructType JSCanvasUnsignedIntArrayConstructor::getConstructData(JSC::ConstructData& constructData) +JSC::ConstructType JSWebGLUnsignedIntArrayConstructor::getConstructData(JSC::ConstructData& constructData) { constructData.native.function = constructCanvasUnsignedIntArray; return ConstructTypeHost; diff --git a/WebCore/bindings/js/JSWebGLUnsignedIntArrayConstructor.h b/WebCore/bindings/js/JSWebGLUnsignedIntArrayConstructor.h new file mode 100644 index 0000000..7eabbc1 --- /dev/null +++ b/WebCore/bindings/js/JSWebGLUnsignedIntArrayConstructor.h @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2009 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef JSWebGLUnsignedIntArrayConstructor_h +#define JSWebGLUnsignedIntArrayConstructor_h + +#include "JSDOMBinding.h" +#include "JSDocument.h" + +namespace WebCore { + + class JSWebGLUnsignedIntArrayConstructor : public DOMConstructorObject { + public: + JSWebGLUnsignedIntArrayConstructor(JSC::ExecState*, JSDOMGlobalObject*); + static const JSC::ClassInfo s_info; + + private: + virtual JSC::ConstructType getConstructData(JSC::ConstructData&); + virtual const JSC::ClassInfo* classInfo() const { return &s_info; } + }; + +} + +#endif // JSWebGLUnsignedIntArrayConstructor_h diff --git a/WebCore/bindings/js/JSCanvasUnsignedIntArrayCustom.cpp b/WebCore/bindings/js/JSWebGLUnsignedIntArrayCustom.cpp index 95a80a7..ea28111 100644 --- a/WebCore/bindings/js/JSCanvasUnsignedIntArrayCustom.cpp +++ b/WebCore/bindings/js/JSWebGLUnsignedIntArrayCustom.cpp @@ -27,22 +27,50 @@ #if ENABLE(3D_CANVAS) -#include "JSCanvasUnsignedIntArray.h" +#include "JSWebGLArrayHelper.h" +#include "JSWebGLUnsignedIntArray.h" -#include "CanvasUnsignedIntArray.h" +#include "WebGLUnsignedIntArray.h" using namespace JSC; namespace WebCore { -void JSCanvasUnsignedIntArray::indexSetter(JSC::ExecState* exec, unsigned index, JSC::JSValue value) +void JSWebGLUnsignedIntArray::indexSetter(JSC::ExecState* exec, unsigned index, JSC::JSValue value) { impl()->set(index, static_cast<unsigned int>(value.toInt32(exec))); } -JSC::JSValue toJS(JSC::ExecState* exec, JSDOMGlobalObject* globalObject, CanvasUnsignedIntArray* object) +JSC::JSValue toJS(JSC::ExecState* exec, JSDOMGlobalObject* globalObject, WebGLUnsignedIntArray* object) { - return getDOMObjectWrapper<JSCanvasUnsignedIntArray>(exec, globalObject, object); + return getDOMObjectWrapper<JSWebGLUnsignedIntArray>(exec, globalObject, object); +} + +JSC::JSValue JSWebGLUnsignedIntArray::set(JSC::ExecState* exec, JSC::ArgList const& args) +{ + if (args.size() > 2) + return throwError(exec, SyntaxError); + + if (args.size() == 2 && args.at(0).isInt32()) { + // void set(in unsigned long index, in long value); + unsigned index = args.at(0).toUInt32(exec); + impl()->set(index, static_cast<signed char>(args.at(1).toInt32(exec))); + return jsUndefined(); + } + + WebGLUnsignedIntArray* array = toWebGLUnsignedIntArray(args.at(0)); + if (array) { + // void set(in WebGLUnsignedIntArray array, [Optional] in unsigned long offset); + unsigned offset = 0; + if (args.size() == 2) + offset = args.at(1).toInt32(exec); + ExceptionCode ec = 0; + impl()->set(array, offset, ec); + setDOMException(exec, ec); + return jsUndefined(); + } + + return setWebGLArrayFromArray(exec, impl(), args); } } // namespace WebCore diff --git a/WebCore/bindings/js/JSCanvasUnsignedShortArrayConstructor.cpp b/WebCore/bindings/js/JSWebGLUnsignedShortArrayConstructor.cpp index 9735693..deaeffd 100644 --- a/WebCore/bindings/js/JSCanvasUnsignedShortArrayConstructor.cpp +++ b/WebCore/bindings/js/JSWebGLUnsignedShortArrayConstructor.cpp @@ -27,36 +27,36 @@ #if ENABLE(3D_CANVAS) -#include "JSCanvasUnsignedShortArrayConstructor.h" +#include "JSWebGLUnsignedShortArrayConstructor.h" #include "Document.h" -#include "CanvasUnsignedShortArray.h" -#include "JSCanvasArrayBuffer.h" -#include "JSCanvasArrayBufferConstructor.h" -#include "JSCanvasUnsignedShortArray.h" +#include "WebGLUnsignedShortArray.h" +#include "JSWebGLArrayBuffer.h" +#include "JSWebGLArrayBufferConstructor.h" +#include "JSWebGLUnsignedShortArray.h" #include <runtime/Error.h> namespace WebCore { using namespace JSC; -const ClassInfo JSCanvasUnsignedShortArrayConstructor::s_info = { "CanvasUnsignedShortArrayConstructor", &JSCanvasArray::s_info, 0, 0 }; +const ClassInfo JSWebGLUnsignedShortArrayConstructor::s_info = { "WebGLUnsignedShortArrayConstructor", &JSWebGLArray::s_info, 0, 0 }; -JSCanvasUnsignedShortArrayConstructor::JSCanvasUnsignedShortArrayConstructor(ExecState* exec, JSDOMGlobalObject* globalObject) - : DOMConstructorObject(JSCanvasUnsignedShortArrayConstructor::createStructure(globalObject->objectPrototype()), globalObject) +JSWebGLUnsignedShortArrayConstructor::JSWebGLUnsignedShortArrayConstructor(ExecState* exec, JSDOMGlobalObject* globalObject) + : DOMConstructorObject(JSWebGLUnsignedShortArrayConstructor::createStructure(globalObject->objectPrototype()), globalObject) { - putDirect(exec->propertyNames().prototype, JSCanvasUnsignedShortArrayPrototype::self(exec, globalObject), None); + putDirect(exec->propertyNames().prototype, JSWebGLUnsignedShortArrayPrototype::self(exec, globalObject), None); putDirect(exec->propertyNames().length, jsNumber(exec, 2), ReadOnly|DontDelete|DontEnum); } static JSObject* constructCanvasUnsignedShortArray(ExecState* exec, JSObject* constructor, const ArgList& args) { - JSCanvasUnsignedShortArrayConstructor* jsConstructor = static_cast<JSCanvasUnsignedShortArrayConstructor*>(constructor); - RefPtr<CanvasUnsignedShortArray> array = static_cast<CanvasUnsignedShortArray*>(construct<CanvasUnsignedShortArray, unsigned short>(exec, args).get()); + JSWebGLUnsignedShortArrayConstructor* jsConstructor = static_cast<JSWebGLUnsignedShortArrayConstructor*>(constructor); + RefPtr<WebGLUnsignedShortArray> array = static_cast<WebGLUnsignedShortArray*>(construct<WebGLUnsignedShortArray, unsigned short>(exec, args).get()); return asObject(toJS(exec, jsConstructor->globalObject(), array.get())); } -JSC::ConstructType JSCanvasUnsignedShortArrayConstructor::getConstructData(JSC::ConstructData& constructData) +JSC::ConstructType JSWebGLUnsignedShortArrayConstructor::getConstructData(JSC::ConstructData& constructData) { constructData.native.function = constructCanvasUnsignedShortArray; return ConstructTypeHost; diff --git a/WebCore/bindings/js/JSCanvasUnsignedByteArrayConstructor.h b/WebCore/bindings/js/JSWebGLUnsignedShortArrayConstructor.h index 9cfb721..5eba20d 100644 --- a/WebCore/bindings/js/JSCanvasUnsignedByteArrayConstructor.h +++ b/WebCore/bindings/js/JSWebGLUnsignedShortArrayConstructor.h @@ -23,17 +23,17 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef JSCanvasUnsignedByteArrayConstructor_h -#define JSCanvasUnsignedByteArrayConstructor_h +#ifndef JSWebGLUnsignedShortArrayConstructor_h +#define JSWebGLUnsignedShortArrayConstructor_h #include "JSDOMBinding.h" #include "JSDocument.h" namespace WebCore { - class JSCanvasUnsignedByteArrayConstructor : public DOMConstructorObject { + class JSWebGLUnsignedShortArrayConstructor : public DOMConstructorObject { public: - JSCanvasUnsignedByteArrayConstructor(JSC::ExecState*, JSDOMGlobalObject*); + JSWebGLUnsignedShortArrayConstructor(JSC::ExecState*, JSDOMGlobalObject*); static const JSC::ClassInfo s_info; private: @@ -43,4 +43,4 @@ namespace WebCore { } -#endif // JSCanvasUnsignedByteArrayConstructor_h +#endif // JSWebGLUnsignedShortArrayConstructor_h diff --git a/WebCore/bindings/js/JSCanvasUnsignedShortArrayCustom.cpp b/WebCore/bindings/js/JSWebGLUnsignedShortArrayCustom.cpp index 290cd4b..898cc06 100644 --- a/WebCore/bindings/js/JSCanvasUnsignedShortArrayCustom.cpp +++ b/WebCore/bindings/js/JSWebGLUnsignedShortArrayCustom.cpp @@ -27,22 +27,50 @@ #if ENABLE(3D_CANVAS) -#include "JSCanvasUnsignedShortArray.h" +#include "JSWebGLArrayHelper.h" +#include "JSWebGLUnsignedShortArray.h" -#include "CanvasUnsignedShortArray.h" +#include "WebGLUnsignedShortArray.h" using namespace JSC; namespace WebCore { -void JSCanvasUnsignedShortArray::indexSetter(JSC::ExecState* exec, unsigned index, JSC::JSValue value) +void JSWebGLUnsignedShortArray::indexSetter(JSC::ExecState* exec, unsigned index, JSC::JSValue value) { impl()->set(index, static_cast<unsigned short>(value.toInt32(exec))); } -JSC::JSValue toJS(JSC::ExecState* exec, JSDOMGlobalObject* globalObject, CanvasUnsignedShortArray* object) +JSC::JSValue toJS(JSC::ExecState* exec, JSDOMGlobalObject* globalObject, WebGLUnsignedShortArray* object) { - return getDOMObjectWrapper<JSCanvasUnsignedShortArray>(exec, globalObject, object); + return getDOMObjectWrapper<JSWebGLUnsignedShortArray>(exec, globalObject, object); +} + +JSC::JSValue JSWebGLUnsignedShortArray::set(JSC::ExecState* exec, JSC::ArgList const& args) +{ + if (args.size() > 2) + return throwError(exec, SyntaxError); + + if (args.size() == 2 && args.at(0).isInt32()) { + // void set(in unsigned long index, in long value); + unsigned index = args.at(0).toUInt32(exec); + impl()->set(index, static_cast<signed char>(args.at(1).toInt32(exec))); + return jsUndefined(); + } + + WebGLUnsignedShortArray* array = toWebGLUnsignedShortArray(args.at(0)); + if (array) { + // void set(in WebGLUnsignedShortArray array, [Optional] in unsigned long offset); + unsigned offset = 0; + if (args.size() == 2) + offset = args.at(1).toInt32(exec); + ExceptionCode ec = 0; + impl()->set(array, offset, ec); + setDOMException(exec, ec); + return jsUndefined(); + } + + return setWebGLArrayFromArray(exec, impl(), args); } } // namespace WebCore diff --git a/WebCore/bindings/js/JSWebSocketCustom.cpp b/WebCore/bindings/js/JSWebSocketCustom.cpp index 33c3fcd..238b041 100644 --- a/WebCore/bindings/js/JSWebSocketCustom.cpp +++ b/WebCore/bindings/js/JSWebSocketCustom.cpp @@ -38,7 +38,6 @@ #include "KURL.h" #include "JSEventListener.h" #include "WebSocket.h" -#include "NotImplemented.h" #include <runtime/Error.h> using namespace JSC; diff --git a/WebCore/bindings/js/JSWorkerContextBase.cpp b/WebCore/bindings/js/JSWorkerContextBase.cpp index 741a269..f0c4efa 100644 --- a/WebCore/bindings/js/JSWorkerContextBase.cpp +++ b/WebCore/bindings/js/JSWorkerContextBase.cpp @@ -45,7 +45,7 @@ ASSERT_CLASS_FITS_IN_CELL(JSWorkerContextBase); const ClassInfo JSWorkerContextBase::s_info = { "WorkerContext", 0, 0, 0 }; JSWorkerContextBase::JSWorkerContextBase(NonNullPassRefPtr<JSC::Structure> structure, PassRefPtr<WorkerContext> impl) - : JSDOMGlobalObject(structure, new JSDOMGlobalObjectData, this) + : JSDOMGlobalObject(structure, new JSDOMGlobalObjectData(normalWorld(*impl->script()->globalData())), this) , m_impl(impl) { } diff --git a/WebCore/bindings/js/ScheduledAction.cpp b/WebCore/bindings/js/ScheduledAction.cpp index 9a21b6b..3223e53 100644 --- a/WebCore/bindings/js/ScheduledAction.cpp +++ b/WebCore/bindings/js/ScheduledAction.cpp @@ -103,7 +103,7 @@ void ScheduledAction::executeFunctionInContext(JSGlobalObject* globalObject, JSV args.append(m_args[i]); globalObject->globalData()->timeoutChecker.start(); - callInWorld(exec, m_function, callType, callData, thisValue, args, m_isolatedWorld.get()); + JSC::call(exec, m_function, callType, callData, thisValue, args); globalObject->globalData()->timeoutChecker.stop(); if (exec->hadException()) @@ -126,7 +126,7 @@ void ScheduledAction::execute(Document* document) executeFunctionInContext(window, window->shell()); Document::updateStyleForAllDocuments(); } else - frame->script()->executeScriptInIsolatedWorld(m_isolatedWorld.get(), m_code); + frame->script()->executeScriptInWorld(m_isolatedWorld.get(), m_code); frame->script()->setProcessingTimerCallback(false); } diff --git a/WebCore/bindings/js/ScriptCachedFrameData.cpp b/WebCore/bindings/js/ScriptCachedFrameData.cpp index e01324e..f2b64de 100644 --- a/WebCore/bindings/js/ScriptCachedFrameData.cpp +++ b/WebCore/bindings/js/ScriptCachedFrameData.cpp @@ -44,19 +44,26 @@ using namespace JSC; namespace WebCore { ScriptCachedFrameData::ScriptCachedFrameData(Frame* frame) + : m_domWindow(0) { JSLock lock(SilenceAssertionsOnly); ScriptController* scriptController = frame->script(); - // FIXME: explicitly save and restore isolated worlds' global objects when using the back/forward cache. <rdar://problem/7328111> - if (JSDOMWindowShell* windowShell = scriptController->existingWindowShell(mainThreadNormalWorld())) { - m_window = windowShell->window(); - scriptController->attachDebugger(0); + ScriptController::ShellMap& windowShells = scriptController->m_windowShells; + + ScriptController::ShellMap::iterator windowShellsEnd = windowShells.end(); + for (ScriptController::ShellMap::iterator iter = windowShells.begin(); iter != windowShellsEnd; ++iter) { + JSDOMWindow* window = iter->second->window(); + m_windows.add(iter->first.get(), window); + m_domWindow = window->impl(); } + + scriptController->attachDebugger(0); } -DOMWindow* ScriptCachedFrameData::domWindow() const { - return m_window ? m_window->impl() : 0; +DOMWindow* ScriptCachedFrameData::domWindow() const +{ + return m_domWindow; } ScriptCachedFrameData::~ScriptCachedFrameData() @@ -71,26 +78,33 @@ void ScriptCachedFrameData::restore(Frame* frame) JSLock lock(SilenceAssertionsOnly); ScriptController* scriptController = frame->script(); - // FIXME: explicitly save and restore isolated worlds' global objects when using the back/forward cache. <rdar://problem/7328111> - if (JSDOMWindowShell* windowShell = scriptController->existingWindowShell(mainThreadNormalWorld())) { - if (m_window) - windowShell->setWindow(m_window.get()); + ScriptController::ShellMap& windowShells = scriptController->m_windowShells; + + ScriptController::ShellMap::iterator windowShellsEnd = windowShells.end(); + for (ScriptController::ShellMap::iterator iter = windowShells.begin(); iter != windowShellsEnd; ++iter) { + DOMWrapperWorld* world = iter->first.get(); + JSDOMWindowShell* windowShell = iter->second.get(); + + if (JSDOMWindow* window = m_windows.get(world)) + windowShell->setWindow(window); else { windowShell->setWindow(frame->domWindow()); - scriptController->attachDebugger(page->debugger()); - windowShell->window()->setProfileGroup(page->group().identifier()); + if (world == debuggerWorld()) { + scriptController->attachDebugger(page->debugger()); + windowShell->window()->setProfileGroup(page->group().identifier()); + } } } } void ScriptCachedFrameData::clear() { - JSLock lock(SilenceAssertionsOnly); + if (m_windows.isEmpty()) + return; - if (m_window) { - m_window = 0; - gcController().garbageCollectSoon(); - } + JSLock lock(SilenceAssertionsOnly); + m_windows.clear(); + gcController().garbageCollectSoon(); } } // namespace WebCore diff --git a/WebCore/bindings/js/ScriptCachedFrameData.h b/WebCore/bindings/js/ScriptCachedFrameData.h index c661f28..5bcaed7 100644 --- a/WebCore/bindings/js/ScriptCachedFrameData.h +++ b/WebCore/bindings/js/ScriptCachedFrameData.h @@ -38,8 +38,11 @@ namespace WebCore { class Frame; class JSDOMWindow; class DOMWindow; + class DOMWrapperWorld; class ScriptCachedFrameData { + typedef HashMap< RefPtr<DOMWrapperWorld>, JSC::ProtectedPtr<JSDOMWindow> > JSDOMWindowSet; + public: ScriptCachedFrameData(Frame*); ~ScriptCachedFrameData(); @@ -49,7 +52,8 @@ namespace WebCore { DOMWindow* domWindow() const; private: - JSC::ProtectedPtr<JSDOMWindow> m_window; + JSDOMWindowSet m_windows; + DOMWindow* m_domWindow; }; } // namespace WebCore diff --git a/WebCore/bindings/js/ScriptCallStack.cpp b/WebCore/bindings/js/ScriptCallStack.cpp index 021ede5..824a07b 100644 --- a/WebCore/bindings/js/ScriptCallStack.cpp +++ b/WebCore/bindings/js/ScriptCallStack.cpp @@ -57,7 +57,7 @@ ScriptCallStack::ScriptCallStack(ExecState* exec, const ArgList& args, unsigned if (function) { m_caller = asInternalFunction(function); unsigned lineNumber = signedLineNumber >= 0 ? signedLineNumber : 0; - m_frames.append(ScriptCallFrame(m_caller->name(&m_exec->globalData()), urlString, lineNumber, args, skipArgumentCount)); + m_frames.append(ScriptCallFrame(m_caller->name(m_exec), urlString, lineNumber, args, skipArgumentCount)); } else { // Caller is unknown, but we should still add the frame, because // something called us, and gave us arguments. @@ -94,7 +94,7 @@ void ScriptCallStack::initialize() while (!func.isNull()) { InternalFunction* internalFunction = asInternalFunction(func); ArgList emptyArgList; - m_frames.append(ScriptCallFrame(internalFunction->name(&m_exec->globalData()), UString(), 0, emptyArgList, 0)); + m_frames.append(ScriptCallFrame(internalFunction->name(m_exec), UString(), 0, emptyArgList, 0)); func = m_exec->interpreter()->retrieveCaller(m_exec, internalFunction); } m_initialized = true; diff --git a/WebCore/bindings/js/ScriptController.cpp b/WebCore/bindings/js/ScriptController.cpp index b0696ba..3de3b23 100644 --- a/WebCore/bindings/js/ScriptController.cpp +++ b/WebCore/bindings/js/ScriptController.cpp @@ -25,8 +25,10 @@ #include "Event.h" #include "EventNames.h" #include "Frame.h" +#include "FrameLoaderClient.h" #include "GCController.h" #include "HTMLPlugInElement.h" +#include "InspectorTimelineAgent.h" #include "JSDocument.h" #include "NP_jsobject.h" #include "Page.h" @@ -43,6 +45,7 @@ #include <runtime/JSLock.h> using namespace JSC; +using namespace std; namespace WebCore { @@ -79,9 +82,6 @@ ScriptController::ScriptController(Frame* frame) ScriptController::~ScriptController() { if (!m_windowShells.isEmpty()) { - for (ShellMap::iterator iter = m_windowShells.begin(); iter != m_windowShells.end(); ++iter) - iter->first->forgetScriptController(this); - m_windowShells.clear(); // It's likely that releasing the global object has created a lot of garbage. @@ -117,10 +117,20 @@ ScriptValue ScriptController::evaluateInWorld(const ScriptSourceCode& sourceCode RefPtr<Frame> protect = m_frame; +#if ENABLE(INSPECTOR) + if (InspectorTimelineAgent* timelineAgent = m_frame->page() ? m_frame->page()->inspectorTimelineAgent() : 0) + timelineAgent->willEvaluateScript(sourceURL, sourceCode.startLine()); +#endif + exec->globalData().timeoutChecker.start(); - Completion comp = WebCore::evaluateInWorld(exec, exec->dynamicGlobalObject()->globalScopeChain(), jsSourceCode, shell, world); + Completion comp = JSC::evaluate(exec, exec->dynamicGlobalObject()->globalScopeChain(), jsSourceCode, shell); exec->globalData().timeoutChecker.stop(); +#if ENABLE(INSPECTOR) + if (InspectorTimelineAgent* timelineAgent = m_frame->page() ? m_frame->page()->inspectorTimelineAgent() : 0) + timelineAgent->didEvaluateScript(); +#endif + // Evaluating the JavaScript could cause the frame to be deallocated // so we start the keep alive timer here. m_frame->keepAlive(); @@ -156,42 +166,14 @@ public: static PassRefPtr<IsolatedWorld> create(JSGlobalData* globalData) { return adoptRef(new IsolatedWorld(globalData)); } }; -static PassRefPtr<IsolatedWorld> findWorld(unsigned worldID) -{ - if (!worldID) - return IsolatedWorld::create(JSDOMWindow::commonJSGlobalData()); - - typedef HashMap<unsigned, RefPtr<IsolatedWorld> > WorldMap; - DEFINE_STATIC_LOCAL(WorldMap, isolatedWorlds, ()); - - WorldMap::iterator iter = isolatedWorlds.find(worldID); - if (iter != isolatedWorlds.end()) - return iter->second; - - RefPtr<IsolatedWorld> newWorld = IsolatedWorld::create(JSDOMWindow::commonJSGlobalData()); - isolatedWorlds.add(worldID, newWorld); - return newWorld; -} - -JSDOMWindow* ScriptController::globalObject(unsigned worldID) +PassRefPtr<DOMWrapperWorld> ScriptController::createWorld() { - RefPtr<DOMWrapperWorld> world = findWorld(worldID); - return windowShell(world.get())->window(); + return IsolatedWorld::create(JSDOMWindow::commonJSGlobalData()); } -ScriptValue ScriptController::evaluateInIsolatedWorld(unsigned worldID, const ScriptSourceCode& sourceCode) +void ScriptController::getAllWorlds(Vector<DOMWrapperWorld*>& worlds) { - RefPtr<DOMWrapperWorld> world = findWorld(worldID); - return evaluateInWorld(sourceCode, world.get()); -} - -void ScriptController::evaluateInIsolatedWorld(unsigned worldID, const Vector<ScriptSourceCode>& sourceCode) -{ - RefPtr<DOMWrapperWorld> world = findWorld(worldID); - - unsigned size = sourceCode.size(); - for (unsigned i = 0; i < size; ++i) - evaluateInWorld(sourceCode[i], world.get()); + static_cast<WebCoreJSClientData*>(JSDOMWindow::commonJSGlobalData()->clientData)->getAllWorlds(worlds); } void ScriptController::clearWindowShell() @@ -206,7 +188,7 @@ void ScriptController::clearWindowShell() attachDebugger(0); for (ShellMap::iterator iter = m_windowShells.begin(); iter != m_windowShells.end(); ++iter) { - DOMWrapperWorld* world = iter->first; + DOMWrapperWorld* world = iter->first.get(); JSDOMWindowShell* windowShell = iter->second; windowShell->window()->willRemoveFromWindowShell(); windowShell->setWindow(m_frame->domWindow()); @@ -228,10 +210,9 @@ JSDOMWindowShell* ScriptController::initScript(DOMWrapperWorld* world) JSLock lock(SilenceAssertionsOnly); - JSDOMWindowShell* windowShell = new JSDOMWindowShell(m_frame->domWindow()); + JSDOMWindowShell* windowShell = new JSDOMWindowShell(m_frame->domWindow(), world); m_windowShells.add(world, windowShell); - world->rememberScriptController(this); - windowShell->window()->updateDocument(world); + windowShell->window()->updateDocument(); if (Page* page = m_frame->page()) { if (world == debuggerWorld()) @@ -239,10 +220,7 @@ JSDOMWindowShell* ScriptController::initScript(DOMWrapperWorld* world) windowShell->window()->setProfileGroup(page->group().identifier()); } - { - EnterDOMWrapperWorld worldEntry(*JSDOMWindow::commonJSGlobalData(), world); - m_frame->loader()->dispatchWindowObjectAvailable(); - } + m_frame->loader()->dispatchDidClearWindowObjectInWorld(world); return windowShell; } @@ -264,9 +242,10 @@ bool ScriptController::processingUserGestureEvent() const const AtomicString& type = event->type(); if ( // mouse events - type == eventNames().clickEvent || type == eventNames().mousedownEvent || - type == eventNames().mouseupEvent || type == eventNames().dblclickEvent || + type == eventNames().clickEvent || type == eventNames().mousedownEvent + || type == eventNames().mouseupEvent || type == eventNames().dblclickEvent // keyboard events +<<<<<<< HEAD:WebCore/bindings/js/ScriptController.cpp type == eventNames().keydownEvent || type == eventNames().keypressEvent || type == eventNames().keyupEvent || #if ENABLE(TOUCH_EVENTS) // Android @@ -274,10 +253,14 @@ bool ScriptController::processingUserGestureEvent() const type == eventNames().touchstartEvent || type == eventNames().touchmoveEvent || type == eventNames().touchendEvent || type == eventNames().touchcancelEvent || #endif +======= + || type == eventNames().keydownEvent || type == eventNames().keypressEvent + || type == eventNames().keyupEvent +>>>>>>> webkit.org at r51976:WebCore/bindings/js/ScriptController.cpp // other accepted events - type == eventNames().selectEvent || type == eventNames().changeEvent || - type == eventNames().focusEvent || type == eventNames().blurEvent || - type == eventNames().submitEvent) + || type == eventNames().selectEvent || type == eventNames().changeEvent + || type == eventNames().focusEvent || type == eventNames().blurEvent + || type == eventNames().submitEvent) return true; } @@ -316,7 +299,7 @@ bool ScriptController::anyPageIsProcessingUserGesture() const bool ScriptController::isEnabled() { Settings* settings = m_frame->settings(); - return (settings && settings->isJavaScriptEnabled()); + return m_frame->loader()->client()->allowJavaScript(settings && settings->isJavaScriptEnabled() && !m_frame->loader()->isSandboxed(SandboxScripts)); } void ScriptController::attachDebugger(JSC::Debugger* debugger) @@ -340,7 +323,7 @@ void ScriptController::updateDocument() JSLock lock(SilenceAssertionsOnly); for (ShellMap::iterator iter = m_windowShells.begin(); iter != m_windowShells.end(); ++iter) - iter->second->window()->updateDocument(iter->first); + iter->second->window()->updateDocument(); } void ScriptController::updateSecurityOrigin() @@ -473,27 +456,7 @@ void ScriptController::clearScriptObjects() #endif } -ScriptValue ScriptController::executeScriptInIsolatedWorld(unsigned worldID, const String& script, bool forceUserGesture) -{ - ScriptSourceCode sourceCode(script, forceUserGesture ? KURL() : m_frame->loader()->url()); - - if (!isEnabled() || isPaused()) - return ScriptValue(); - - bool wasInExecuteScript = m_inExecuteScript; - m_inExecuteScript = true; - - ScriptValue result = evaluateInIsolatedWorld(worldID, sourceCode); - - if (!wasInExecuteScript) { - m_inExecuteScript = false; - Document::updateStyleForAllDocuments(); - } - - return result; -} - -ScriptValue ScriptController::executeScriptInIsolatedWorld(DOMWrapperWorld* world, const String& script, bool forceUserGesture) +ScriptValue ScriptController::executeScriptInWorld(DOMWrapperWorld* world, const String& script, bool forceUserGesture) { ScriptSourceCode sourceCode(script, forceUserGesture ? KURL() : m_frame->loader()->url()); diff --git a/WebCore/bindings/js/ScriptController.h b/WebCore/bindings/js/ScriptController.h index f2a497d..8801622 100644 --- a/WebCore/bindings/js/ScriptController.h +++ b/WebCore/bindings/js/ScriptController.h @@ -63,12 +63,15 @@ class XSSAuditor; typedef HashMap<void*, RefPtr<JSC::Bindings::RootObject> > RootObjectMap; class ScriptController { - typedef WTF::HashMap<DOMWrapperWorld*, JSC::ProtectedPtr<JSDOMWindowShell> > ShellMap; + friend class ScriptCachedFrameData; + typedef WTF::HashMap< RefPtr<DOMWrapperWorld>, JSC::ProtectedPtr<JSDOMWindowShell> > ShellMap; public: ScriptController(Frame*); ~ScriptController(); + static PassRefPtr<DOMWrapperWorld> createWorld(); + JSDOMWindowShell* windowShell(DOMWrapperWorld* world) { ShellMap::iterator iter = m_windowShells.find(world); @@ -83,17 +86,12 @@ public: { return windowShell(world)->window(); } - JSDOMWindow* globalObject(unsigned worldID); - void forgetWorld(DOMWrapperWorld* world) - { - m_windowShells.remove(world); - } + static void getAllWorlds(Vector<DOMWrapperWorld*>&); ScriptValue executeScript(const ScriptSourceCode&); ScriptValue executeScript(const String& script, bool forceUserGesture = false); - ScriptValue executeScriptInIsolatedWorld(unsigned worldID, const String& script, bool forceUserGesture = false); - ScriptValue executeScriptInIsolatedWorld(DOMWrapperWorld* world, const String& script, bool forceUserGesture = false); + ScriptValue executeScriptInWorld(DOMWrapperWorld* world, const String& script, bool forceUserGesture = false); // Returns true if argument is a JavaScript URL. bool executeIfJavaScriptURL(const KURL&, bool userGesture = false, bool replaceDocument = true); @@ -104,8 +102,6 @@ public: ScriptValue evaluate(const ScriptSourceCode&); ScriptValue evaluateInWorld(const ScriptSourceCode&, DOMWrapperWorld*); - ScriptValue evaluateInIsolatedWorld(unsigned /*worldID*/, const ScriptSourceCode&); - void evaluateInIsolatedWorld(unsigned /*worldID*/, const Vector<ScriptSourceCode>&); void setEventHandlerLineNumber(int lineno) { m_handlerLineNumber = lineno; } int eventHandlerLineNumber() { return m_handlerLineNumber; } diff --git a/WebCore/bindings/js/ScriptFunctionCall.cpp b/WebCore/bindings/js/ScriptFunctionCall.cpp index 91b2a57..e38acb9 100644 --- a/WebCore/bindings/js/ScriptFunctionCall.cpp +++ b/WebCore/bindings/js/ScriptFunctionCall.cpp @@ -72,6 +72,13 @@ void ScriptFunctionCall::appendArgument(const String& argument) void ScriptFunctionCall::appendArgument(const JSC::UString& argument) { + JSLock lock(SilenceAssertionsOnly); + m_arguments.append(jsString(m_exec, argument)); +} + +void ScriptFunctionCall::appendArgument(const char* argument) +{ + JSLock lock(SilenceAssertionsOnly); m_arguments.append(jsString(m_exec, argument)); } @@ -80,6 +87,12 @@ void ScriptFunctionCall::appendArgument(JSC::JSValue argument) m_arguments.append(argument); } +void ScriptFunctionCall::appendArgument(long argument) +{ + JSLock lock(SilenceAssertionsOnly); + m_arguments.append(jsNumber(m_exec, argument)); +} + void ScriptFunctionCall::appendArgument(long long argument) { JSLock lock(SilenceAssertionsOnly); @@ -92,6 +105,12 @@ void ScriptFunctionCall::appendArgument(unsigned int argument) m_arguments.append(jsNumber(m_exec, argument)); } +void ScriptFunctionCall::appendArgument(unsigned long argument) +{ + JSLock lock(SilenceAssertionsOnly); + m_arguments.append(jsNumber(m_exec, argument)); +} + void ScriptFunctionCall::appendArgument(int argument) { JSLock lock(SilenceAssertionsOnly); @@ -123,8 +142,7 @@ ScriptValue ScriptFunctionCall::call(bool& hadException, bool reportExceptions) if (callType == CallTypeNone) return ScriptValue(); - // FIXME: Should this function take a worldID? - only used by inspector? - JSValue result = callInWorld(m_exec, function, callType, callData, thisObject, m_arguments, debuggerWorld()); + JSValue result = JSC::call(m_exec, function, callType, callData, thisObject, m_arguments); if (m_exec->hadException()) { if (reportExceptions) reportException(m_exec, m_exec->exception()); @@ -162,8 +180,7 @@ ScriptObject ScriptFunctionCall::construct(bool& hadException, bool reportExcept if (constructType == ConstructTypeNone) return ScriptObject(); - // FIXME: Currently this method constructs objects in debuggerWorld(). We could use the current world, or pass a worldID to this function? - JSValue result = constructInWorld(m_exec, constructor, constructType, constructData, m_arguments, debuggerWorld()); + JSValue result = JSC::construct(m_exec, constructor, constructType, constructData, m_arguments); if (m_exec->hadException()) { if (reportExceptions) reportException(m_exec, m_exec->exception()); diff --git a/WebCore/bindings/js/ScriptFunctionCall.h b/WebCore/bindings/js/ScriptFunctionCall.h index 079ac21..7c5074f 100644 --- a/WebCore/bindings/js/ScriptFunctionCall.h +++ b/WebCore/bindings/js/ScriptFunctionCall.h @@ -55,10 +55,13 @@ namespace WebCore { void appendArgument(const ScriptString&); void appendArgument(const ScriptValue&); void appendArgument(const String&); + void appendArgument(const char*); void appendArgument(const JSC::UString&); void appendArgument(JSC::JSValue); + void appendArgument(long); void appendArgument(long long); void appendArgument(unsigned int); + void appendArgument(unsigned long); void appendArgument(int); void appendArgument(bool); ScriptValue call(bool& hadException, bool reportExceptions = true); @@ -70,6 +73,12 @@ namespace WebCore { ScriptObject m_thisObject; String m_name; JSC::MarkedArgumentBuffer m_arguments; + + private: + // MarkedArgumentBuffer must be stack allocated, so prevent heap + // alloc of ScriptFunctionCall as well. + void* operator new(size_t) { ASSERT_NOT_REACHED(); return reinterpret_cast<void*>(0xbadbeef); } + void* operator new[](size_t) { ASSERT_NOT_REACHED(); return reinterpret_cast<void*>(0xbadbeef); } }; } // namespace WebCore diff --git a/WebCore/bindings/js/ScriptObject.cpp b/WebCore/bindings/js/ScriptObject.cpp index f14145e..0e62903 100644 --- a/WebCore/bindings/js/ScriptObject.cpp +++ b/WebCore/bindings/js/ScriptObject.cpp @@ -36,7 +36,15 @@ #include <runtime/JSLock.h> #if ENABLE(INSPECTOR) +<<<<<<< HEAD:WebCore/bindings/js/ScriptObject.cpp +======= +#include "JSInjectedScriptHost.h" +>>>>>>> webkit.org at r51976:WebCore/bindings/js/ScriptObject.cpp #include "JSInspectorBackend.h" +<<<<<<< HEAD:WebCore/bindings/js/ScriptObject.cpp +======= +#include "JSInspectorFrontendHost.h" +>>>>>>> webkit.org at r51976:WebCore/bindings/js/ScriptObject.cpp #endif using namespace JSC; @@ -90,6 +98,14 @@ bool ScriptObject::set(const char* name, double value) return handleException(m_scriptState); } +bool ScriptObject::set(const char* name, long value) +{ + JSLock lock(SilenceAssertionsOnly); + PutPropertySlot slot; + jsObject()->put(m_scriptState, Identifier(m_scriptState, name), jsNumber(m_scriptState, value), slot); + return handleException(m_scriptState); +} + bool ScriptObject::set(const char* name, long long value) { JSLock lock(SilenceAssertionsOnly); @@ -114,6 +130,14 @@ bool ScriptObject::set(const char* name, unsigned value) return handleException(m_scriptState); } +bool ScriptObject::set(const char* name, unsigned long value) +{ + JSLock lock(SilenceAssertionsOnly); + PutPropertySlot slot; + jsObject()->put(m_scriptState, Identifier(m_scriptState, name), jsNumber(m_scriptState, value), slot); + return handleException(m_scriptState); +} + bool ScriptObject::set(const char* name, bool value) { JSLock lock(SilenceAssertionsOnly); @@ -143,6 +167,22 @@ bool ScriptGlobalObject::set(ScriptState* scriptState, const char* name, Inspect globalObject->putDirect(Identifier(scriptState, name), toJS(scriptState, globalObject, value)); return handleException(scriptState); } + +bool ScriptGlobalObject::set(ScriptState* scriptState, const char* name, InspectorFrontendHost* value) +{ + JSLock lock(SilenceAssertionsOnly); + JSDOMGlobalObject* globalObject = static_cast<JSDOMGlobalObject*>(scriptState->lexicalGlobalObject()); + globalObject->putDirect(Identifier(scriptState, name), toJS(scriptState, globalObject, value)); + return handleException(scriptState); +} + +bool ScriptGlobalObject::set(ScriptState* scriptState, const char* name, InjectedScriptHost* value) +{ + JSLock lock(SilenceAssertionsOnly); + JSDOMGlobalObject* globalObject = static_cast<JSDOMGlobalObject*>(scriptState->lexicalGlobalObject()); + globalObject->putDirect(Identifier(scriptState, name), toJS(scriptState, globalObject, value)); + return handleException(scriptState); +} #endif // ENABLE(INSPECTOR) bool ScriptGlobalObject::get(ScriptState* scriptState, const char* name, ScriptObject& value) diff --git a/WebCore/bindings/js/ScriptObject.h b/WebCore/bindings/js/ScriptObject.h index 31381f3..fed7339 100644 --- a/WebCore/bindings/js/ScriptObject.h +++ b/WebCore/bindings/js/ScriptObject.h @@ -38,7 +38,9 @@ #include <runtime/Protect.h> namespace WebCore { + class InjectedScriptHost; class InspectorBackend; + class InspectorFrontendHost; class ScriptObject : public ScriptValue { public: @@ -50,9 +52,11 @@ namespace WebCore { bool set(const char* name, const ScriptObject&); bool set(const char* name, const String&); bool set(const char* name, double); + bool set(const char* name, long); bool set(const char* name, long long); bool set(const char* name, int); bool set(const char* name, unsigned); + bool set(const char* name, unsigned long); bool set(const char* name, bool); static ScriptObject createNew(ScriptState*); @@ -66,6 +70,8 @@ namespace WebCore { static bool set(ScriptState*, const char* name, const ScriptObject&); #if ENABLE(INSPECTOR) static bool set(ScriptState*, const char* name, InspectorBackend*); + static bool set(ScriptState*, const char* name, InspectorFrontendHost*); + static bool set(ScriptState*, const char* name, InjectedScriptHost*); #endif static bool get(ScriptState*, const char* name, ScriptObject&); static bool remove(ScriptState*, const char* name); diff --git a/WebCore/bindings/js/ScriptObjectQuarantine.cpp b/WebCore/bindings/js/ScriptObjectQuarantine.cpp deleted file mode 100644 index 313530f..0000000 --- a/WebCore/bindings/js/ScriptObjectQuarantine.cpp +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Copyright (C) 2009 Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "ScriptObjectQuarantine.h" - -#if ENABLE(INSPECTOR) - -#include "Document.h" -#include "Frame.h" -#include "JSDOMBinding.h" -#include "JSInspectedObjectWrapper.h" -#include "JSNode.h" -#include "ScriptObject.h" -#include "ScriptValue.h" -#include "Storage.h" - -#include <runtime/JSLock.h> - -#if ENABLE(DATABASE) -#include "Database.h" -#include "JSDatabase.h" -#endif - -#if ENABLE(DOM_STORAGE) -#include "JSStorage.h" -#endif - -using namespace JSC; - -namespace WebCore { - -ScriptValue quarantineValue(ScriptState* scriptState, const ScriptValue& value) -{ - JSLock lock(SilenceAssertionsOnly); - return ScriptValue(JSInspectedObjectWrapper::wrap(scriptState, value.jsValue())); -} - -#if ENABLE(DATABASE) -bool getQuarantinedScriptObject(Database* database, ScriptObject& quarantinedObject) -{ - ASSERT(database); - - Frame* frame = database->document()->frame(); - if (!frame) - return false; - - JSDOMGlobalObject* globalObject = toJSDOMWindow(frame, debuggerWorld()); - ExecState* exec = globalObject->globalExec(); - - JSLock lock(SilenceAssertionsOnly); - quarantinedObject = ScriptObject(exec, asObject(JSInspectedObjectWrapper::wrap(exec, toJS(exec, globalObject, database)))); - - return true; -} -#endif - -#if ENABLE(DOM_STORAGE) -bool getQuarantinedScriptObject(Storage* storage, ScriptObject& quarantinedObject) -{ - ASSERT(storage); - Frame* frame = storage->frame(); - ASSERT(frame); - - JSDOMGlobalObject* globalObject = toJSDOMWindow(frame, debuggerWorld()); - ExecState* exec = globalObject->globalExec(); - - JSLock lock(SilenceAssertionsOnly); - quarantinedObject = ScriptObject(exec, asObject(JSInspectedObjectWrapper::wrap(exec, toJS(exec, globalObject, storage)))); - - return true; -} -#endif - -bool getQuarantinedScriptObject(Node* node, ScriptObject& quarantinedObject) -{ - ExecState* exec = scriptStateFromNode(node); - if (!exec) - return false; - - JSLock lock(SilenceAssertionsOnly); - // FIXME: Should use some sort of globalObjectFromNode() - quarantinedObject = ScriptObject(exec, asObject(JSInspectedObjectWrapper::wrap(exec, toJS(exec, deprecatedGlobalObjectForPrototype(exec), node)))); - - return true; -} - -bool getQuarantinedScriptObject(DOMWindow* domWindow, ScriptObject& quarantinedObject) -{ - ASSERT(domWindow); - - JSDOMWindow* window = toJSDOMWindow(domWindow->frame(), debuggerWorld()); - ExecState* exec = window->globalExec(); - - JSLock lock(SilenceAssertionsOnly); - quarantinedObject = ScriptObject(exec, asObject(JSInspectedObjectWrapper::wrap(exec, window))); - - return true; -} - - -} // namespace WebCore - -#endif // ENABLE(INSPECTOR) diff --git a/WebCore/bindings/js/ScriptState.cpp b/WebCore/bindings/js/ScriptState.cpp index 60ba2a0..b9f78ef 100644 --- a/WebCore/bindings/js/ScriptState.cpp +++ b/WebCore/bindings/js/ScriptState.cpp @@ -38,7 +38,7 @@ namespace WebCore { -ScriptState* scriptStateFromNode(Node* node) +ScriptState* scriptStateFromNode(DOMWrapperWorld* world, Node* node) { if (!node) return 0; @@ -50,12 +50,12 @@ ScriptState* scriptStateFromNode(Node* node) return 0; if (!frame->script()->isEnabled()) return 0; - return frame->script()->globalObject(mainThreadCurrentWorld())->globalExec(); + return frame->script()->globalObject(world)->globalExec(); } -ScriptState* scriptStateFromPage(Page* page) +ScriptState* scriptStateFromPage(DOMWrapperWorld* world, Page* page) { - return page->mainFrame()->script()->globalObject(mainThreadCurrentWorld())->globalExec(); + return page->mainFrame()->script()->globalObject(world)->globalExec(); } } diff --git a/WebCore/bindings/js/ScriptState.h b/WebCore/bindings/js/ScriptState.h index 279234e..6257929 100644 --- a/WebCore/bindings/js/ScriptState.h +++ b/WebCore/bindings/js/ScriptState.h @@ -45,8 +45,8 @@ namespace WebCore { // For now, the separation is purely by convention. typedef JSC::ExecState ScriptState; - ScriptState* scriptStateFromNode(Node*); - ScriptState* scriptStateFromPage(Page*); + ScriptState* scriptStateFromNode(DOMWrapperWorld*, Node*); + ScriptState* scriptStateFromPage(DOMWrapperWorld*, Page*); } // namespace WebCore diff --git a/WebCore/bindings/js/ScriptValue.cpp b/WebCore/bindings/js/ScriptValue.cpp index 6eac102..5444e0e 100644 --- a/WebCore/bindings/js/ScriptValue.cpp +++ b/WebCore/bindings/js/ScriptValue.cpp @@ -32,6 +32,8 @@ #include <JavaScriptCore/APICast.h> #include <JavaScriptCore/JSValueRef.h> +#include "JSInspectedObjectWrapper.h" + #include <runtime/JSLock.h> #include <runtime/Protect.h> #include <runtime/UString.h> @@ -40,13 +42,21 @@ using namespace JSC; namespace WebCore { -bool ScriptValue::getString(String& result) const +#if ENABLE(INSPECTOR) +ScriptValue ScriptValue::quarantineValue(ScriptState* scriptState, const ScriptValue& value) +{ + JSLock lock(SilenceAssertionsOnly); + return ScriptValue(JSInspectedObjectWrapper::wrap(scriptState, value.jsValue())); +} +#endif + +bool ScriptValue::getString(ScriptState* scriptState, String& result) const { if (!m_value) return false; JSLock lock(SilenceAssertionsOnly); UString ustring; - if (!m_value.get().getString(ustring)) + if (!m_value.get().getString(scriptState, ustring)) return false; result = ustring; return true; diff --git a/WebCore/bindings/js/ScriptValue.h b/WebCore/bindings/js/ScriptValue.h index 19bb693..e11fa55 100644 --- a/WebCore/bindings/js/ScriptValue.h +++ b/WebCore/bindings/js/ScriptValue.h @@ -41,11 +41,13 @@ class String; class ScriptValue { public: + static ScriptValue quarantineValue(ScriptState* scriptState, const ScriptValue& value); + ScriptValue(JSC::JSValue value = JSC::JSValue()) : m_value(value) {} virtual ~ScriptValue() {} JSC::JSValue jsValue() const { return m_value.get(); } - bool getString(String& result) const; + bool getString(ScriptState*, String& result) const; String toString(ScriptState* scriptState) const { return m_value.get().toString(scriptState); } bool isEqual(ScriptState*, const ScriptValue&) const; bool isNull() const; diff --git a/WebCore/bindings/js/SerializedScriptValue.cpp b/WebCore/bindings/js/SerializedScriptValue.cpp index 48cd92d..7c4ad62 100644 --- a/WebCore/bindings/js/SerializedScriptValue.cpp +++ b/WebCore/bindings/js/SerializedScriptValue.cpp @@ -27,6 +27,11 @@ #include "config.h" #include "SerializedScriptValue.h" +#include "File.h" +#include "JSDOMGlobalObject.h" +#include "JSFile.h" +#include "JSFileList.h" +#include <JavaScriptCore/APICast.h> #include <runtime/DateInstance.h> #include <runtime/ExceptionHelpers.h> #include <runtime/PropertyNameArray.h> @@ -148,6 +153,12 @@ SerializedScriptValueData::SerializedScriptValueData(RefPtr<SerializedArray> dat { } +SerializedScriptValueData::SerializedScriptValueData(const File* file) + : m_type(FileType) + , m_string(file->path().crossThreadString()) +{ +} + SerializedArray* SharedSerializedData::asArray() { return static_cast<SerializedArray*>(this); @@ -470,7 +481,7 @@ struct SerializingTreeWalker : public BaseWalker { return SerializedScriptValueData(value); if (value.isString()) - return SerializedScriptValueData(asString(value)->value()); + return SerializedScriptValueData(asString(value)->value(m_exec)); if (value.isNumber()) return SerializedScriptValueData(SerializedScriptValueData::NumberType, value.uncheckedGetNumber()); @@ -481,10 +492,15 @@ struct SerializingTreeWalker : public BaseWalker { if (isArray(value)) return SerializedScriptValueData(); - CallData unusedData; - if (value.isObject() && value.getCallData(unusedData) == CallTypeNone) - return SerializedScriptValueData(); - + if (value.isObject()) { + JSObject* obj = asObject(value); + if (obj->inherits(&JSFile::s_info)) + return SerializedScriptValueData(toFile(obj)); + + CallData unusedData; + if (value.getCallData(unusedData) == CallTypeNone) + return SerializedScriptValueData(); + } // Any other types are expected to serialize as null. return SerializedScriptValueData(jsNull()); } @@ -640,6 +656,8 @@ struct DeserializingTreeWalker : public BaseWalker { return jsNumber(m_exec, value.asDouble()); case SerializedScriptValueData::DateType: return new (m_exec) DateInstance(m_exec, value.asDouble()); + case SerializedScriptValueData::FileType: + return toJS(m_exec, static_cast<JSDOMGlobalObject*>(m_exec->lexicalGlobalObject()), File::create(value.asString().crossThreadString())); default: ASSERT_NOT_REACHED(); return JSValue(); @@ -836,4 +854,36 @@ void SerializedScriptValueData::tearDownSerializedData() walk<TeardownTreeWalker>(context, *this); } +SerializedScriptValue::~SerializedScriptValue() +{ +} + +PassRefPtr<SerializedScriptValue> SerializedScriptValue::create(JSContextRef originContext, JSValueRef apiValue, JSValueRef* exception) +{ + ExecState* exec = toJS(originContext); + JSValue value = toJS(exec, apiValue); + PassRefPtr<SerializedScriptValue> serializedValue = SerializedScriptValue::create(exec, value); + if (exec->hadException()) { + if (exception) + *exception = toRef(exec, exec->exception()); + exec->clearException(); + return 0; + } + + return serializedValue; +} + +JSValueRef SerializedScriptValue::deserialize(JSContextRef destinationContext, JSValueRef* exception) +{ + ExecState* exec = toJS(destinationContext); + JSValue value = deserialize(exec); + if (exec->hadException()) { + if (exception) + *exception = toRef(exec, exec->exception()); + exec->clearException(); + return 0; + } + return toRef(exec, value); +} + } diff --git a/WebCore/bindings/js/SerializedScriptValue.h b/WebCore/bindings/js/SerializedScriptValue.h index f8a126f..57a4a66 100644 --- a/WebCore/bindings/js/SerializedScriptValue.h +++ b/WebCore/bindings/js/SerializedScriptValue.h @@ -29,7 +29,11 @@ #include "ScriptValue.h" +typedef const struct OpaqueJSContext* JSContextRef; +typedef const struct OpaqueJSValue* JSValueRef; + namespace WebCore { + class File; class SerializedObject; class SerializedArray; @@ -51,7 +55,8 @@ namespace WebCore { ImmediateType, ObjectType, ArrayType, - StringType + StringType, + FileType }; SerializedType type() const { return m_type; } @@ -74,6 +79,8 @@ namespace WebCore { , m_string(string.crossThreadString()) // FIXME: Should be able to just share the Rep { } + + explicit SerializedScriptValueData(const File*); explicit SerializedScriptValueData(JSC::JSValue value) : m_type(ImmediateType) @@ -105,7 +112,7 @@ namespace WebCore { String asString() const { - ASSERT(m_type == StringType); + ASSERT(m_type == StringType || m_type == FileType); return m_string; } @@ -150,6 +157,8 @@ namespace WebCore { return adoptRef(new SerializedScriptValue(SerializedScriptValueData::serialize(exec, value))); } + static PassRefPtr<SerializedScriptValue> create(JSContextRef, JSValueRef value, JSValueRef* exception); + static PassRefPtr<SerializedScriptValue> create(String string) { return adoptRef(new SerializedScriptValue(SerializedScriptValueData(string))); @@ -182,7 +191,8 @@ namespace WebCore { return m_value.deserialize(exec, m_mustCopy); } - ~SerializedScriptValue() {} + JSValueRef deserialize(JSContextRef, JSValueRef* exception); + ~SerializedScriptValue(); private: SerializedScriptValue(SerializedScriptValueData value) diff --git a/WebCore/bindings/js/WorkerScriptController.cpp b/WebCore/bindings/js/WorkerScriptController.cpp index b66b0e8..5e27ef7 100644 --- a/WebCore/bindings/js/WorkerScriptController.cpp +++ b/WebCore/bindings/js/WorkerScriptController.cpp @@ -123,7 +123,7 @@ ScriptValue WorkerScriptController::evaluate(const ScriptSourceCode& sourceCode, ExecState* exec = m_workerContextWrapper->globalExec(); m_workerContextWrapper->globalData()->timeoutChecker.start(); - Completion comp = evaluateInWorld(exec, exec->dynamicGlobalObject()->globalScopeChain(), sourceCode.jsSourceCode(), m_workerContextWrapper, currentWorld(exec)); + Completion comp = JSC::evaluate(exec, exec->dynamicGlobalObject()->globalScopeChain(), sourceCode.jsSourceCode(), m_workerContextWrapper); m_workerContextWrapper->globalData()->timeoutChecker.stop(); if (comp.complType() == Normal || comp.complType() == ReturnValue) diff --git a/WebCore/bindings/objc/DOMHTML.mm b/WebCore/bindings/objc/DOMHTML.mm index 1043d8e..3488b35 100644 --- a/WebCore/bindings/objc/DOMHTML.mm +++ b/WebCore/bindings/objc/DOMHTML.mm @@ -140,7 +140,12 @@ return NSMakeRange(start, end - start); } return NSMakeRange(NSNotFound, 0); -} +} + +- (BOOL)_isAutofilled +{ + return core(self)->isAutofilled(); +} - (void)_setAutofilled:(BOOL)filled { @@ -156,8 +161,9 @@ - (void)_activateItemAtIndex:(int)index { + // Use the setSelectedIndexByUser function so a change event will be fired. <rdar://problem/6760590> if (WebCore::HTMLSelectElement* select = core(self)) - select->setSelectedIndex(index); + select->setSelectedIndexByUser(index, true, true); } @end @@ -167,7 +173,7 @@ - (BOOL)_isEdited { WebCore::RenderObject *renderer = core(self)->renderer(); - return renderer && [self _isTextField] && static_cast<WebCore::RenderTextControl *>(renderer)->isUserEdited(); + return renderer && [self _isTextField] && static_cast<WebCore::RenderTextControl *>(renderer)->lastChangeWasUserEdit(); } @end @@ -177,7 +183,7 @@ - (BOOL)_isEdited { WebCore::RenderObject* renderer = core(self)->renderer(); - return renderer && static_cast<WebCore::RenderTextControl*>(renderer)->isUserEdited(); + return renderer && static_cast<WebCore::RenderTextControl*>(renderer)->lastChangeWasUserEdit(); } @end diff --git a/WebCore/bindings/objc/DOMPrivate.h b/WebCore/bindings/objc/DOMPrivate.h index 4291cbc..b8e4460 100644 --- a/WebCore/bindings/objc/DOMPrivate.h +++ b/WebCore/bindings/objc/DOMPrivate.h @@ -67,10 +67,10 @@ @end // All the methods in this category are used by Safari forms autofill and should not be used for any other purpose. -// They are stopgap measures until we finish transitioning form controls to not use NSView. Each one should become -// replaceable by public DOM API, and when that happens Safari will switch to implementations using that public API, -// and these will be deleted. +// Each one should eventually be replaced by public DOM API, and when that happens Safari will switch to implementations +// using that public API, and these will be deleted. @interface DOMHTMLInputElement (FormsAutoFillTransition) +- (BOOL)_isAutofilled; - (BOOL)_isTextField; - (NSRect)_rectOnScreen; // bounding box of the text field, in screen coordinates - (void)_replaceCharactersInRange:(NSRange)targetRange withString:(NSString *)replacementString selectingFromIndex:(int)index; diff --git a/WebCore/bindings/objc/WebScriptObject.mm b/WebCore/bindings/objc/WebScriptObject.mm index 6d86001..1622a3c 100644 --- a/WebCore/bindings/objc/WebScriptObject.mm +++ b/WebCore/bindings/objc/WebScriptObject.mm @@ -299,7 +299,7 @@ static void getListFromNSArray(ExecState *exec, NSArray *array, RootObject* root return nil; [self _rootObject]->globalObject()->globalData()->timeoutChecker.start(); - JSValue result = callInWorld(exec, function, callType, callData, [self _imp], argList, pluginWorld()); + JSValue result = JSC::call(exec, function, callType, callData, [self _imp], argList); [self _rootObject]->globalObject()->globalData()->timeoutChecker.stop(); if (exec->hadException()) { @@ -328,7 +328,7 @@ static void getListFromNSArray(ExecState *exec, NSArray *array, RootObject* root JSLock lock(SilenceAssertionsOnly); [self _rootObject]->globalObject()->globalData()->timeoutChecker.start(); - Completion completion = evaluateInWorld([self _rootObject]->globalObject()->globalExec(), [self _rootObject]->globalObject()->globalScopeChain(), makeSource(String(script)), JSC::JSValue(), pluginWorld()); + Completion completion = JSC::evaluate([self _rootObject]->globalObject()->globalExec(), [self _rootObject]->globalObject()->globalScopeChain(), makeSource(String(script)), JSC::JSValue()); [self _rootObject]->globalObject()->globalData()->timeoutChecker.stop(); ComplType type = completion.complType(); @@ -529,7 +529,8 @@ static void getListFromNSArray(ExecState *exec, NSArray *array, RootObject* root } if (value.isString()) { - const UString& u = asString(value)->value(); + ExecState* exec = rootObject->globalObject()->globalExec(); + const UString& u = asString(value)->value(exec); return [NSString stringWithCharacters:u.data() length:u.size()]; } diff --git a/WebCore/bindings/scripts/CodeGeneratorCOM.pm b/WebCore/bindings/scripts/CodeGeneratorCOM.pm index 4ca441b..e98379b 100644 --- a/WebCore/bindings/scripts/CodeGeneratorCOM.pm +++ b/WebCore/bindings/scripts/CodeGeneratorCOM.pm @@ -16,7 +16,7 @@ # Library General Public License for more details. # # You should have received a copy of the GNU Library General Public License -# aint with this library; see the file COPYING.LIB. If not, write to +# along with this library; see the file COPYING.LIB. If not, write to # the Free Software Foundation, Inc., 59 Temple Place - Suite 330, # Boston, MA 02111-1307, USA. diff --git a/WebCore/bindings/scripts/CodeGeneratorJS.pm b/WebCore/bindings/scripts/CodeGeneratorJS.pm index d8367ac..6ccf739 100644 --- a/WebCore/bindings/scripts/CodeGeneratorJS.pm +++ b/WebCore/bindings/scripts/CodeGeneratorJS.pm @@ -316,7 +316,14 @@ sub GenerateGetOwnPropertySlotBody if ($dataNode->extendedAttributes->{"HasIndexGetter"} || $dataNode->extendedAttributes->{"HasCustomIndexGetter"} || $dataNode->extendedAttributes->{"HasNumericIndexGetter"}) { push(@getOwnPropertySlotImpl, " bool ok;\n"); push(@getOwnPropertySlotImpl, " unsigned index = propertyName.toUInt32(&ok, false);\n"); - push(@getOwnPropertySlotImpl, " if (ok && index < static_cast<$implClassName*>(impl())->length()) {\n"); + + # If the item function returns a string then we let the ConvertNullStringTo handle the cases + # where the index is out of range. + if (IndexGetterReturnsStrings($implClassName)) { + push(@getOwnPropertySlotImpl, " if (ok) {\n"); + } else { + push(@getOwnPropertySlotImpl, " if (ok && index < static_cast<$implClassName*>(impl())->length()) {\n"); + } if ($dataNode->extendedAttributes->{"HasCustomIndexGetter"} || $dataNode->extendedAttributes->{"HasNumericIndexGetter"}) { push(@getOwnPropertySlotImpl, " slot.setValue(getByIndex(exec, index));\n"); } else { @@ -368,6 +375,14 @@ sub GenerateGetOwnPropertyDescriptorBody my $namespaceMaybe = ($inlined ? "JSC::" : ""); my @getOwnPropertyDescriptorImpl = (); + if ($dataNode->extendedAttributes->{"CheckDomainSecurity"}) { + if ($interfaceName eq "DOMWindow") { + push(@implContent, " if (!static_cast<$className*>(thisObject)->allowsAccessFrom(exec))\n"); + } else { + push(@implContent, " if (!allowsAccessFromFrame(exec, static_cast<$className*>(thisObject)->impl()->frame()))\n"); + } + push(@implContent, " return false;\n"); + } if ($interfaceName eq "NamedNodeMap" or $interfaceName eq "HTMLCollection" or $interfaceName eq "HTMLAllCollection") { push(@getOwnPropertyDescriptorImpl, " ${namespaceMaybe}JSValue proto = prototype();\n"); @@ -643,9 +658,6 @@ sub GenerateHeader $structureFlags{"JSC::OverridesGetPropertyNames"} = 1; } - # Custom getPropertyAttributes function - push(@headerContent, " virtual bool getPropertyAttributes(JSC::ExecState*, const JSC::Identifier&, unsigned& attributes) const;\n") if $dataNode->extendedAttributes->{"CustomGetPropertyAttributes"}; - # Custom defineGetter function push(@headerContent, " virtual void defineGetter(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::JSObject* getterFunction, unsigned attributes);\n") if $dataNode->extendedAttributes->{"CustomDefineGetter"}; diff --git a/WebCore/bindings/scripts/CodeGeneratorV8.pm b/WebCore/bindings/scripts/CodeGeneratorV8.pm index 2e0f9ee..77e9512 100644 --- a/WebCore/bindings/scripts/CodeGeneratorV8.pm +++ b/WebCore/bindings/scripts/CodeGeneratorV8.pm @@ -7,8 +7,6 @@ # Copyright (C) 2007, 2008, 2009 Google Inc. # Copyright (C) 2009 Cameron McCormack <cam@mcc.id.au> # -# This file is part of the KDE project -# # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Library General Public # License as published by the Free Software Foundation; either @@ -352,15 +350,16 @@ sub HolderToNative my $dataNode = shift; my $implClassName = shift; my $classIndex = shift; + my $holder = shift || "holder"; # optional param if (IsNodeSubType($dataNode)) { push(@implContentDecls, <<END); - $implClassName* imp = V8DOMWrapper::convertDOMWrapperToNode<$implClassName>(holder); + $implClassName* imp = v8DOMWrapperToNode<$implClassName>($holder); END } else { push(@implContentDecls, <<END); - $implClassName* imp = V8DOMWrapper::convertToNativeObject<$implClassName>(V8ClassIndex::$classIndex, holder); + $implClassName* imp = v8DOMWrapperTo<$implClassName>(V8ClassIndex::$classIndex, $holder); END } @@ -399,7 +398,7 @@ sub GenerateDomainSafeFunctionGetter } END - HolderToNative($dataNode, $implClassName, $classIndex); + HolderToNative($dataNode, $implClassName, $classIndex); push(@implContentDecls, <<END); if (!V8Proxy::canAccessFrame(imp->frame(), false)) { @@ -430,7 +429,7 @@ END if ($classIndex eq "DOMWINDOW") { push(@implContentDecls, <<END); - DOMWindow* window = V8DOMWrapper::convertToNativeObject<DOMWindow>(V8ClassIndex::DOMWINDOW, info.Holder()); + DOMWindow* window = v8DOMWrapperTo<DOMWindow>(V8ClassIndex::DOMWINDOW, info.Holder()); // Get the proxy corresponding to the DOMWindow if possible to // make sure that the constructor function is constructed in the // context of the DOMWindow and not in the context of the caller. @@ -439,11 +438,11 @@ END } elsif ($classIndex eq "DEDICATEDWORKERCONTEXT" or $classIndex eq "WORKERCONTEXT" or $classIndex eq "SHAREDWORKERCONTEXT") { $implIncludes{"WorkerContextExecutionProxy.h"} = 1; push(@implContentDecls, <<END); - WorkerContext* workerContext = V8DOMWrapper::convertToNativeObject<WorkerContext>(V8ClassIndex::WORKERCONTEXT, info.Holder()); + WorkerContext* workerContext = v8DOMWrapperTo<WorkerContext>(V8ClassIndex::WORKERCONTEXT, info.Holder()); return V8DOMWrapper::getConstructor(type, workerContext); END } else { - push(@implContentDecls, " return v8::Undefined();"); + push(@implContentDecls, " return v8::Handle<v8::Value>();"); } push(@implContentDecls, <<END); @@ -469,7 +468,7 @@ sub GenerateNormalAttrGetter my $attrType = GetTypeFromSignature($attribute->signature); my $attrIsPodType = IsPodType($attrType); - my $nativeType = GetNativeTypeFromSignature($attribute->signature, 0); + my $nativeType = GetNativeTypeFromSignature($attribute->signature, -1); my $isPodType = IsPodType($implClassName); my $skipContext = 0; @@ -506,7 +505,7 @@ END if ($isPodType) { push(@implContentDecls, <<END); - V8SVGPODTypeWrapper<$implClassName>* imp_wrapper = V8DOMWrapper::convertToNativeObject<V8SVGPODTypeWrapper<$implClassName> >(V8ClassIndex::$classIndex, info.Holder()); + V8SVGPODTypeWrapper<$implClassName>* imp_wrapper = v8DOMWrapperTo<V8SVGPODTypeWrapper<$implClassName> >(V8ClassIndex::$classIndex, info.Holder()); $implClassName imp_instance = *imp_wrapper; END if ($getterStringUsesImp) { @@ -524,22 +523,34 @@ END # perform lookup first push(@implContentDecls, <<END); v8::Handle<v8::Object> holder = V8DOMWrapper::lookupDOMWrapper(V8ClassIndex::$classIndex, info.This()); - if (holder.IsEmpty()) return v8::Undefined(); + if (holder.IsEmpty()) return v8::Handle<v8::Value>(); END } - HolderToNative($dataNode, $implClassName, $classIndex); + HolderToNative($dataNode, $implClassName, $classIndex, "info"); } else { + my $reflect = $attribute->signature->extendedAttributes->{"Reflect"}; + if ($getterStringUsesImp && $reflect && IsNodeSubType($dataNode) && $codeGenerator->IsStringType($attrType)) { + # Generate super-compact call for regular attribute getter: + my $contentAttributeName = $reflect eq "1" ? $attrName : $reflect; + my $namespace = $codeGenerator->NamespaceForAttributeName($interfaceName, $contentAttributeName); + $implIncludes{"${namespace}.h"} = 1; + push(@implContentDecls, " return getElementStringAttr(info, ${namespace}::${contentAttributeName}Attr);\n"); + push(@implContentDecls, " }\n\n"); + return; + # Skip the rest of the function! + } + push(@implContentDecls, <<END); v8::Handle<v8::Object> holder = info.Holder(); END - HolderToNative($dataNode, $implClassName, $classIndex); + HolderToNative($dataNode, $implClassName, $classIndex, "info"); } # Generate security checks if necessary if ($attribute->signature->extendedAttributes->{"CheckNodeSecurity"}) { - push(@implContentDecls, " if (!V8Proxy::checkNodeSecurity(imp->$attrName())) return v8::Undefined();\n\n"); + push(@implContentDecls, " if (!V8Proxy::checkNodeSecurity(imp->$attrName())) return v8::Handle<v8::Value>();\n\n"); } elsif ($attribute->signature->extendedAttributes->{"CheckFrameSecurity"}) { - push(@implContentDecls, " if (!V8Proxy::checkNodeSecurity(imp->contentDocument())) return v8::Undefined();\n\n"); + push(@implContentDecls, " if (!V8Proxy::checkNodeSecurity(imp->contentDocument())) return v8::Handle<v8::Value>();\n\n"); } my $useExceptions = 1 if @{$attribute->getterExceptions} and !($isPodType); @@ -553,7 +564,12 @@ END } my $getterFunc = $codeGenerator->WK_lcfirst($attrName); - $getterFunc .= "Animated" if $codeGenerator->IsSVGAnimatedType($attribute->signature->type); + + if ($codeGenerator->IsSVGAnimatedType($attribute->signature->type)) { + # Some SVGFE*Element.idl use 'operator' as attribute name; rewrite as '_operator' to avoid clashes with C/C++ + $getterFunc = "_" . $getterFunc if ($attrName =~ /operator/); + $getterFunc .= "Animated"; + } my $returnType = GetTypeFromSignature($attribute->signature); @@ -579,10 +595,6 @@ END $getterString = "imp_instance"; } - if ($nativeType eq "String") { - $getterString = "toString($getterString)"; - } - my $result; my $wrapper; @@ -619,7 +631,7 @@ END } else { if ($attribute->signature->type eq "EventListener" && $dataNode->name eq "DOMWindow") { push(@implContentDecls, " if (!imp->document())\n"); - push(@implContentDecls, " return v8::Undefined();\n"); + push(@implContentDecls, " return v8::Handle<v8::Value>();\n"); } if ($useExceptions) { @@ -635,12 +647,12 @@ END } if (IsSVGTypeNeedingContextParameter($attrType) && !$skipContext) { - my $resultObject = $result; if ($attrIsPodType) { - $resultObject = "wrapper"; + push(@implContentDecls, GenerateSVGContextAssignment($implClassName, "wrapper.get()", " ")); + } else { + push(@implContentDecls, GenerateSVGContextRetrieval($implClassName, " ")); + $result = "V8Proxy::withSVGContext($result, context)"; } - $resultObject = "WTF::getPtr(" . $resultObject . ")"; - push(@implContentDecls, GenerateSVGContextAssignment($implClassName, $resultObject, " ")); } if ($attrIsPodType) { @@ -696,7 +708,7 @@ sub GenerateNormalAttrSetter if ($isPodType) { $implClassName = GetNativeType($implClassName); $implIncludes{"V8SVGPODTypeWrapper.h"} = 1; - push(@implContentDecls, " V8SVGPODTypeWrapper<$implClassName>* wrapper = V8DOMWrapper::convertToNativeObject<V8SVGPODTypeWrapper<$implClassName> >(V8ClassIndex::$classIndex, info.Holder());\n"); + push(@implContentDecls, " V8SVGPODTypeWrapper<$implClassName>* wrapper = v8DOMWrapperTo<V8SVGPODTypeWrapper<$implClassName> >(V8ClassIndex::$classIndex, info.Holder());\n"); push(@implContentDecls, " $implClassName imp_instance = *wrapper;\n"); push(@implContentDecls, " $implClassName* imp = &imp_instance;\n"); @@ -712,12 +724,26 @@ END if (holder.IsEmpty()) return; END } - HolderToNative($dataNode, $implClassName, $classIndex); + HolderToNative($dataNode, $implClassName, $classIndex, "info"); } else { + my $attrType = GetTypeFromSignature($attribute->signature); + my $reflect = $attribute->signature->extendedAttributes->{"Reflect"}; + my $reflectURL = $attribute->signature->extendedAttributes->{"ReflectURL"}; + if (($reflect || $reflectURL) && IsNodeSubType($dataNode) && $codeGenerator->IsStringType($attrType)) { + # Generate super-compact call for regular attribute setter: + my $contentAttributeName = ($reflect || $reflectURL) eq "1" ? $attrName : ($reflect || $reflectURL); + my $namespace = $codeGenerator->NamespaceForAttributeName($interfaceName, $contentAttributeName); + $implIncludes{"${namespace}.h"} = 1; + push(@implContentDecls, " setElementStringAttr(info, ${namespace}::${contentAttributeName}Attr, value);\n"); + push(@implContentDecls, " }\n\n"); + return; + # Skip the rest of the function! + } + push(@implContentDecls, <<END); v8::Handle<v8::Object> holder = info.Holder(); END - HolderToNative($dataNode, $implClassName, $classIndex); + HolderToNative($dataNode, $implClassName, $classIndex, "info"); } my $nativeType = GetNativeTypeFromSignature($attribute->signature, 0); @@ -726,7 +752,6 @@ END push(@implContentDecls, " if (!imp->document())\n"); push(@implContentDecls, " return;\n"); } - push(@implContentDecls, " $nativeType v = V8DOMWrapper::getEventListener(imp, value, true, ListenerFindOrCreate);\n"); } else { push(@implContentDecls, " $nativeType v = " . JSValueToNative($attribute->signature, "value") . ";\n"); } @@ -766,18 +791,10 @@ END $implIncludes{"V8AbstractEventListener.h"} = 1; $implIncludes{"V8CustomBinding.h"} = 1; $cacheIndex = GetHiddenDependencyIndex($dataNode, $attrName); - push(@implContentDecls, " $nativeType old = imp->$attrName();\n"); - push(@implContentDecls, " V8AbstractEventListener* oldListener = old ? V8AbstractEventListener::cast(old.get()) : 0;\n"); - push(@implContentDecls, " if (oldListener) {\n"); - push(@implContentDecls, " v8::Local<v8::Object> oldListenerObject = oldListener->getExistingListenerObject();\n"); - push(@implContentDecls, " if (!oldListenerObject.IsEmpty())\n"); - push(@implContentDecls, " removeHiddenDependency(holder, oldListenerObject, $cacheIndex);\n"); - push(@implContentDecls, " }\n"); - push(@implContentDecls, " imp->set$implSetterFunctionName($result);\n"); - push(@implContentDecls, " if ($result)\n"); - push(@implContentDecls, " createHiddenDependency(holder, value, $cacheIndex"); + push(@implContentDecls, " transferHiddenDependency(holder, imp->$attrName(), value, $cacheIndex);\n"); + push(@implContentDecls, " imp->set$implSetterFunctionName(V8DOMWrapper::getEventListener(imp, value, true, ListenerFindOrCreate)"); } else { - push(@implContentDecls, " imp->set$implSetterFunctionName(" . $result); + push(@implContentDecls, " imp->set$implSetterFunctionName($result"); } push(@implContentDecls, ", ec") if $useExceptions; push(@implContentDecls, ");\n"); @@ -807,12 +824,11 @@ END push(@implContentDecls, " }\n\n"); # end of setter } -sub GenerateNewFunctionTemplate +sub GetFunctionTemplateCallbackName { $function = shift; $dataNode = shift; - $signature = shift; - + my $interfaceName = $dataNode->name; my $name = $function->signature->name; @@ -827,12 +843,22 @@ sub GenerateNewFunctionTemplate if ($customFunc eq 1) { $customFunc = $interfaceName . $codeGenerator->WK_ucfirst($name); } - return "v8::FunctionTemplate::New(V8Custom::v8${customFunc}Callback, v8::Handle<v8::Value>(), $signature)"; + return "V8Custom::v8${customFunc}Callback"; } else { - return "v8::FunctionTemplate::New(${interfaceName}Internal::${name}Callback, v8::Handle<v8::Value>(), $signature)"; + return "${interfaceName}Internal::${name}Callback"; } } +sub GenerateNewFunctionTemplate +{ + $function = shift; + $dataNode = shift; + $signature = shift; + + my $callback = GetFunctionTemplateCallbackName($function, $dataNode); + return "v8::FunctionTemplate::New($callback, v8::Handle<v8::Value>(), $signature)"; +} + sub GenerateFunctionCallback { my $function = shift; @@ -851,12 +877,12 @@ sub GenerateFunctionCallback if ($function->signature->extendedAttributes->{"RequiresAllArguments"}) { push(@implContentDecls, - " if (args.Length() < $numParameters) return v8::Undefined();\n"); + " if (args.Length() < $numParameters) return v8::Handle<v8::Value>();\n"); } if (IsPodType($implClassName)) { my $nativeClassName = GetNativeType($implClassName); - push(@implContentDecls, " V8SVGPODTypeWrapper<$nativeClassName>* imp_wrapper = V8DOMWrapper::convertToNativeObject<V8SVGPODTypeWrapper<$nativeClassName> >(V8ClassIndex::$classIndex, args.Holder());\n"); + push(@implContentDecls, " V8SVGPODTypeWrapper<$nativeClassName>* imp_wrapper = v8DOMWrapperTo<V8SVGPODTypeWrapper<$nativeClassName> >(V8ClassIndex::$classIndex, args.Holder());\n"); push(@implContentDecls, " $nativeClassName imp_instance = *imp_wrapper;\n"); push(@implContentDecls, " $nativeClassName* imp = &imp_instance;\n"); } else { @@ -873,24 +899,39 @@ END # We have not find real use cases yet. push(@implContentDecls, " if (!V8Proxy::canAccessFrame(imp->frame(), true)) {\n". -" return v8::Undefined();\n" . +" return v8::Handle<v8::Value>();\n" . " }\n"); } + + my $raisesExceptions = @{$function->raisesExceptions}; + if (!$raisesExceptions) { + foreach my $parameter (@{$function->parameters}) { + if (TypeCanFailConversion($parameter) or $parameter->extendedAttributes->{"IsIndex"}) { + $raisesExceptions = 1; + } + } + } - - if (@{$function->raisesExceptions}) { + if ($raisesExceptions) { $implIncludes{"ExceptionCode.h"} = 1; push(@implContentDecls, " ExceptionCode ec = 0;\n"); + push(@implContentDecls, " {\n"); + # The brace here is needed to prevent the ensuing 'goto fail's from jumping past constructors + # of objects (like Strings) declared later, causing compile errors. The block scope ends + # right before the label 'fail:'. } if ($function->signature->extendedAttributes->{"CustomArgumentHandling"}) { - push(@implContentDecls, " ScriptCallStack callStack(args, $numParameters);\n"); + push(@implContentDecls, +" OwnPtr<ScriptCallStack> callStack(ScriptCallStack::create(args, $numParameters));\n". +" if (!callStack)\n". +" return v8::Undefined();\n"); $implIncludes{"ScriptCallStack.h"} = 1; } if ($function->signature->extendedAttributes->{"SVGCheckSecurityDocument"}) { push(@implContentDecls, " if (!V8Proxy::checkNodeSecurity(imp->getSVGDocument(ec)))\n" . -" return v8::Undefined();\n"); +" return v8::Handle<v8::Value>();\n"); } my $paramIndex = 0; @@ -911,7 +952,7 @@ END push(@implContentDecls, " bool ${parameterName}Ok;\n"); } - push(@implContentDecls, " " . GetNativeTypeFromSignature($parameter, 1) . " $parameterName = "); + push(@implContentDecls, " " . GetNativeTypeFromSignature($parameter, $paramIndex) . " $parameterName = "); push(@implContentDecls, JSValueToNative($parameter, "args[$paramIndex]", BasicTypeCanFailConversion($parameter) ? "${parameterName}Ok" : undef) . ";\n"); @@ -919,8 +960,8 @@ END $implIncludes{"ExceptionCode.h"} = 1; push(@implContentDecls, " if (UNLIKELY(!$parameterName" . (BasicTypeCanFailConversion($parameter) ? "Ok" : "") . ")) {\n" . -" V8Proxy::setDOMException(TYPE_MISMATCH_ERR);\n" . -" return v8::Handle<v8::Value>();\n" . +" ec = TYPE_MISMATCH_ERR;\n" . +" goto fail;\n" . " }\n"); } @@ -928,8 +969,8 @@ END $implIncludes{"ExceptionCode.h"} = 1; push(@implContentDecls, " if (UNLIKELY($parameterName < 0)) {\n" . -" V8Proxy::setDOMException(INDEX_SIZE_ERR);\n" . -" return v8::Handle<v8::Value>();\n" . +" ec = INDEX_SIZE_ERR;\n" . +" goto fail;\n" . " }\n"); } @@ -939,6 +980,14 @@ END # Build the function call string. my $callString = GenerateFunctionCallString($function, $paramIndex, " ", $implClassName); push(@implContentDecls, "$callString"); + + if ($raisesExceptions) { + push(@implContentDecls, " }\n"); + push(@implContentDecls, " fail:\n"); + push(@implContentDecls, " V8Proxy::setDOMException(ec);\n"); + push(@implContentDecls, " return v8::Handle<v8::Value>();\n"); + } + push(@implContentDecls, " }\n\n"); } @@ -1217,6 +1266,38 @@ sub GenerateImplementation GenerateBatchedAttributeData($dataNode, $attributes); push(@implContent, "};\n"); } + + # Setup table of standard callback functions + $num_callbacks = 0; + $has_callbacks = 0; + foreach my $function (@{$dataNode->functions}) { + my $attrExt = $function->signature->extendedAttributes; + # Don't put any nonstandard functions into this table: + if ($attrExt->{"V8OnInstance"}) { + next; + } + if ($attrExt->{"EnabledAtRuntime"} || RequiresCustomSignature($function) || $attrExt->{"V8DoNotCheckSignature"}) { + next; + } + if ($attrExt->{"DoNotCheckDomainSecurity"} && + ($dataNode->extendedAttributes->{"CheckDomainSecurity"} || $interfaceName eq "DOMWindow")) { + next; + } + if ($attrExt->{"DontEnum"} || $attrExt->{"V8ReadOnly"}) { + next; + } + if (!$has_callbacks) { + $has_callbacks = 1; + push(@implContent, "static const BatchedCallback ${interfaceName}_callbacks[] = {\n"); + } + my $name = $function->signature->name; + my $callback = GetFunctionTemplateCallbackName($function, $dataNode); + push(@implContent, <<END); + {"$name", $callback}, +END + $num_callbacks++; + } + push(@implContent, "};\n") if $has_callbacks; # Setup constants my $has_constants = 0; @@ -1240,7 +1321,7 @@ END push(@implContentDecls, "} // namespace ${interfaceName}Internal\n\n"); - my $access_check = "/* no access check */"; + my $access_check = ""; if ($dataNode->extendedAttributes->{"CheckDomainSecurity"} && !($interfaceName eq "DOMWindow")) { $access_check = "instance->SetAccessCheckCallbacks(V8Custom::v8${interfaceName}NamedSecurityCheck, V8Custom::v8${interfaceName}IndexedSecurityCheck, v8::Integer::New(V8ClassIndex::ToInt(V8ClassIndex::${classIndex})));"; } @@ -1259,35 +1340,59 @@ static v8::Persistent<v8::ObjectTemplate> ConfigureShadowObjectTemplate(v8::Pers END } + # find the super descriptor + my $parentClassIndex = "INVALID_CLASS_INDEX"; + foreach (@{$dataNode->parents}) { + my $parent = $codeGenerator->StripModule($_); + if ($parent eq "EventTarget") { next; } + $implIncludes{"V8${parent}.h"} = 1; + $parentClassIndex = uc($codeGenerator->StripModule($parent)); + last; + } + + # find the field count + my $fieldCount = "V8Custom::kDefaultWrapperInternalFieldCount"; + if (IsNodeSubType($dataNode)) { + $fieldCount = "V8Custom::kNodeMinimumInternalFieldCount"; + } + # Generate the template configuration method push(@implContent, <<END); static v8::Persistent<v8::FunctionTemplate> Configure${className}Template(v8::Persistent<v8::FunctionTemplate> desc) { - v8::Local<v8::ObjectTemplate> instance = desc->InstanceTemplate(); + v8::Local<v8::Signature> default_signature = configureTemplate(desc, \"${interfaceName}\", + V8ClassIndex::$parentClassIndex, $fieldCount, END - if (IsNodeSubType($dataNode)) { + + # Set up our attributes if we have them + if ($has_attributes) { push(@implContent, <<END); - instance->SetInternalFieldCount(V8Custom::kNodeMinimumInternalFieldCount); + ${interfaceName}_attrs, sizeof(${interfaceName}_attrs)/sizeof(*${interfaceName}_attrs), END } else { push(@implContent, <<END); - instance->SetInternalFieldCount(V8Custom::kDefaultWrapperInternalFieldCount); + NULL, 0, +END + } + + if ($has_callbacks) { + push(@implContent, <<END); + ${interfaceName}_callbacks, sizeof(${interfaceName}_callbacks)/sizeof(*${interfaceName}_callbacks)); +END + } else { + push(@implContent, <<END); + NULL, 0); END } + if ($access_check or @enabledAtRuntime or @{$dataNode->functions} or $has_constants) { push(@implContent, <<END); - v8::Local<v8::Signature> default_signature = v8::Signature::New(desc); + v8::Local<v8::ObjectTemplate> instance = desc->InstanceTemplate(); v8::Local<v8::ObjectTemplate> proto = desc->PrototypeTemplate(); - $access_check -END - - - # Set up our attributes if we have them - if ($has_attributes) { - push(@implContent, <<END); - batchConfigureAttributes(instance, proto, ${interfaceName}_attrs, sizeof(${interfaceName}_attrs)/sizeof(*${interfaceName}_attrs)); END } + push(@implContent, " $access_check\n"); + # Setup the enable-at-runtime attrs if we have them foreach my $runtime_attr (@enabledAtRuntime) { $enable_function = $interfaceName . $codeGenerator->WK_ucfirst($runtime_attr->signature->name); @@ -1304,7 +1409,9 @@ END } # Define our functions with Set() or SetAccessor() + $total_functions = 0; foreach my $function (@{$dataNode->functions}) { + $total_functions++; my $attrExt = $function->signature->extendedAttributes; my $name = $function->signature->name; @@ -1358,6 +1465,7 @@ END v8::ALL_CAN_READ, static_cast<v8::PropertyAttribute>($property_attributes)); END + $num_callbacks++; next; } @@ -1372,31 +1480,26 @@ END } # Normal function call is a template - my $templateFunction = GenerateNewFunctionTemplate($function, $dataNode, $signature); - - + my $callback = GetFunctionTemplateCallbackName($function, $dataNode); + + if ($property_attributes eq "v8::DontDelete") { + $property_attributes = ""; + } else { + $property_attributes = ", static_cast<v8::PropertyAttribute>($property_attributes)"; + } + + if ($template eq "proto" && $conditional eq "" && $signature eq "default_signature" && $property_attributes eq "") { + # Standard type of callback, already created in the batch, so skip it here. + next; + } + push(@implContent, <<END); - - // $commentInfo - $conditional ${template}->Set( - v8::String::New("$name"), - $templateFunction, - static_cast<v8::PropertyAttribute>($property_attributes)); + ${conditional}createCallback($template, "$name", $callback, ${signature}$property_attributes); END + $num_callbacks++; } - - # set the super descriptor - foreach (@{$dataNode->parents}) { - my $parent = $codeGenerator->StripModule($_); - if ($parent eq "EventTarget") { next; } - $implIncludes{"V8${parent}.h"} = 1; - my $parentClassIndex = uc($codeGenerator->StripModule($parent)); - push(@implContent, " desc->Inherit(V8DOMWrapper::getTemplate(V8ClassIndex::${parentClassIndex}));\n"); - last; - } - - # Set the class name. This is used when printing objects. - push(@implContent, " desc->SetClassName(v8::String::New(\"${interfaceName}\"));\n"); + + die "Wrong number of callbacks generated for $interfaceName ($num_callbacks, should be $total_functions)" if $num_callbacks != $total_functions; if ($has_constants) { push(@implContent, <<END); @@ -1409,19 +1512,12 @@ END } v8::Persistent<v8::FunctionTemplate> ${className}::GetRawTemplate() { - static v8::Persistent<v8::FunctionTemplate> ${className}_raw_cache_; - if (${className}_raw_cache_.IsEmpty()) { - v8::HandleScope scope; - v8::Local<v8::FunctionTemplate> result = v8::FunctionTemplate::New(V8Proxy::checkNewLegal); - ${className}_raw_cache_ = v8::Persistent<v8::FunctionTemplate>::New(result); - } + static v8::Persistent<v8::FunctionTemplate> ${className}_raw_cache_ = createRawTemplate(); return ${className}_raw_cache_; } v8::Persistent<v8::FunctionTemplate> ${className}::GetTemplate() { - static v8::Persistent<v8::FunctionTemplate> ${className}_cache_; - if (${className}_cache_.IsEmpty()) - ${className}_cache_ = Configure${className}Template(GetRawTemplate()); + static v8::Persistent<v8::FunctionTemplate> ${className}_cache_ = Configure${className}Template(GetRawTemplate()); return ${className}_cache_; } @@ -1528,7 +1624,7 @@ sub GenerateFunctionCallString() if ($function->signature->extendedAttributes->{"CustomArgumentHandling"}) { $functionString .= ", " if not $first; - $functionString .= "&callStack"; + $functionString .= "callStack.get()"; if ($first) { $first = 0; } } @@ -1546,7 +1642,7 @@ sub GenerateFunctionCallString() # appendChild functions from Node. $result .= $indent . "bool success = $functionString;\n"; if (@{$function->raisesExceptions}) { - $result .= GenerateSetDOMException($indent); + $result .= $indent . "if (UNLIKELY(ec)) goto fail;\n"; } $result .= $indent . "if (success)\n"; $result .= $indent . " " . @@ -1570,7 +1666,7 @@ sub GenerateFunctionCallString() } if (@{$function->raisesExceptions}) { - $result .= GenerateSetDOMException($indent); + $result .= $indent . "if (UNLIKELY(ec)) goto fail;\n"; } # If the return type is a POD type, separate out the wrapper generation @@ -1627,19 +1723,14 @@ sub GetTypeFromSignature { my $signature = shift; - my $type = $codeGenerator->StripModule($signature->type); - if (($type eq "DOMString") && $signature->extendedAttributes->{"HintAtomic"}) { - $type = "AtomicString"; - } - - return $type; + return $codeGenerator->StripModule($signature->type); } sub GetNativeTypeFromSignature { my $signature = shift; - my $isParameter = shift; + my $parameterIndex = shift; my $type = GetTypeFromSignature($signature); @@ -1648,32 +1739,28 @@ sub GetNativeTypeFromSignature return "int"; } - return GetNativeType($type, $isParameter); + $type = GetNativeType($type, $parameterIndex >= 0 ? 1 : 0); + + if ($parameterIndex >= 0 && $type eq "V8Parameter") { + my $mode = ""; + if ($signature->extendedAttributes->{"ConvertUndefinedOrNullToNullString"}) { + $mode = "WithUndefinedOrNullCheck"; + } elsif ($signature->extendedAttributes->{"ConvertNullToNullString"}) { + $mode = "WithNullCheck"; + } + $type .= "<$mode>"; + } + + return $type; } sub IsRefPtrType { my $type = shift; return 1 if $type eq "Attr"; - return 1 if $type eq "CanvasActiveInfo"; - return 1 if $type eq "CanvasArray"; - return 1 if $type eq "CanvasArrayBuffer"; return 1 if $type eq "CanvasBooleanArray"; - return 1 if $type eq "CanvasByteArray"; - return 1 if $type eq "CanvasBuffer"; - return 1 if $type eq "CanvasFloatArray"; - return 1 if $type eq "CanvasFramebuffer"; return 1 if $type eq "CanvasGradient"; - return 1 if $type eq "CanvasIntArray"; return 1 if $type eq "CanvasObject"; - return 1 if $type eq "CanvasProgram"; - return 1 if $type eq "CanvasRenderbuffer"; - return 1 if $type eq "CanvasShader"; - return 1 if $type eq "CanvasShortArray"; - return 1 if $type eq "CanvasTexture"; - return 1 if $type eq "CanvasUnsignedByteArray"; - return 1 if $type eq "CanvasUnsignedIntArray"; - return 1 if $type eq "CanvasUnsignedShortArray"; return 1 if $type eq "ClientRect"; return 1 if $type eq "ClientRectList"; return 1 if $type eq "CDATASection"; @@ -1721,6 +1808,23 @@ sub IsRefPtrType return 1 if $type eq "TextMetrics"; return 1 if $type eq "TimeRanges"; return 1 if $type eq "TreeWalker"; + return 1 if $type eq "WebGLActiveInfo"; + return 1 if $type eq "WebGLArray"; + return 1 if $type eq "WebGLArrayBuffer"; + return 1 if $type eq "WebGLByteArray"; + return 1 if $type eq "WebGLBuffer"; + return 1 if $type eq "WebGLFloatArray"; + return 1 if $type eq "WebGLFramebuffer"; + return 1 if $type eq "WebGLIntArray"; + return 1 if $type eq "WebGLProgram"; + return 1 if $type eq "WebGLRenderbuffer"; + return 1 if $type eq "WebGLShader"; + return 1 if $type eq "WebGLShortArray"; + return 1 if $type eq "WebGLTexture"; + return 1 if $type eq "WebGLUniformLocation"; + return 1 if $type eq "WebGLUnsignedByteArray"; + return 1 if $type eq "WebGLUnsignedIntArray"; + return 1 if $type eq "WebGLUnsignedShortArray"; return 1 if $type eq "WebKitCSSMatrix"; return 1 if $type eq "WebKitPoint"; return 1 if $type eq "XPathExpression"; @@ -1766,10 +1870,11 @@ sub GetNativeType my $type = shift; my $isParameter = shift; - if ($type eq "float" or $type eq "AtomicString" or $type eq "double") { + if ($type eq "float" or $type eq "double") { return $type; } + return "V8Parameter" if ($type eq "DOMString" or $type eq "DOMUserData") and $isParameter; return "int" if $type eq "int"; return "int" if $type eq "short" or $type eq "unsigned short"; return "unsigned" if $type eq "unsigned long"; @@ -1805,21 +1910,21 @@ sub GetNativeType my %typeCanFailConversion = ( - "AtomicString" => 0, "Attr" => 1, - "CanvasArray" => 0, - "CanvasBuffer" => 0, - "CanvasByteArray" => 0, - "CanvasFloatArray" => 0, - "CanvasFramebuffer" => 0, + "WebGLArray" => 0, + "WebGLBuffer" => 0, + "WebGLByteArray" => 0, + "WebGLFloatArray" => 0, + "WebGLFramebuffer" => 0, "CanvasGradient" => 0, - "CanvasIntArray" => 0, + "WebGLIntArray" => 0, "CanvasPixelArray" => 0, - "CanvasProgram" => 0, - "CanvasRenderbuffer" => 0, - "CanvasShader" => 0, - "CanvasShortArray" => 0, - "CanvasTexture" => 0, + "WebGLProgram" => 0, + "WebGLRenderbuffer" => 0, + "WebGLShader" => 0, + "WebGLShortArray" => 0, + "WebGLTexture" => 0, + "WebGLUniformLocation" => 0, "CompareHow" => 0, "DataGridColumn" => 0, "DOMString" => 0, @@ -1921,16 +2026,8 @@ sub JSValueToNative return "static_cast<Range::CompareHow>($value->Int32Value())" if $type eq "CompareHow"; return "static_cast<SVGPaint::SVGPaintType>($value->ToInt32()->Int32Value())" if $type eq "SVGPaintType"; - if ($type eq "AtomicString") { - return "v8ValueToAtomicWebCoreStringWithNullCheck($value)" if $signature->extendedAttributes->{"ConvertNullToNullString"}; - return "v8ValueToAtomicWebCoreString($value)"; - } - - return "toWebCoreString($value)" if $type eq "DOMUserData"; - if ($type eq "DOMString") { - return "toWebCoreStringWithNullCheck($value)" if $signature->extendedAttributes->{"ConvertNullToNullString"}; - return "toWebCoreStringWithNullOrUndefinedCheck($value)" if $signature->extendedAttributes->{"ConvertUndefinedOrNullToNullString"}; - return "toWebCoreString($value)"; + if ($type eq "DOMString" or $type eq "DOMUserData") { + return $value; } if ($type eq "SerializedScriptValue") { @@ -1956,7 +2053,7 @@ sub JSValueToNative $implIncludes{"V8Node.h"} = 1; # EventTarget is not in DOM hierarchy, but all Nodes are EventTarget. - return "V8Node::HasInstance($value) ? V8DOMWrapper::convertDOMWrapperToNode<Node>(v8::Handle<v8::Object>::Cast($value)) : 0"; + return "V8Node::HasInstance($value) ? v8DOMWrapperToNode<Node>(v8::Handle<v8::Object>::Cast($value)) : 0"; } if ($type eq "XPathNSResolver") { @@ -1971,7 +2068,7 @@ sub JSValueToNative # Perform type checks on the parameter, if it is expected Node type, # return NULL. - return "V8${type}::HasInstance($value) ? V8DOMWrapper::convertDOMWrapperToNode<${type}>(v8::Handle<v8::Object>::Cast($value)) : 0"; + return "V8${type}::HasInstance($value) ? v8DOMWrapperToNode<${type}>(v8::Handle<v8::Object>::Cast($value)) : 0"; } else { # TODO: Temporary to avoid Window name conflict. my $classIndex = uc($type); @@ -1990,7 +2087,7 @@ sub JSValueToNative # Perform type checks on the parameter, if it is expected Node type, # return NULL. - return "V8${type}::HasInstance($value) ? V8DOMWrapper::convertToNativeObject<${implClassName}>(V8ClassIndex::${classIndex}, v8::Handle<v8::Object>::Cast($value)) : 0"; + return "V8${type}::HasInstance($value) ? v8DOMWrapperTo<${implClassName}>(V8ClassIndex::${classIndex}, v8::Handle<v8::Object>::Cast($value)) : 0"; } } @@ -2054,7 +2151,6 @@ sub RequiresCustomSignature my %non_wrapper_types = ( 'float' => 1, - 'AtomicString' => 1, 'double' => 1, 'short' => 1, 'unsigned short' => 1, @@ -2123,8 +2219,8 @@ sub ReturnNativeToJSValue my $className= "V8$type"; return "return v8::Date::New(static_cast<double>($value))" if $type eq "DOMTimeStamp"; - return "return $value ? v8::True() : v8::False()" if $type eq "boolean"; - return "return v8::Undefined()" if $type eq "void"; + return "return v8Boolean($value)" if $type eq "boolean"; + return "return v8::Handle<v8::Value>()" if $type eq "void"; # equivalent to v8::Undefined() # For all the types where we use 'int' as the representation type, # we use Integer::New which has a fast Smi conversion check. diff --git a/WebCore/bindings/scripts/IDLParser.pm b/WebCore/bindings/scripts/IDLParser.pm index 4abdb45..5affe94 100644 --- a/WebCore/bindings/scripts/IDLParser.pm +++ b/WebCore/bindings/scripts/IDLParser.pm @@ -3,8 +3,6 @@ # # Copyright (C) 2005 Nikolas Zimmermann <wildfox@kde.org> # -# This file is part of the KDE project -# # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Library General Public # License as published by the Free Software Foundation; either diff --git a/WebCore/bindings/scripts/IDLStructure.pm b/WebCore/bindings/scripts/IDLStructure.pm index 5a59ff1..f5970b4 100644 --- a/WebCore/bindings/scripts/IDLStructure.pm +++ b/WebCore/bindings/scripts/IDLStructure.pm @@ -3,8 +3,6 @@ # # Copyright (C) 2005 Nikolas Zimmermann <wildfox@kde.org> # -# This file is part of the KDE project -# # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Library General Public # License as published by the Free Software Foundation; either diff --git a/WebCore/bindings/v8/DOMData.cpp b/WebCore/bindings/v8/DOMData.cpp index 07254fe..54bcc55 100644 --- a/WebCore/bindings/v8/DOMData.cpp +++ b/WebCore/bindings/v8/DOMData.cpp @@ -33,6 +33,7 @@ #include "ChildThreadDOMData.h" #include "MainThreadDOMData.h" +#include "WebGLUniformLocation.h" namespace WebCore { @@ -46,19 +47,12 @@ DOMData::DOMData() DOMData* DOMData::getCurrent() { if (WTF::isMainThread()) - return getCurrentMainThread(); + return MainThreadDOMData::getCurrent(); DEFINE_STATIC_LOCAL(WTF::ThreadSpecific<ChildThreadDOMData>, childThreadDOMData, ()); return childThreadDOMData; } -DOMData* DOMData::getCurrentMainThread() -{ - ASSERT(WTF::isMainThread()); - DEFINE_STATIC_LOCAL(MainThreadDOMData, mainThreadDOMData, ()); - return &mainThreadDOMData; -} - void DOMData::ensureDeref(V8ClassIndex::V8WrapperType type, void* domObject) { if (m_owningThread == WTF::currentThread()) { diff --git a/WebCore/bindings/v8/DOMData.h b/WebCore/bindings/v8/DOMData.h index e67adb4..7bf9f91 100644 --- a/WebCore/bindings/v8/DOMData.h +++ b/WebCore/bindings/v8/DOMData.h @@ -50,7 +50,6 @@ namespace WebCore { #endif static DOMData* getCurrent(); - static DOMData* getCurrentMainThread(); // Caller must be on the main thread. virtual DOMDataStore& getStore() = 0; template<typename T> @@ -87,20 +86,10 @@ namespace WebCore { ThreadIdentifier m_owningThread; }; - // Called when the dead object is not in GC thread's map. Go through all - // thread maps to find the one containing it. Then clear the JS reference - // and push the DOM object into the delayed queue for it to be deref-ed at - // later time from the owning thread. - // - // * This is called when the GC thread is not the owning thread. - // * This can be called on any thread that has GC running. - // * Only one V8 instance is running at a time due to V8::Locker. So we don't need to worry about concurrency. - // template<typename T> void DOMData::handleWeakObject(DOMDataStore::DOMWrapperMapType mapType, v8::Handle<v8::Object> v8Object, T* domObject) { - - WTF::MutexLocker locker(DOMDataStore::allStoresMutex()); + ASSERT(WTF::isMainThread()); DOMDataList& list = DOMDataStore::allStores(); for (size_t i = 0; i < list.size(); ++i) { DOMDataStore* store = list[i]; @@ -111,7 +100,8 @@ namespace WebCore { if (*wrapper == *v8Object) { // Clear the JS reference. domMap->forgetOnly(domObject); - store->domData()->ensureDeref(V8DOMWrapper::domWrapperType(v8Object), domObject); + ASSERT(store->domData()->owningThread() == WTF::currentThread()); + store->domData()->derefObject(V8DOMWrapper::domWrapperType(v8Object), domObject); } } } diff --git a/WebCore/bindings/v8/DOMObjectsInclude.h b/WebCore/bindings/v8/DOMObjectsInclude.h index 213873b..6ed14be 100644 --- a/WebCore/bindings/v8/DOMObjectsInclude.h +++ b/WebCore/bindings/v8/DOMObjectsInclude.h @@ -31,36 +31,38 @@ #ifndef DOMObjectsInclude_h #define DOMObjectsInclude_h +#include "Attr.h" #include "BarInfo.h" #include "BeforeLoadEvent.h" -#include "CanvasActiveInfo.h" -#include "CanvasArray.h" -#include "CanvasArrayBuffer.h" -#include "CanvasBuffer.h" -#include "CanvasByteArray.h" -#include "CanvasFloatArray.h" -#include "CanvasFramebuffer.h" +#include "WebGLActiveInfo.h" +#include "WebGLArray.h" +#include "WebGLArrayBuffer.h" +#include "WebGLBuffer.h" +#include "WebGLByteArray.h" +#include "WebGLFloatArray.h" +#include "WebGLFramebuffer.h" #include "CanvasGradient.h" -#include "CanvasIntArray.h" +#include "WebGLIntArray.h" #include "CanvasObject.h" #include "CanvasPattern.h" #include "CanvasPixelArray.h" -#include "CanvasProgram.h" -#include "CanvasRenderbuffer.h" +#include "WebGLProgram.h" +#include "WebGLRenderbuffer.h" #include "CanvasRenderingContext.h" #include "CanvasRenderingContext2D.h" -#include "CanvasRenderingContext3D.h" -#include "CanvasShader.h" -#include "CanvasShortArray.h" -#include "CanvasUnsignedByteArray.h" -#include "CanvasUnsignedIntArray.h" -#include "CanvasUnsignedShortArray.h" +#include "WebGLRenderingContext.h" +#include "WebGLShader.h" +#include "WebGLShortArray.h" +#include "WebGLUnsignedByteArray.h" +#include "WebGLUnsignedIntArray.h" +#include "WebGLUnsignedShortArray.h" #include "CanvasStyle.h" -#include "CanvasTexture.h" +#include "WebGLTexture.h" #include "CharacterData.h" #include "ClientRect.h" #include "ClientRectList.h" #include "Clipboard.h" +#include "CompositionEvent.h" #include "Console.h" #include "Counter.h" #include "CSSCharsetRule.h" @@ -271,7 +273,9 @@ #endif // XSLT #if ENABLE(INSPECTOR) +#include "InjectedScriptHost.h" #include "InspectorBackend.h" +#include "InspectorFrontendHost.h" #endif // INSPECTOR namespace WebCore { diff --git a/WebCore/bindings/v8/DerivedSourcesAllInOne.cpp b/WebCore/bindings/v8/DerivedSourcesAllInOne.cpp index 0a88da7..bd2bb7b 100644 --- a/WebCore/bindings/v8/DerivedSourcesAllInOne.cpp +++ b/WebCore/bindings/v8/DerivedSourcesAllInOne.cpp @@ -31,38 +31,45 @@ // This source file coalesces the V8 derived sources into a single object file to // reduce bloat and allow us to link release builds on 32-bit Windows. +// Require explicit conversion to AtomicString. This helps catch cases where +// the generated bindings cause an expensive implicit conversion. +#define NO_IMPLICIT_ATOMICSTRING + #include "bindings/V8Attr.cpp" #include "bindings/V8BarInfo.cpp" #include "bindings/V8BeforeLoadEvent.cpp" -#include "bindings/V8CanvasActiveInfo.cpp" -#include "bindings/V8CanvasArray.cpp" -#include "bindings/V8CanvasArrayBuffer.cpp" -#include "bindings/V8CanvasBuffer.cpp" -#include "bindings/V8CanvasByteArray.cpp" -#include "bindings/V8CanvasFloatArray.cpp" -#include "bindings/V8CanvasFramebuffer.cpp" +#include "bindings/V8WebGLActiveInfo.cpp" +#include "bindings/V8WebGLArray.cpp" +#include "bindings/V8WebGLArrayBuffer.cpp" +#include "bindings/V8WebGLBuffer.cpp" +#include "bindings/V8WebGLByteArray.cpp" +#include "bindings/V8WebGLFloatArray.cpp" +#include "bindings/V8WebGLFramebuffer.cpp" #include "bindings/V8CanvasGradient.cpp" -#include "bindings/V8CanvasIntArray.cpp" +#include "bindings/V8WebGLIntArray.cpp" #include "bindings/V8CanvasPattern.cpp" #include "bindings/V8CanvasPixelArray.cpp" -#include "bindings/V8CanvasProgram.cpp" -#include "bindings/V8CanvasRenderbuffer.cpp" +#include "bindings/V8WebGLProgram.cpp" +#include "bindings/V8WebGLRenderbuffer.cpp" #include "bindings/V8CanvasRenderingContext.cpp" #include "bindings/V8CanvasRenderingContext2D.cpp" -#include "bindings/V8CanvasRenderingContext3D.cpp" -#include "bindings/V8CanvasShader.cpp" -#include "bindings/V8CanvasShortArray.cpp" -#include "bindings/V8CanvasTexture.cpp" -#include "bindings/V8CanvasUnsignedByteArray.cpp" -#include "bindings/V8CanvasUnsignedIntArray.cpp" -#include "bindings/V8CanvasUnsignedShortArray.cpp" +#include "bindings/V8WebGLRenderingContext.cpp" +#include "bindings/V8WebGLShader.cpp" +#include "bindings/V8WebGLShortArray.cpp" +#include "bindings/V8WebGLTexture.cpp" +#include "bindings/V8WebGLUniformLocation.cpp" +#include "bindings/V8WebGLUnsignedByteArray.cpp" +#include "bindings/V8WebGLUnsignedIntArray.cpp" +#include "bindings/V8WebGLUnsignedShortArray.cpp" #include "bindings/V8CDATASection.cpp" #include "bindings/V8CharacterData.cpp" #include "bindings/V8ClientRect.cpp" #include "bindings/V8ClientRectList.cpp" #include "bindings/V8Clipboard.cpp" #include "bindings/V8Comment.cpp" +#include "bindings/V8CompositionEvent.cpp" #include "bindings/V8Console.cpp" +#include "bindings/V8Coordinates.cpp" #include "bindings/V8Counter.cpp" #include "bindings/V8CSSCharsetRule.cpp" #include "bindings/V8CSSFontFaceRule.cpp" @@ -97,6 +104,8 @@ #include "bindings/V8EventException.cpp" #include "bindings/V8File.cpp" #include "bindings/V8FileList.cpp" +#include "bindings/V8Geolocation.cpp" +#include "bindings/V8Geoposition.cpp" #include "bindings/V8History.cpp" #include "bindings/V8HTMLAllCollection.cpp" #include "bindings/V8HTMLAnchorElement.cpp" @@ -193,6 +202,7 @@ #include "bindings/V8PageTransitionEvent.cpp" #include "bindings/V8Plugin.cpp" #include "bindings/V8PluginArray.cpp" +#include "bindings/V8PositionError.cpp" #include "bindings/V8ProcessingInstruction.cpp" #include "bindings/V8ProgressEvent.cpp" #include "bindings/V8Range.cpp" @@ -282,6 +292,7 @@ #include "bindings/V8SVGCircleElement.cpp" #include "bindings/V8SVGClipPathElement.cpp" #include "bindings/V8SVGColor.cpp" +#include "bindings/V8SVGComponentTransferFunctionElement.cpp" #include "bindings/V8SVGCursorElement.cpp" #include "bindings/V8SVGDefsElement.cpp" #include "bindings/V8SVGDescElement.cpp" @@ -291,6 +302,30 @@ #include "bindings/V8SVGElementInstanceList.cpp" #include "bindings/V8SVGEllipseElement.cpp" #include "bindings/V8SVGException.cpp" +#include "bindings/V8SVGFEBlendElement.cpp" +#include "bindings/V8SVGFEColorMatrixElement.cpp" +#include "bindings/V8SVGFEComponentTransferElement.cpp" +#include "bindings/V8SVGFECompositeElement.cpp" +#include "bindings/V8SVGFEDiffuseLightingElement.cpp" +#include "bindings/V8SVGFEDisplacementMapElement.cpp" +#include "bindings/V8SVGFEDistantLightElement.cpp" +#include "bindings/V8SVGFEFloodElement.cpp" +#include "bindings/V8SVGFEFuncAElement.cpp" +#include "bindings/V8SVGFEFuncBElement.cpp" +#include "bindings/V8SVGFEFuncGElement.cpp" +#include "bindings/V8SVGFEFuncRElement.cpp" +#include "bindings/V8SVGFEGaussianBlurElement.cpp" +#include "bindings/V8SVGFEImageElement.cpp" +#include "bindings/V8SVGFEMergeElement.cpp" +#include "bindings/V8SVGFEMergeNodeElement.cpp" +#include "bindings/V8SVGFEMorphologyElement.cpp" +#include "bindings/V8SVGFEOffsetElement.cpp" +#include "bindings/V8SVGFEPointLightElement.cpp" +#include "bindings/V8SVGFESpecularLightingElement.cpp" +#include "bindings/V8SVGFESpotLightElement.cpp" +#include "bindings/V8SVGFETileElement.cpp" +#include "bindings/V8SVGFETurbulenceElement.cpp" +#include "bindings/V8SVGFilterElement.cpp" #include "bindings/V8SVGFontElement.cpp" #include "bindings/V8SVGFontFaceElement.cpp" #include "bindings/V8SVGFontFaceFormatElement.cpp" @@ -382,5 +417,7 @@ #endif #if ENABLE(INSPECTOR) +#include "bindings/V8InjectedScriptHost.cpp" #include "bindings/V8InspectorBackend.cpp" +#include "bindings/V8InspectorFrontendHost.cpp" #endif diff --git a/WebCore/bindings/v8/MainThreadDOMData.cpp b/WebCore/bindings/v8/MainThreadDOMData.cpp index ea34444..b1b63bf 100644 --- a/WebCore/bindings/v8/MainThreadDOMData.cpp +++ b/WebCore/bindings/v8/MainThreadDOMData.cpp @@ -39,14 +39,30 @@ MainThreadDOMData::MainThreadDOMData() : m_defaultStore(this) { } + +MainThreadDOMData* MainThreadDOMData::getCurrent() +{ + ASSERT(WTF::isMainThread()); + DEFINE_STATIC_LOCAL(MainThreadDOMData, mainThreadDOMData, ()); + return &mainThreadDOMData; +} -DOMDataStore& MainThreadDOMData::getStore() +DOMDataStore& MainThreadDOMData::getMainThreadStore() { + // This is broken out as a separate non-virtual method from getStore() + // so that it can be inlined by getCurrentMainThreadStore, which is + // a hot spot in Dromaeo DOM tests. ASSERT(WTF::isMainThread()); V8IsolatedWorld* world = V8IsolatedWorld::getEntered(); - if (world) + if (UNLIKELY(world != 0)) return *world->getDOMDataStore(); return m_defaultStore; } +DOMDataStore& MainThreadDOMData::getCurrentMainThreadStore() +{ + return getCurrent()->getMainThreadStore(); +} + + } // namespace WebCore diff --git a/WebCore/bindings/v8/MainThreadDOMData.h b/WebCore/bindings/v8/MainThreadDOMData.h index 5c78cec..e8f99c9 100644 --- a/WebCore/bindings/v8/MainThreadDOMData.h +++ b/WebCore/bindings/v8/MainThreadDOMData.h @@ -38,10 +38,16 @@ namespace WebCore { class MainThreadDOMData : public DOMData { public: - MainThreadDOMData(); - DOMDataStore& getStore(); + static MainThreadDOMData* getCurrent(); // Caller must be on the main thread. + static DOMDataStore& getCurrentMainThreadStore(); + + virtual DOMDataStore& getStore() { return getMainThreadStore(); } + private: + MainThreadDOMData(); + DOMDataStore& getMainThreadStore(); + StaticDOMDataStore m_defaultStore; // Note: The DOMDataStores for isolated world are owned by the world object. }; diff --git a/WebCore/bindings/v8/NPV8Object.cpp b/WebCore/bindings/v8/NPV8Object.cpp index 13403ec..69cd303 100644 --- a/WebCore/bindings/v8/NPV8Object.cpp +++ b/WebCore/bindings/v8/NPV8Object.cpp @@ -413,7 +413,7 @@ bool _NPN_HasMethod(NPP npp, NPObject* npObject, NPIdentifier methodName) void _NPN_SetException(NPObject* npObject, const NPUTF8 *message) { - if (npObject->_class != npScriptObjectClass) { + if (!npObject || npObject->_class != npScriptObjectClass) { // We won't be able to find a proper scope for this exception, so just throw it. // This is consistent with JSC, which throws a global exception all the time. V8Proxy::throwError(V8Proxy::GeneralError, message); diff --git a/WebCore/bindings/v8/RuntimeEnabledFeatures.cpp b/WebCore/bindings/v8/RuntimeEnabledFeatures.cpp index 21293a5..cf97b5b 100644 --- a/WebCore/bindings/v8/RuntimeEnabledFeatures.cpp +++ b/WebCore/bindings/v8/RuntimeEnabledFeatures.cpp @@ -36,5 +36,7 @@ namespace WebCore { bool RuntimeEnabledFeatures::isDatabaseEnabled = false; bool RuntimeEnabledFeatures::isLocalStorageEnabled = true; bool RuntimeEnabledFeatures::isSessionStorageEnabled = true; +bool RuntimeEnabledFeatures::isNotificationsEnabled = false; +bool RuntimeEnabledFeatures::isApplicationCacheEnabled = false; } // namespace WebCore diff --git a/WebCore/bindings/v8/RuntimeEnabledFeatures.h b/WebCore/bindings/v8/RuntimeEnabledFeatures.h index fa42024..d8078c5 100644 --- a/WebCore/bindings/v8/RuntimeEnabledFeatures.h +++ b/WebCore/bindings/v8/RuntimeEnabledFeatures.h @@ -45,6 +45,12 @@ public: static void setSessionStorageEnabled(bool isEnabled) { isSessionStorageEnabled = isEnabled; } static bool sessionStorageEnabled() { return isSessionStorageEnabled; } + static void setNotificationsEnabled(bool isEnabled) { isNotificationsEnabled = isEnabled; } + static bool notificationsEnabled() { return isNotificationsEnabled; } + + static void setApplicationCacheEnabled(bool isEnabled) { isApplicationCacheEnabled = isEnabled; } + static bool applicationCacheEnabled() { return isApplicationCacheEnabled; } + private: // Never instantiate. RuntimeEnabledFeatures() { } @@ -52,6 +58,8 @@ private: static bool isDatabaseEnabled; static bool isLocalStorageEnabled; static bool isSessionStorageEnabled; + static bool isNotificationsEnabled; + static bool isApplicationCacheEnabled; }; } // namespace WebCore diff --git a/WebCore/bindings/v8/ScriptCallStack.cpp b/WebCore/bindings/v8/ScriptCallStack.cpp index 8eb9478..d9b2fcf 100644 --- a/WebCore/bindings/v8/ScriptCallStack.cpp +++ b/WebCore/bindings/v8/ScriptCallStack.cpp @@ -38,8 +38,21 @@ namespace WebCore { -ScriptCallStack::ScriptCallStack(const v8::Arguments& arguments, unsigned skipArgumentCount) - : m_lastCaller(String(), V8Proxy::sourceName(), V8Proxy::sourceLineNumber() + 1, arguments, skipArgumentCount) +ScriptCallStack* ScriptCallStack::create(const v8::Arguments& arguments, unsigned skipArgumentCount) { + String sourceName; + int sourceLineNumber; + if (!V8Proxy::sourceName(sourceName)) { + return 0; + } + if (!V8Proxy::sourceLineNumber(sourceLineNumber)) { + return 0; + } + sourceLineNumber += 1; + return new ScriptCallStack(arguments, skipArgumentCount, sourceName, sourceLineNumber); +} + +ScriptCallStack::ScriptCallStack(const v8::Arguments& arguments, unsigned skipArgumentCount, String sourceName, int sourceLineNumber) + : m_lastCaller(String(), sourceName, sourceLineNumber, arguments, skipArgumentCount) , m_scriptState(new ScriptState(V8Proxy::retrieveFrameForCurrentContext())) { } diff --git a/WebCore/bindings/v8/ScriptCallStack.h b/WebCore/bindings/v8/ScriptCallStack.h index 3ba01c5..f6a7e39 100644 --- a/WebCore/bindings/v8/ScriptCallStack.h +++ b/WebCore/bindings/v8/ScriptCallStack.h @@ -45,7 +45,7 @@ namespace WebCore { class ScriptCallStack : public Noncopyable { public: - ScriptCallStack(const v8::Arguments&, unsigned skipArgumentCount = 0); + static ScriptCallStack* create(const v8::Arguments&, unsigned skipArgumentCount = 0); ~ScriptCallStack(); const ScriptCallFrame& at(unsigned) const; @@ -55,6 +55,8 @@ namespace WebCore { ScriptState* state() const { return m_scriptState.get(); } private: + ScriptCallStack(const v8::Arguments& arguments, unsigned skipArgumentCount, String sourceName, int sourceLineNumber); + ScriptCallFrame m_lastCaller; OwnPtr<ScriptState> m_scriptState; }; diff --git a/WebCore/bindings/v8/ScriptController.cpp b/WebCore/bindings/v8/ScriptController.cpp index 35a2d73..5b4dbc2 100644 --- a/WebCore/bindings/v8/ScriptController.cpp +++ b/WebCore/bindings/v8/ScriptController.cpp @@ -45,18 +45,21 @@ #include "EventListener.h" #include "EventNames.h" #include "Frame.h" +#include "FrameLoaderClient.h" #include "Node.h" #include "NotImplemented.h" #include "npruntime_impl.h" #include "npruntime_priv.h" #include "NPV8Object.h" #include "ScriptSourceCode.h" -#include "Widget.h" -#include "XSSAuditor.h" - +#include "ScriptState.h" +#include "Settings.h" #include "V8Binding.h" #include "V8NPObject.h" #include "V8Proxy.h" +#include "Widget.h" +#include "XSSAuditor.h" +#include <wtf/StdLibExtras.h> namespace WebCore { @@ -295,7 +298,8 @@ bool ScriptController::haveInterpreter() const bool ScriptController::isEnabled() const { - return m_proxy->isEnabled(); + Settings* settings = m_proxy->frame()->settings(); + return m_proxy->frame()->loader()->client()->allowJavaScript(settings && settings->isJavaScriptEnabled() && !m_frame->loader()->isSandboxed(SandboxScripts)); } PassScriptInstance ScriptController::createScriptInstanceForWidget(Widget* widget) @@ -362,6 +366,18 @@ void ScriptController::cleanupScriptObjectsForPlugin(Widget* nativeHandle) m_pluginObjects.remove(it); } +void ScriptController::getAllWorlds(Vector<DOMWrapperWorld*>& worlds) +{ + worlds.append(mainThreadNormalWorld()); +} + +ScriptState* ScriptController::mainWorldScriptState() +{ + if (!m_mainWorldScriptState) + m_mainWorldScriptState.set(new ScriptState(m_frame, V8Proxy::mainWorldContext(m_frame))); + return m_mainWorldScriptState.get(); +} + static NPObject* createNoScriptObject() { notImplemented(); @@ -440,10 +456,4 @@ void ScriptController::updateDocument() m_proxy->updateDocument(); } -// FIXME: Stub method so we compile. Currently called from FrameLoader.cpp. -DOMWrapperWorld* mainThreadNormalWorld() -{ - return 0; -} - } // namespace WebCore diff --git a/WebCore/bindings/v8/ScriptController.h b/WebCore/bindings/v8/ScriptController.h index a958ead..fb7bbee 100644 --- a/WebCore/bindings/v8/ScriptController.h +++ b/WebCore/bindings/v8/ScriptController.h @@ -39,6 +39,7 @@ #include <v8.h> #include <wtf/HashMap.h> +#include <wtf/RefCounted.h> #include <wtf/Vector.h> namespace WebCore { @@ -47,6 +48,7 @@ namespace WebCore { class Frame; class HTMLPlugInElement; class ScriptSourceCode; + class ScriptState; class String; class Widget; class XSSAuditor; @@ -165,6 +167,13 @@ namespace WebCore { NPObject* windowScriptNPObject(); #endif + // Dummy method to avoid a bunch of ifdef's in WebCore. + void evaluateInWorld(const ScriptSourceCode&, DOMWrapperWorld*) { } + static void getAllWorlds(Vector<DOMWrapperWorld*>& worlds); + + // Script state for the main world context. + ScriptState* mainWorldScriptState(); + private: Frame* m_frame; const String* m_sourceURL; @@ -187,9 +196,10 @@ namespace WebCore { #endif // The XSSAuditor associated with this ScriptController. OwnPtr<XSSAuditor> m_XSSAuditor; - }; - DOMWrapperWorld* mainThreadNormalWorld(); + // Script state for the main world context. + OwnPtr<ScriptState> m_mainWorldScriptState; + }; } // namespace WebCore diff --git a/WebCore/bindings/v8/ScriptEventListener.cpp b/WebCore/bindings/v8/ScriptEventListener.cpp index 03713be..51d53ab 100644 --- a/WebCore/bindings/v8/ScriptEventListener.cpp +++ b/WebCore/bindings/v8/ScriptEventListener.cpp @@ -68,7 +68,7 @@ PassRefPtr<V8LazyEventListener> createAttributeEventListener(Node* node, Attribu sourceURL = node->document()->url().string(); } - return V8LazyEventListener::create(attr->localName().string(), node->isSVGElement(), attr->value(), sourceURL, lineNumber, columnNumber); + return V8LazyEventListener::create(attr->localName().string(), node->isSVGElement(), attr->value(), sourceURL, lineNumber, columnNumber, WorldContextHandle(UseMainWorld)); } PassRefPtr<V8LazyEventListener> createAttributeEventListener(Frame* frame, Attribute* attr) @@ -95,7 +95,7 @@ PassRefPtr<V8LazyEventListener> createAttributeEventListener(Frame* frame, Attri columnNumber = frame->document()->tokenizer()->columnNumber(); } sourceURL = frame->document()->url().string(); - return V8LazyEventListener::create(attr->localName().string(), frame->document()->isSVGDocument(), attr->value(), sourceURL, lineNumber, columnNumber); + return V8LazyEventListener::create(attr->localName().string(), frame->document()->isSVGDocument(), attr->value(), sourceURL, lineNumber, columnNumber, WorldContextHandle(UseMainWorld)); } String getEventListenerHandlerBody(ScriptExecutionContext* context, ScriptState* scriptState, EventListener* listener) diff --git a/WebCore/bindings/v8/ScriptFunctionCall.cpp b/WebCore/bindings/v8/ScriptFunctionCall.cpp index 9ff6b8c..a232acd 100644 --- a/WebCore/bindings/v8/ScriptFunctionCall.cpp +++ b/WebCore/bindings/v8/ScriptFunctionCall.cpp @@ -74,6 +74,18 @@ void ScriptFunctionCall::appendArgument(const String& argument) m_arguments.append(v8String(argument)); } +void ScriptFunctionCall::appendArgument(const char* argument) +{ + ScriptScope scope(m_scriptState); + m_arguments.append(v8String(argument)); +} + +void ScriptFunctionCall::appendArgument(long argument) +{ + ScriptScope scope(m_scriptState); + m_arguments.append(v8::Number::New(argument)); +} + void ScriptFunctionCall::appendArgument(long long argument) { ScriptScope scope(m_scriptState); @@ -86,6 +98,12 @@ void ScriptFunctionCall::appendArgument(unsigned int argument) m_arguments.append(v8::Number::New(argument)); } +void ScriptFunctionCall::appendArgument(unsigned long argument) +{ + ScriptScope scope(m_scriptState); + m_arguments.append(v8::Number::New(argument)); +} + void ScriptFunctionCall::appendArgument(int argument) { ScriptScope scope(m_scriptState); diff --git a/WebCore/bindings/v8/ScriptFunctionCall.h b/WebCore/bindings/v8/ScriptFunctionCall.h index 8365a4e..6203402 100644 --- a/WebCore/bindings/v8/ScriptFunctionCall.h +++ b/WebCore/bindings/v8/ScriptFunctionCall.h @@ -50,8 +50,11 @@ namespace WebCore { void appendArgument(const ScriptString&); void appendArgument(const ScriptValue&); void appendArgument(const String&); + void appendArgument(const char*); + void appendArgument(long); void appendArgument(long long); void appendArgument(unsigned int); + void appendArgument(unsigned long); void appendArgument(int); void appendArgument(bool); ScriptValue call(bool& hadException, bool reportExceptions = true); diff --git a/WebCore/bindings/v8/ScriptObject.cpp b/WebCore/bindings/v8/ScriptObject.cpp index ac8051d..5f5609c 100644 --- a/WebCore/bindings/v8/ScriptObject.cpp +++ b/WebCore/bindings/v8/ScriptObject.cpp @@ -36,6 +36,8 @@ #include "Document.h" #include "Frame.h" +#include "InspectorBackend.h" +#include "InspectorFrontendHost.h" #include "V8Binding.h" #include "V8Proxy.h" @@ -83,6 +85,13 @@ bool ScriptObject::set(const char* name, double value) return scope.success(); } +bool ScriptObject::set(const char* name, long value) +{ + ScriptScope scope(m_scriptState); + v8Object()->Set(v8::String::New(name), v8::Number::New(value)); + return scope.success(); +} + bool ScriptObject::set(const char* name, long long value) { ScriptScope scope(m_scriptState); @@ -104,6 +113,13 @@ bool ScriptObject::set(const char* name, unsigned value) return scope.success(); } +bool ScriptObject::set(const char* name, unsigned long value) +{ + ScriptScope scope(m_scriptState); + v8Object()->Set(v8::String::New(name), v8::Number::New(value)); + return scope.success(); +} + bool ScriptObject::set(const char* name, bool value) { ScriptScope scope(m_scriptState); @@ -124,6 +140,7 @@ bool ScriptGlobalObject::set(ScriptState* scriptState, const char* name, const S return scope.success(); } +#if ENABLE(INSPECTOR) bool ScriptGlobalObject::set(ScriptState* scriptState, const char* name, InspectorBackend* value) { ScriptScope scope(scriptState); @@ -133,6 +150,21 @@ bool ScriptGlobalObject::set(ScriptState* scriptState, const char* name, Inspect return scope.success(); } +bool ScriptGlobalObject::set(ScriptState* scriptState, const char* name, InspectorFrontendHost* value) +{ + ScriptScope scope(scriptState); + scope.global()->Set(v8::String::New(name), V8DOMWrapper::convertToV8Object(V8ClassIndex::INSPECTORFRONTENDHOST, value)); + return scope.success(); +} + +bool ScriptGlobalObject::set(ScriptState* scriptState, const char* name, InjectedScriptHost* value) +{ + ScriptScope scope(scriptState); + scope.global()->Set(v8::String::New(name), V8DOMWrapper::convertToV8Object(V8ClassIndex::INJECTEDSCRIPTHOST, value)); + return scope.success(); +} +#endif + bool ScriptGlobalObject::get(ScriptState* scriptState, const char* name, ScriptObject& value) { ScriptScope scope(scriptState); diff --git a/WebCore/bindings/v8/ScriptObject.h b/WebCore/bindings/v8/ScriptObject.h index f741f89..630d3b9 100644 --- a/WebCore/bindings/v8/ScriptObject.h +++ b/WebCore/bindings/v8/ScriptObject.h @@ -36,7 +36,9 @@ #include <v8.h> namespace WebCore { + class InjectedScriptHost; class InspectorBackend; + class InspectorFrontendHost; class ScriptState; class ScriptObject : public ScriptValue { @@ -51,9 +53,11 @@ namespace WebCore { bool set(const char* name, const ScriptObject&); bool set(const char* name, const String&); bool set(const char* name, double); + bool set(const char* name, long); bool set(const char* name, long long); bool set(const char* name, int); bool set(const char* name, unsigned); + bool set(const char* name, unsigned long); bool set(const char* name, bool); static ScriptObject createNew(ScriptState*); @@ -65,6 +69,8 @@ namespace WebCore { public: static bool set(ScriptState*, const char* name, const ScriptObject&); static bool set(ScriptState*, const char* name, InspectorBackend*); + static bool set(ScriptState*, const char* name, InspectorFrontendHost*); + static bool set(ScriptState*, const char* name, InjectedScriptHost*); static bool get(ScriptState*, const char* name, ScriptObject&); static bool remove(ScriptState*, const char* name); private: diff --git a/WebCore/bindings/v8/ScriptObjectQuarantine.cpp b/WebCore/bindings/v8/ScriptObjectQuarantine.cpp deleted file mode 100644 index 6528c9d..0000000 --- a/WebCore/bindings/v8/ScriptObjectQuarantine.cpp +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright (C) 2009 Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "ScriptObjectQuarantine.h" - -#include "Database.h" -#include "Document.h" -#include "DOMWindow.h" -#include "Frame.h" -#include "InspectorController.h" -#include "Page.h" -#include "ScriptObject.h" -#include "ScriptValue.h" -#include "Storage.h" - -#include "V8Binding.h" -#include "V8Proxy.h" - -#include <v8.h> - -namespace WebCore { - -ScriptValue quarantineValue(ScriptState* scriptState, const ScriptValue& value) -{ - return value; -} - -bool getQuarantinedScriptObject(Database* database, ScriptObject& quarantinedObject) -{ - ASSERT(database); - -#if ENABLE(DATABASE) - v8::HandleScope handleScope; - Frame* frame = database->document()->frame(); - if (!frame) - return false; - - v8::Local<v8::Context> context = V8Proxy::context(frame); - if (context.IsEmpty()) - return false; - - v8::Context::Scope scope(context); - v8::Handle<v8::Value> v8Database = V8DOMWrapper::convertToV8Object(V8ClassIndex::DATABASE, database); - ScriptState* scriptState = frame->page()->inspectorController()->frontendScriptState(); - quarantinedObject = ScriptObject(scriptState, v8::Local<v8::Object>(v8::Object::Cast(*v8Database))); -#else - ASSERT_NOT_REACHED(); - quarantinedObject = ScriptObject(); -#endif - return true; -} - -bool getQuarantinedScriptObject(Storage* storage, ScriptObject& quarantinedObject) -{ - ASSERT(storage); - Frame* frame = storage->frame(); - ASSERT(frame); - -#if ENABLE(DOM_STORAGE) - v8::HandleScope handleScope; - v8::Local<v8::Context> context = V8Proxy::context(frame); - if (context.IsEmpty()) - return false; - - v8::Context::Scope scope(context); - - v8::Handle<v8::Value> v8Storage = V8DOMWrapper::convertToV8Object(V8ClassIndex::STORAGE, storage); - ScriptState* scriptState = frame->page()->inspectorController()->frontendScriptState(); - quarantinedObject = ScriptObject(scriptState, v8::Local<v8::Object>(v8::Object::Cast(*v8Storage))); -#else - ASSERT_NOT_REACHED(); - quarantinedObject = ScriptObject(); -#endif - return true; -} - -bool getQuarantinedScriptObject(Node* node, ScriptObject& quarantinedObject) -{ - ASSERT(node); - - v8::HandleScope handleScope; - // FIXME: What if document() is null? - // FIXME: Why are we grabbing the mainFrame? - Frame* frame = node->document()->page()->mainFrame(); - v8::Local<v8::Context> context = V8Proxy::context(frame); - // FIXME: What if context.IsEmpty()? - v8::Context::Scope scope(context); - - v8::Handle<v8::Value> v8Node = V8DOMWrapper::convertNodeToV8Object(node); - ScriptState* scriptState = frame->page()->inspectorController()->frontendScriptState(); - quarantinedObject = ScriptObject(scriptState, v8::Local<v8::Object>(v8::Object::Cast(*v8Node))); - - return true; -} - -bool getQuarantinedScriptObject(DOMWindow* domWindow, ScriptObject& quarantinedObject) -{ - ASSERT(domWindow); - - v8::HandleScope handleScope; - Frame* frame = domWindow->frame(); - // FIXME: What if frame is null? - v8::Local<v8::Context> context = V8Proxy::context(frame); - // FIXME: What if context.IsEmpty()? - v8::Context::Scope scope(context); - - v8::Handle<v8::Value> v8DomWindow = V8DOMWrapper::convertToV8Object(V8ClassIndex::DOMWINDOW, domWindow); - ScriptState* scriptState = frame->page()->inspectorController()->frontendScriptState(); - quarantinedObject = ScriptObject(scriptState, v8::Local<v8::Object>(v8::Object::Cast(*v8DomWindow))); - - return true; -} - - -} // namespace WebCore diff --git a/WebCore/bindings/v8/ScriptState.cpp b/WebCore/bindings/v8/ScriptState.cpp index 99557b5..68593e7 100644 --- a/WebCore/bindings/v8/ScriptState.cpp +++ b/WebCore/bindings/v8/ScriptState.cpp @@ -37,6 +37,7 @@ #include "ScriptController.h" #include <wtf/Assertions.h> +#include <wtf/StdLibExtras.h> namespace WebCore { @@ -58,7 +59,7 @@ ScriptState::~ScriptState() m_context.Clear(); } -ScriptState* scriptStateFromNode(Node* node) +ScriptState* scriptStateFromNode(DOMWrapperWorld*, Node* node) { // This should be never reached with V8 bindings (WebKit only uses it // for non-JS bindings) @@ -66,11 +67,17 @@ ScriptState* scriptStateFromNode(Node* node) return 0; } -ScriptState* scriptStateFromPage(Page* page) +ScriptState* scriptStateFromPage(DOMWrapperWorld*, Page* page) { - // This should be never reached with V8 bindings. - ASSERT_NOT_REACHED(); - return 0; + // This should be only reached with V8 bindings from single process layout tests. + return page->mainFrame()->script()->mainWorldScriptState(); +} + +// FIXME: Stub method so we compile. Currently called from FrameLoader.cpp. +DOMWrapperWorld* mainThreadNormalWorld() +{ + DEFINE_STATIC_LOCAL(DOMWrapperWorld, oneWorld, ()); + return &oneWorld; } } diff --git a/WebCore/bindings/v8/ScriptState.h b/WebCore/bindings/v8/ScriptState.h index e44e914..12a1388 100644 --- a/WebCore/bindings/v8/ScriptState.h +++ b/WebCore/bindings/v8/ScriptState.h @@ -33,8 +33,10 @@ #include <v8.h> #include <wtf/Noncopyable.h> +#include <wtf/RefCounted.h> namespace WebCore { + class DOMWrapperWorld; class Node; class Page; class Frame; @@ -65,8 +67,17 @@ namespace WebCore { v8::Persistent<v8::Context> m_context; }; - ScriptState* scriptStateFromNode(Node*); - ScriptState* scriptStateFromPage(Page*); + ScriptState* scriptStateFromNode(DOMWrapperWorld*, Node*); + ScriptState* scriptStateFromPage(DOMWrapperWorld*, Page*); + + DOMWrapperWorld* mainThreadNormalWorld(); + inline DOMWrapperWorld* debuggerWorld() { return mainThreadNormalWorld(); } + inline DOMWrapperWorld* pluginWorld() { return mainThreadNormalWorld(); } + + // Dummy class to avoid a bunch of ifdef's in WebCore. + class DOMWrapperWorld : public RefCounted<DOMWrapperWorld> { + }; + } #endif // ScriptState_h diff --git a/WebCore/bindings/v8/ScriptValue.h b/WebCore/bindings/v8/ScriptValue.h index a429593..c0ba8d5 100644 --- a/WebCore/bindings/v8/ScriptValue.h +++ b/WebCore/bindings/v8/ScriptValue.h @@ -44,6 +44,11 @@ namespace WebCore { class ScriptValue { public: + static ScriptValue quarantineValue(ScriptState* scriptState, const ScriptValue& value) + { + return value; + } + ScriptValue() {} ScriptValue(v8::Handle<v8::Value> value) @@ -139,6 +144,7 @@ public: } v8::Handle<v8::Value> v8Value() const { return m_value; } + bool getString(ScriptState*, String& result) const { return getString(result); } bool getString(String& result) const; String toString(ScriptState*) const; diff --git a/WebCore/bindings/v8/SharedPersistent.h b/WebCore/bindings/v8/SharedPersistent.h index c1232ae..8825bd5 100644 --- a/WebCore/bindings/v8/SharedPersistent.h +++ b/WebCore/bindings/v8/SharedPersistent.h @@ -32,6 +32,8 @@ #define SharedPersistent_h #include <v8.h> +#include <wtf/PassRefPtr.h> +#include <wtf/RefCounted.h> namespace WebCore { @@ -40,7 +42,7 @@ namespace WebCore { // object and when it should no longer be accessible the object's // owner can clear it. template <typename T> - class SharedPersistent : public WTF::RefCounted<SharedPersistent<T> > { + class SharedPersistent : public RefCounted<SharedPersistent<T> > { public: void set(v8::Persistent<T> value) { diff --git a/WebCore/bindings/v8/V8AbstractEventListener.cpp b/WebCore/bindings/v8/V8AbstractEventListener.cpp index f27c619..0f5b5c8 100644 --- a/WebCore/bindings/v8/V8AbstractEventListener.cpp +++ b/WebCore/bindings/v8/V8AbstractEventListener.cpp @@ -50,11 +50,11 @@ static void weakEventListenerCallback(v8::Persistent<v8::Value>, void* parameter listener->disposeListenerObject(); } -V8AbstractEventListener::V8AbstractEventListener(PassRefPtr<V8ListenerGuard> guard, bool isAttribute) +V8AbstractEventListener::V8AbstractEventListener(bool isAttribute, const WorldContextHandle& worldContext) : EventListener(JSEventListenerType) , m_isWeak(true) , m_isAttribute(isAttribute) - , m_guard(guard) + , m_worldContext(worldContext) { } @@ -70,17 +70,13 @@ V8AbstractEventListener::~V8AbstractEventListener() void V8AbstractEventListener::handleEvent(ScriptExecutionContext* context, Event* event) { - // EventListener could be disconnected from the frame. - if (disconnected()) - return; - // The callback function on XMLHttpRequest can clear the event listener and destroys 'this' object. Keep a local reference to it. // See issue 889829. RefPtr<V8AbstractEventListener> protect(this); v8::HandleScope handleScope; - v8::Local<v8::Context> v8Context = toV8Context(context); + v8::Local<v8::Context> v8Context = toV8Context(context, worldContext()); if (v8Context.IsEmpty()) return; @@ -120,7 +116,7 @@ void V8AbstractEventListener::setListenerObject(v8::Handle<v8::Object> listener) void V8AbstractEventListener::invokeEventHandler(ScriptExecutionContext* context, Event* event, v8::Handle<v8::Value> jsEvent) { - v8::Local<v8::Context> v8Context = toV8Context(context); + v8::Local<v8::Context> v8Context = toV8Context(context, worldContext()); if (v8Context.IsEmpty()) return; @@ -146,7 +142,6 @@ void V8AbstractEventListener::invokeEventHandler(ScriptExecutionContext* context tryCatch.Reset(); // Call the event handler. - tryCatch.SetVerbose(false); // We do not want to report the exception to the inspector console. returnValue = callListenerFunction(context, jsEvent, event); if (!tryCatch.CanContinue()) return; @@ -158,7 +153,6 @@ void V8AbstractEventListener::invokeEventHandler(ScriptExecutionContext* context } // Restore the old event. This must be done for all exit paths through this method. - tryCatch.SetVerbose(true); if (savedEvent.IsEmpty()) v8Context->Global()->SetHiddenValue(eventSymbol, v8::Undefined()); else diff --git a/WebCore/bindings/v8/V8AbstractEventListener.h b/WebCore/bindings/v8/V8AbstractEventListener.h index ceff001..0afbed5 100644 --- a/WebCore/bindings/v8/V8AbstractEventListener.h +++ b/WebCore/bindings/v8/V8AbstractEventListener.h @@ -32,8 +32,8 @@ #define V8AbstractEventListener_h #include "EventListener.h" -#include "OwnHandle.h" -#include "SharedPersistent.h" +#include "WorldContextHandle.h" + #include <v8.h> #include <wtf/PassRefPtr.h> #include <wtf/RefCounted.h> @@ -44,29 +44,6 @@ namespace WebCore { class Frame; class V8Proxy; - // Shared by listener objects and V8Proxy so that V8Proxy can - // silence listeners when needed. - class V8ListenerGuard : public RefCounted<V8ListenerGuard> { - public: - static PassRefPtr<V8ListenerGuard> create() - { - return adoptRef(new V8ListenerGuard); - } - - bool isDisconnected() const { return m_disconnected; } - - void disconnectListeners() - { - m_disconnected = true; - } - - private: - V8ListenerGuard() - : m_disconnected(false) { } - - bool m_disconnected; - }; - // There are two kinds of event listeners: HTML or non-HMTL. onload, // onfocus, etc (attributes) are always HTML event handler type; Event // listeners added by Window.addEventListener or @@ -119,10 +96,8 @@ namespace WebCore { // Dispose listener object and clear the handle. void disposeListenerObject(); - virtual bool disconnected() const { return m_guard && m_guard->isDisconnected(); } - protected: - V8AbstractEventListener(PassRefPtr<V8ListenerGuard>, bool isAttribute); + V8AbstractEventListener(bool isAttribute, const WorldContextHandle& worldContext); virtual void prepareListenerObject(ScriptExecutionContext*) { } @@ -132,6 +107,9 @@ namespace WebCore { // Get the receiver object to use for event listener call. v8::Local<v8::Object> getReceiverObject(Event*); + + const WorldContextHandle& worldContext() const { return m_worldContext; } + private: // Implementation of EventListener function. virtual bool virtualisAttribute() const { return m_isAttribute; } @@ -146,7 +124,7 @@ namespace WebCore { // Indicates if this is an HTML type listener. bool m_isAttribute; - RefPtr<V8ListenerGuard> m_guard; + WorldContextHandle m_worldContext; }; } // namespace WebCore diff --git a/WebCore/bindings/v8/V8Binding.cpp b/WebCore/bindings/v8/V8Binding.cpp index 9ac7eae..00286e5 100644 --- a/WebCore/bindings/v8/V8Binding.cpp +++ b/WebCore/bindings/v8/V8Binding.cpp @@ -33,8 +33,10 @@ #include "AtomicString.h" #include "CString.h" +#include "Element.h" #include "MathExtras.h" #include "PlatformString.h" +#include "QualifiedName.h" #include "StdLibExtras.h" #include "StringBuffer.h" #include "StringHash.h" @@ -104,10 +106,6 @@ public: return m_atomicString; } - // Returns right string type based on a dummy parameter. - String string(String) { return webcoreString(); } - AtomicString string(AtomicString) { return atomicString(); } - static WebCoreStringResource* toStringResource(v8::Handle<v8::String> v8String) { return static_cast<WebCoreStringResource*>(v8String->GetExternalStringResource()); @@ -128,17 +126,177 @@ private: #endif }; -enum ExternalMode { - Externalize, - DoNotExternalize + +void* v8DOMWrapperToNative(v8::Handle<v8::Object> object) { + return object->GetPointerFromInternalField(V8Custom::kDOMWrapperObjectIndex); +} + +void* v8DOMWrapperToNative(const v8::AccessorInfo& info) { + return info.Holder()->GetPointerFromInternalField(V8Custom::kDOMWrapperObjectIndex); +} + + +String v8ValueToWebCoreString(v8::Handle<v8::Value> value) +{ + if (value->IsString()) + return v8StringToWebCoreString(v8::Handle<v8::String>::Cast(value)); + return v8NonStringValueToWebCoreString(value); +} + +AtomicString v8ValueToAtomicWebCoreString(v8::Handle<v8::Value> value) +{ + if (value->IsString()) + return v8StringToAtomicWebCoreString(v8::Handle<v8::String>::Cast(value)); + return v8NonStringValueToAtomicWebCoreString(value); +} + +int toInt32(v8::Handle<v8::Value> value, bool& ok) +{ + ok = true; + + // Fast case. The value is already a 32-bit integer. + if (value->IsInt32()) + return value->Int32Value(); + + // Can the value be converted to a number? + v8::Local<v8::Number> numberObject = value->ToNumber(); + if (numberObject.IsEmpty()) { + ok = false; + return 0; + } + + // Does the value convert to nan or to an infinity? + double numberValue = numberObject->Value(); + if (isnan(numberValue) || isinf(numberValue)) { + ok = false; + return 0; + } + + // Can the value be converted to a 32-bit integer? + v8::Local<v8::Int32> intValue = value->ToInt32(); + if (intValue.IsEmpty()) { + ok = false; + return 0; + } + + // Return the result of the int32 conversion. + return intValue->Value(); +} + +String toWebCoreString(const v8::Arguments& args, int index) { + return v8ValueToWebCoreString(args[index]); +} + + +String toWebCoreStringWithNullCheck(v8::Handle<v8::Value> value) +{ + if (value->IsNull()) + return String(); + return v8ValueToWebCoreString(value); +} + +AtomicString toAtomicWebCoreStringWithNullCheck(v8::Handle<v8::Value> value) +{ + if (value->IsNull()) + return AtomicString(); + return v8ValueToAtomicWebCoreString(value); +} + +String toWebCoreStringWithNullOrUndefinedCheck(v8::Handle<v8::Value> value) +{ + if (value->IsNull() || value->IsUndefined()) + return String(); + return toWebCoreString(value); +} + +bool isUndefinedOrNull(v8::Handle<v8::Value> value) +{ + return value->IsNull() || value->IsUndefined(); +} + +v8::Handle<v8::Boolean> v8Boolean(bool value) +{ + return value ? v8::True() : v8::False(); +} + +v8::Handle<v8::String> v8UndetectableString(const String& str) +{ + return v8::String::NewUndetectable(fromWebCoreString(str), str.length()); +} + +v8::Handle<v8::Value> v8StringOrNull(const String& str) +{ + return str.isNull() ? v8::Handle<v8::Value>(v8::Null()) : v8::Handle<v8::Value>(v8String(str)); +} + +v8::Handle<v8::Value> v8StringOrUndefined(const String& str) +{ + return str.isNull() ? v8::Handle<v8::Value>(v8::Undefined()) : v8::Handle<v8::Value>(v8String(str)); +} + +v8::Handle<v8::Value> v8StringOrFalse(const String& str) +{ + return str.isNull() ? v8::Handle<v8::Value>(v8::False()) : v8::Handle<v8::Value>(v8String(str)); +} + + +template <class S> struct StringTraits +{ + static S fromStringResource(WebCoreStringResource* resource); + + static S fromV8String(v8::Handle<v8::String> v8String, int length); +}; + +template<> +struct StringTraits<String> +{ + static String fromStringResource(WebCoreStringResource* resource) + { + return resource->webcoreString(); + } + + static String fromV8String(v8::Handle<v8::String> v8String, int length) + { + ASSERT(v8String->Length() == length); + // NOTE: as of now, String(const UChar*, int) performs String::createUninitialized + // anyway, so no need to optimize like we do for AtomicString below. + UChar* buffer; + String result = String::createUninitialized(length, buffer); + v8String->Write(reinterpret_cast<uint16_t*>(buffer), 0, length); + return result; + } +}; + +template<> +struct StringTraits<AtomicString> +{ + static AtomicString fromStringResource(WebCoreStringResource* resource) + { + return resource->atomicString(); + } + + static AtomicString fromV8String(v8::Handle<v8::String> v8String, int length) + { + ASSERT(v8String->Length() == length); + static const int inlineBufferSize = 16; + if (length <= inlineBufferSize) { + UChar inlineBuffer[inlineBufferSize]; + v8String->Write(reinterpret_cast<uint16_t*>(inlineBuffer), 0, length); + return AtomicString(inlineBuffer, length); + } + UChar* buffer; + String tmp = String::createUninitialized(length, buffer); + v8String->Write(reinterpret_cast<uint16_t*>(buffer), 0, length); + return AtomicString(tmp); + } }; template <typename StringType> -static StringType v8StringToWebCoreString(v8::Handle<v8::String> v8String, ExternalMode external) +StringType v8StringToWebCoreString(v8::Handle<v8::String> v8String, ExternalMode external) { WebCoreStringResource* stringResource = WebCoreStringResource::toStringResource(v8String); if (stringResource) - return stringResource->string(StringType()); + return StringTraits<StringType>::fromStringResource(stringResource); int length = v8String->Length(); if (!length) { @@ -146,18 +304,7 @@ static StringType v8StringToWebCoreString(v8::Handle<v8::String> v8String, Exter return StringImpl::empty(); } - StringType result; - static const int inlineBufferSize = 16; - if (length <= inlineBufferSize) { - UChar inlineBuffer[inlineBufferSize]; - v8String->Write(reinterpret_cast<uint16_t*>(inlineBuffer), 0, length); - result = StringType(inlineBuffer, length); - } else { - UChar* buffer; - String tmp = String::createUninitialized(length, buffer); - v8String->Write(reinterpret_cast<uint16_t*>(buffer), 0, length); - result = StringType(tmp); - } + StringType result(StringTraits<StringType>::fromV8String(v8String, length)); if (external == Externalize && v8String->CanMakeExternal()) { stringResource = new WebCoreStringResource(result); @@ -168,16 +315,12 @@ static StringType v8StringToWebCoreString(v8::Handle<v8::String> v8String, Exter } return result; } + +// Explicitly instantiate the above template with the expected parameterizations, +// to ensure the compiler generates the code; otherwise link errors can result in GCC 4.4. +template String v8StringToWebCoreString<String>(v8::Handle<v8::String>, ExternalMode); +template AtomicString v8StringToWebCoreString<AtomicString>(v8::Handle<v8::String>, ExternalMode); -String v8StringToWebCoreString(v8::Handle<v8::String> v8String) -{ - return v8StringToWebCoreString<String>(v8String, Externalize); -} - -AtomicString v8StringToAtomicWebCoreString(v8::Handle<v8::String> v8String) -{ - return v8StringToWebCoreString<AtomicString>(v8String, Externalize); -} String v8NonStringValueToWebCoreString(v8::Handle<v8::Value> object) { @@ -254,13 +397,13 @@ static void cachedStringCallback(v8::Persistent<v8::Value> wrapper, void* parame v8::Local<v8::String> v8ExternalString(const String& string) { - if (!string.length()) + StringImpl* stringImpl = string.impl(); + if (!stringImpl || !stringImpl->length()) return v8::String::Empty(); if (!stringImplCacheEnabled) return makeExternalString(string); - StringImpl* stringImpl = string.impl(); StringCache& stringCache = getStringCache(); v8::String* cachedV8String = stringCache.get(stringImpl); if (cachedV8String) @@ -280,5 +423,65 @@ v8::Local<v8::String> v8ExternalString(const String& string) return newString; } + +v8::Persistent<v8::FunctionTemplate> createRawTemplate() +{ + v8::HandleScope scope; + v8::Local<v8::FunctionTemplate> result = v8::FunctionTemplate::New(V8Proxy::checkNewLegal); + return v8::Persistent<v8::FunctionTemplate>::New(result); +} + +v8::Local<v8::Signature> configureTemplate(v8::Persistent<v8::FunctionTemplate>desc, + const char *interfaceName, + V8ClassIndex::V8WrapperType parentClassIndex, + int fieldCount, + const BatchedAttribute* attributes, + size_t attributeCount, + const BatchedCallback* callbacks, + size_t callbackCount) +{ + desc->SetClassName(v8::String::New(interfaceName)); + v8::Local<v8::ObjectTemplate> instance = desc->InstanceTemplate(); + instance->SetInternalFieldCount(fieldCount); + if (parentClassIndex) + desc->Inherit(V8DOMWrapper::getTemplate(parentClassIndex)); + if (attributeCount) + batchConfigureAttributes(instance, desc->PrototypeTemplate(), + attributes, attributeCount); + v8::Local<v8::Signature> defaultSignature = v8::Signature::New(desc); + if (callbackCount) + batchConfigureCallbacks(desc->PrototypeTemplate(), + defaultSignature, + static_cast<v8::PropertyAttribute>(v8::DontDelete), + callbacks, callbackCount); + return defaultSignature; +} + +void createCallback(v8::Local<v8::ObjectTemplate> proto, + const char *name, + v8::InvocationCallback callback, + v8::Handle<v8::Signature> signature, + v8::PropertyAttribute attribute) +{ + proto->Set(v8::String::New(name), + v8::FunctionTemplate::New(callback, v8::Handle<v8::Value>(), signature), + attribute); +} + +v8::Handle<v8::Value> getElementStringAttr(const v8::AccessorInfo& info, + const QualifiedName& name) +{ + Element *imp = v8DOMWrapperToNode<Element>(info); + return v8ExternalString(imp->getAttribute(name)); +} + +void setElementStringAttr(const v8::AccessorInfo& info, + const QualifiedName& name, + v8::Local<v8::Value> value) +{ + Element* imp = v8DOMWrapperToNode<Element>(info); + AtomicString v = toAtomicWebCoreStringWithNullCheck(value); + imp->setAttribute(name, v); +} } // namespace WebCore diff --git a/WebCore/bindings/v8/V8Binding.h b/WebCore/bindings/v8/V8Binding.h index 237bc4d..de5bb4c 100644 --- a/WebCore/bindings/v8/V8Binding.h +++ b/WebCore/bindings/v8/V8Binding.h @@ -34,37 +34,107 @@ #include "AtomicString.h" #include "MathExtras.h" #include "PlatformString.h" +#include "V8DOMWrapper.h" +#include "V8Index.h" #include <v8.h> namespace WebCore { + + class EventListener; + class EventTarget; + + // A helper function extract native object pointer from a DOM wrapper + // and cast to the specified type. + void* v8DOMWrapperToNative(v8::Handle<v8::Object>); + + template <class C> + C* v8DOMWrapperTo(v8::Handle<v8::Object> object) + { + ASSERT(V8DOMWrapper::maybeDOMWrapper(object)); + return reinterpret_cast<C*>(v8DOMWrapperToNative(object)); + } + template <class C> + C* v8DOMWrapperToNode(v8::Handle<v8::Object> object) + { + ASSERT(V8DOMWrapper::maybeDOMWrapper(object)); + ASSERT(V8DOMWrapper::domWrapperType(object) == V8ClassIndex::NODE); + return reinterpret_cast<C*>(v8DOMWrapperToNative(object)); + } + + void* v8DOMWrapperToNative(const v8::AccessorInfo&); + + template <class C> + C* v8DOMWrapperTo(const v8::AccessorInfo& info) { + ASSERT(V8DOMWrapper::maybeDOMWrapper(info.Holder())); + return reinterpret_cast<C*>(v8DOMWrapperToNative(info)); + } + template <class C> + C* v8DOMWrapperToNode(const v8::AccessorInfo& info) { + ASSERT(V8DOMWrapper::domWrapperType(info.Holder()) == V8ClassIndex::NODE); + return reinterpret_cast<C*>(v8DOMWrapperToNative(info)); + } + + template <class C> + C* v8DOMWrapperTo(V8ClassIndex::V8WrapperType type, v8::Handle<v8::Object> object) + { + // Native event listener is per frame, it cannot be handled by this generic function. + ASSERT(type != V8ClassIndex::EVENTLISTENER); + ASSERT(type != V8ClassIndex::EVENTTARGET); + + ASSERT(V8DOMWrapper::maybeDOMWrapper(object)); + +#ifndef NDEBUG + const bool typeIsValid = +#define MAKE_CASE(TYPE, NAME) (type != V8ClassIndex::TYPE) && + DOM_NODE_TYPES(MAKE_CASE) +#if ENABLE(SVG) + SVG_NODE_TYPES(MAKE_CASE) +#endif +#undef MAKE_CASE + true; + ASSERT(typeIsValid); +#endif + + return v8DOMWrapperTo<C>(object); + } + + template <class C> + C* v8DOMWrapperTo(V8ClassIndex::V8WrapperType type, const v8::AccessorInfo& info) + { +#ifndef NDEBUG + return v8DOMWrapperTo<C>(type, info.Holder()); +#else + return reinterpret_cast<C*>(v8DOMWrapperToNative(info)); +#endif + } + + + enum ExternalMode { + Externalize, + DoNotExternalize + }; + + template <typename StringType> + StringType v8StringToWebCoreString(v8::Handle<v8::String> v8String, ExternalMode external); // Convert v8 types to a WebCore::String. If the V8 string is not already // an external string then it is transformed into an external string at this // point to avoid repeated conversions. - String v8StringToWebCoreString(v8::Handle<v8::String>); - String v8NonStringValueToWebCoreString(v8::Handle<v8::Value>); - inline String v8ValueToWebCoreString(v8::Handle<v8::Value> value) + inline String v8StringToWebCoreString(v8::Handle<v8::String> v8String) { - if (value->IsString()) - return v8StringToWebCoreString(v8::Handle<v8::String>::Cast(value)); - return v8NonStringValueToWebCoreString(value); + return v8StringToWebCoreString<String>(v8String, Externalize); } + String v8NonStringValueToWebCoreString(v8::Handle<v8::Value>); + String v8ValueToWebCoreString(v8::Handle<v8::Value> value); // Convert v8 types to a WebCore::AtomicString. - AtomicString v8StringToAtomicWebCoreString(v8::Handle<v8::String>); - AtomicString v8NonStringValueToAtomicWebCoreString(v8::Handle<v8::Value>); - inline AtomicString v8ValueToAtomicWebCoreString(v8::Handle<v8::Value> value) - { - if (value->IsString()) - return v8StringToAtomicWebCoreString(v8::Handle<v8::String>::Cast(value)); - return v8NonStringValueToAtomicWebCoreString(value); - } - - inline const String& toString(const String& string) + inline AtomicString v8StringToAtomicWebCoreString(v8::Handle<v8::String> v8String) { - return string; + return v8StringToWebCoreString<AtomicString>(v8String, Externalize); } + AtomicString v8NonStringValueToAtomicWebCoreString(v8::Handle<v8::Value>); + AtomicString v8ValueToAtomicWebCoreString(v8::Handle<v8::Value> value); // Return a V8 external string that shares the underlying buffer with the given // WebCore string. The reference counting mechanism is used to keep the @@ -84,38 +154,7 @@ namespace WebCore { // Convert a value to a 32-bit integer. The conversion fails if the // value cannot be converted to an integer or converts to nan or to an infinity. - inline int toInt32(v8::Handle<v8::Value> value, bool& ok) - { - ok = true; - - // Fast case. The value is already a 32-bit integer. - if (value->IsInt32()) - return value->Int32Value(); - - // Can the value be converted to a number? - v8::Local<v8::Number> numberObject = value->ToNumber(); - if (numberObject.IsEmpty()) { - ok = false; - return 0; - } - - // Does the value convert to nan or to an infinity? - double numberValue = numberObject->Value(); - if (isnan(numberValue) || isinf(numberValue)) { - ok = false; - return 0; - } - - // Can the value be converted to a 32-bit integer? - v8::Local<v8::Int32> intValue = value->ToInt32(); - if (intValue.IsEmpty()) { - ok = false; - return 0; - } - - // Return the result of the int32 conversion. - return intValue->Value(); - } + int toInt32(v8::Handle<v8::Value> value, bool& ok); // Convert a value to a 32-bit integer assuming the conversion cannot fail. inline int toInt32(v8::Handle<v8::Value> value) @@ -134,6 +173,8 @@ namespace WebCore { { return v8ValueToWebCoreString(object); } + + String toWebCoreString(const v8::Arguments&, int index); // The string returned by this function is still owned by the argument // and will be deallocated when the argument is deallocated. @@ -142,56 +183,78 @@ namespace WebCore { return reinterpret_cast<const uint16_t*>(str.characters()); } - inline bool isUndefinedOrNull(v8::Handle<v8::Value> value) - { - return value->IsNull() || value->IsUndefined(); - } + bool isUndefinedOrNull(v8::Handle<v8::Value> value); - inline v8::Handle<v8::Boolean> v8Boolean(bool value) - { - return value ? v8::True() : v8::False(); - } + v8::Handle<v8::Boolean> v8Boolean(bool value); - inline String toWebCoreStringWithNullCheck(v8::Handle<v8::Value> value) - { - if (value->IsNull()) - return String(); - return v8ValueToWebCoreString(value); - } + String toWebCoreStringWithNullCheck(v8::Handle<v8::Value> value); - inline AtomicString v8ValueToAtomicWebCoreStringWithNullCheck(v8::Handle<v8::Value> value) - { - if (value->IsNull()) - return AtomicString(); - return v8ValueToAtomicWebCoreString(value); - } + AtomicString toAtomicWebCoreStringWithNullCheck(v8::Handle<v8::Value> value); - inline String toWebCoreStringWithNullOrUndefinedCheck(v8::Handle<v8::Value> value) - { - if (value->IsNull() || value->IsUndefined()) - return String(); - return toWebCoreString(value); - } + String toWebCoreStringWithNullOrUndefinedCheck(v8::Handle<v8::Value> value); - inline v8::Handle<v8::String> v8UndetectableString(const String& str) - { - return v8::String::NewUndetectable(fromWebCoreString(str), str.length()); - } + v8::Handle<v8::String> v8UndetectableString(const String& str); - inline v8::Handle<v8::Value> v8StringOrNull(const String& str) - { - return str.isNull() ? v8::Handle<v8::Value>(v8::Null()) : v8::Handle<v8::Value>(v8String(str)); - } + v8::Handle<v8::Value> v8StringOrNull(const String& str); - inline v8::Handle<v8::Value> v8StringOrUndefined(const String& str) - { - return str.isNull() ? v8::Handle<v8::Value>(v8::Undefined()) : v8::Handle<v8::Value>(v8String(str)); - } + v8::Handle<v8::Value> v8StringOrUndefined(const String& str); + + v8::Handle<v8::Value> v8StringOrFalse(const String& str); + + v8::Persistent<v8::FunctionTemplate> createRawTemplate(); + + struct BatchedAttribute; + struct BatchedCallback; + + v8::Local<v8::Signature> configureTemplate(v8::Persistent<v8::FunctionTemplate>, + const char *interfaceName, + V8ClassIndex::V8WrapperType parentClassIndex, + int fieldCount, + const BatchedAttribute*, + size_t attributeCount, + const BatchedCallback*, + size_t callbackCount); + + void createCallback(v8::Local<v8::ObjectTemplate> proto, + const char *name, + v8::InvocationCallback, + v8::Handle<v8::Signature>, + v8::PropertyAttribute attributes = v8::DontDelete); + + v8::Handle<v8::Value> getElementStringAttr(const v8::AccessorInfo&, + const QualifiedName&); + void setElementStringAttr(const v8::AccessorInfo&, + const QualifiedName&, + v8::Local<v8::Value>); + + v8::Handle<v8::Value> getElementEventHandlerAttr(const v8::AccessorInfo&, + const AtomicString&); + + // V8Parameter is an adapter class that converts V8 values to Strings + // or AtomicStrings as appropriate, using multiple typecast operators. + enum V8ParameterMode { + DefaultMode, + WithNullCheck, + WithUndefinedOrNullCheck + }; + template <V8ParameterMode MODE = DefaultMode> + class V8Parameter { + public: + V8Parameter (v8::Local<v8::Value> object) :m_v8Object(object) { } + operator String(); + operator AtomicString(); + private: + v8::Local<v8::Value> m_v8Object; + }; + + template<> inline V8Parameter<DefaultMode>::operator String() { return toWebCoreString(m_v8Object); } + template<> inline V8Parameter<WithNullCheck>::operator String() { return toWebCoreStringWithNullCheck(m_v8Object); } + template<> inline V8Parameter<WithUndefinedOrNullCheck>::operator String() { return toWebCoreStringWithNullOrUndefinedCheck(m_v8Object); } + + template<> inline V8Parameter<DefaultMode>::operator AtomicString() { return v8ValueToAtomicWebCoreString(m_v8Object); } + template<> inline V8Parameter<WithNullCheck>::operator AtomicString() { return toAtomicWebCoreStringWithNullCheck(m_v8Object); } + template<> inline V8Parameter<WithUndefinedOrNullCheck>::operator AtomicString() { return toAtomicWebCoreStringWithNullCheck(m_v8Object); } - inline v8::Handle<v8::Value> v8StringOrFalse(const String& str) - { - return str.isNull() ? v8::Handle<v8::Value>(v8::False()) : v8::Handle<v8::Value>(v8String(str)); - } } // namespace WebCore #endif // V8Binding_h diff --git a/WebCore/bindings/v8/V8Collection.h b/WebCore/bindings/v8/V8Collection.h index e72dc07..0a4134e 100644 --- a/WebCore/bindings/v8/V8Collection.h +++ b/WebCore/bindings/v8/V8Collection.h @@ -177,6 +177,18 @@ namespace WebCore { } + // A template for indexed getters on collections of strings. + template<class Collection> static v8::Handle<v8::Value> collectionStringIndexedPropertyGetter(uint32_t index, const v8::AccessorInfo& info) + { + // FIXME: assert that object must be a collection type + ASSERT(V8DOMWrapper::maybeDOMWrapper(info.Holder())); + V8ClassIndex::V8WrapperType wrapperType = V8DOMWrapper::domWrapperType(info.Holder()); + Collection* collection = V8DOMWrapper::convertToNativeObject<Collection>(wrapperType, info.Holder()); + String result = collection->item(index); + return v8String(result); + } + + // Add indexed getter to the function template for a collection. template<class Collection, class ItemType> static void setCollectionIndexedGetter(v8::Handle<v8::FunctionTemplate> desc, V8ClassIndex::V8WrapperType type) { @@ -208,6 +220,13 @@ namespace WebCore { desc->InstanceTemplate()->SetIndexedPropertyHandler(collectionStringOrNullIndexedPropertyGetter<Collection>, 0, 0, 0, collectionIndexedPropertyEnumerator<Collection>); } + + // Add indexed getter returning a string to a function template for a collection. + template<class Collection> static void setCollectionStringIndexedGetter(v8::Handle<v8::FunctionTemplate> desc) + { + desc->InstanceTemplate()->SetIndexedPropertyHandler(collectionStringIndexedPropertyGetter<Collection>, 0, 0, 0, collectionIndexedPropertyEnumerator<Collection>); + } + v8::Handle<v8::Value> toOptionsCollectionSetter(uint32_t index, v8::Handle<v8::Value>, HTMLSelectElement*); } // namespace WebCore diff --git a/WebCore/bindings/v8/V8DOMMap.cpp b/WebCore/bindings/v8/V8DOMMap.cpp index 1bd68f7..acd88ec 100644 --- a/WebCore/bindings/v8/V8DOMMap.cpp +++ b/WebCore/bindings/v8/V8DOMMap.cpp @@ -34,6 +34,7 @@ #include "DOMData.h" #include "DOMDataStore.h" #include "DOMObjectsInclude.h" +#include "MainThreadDOMData.h" #include "ScopedDOMDataStore.h" namespace WebCore { @@ -47,33 +48,49 @@ DOMDataStoreHandle::~DOMDataStoreHandle() { } +static bool fasterDOMStoreAccess = false; + +static inline DOMDataStore& getDOMDataStore() +{ + if (LIKELY(fasterDOMStoreAccess)) { + ASSERT(WTF::isMainThread()); + return MainThreadDOMData::getCurrentMainThreadStore(); + } + + return DOMData::getCurrent()->getStore(); +} + +void enableFasterDOMStoreAccess() +{ + fasterDOMStoreAccess = true; +} + DOMWrapperMap<Node>& getDOMNodeMap() { - // Nodes only exist on the main thread. - return DOMData::getCurrentMainThread()->getStore().domNodeMap(); + return getDOMDataStore().domNodeMap(); } DOMWrapperMap<void>& getDOMObjectMap() { - return DOMData::getCurrent()->getStore().domObjectMap(); + return getDOMDataStore().domObjectMap(); } DOMWrapperMap<void>& getActiveDOMObjectMap() { - return DOMData::getCurrent()->getStore().activeDomObjectMap(); + return getDOMDataStore().activeDomObjectMap(); } #if ENABLE(SVG) DOMWrapperMap<SVGElementInstance>& getDOMSVGElementInstanceMap() { - return DOMData::getCurrent()->getStore().domSvgElementInstanceMap(); + return getDOMDataStore().domSvgElementInstanceMap(); } // Map of SVG objects with contexts to V8 objects DOMWrapperMap<void>& getDOMSVGObjectWithContextMap() { - return DOMData::getCurrent()->getStore().domSvgObjectWithContextMap(); + return getDOMDataStore().domSvgObjectWithContextMap(); } #endif // ENABLE(SVG) diff --git a/WebCore/bindings/v8/V8DOMMap.h b/WebCore/bindings/v8/V8DOMMap.h index 754ac3a..b6861d4 100644 --- a/WebCore/bindings/v8/V8DOMMap.h +++ b/WebCore/bindings/v8/V8DOMMap.h @@ -140,6 +140,8 @@ namespace WebCore { DOMWrapperMap<void>& getDOMSVGObjectWithContextMap(); void visitDOMSVGObjectsInCurrentThread(DOMWrapperMap<void>::Visitor*); #endif + + void enableFasterDOMStoreAccess(); } // namespace WebCore #endif // V8DOMMap_h diff --git a/WebCore/bindings/v8/V8DOMWrapper.cpp b/WebCore/bindings/v8/V8DOMWrapper.cpp index 4e41a8c..7ecc29c 100644 --- a/WebCore/bindings/v8/V8DOMWrapper.cpp +++ b/WebCore/bindings/v8/V8DOMWrapper.cpp @@ -57,6 +57,8 @@ #include "V8Index.h" #include "V8IsolatedWorld.h" #include "V8Proxy.h" +#include "WebGLArray.h" +#include "WebGLUniformLocation.h" #include "WorkerContextExecutionProxy.h" #include <algorithm> @@ -156,11 +158,64 @@ v8::Handle<v8::Value> V8DOMWrapper::convertSVGObjectWithContextToV8Object(V8Clas #endif +#if ENABLE(3D_CANVAS) +void V8DOMWrapper::setIndexedPropertiesToExternalArray(v8::Handle<v8::Object> wrapper, + int index, + void* address, + int length) +{ + v8::ExternalArrayType array_type = v8::kExternalByteArray; + V8ClassIndex::V8WrapperType classIndex = V8ClassIndex::FromInt(index); + switch (classIndex) { + case V8ClassIndex::WEBGLBYTEARRAY: + array_type = v8::kExternalByteArray; + break; + case V8ClassIndex::WEBGLUNSIGNEDBYTEARRAY: + array_type = v8::kExternalUnsignedByteArray; + break; + case V8ClassIndex::WEBGLSHORTARRAY: + array_type = v8::kExternalShortArray; + break; + case V8ClassIndex::WEBGLUNSIGNEDSHORTARRAY: + array_type = v8::kExternalUnsignedShortArray; + break; + case V8ClassIndex::WEBGLINTARRAY: + array_type = v8::kExternalIntArray; + break; + case V8ClassIndex::WEBGLUNSIGNEDINTARRAY: + array_type = v8::kExternalUnsignedIntArray; + break; + case V8ClassIndex::WEBGLFLOATARRAY: + array_type = v8::kExternalFloatArray; + break; + default: + ASSERT_NOT_REACHED(); + } + wrapper->SetIndexedPropertiesToExternalArrayData(address, + array_type, + length); +} +#endif + bool V8DOMWrapper::domObjectHasJSWrapper(void* object) { return getDOMObjectMap().contains(object) || getActiveDOMObjectMap().contains(object); } +v8::Persistent<v8::Object> V8DOMWrapper::jsWrapperForDOMObject(void* object) +{ + v8::Persistent<v8::Object> wrapper = getDOMObjectMap().get(object); + ASSERT(!wrapper.IsEmpty()); + return wrapper; +} + +v8::Persistent<v8::Object> V8DOMWrapper::jsWrapperForActiveDOMObject(void* object) +{ + v8::Persistent<v8::Object> wrapper = getActiveDOMObjectMap().get(object); + ASSERT(!wrapper.IsEmpty()); + return wrapper; +} + // The caller must have increased obj's ref count. void V8DOMWrapper::setJSWrapperForDOMObject(void* object, v8::Persistent<v8::Object> wrapper) { @@ -228,7 +283,7 @@ v8::Persistent<v8::FunctionTemplate> V8DOMWrapper::getTemplate(V8ClassIndex::V8W // setter. Therefore, the interceptor has to be on the object // itself and not on the prototype object. descriptor->InstanceTemplate()->SetNamedPropertyHandler( USE_NAMED_PROPERTY_GETTER(CSSStyleDeclaration), USE_NAMED_PROPERTY_SETTER(CSSStyleDeclaration)); - setCollectionStringOrNullIndexedGetter<CSSStyleDeclaration>(descriptor); + setCollectionStringIndexedGetter<CSSStyleDeclaration>(descriptor); break; case V8ClassIndex::CSSRULELIST: setCollectionIndexedGetter<CSSRuleList, CSSRule>(descriptor, V8ClassIndex::CSSRULE); @@ -237,7 +292,7 @@ v8::Persistent<v8::FunctionTemplate> V8DOMWrapper::getTemplate(V8ClassIndex::V8W setCollectionIndexedGetter<CSSValueList, CSSValue>(descriptor, V8ClassIndex::CSSVALUE); break; case V8ClassIndex::CSSVARIABLESDECLARATION: - setCollectionStringOrNullIndexedGetter<CSSVariablesDeclaration>(descriptor); + setCollectionStringIndexedGetter<CSSVariablesDeclaration>(descriptor); break; case V8ClassIndex::WEBKITCSSTRANSFORMVALUE: setCollectionIndexedGetter<WebKitCSSTransformValue, CSSValue>(descriptor, V8ClassIndex::CSSVALUE); @@ -319,10 +374,15 @@ v8::Persistent<v8::FunctionTemplate> V8DOMWrapper::getTemplate(V8ClassIndex::V8W case V8ClassIndex::MIMETYPEARRAY: setCollectionIndexedAndNamedGetters<MimeTypeArray, MimeType>(descriptor, V8ClassIndex::MIMETYPE); break; - case V8ClassIndex::NAMEDNODEMAP: - descriptor->InstanceTemplate()->SetNamedPropertyHandler(USE_NAMED_PROPERTY_GETTER(NamedNodeMap)); - descriptor->InstanceTemplate()->SetIndexedPropertyHandler(USE_INDEXED_PROPERTY_GETTER(NamedNodeMap), 0, 0, 0, collectionIndexedPropertyEnumerator<NamedNodeMap>, v8::Integer::New(V8ClassIndex::NODE)); + case V8ClassIndex::NAMEDNODEMAP: { + // We add an extra internal field to hold a reference to the owner node. + v8::Local<v8::ObjectTemplate> instanceTemplate = descriptor->InstanceTemplate(); + ASSERT(instanceTemplate->InternalFieldCount() == V8Custom::kDefaultWrapperInternalFieldCount); + instanceTemplate->SetInternalFieldCount(V8Custom::kNamedNodeMapInternalFieldCount); + instanceTemplate->SetNamedPropertyHandler(USE_NAMED_PROPERTY_GETTER(NamedNodeMap)); + instanceTemplate->SetIndexedPropertyHandler(USE_INDEXED_PROPERTY_GETTER(NamedNodeMap), 0, 0, 0, collectionIndexedPropertyEnumerator<NamedNodeMap>, v8::Integer::New(V8ClassIndex::NODE)); break; + } #if ENABLE(DOM_STORAGE) case V8ClassIndex::STORAGE: descriptor->InstanceTemplate()->SetNamedPropertyHandler(USE_NAMED_PROPERTY_GETTER(Storage), USE_NAMED_PROPERTY_SETTER(Storage), 0, USE_NAMED_PROPERTY_DELETER(Storage), V8Custom::v8StorageNamedPropertyEnumerator); @@ -474,36 +534,29 @@ v8::Persistent<v8::FunctionTemplate> V8DOMWrapper::getTemplate(V8ClassIndex::V8W #if ENABLE(3D_CANVAS) // The following objects are created from JavaScript. - case V8ClassIndex::CANVASARRAYBUFFER: - descriptor->SetCallHandler(USE_CALLBACK(CanvasArrayBufferConstructor)); + case V8ClassIndex::WEBGLARRAYBUFFER: + descriptor->SetCallHandler(USE_CALLBACK(WebGLArrayBufferConstructor)); break; - case V8ClassIndex::CANVASBYTEARRAY: - descriptor->SetCallHandler(USE_CALLBACK(CanvasByteArrayConstructor)); - descriptor->InstanceTemplate()->SetIndexedPropertyHandler(USE_INDEXED_PROPERTY_GETTER(CanvasByteArray), USE_INDEXED_PROPERTY_SETTER(CanvasByteArray)); + case V8ClassIndex::WEBGLBYTEARRAY: + descriptor->SetCallHandler(USE_CALLBACK(WebGLByteArrayConstructor)); break; - case V8ClassIndex::CANVASFLOATARRAY: - descriptor->SetCallHandler(USE_CALLBACK(CanvasFloatArrayConstructor)); - descriptor->InstanceTemplate()->SetIndexedPropertyHandler(USE_INDEXED_PROPERTY_GETTER(CanvasFloatArray), USE_INDEXED_PROPERTY_SETTER(CanvasFloatArray)); + case V8ClassIndex::WEBGLFLOATARRAY: + descriptor->SetCallHandler(USE_CALLBACK(WebGLFloatArrayConstructor)); break; - case V8ClassIndex::CANVASINTARRAY: - descriptor->SetCallHandler(USE_CALLBACK(CanvasIntArrayConstructor)); - descriptor->InstanceTemplate()->SetIndexedPropertyHandler(USE_INDEXED_PROPERTY_GETTER(CanvasIntArray), USE_INDEXED_PROPERTY_SETTER(CanvasIntArray)); + case V8ClassIndex::WEBGLINTARRAY: + descriptor->SetCallHandler(USE_CALLBACK(WebGLIntArrayConstructor)); break; - case V8ClassIndex::CANVASSHORTARRAY: - descriptor->SetCallHandler(USE_CALLBACK(CanvasShortArrayConstructor)); - descriptor->InstanceTemplate()->SetIndexedPropertyHandler(USE_INDEXED_PROPERTY_GETTER(CanvasShortArray), USE_INDEXED_PROPERTY_SETTER(CanvasShortArray)); + case V8ClassIndex::WEBGLSHORTARRAY: + descriptor->SetCallHandler(USE_CALLBACK(WebGLShortArrayConstructor)); break; - case V8ClassIndex::CANVASUNSIGNEDBYTEARRAY: - descriptor->SetCallHandler(USE_CALLBACK(CanvasUnsignedByteArrayConstructor)); - descriptor->InstanceTemplate()->SetIndexedPropertyHandler(USE_INDEXED_PROPERTY_GETTER(CanvasUnsignedByteArray), USE_INDEXED_PROPERTY_SETTER(CanvasUnsignedByteArray)); + case V8ClassIndex::WEBGLUNSIGNEDBYTEARRAY: + descriptor->SetCallHandler(USE_CALLBACK(WebGLUnsignedByteArrayConstructor)); break; - case V8ClassIndex::CANVASUNSIGNEDINTARRAY: - descriptor->SetCallHandler(USE_CALLBACK(CanvasUnsignedIntArrayConstructor)); - descriptor->InstanceTemplate()->SetIndexedPropertyHandler(USE_INDEXED_PROPERTY_GETTER(CanvasUnsignedIntArray), USE_INDEXED_PROPERTY_SETTER(CanvasUnsignedIntArray)); + case V8ClassIndex::WEBGLUNSIGNEDINTARRAY: + descriptor->SetCallHandler(USE_CALLBACK(WebGLUnsignedIntArrayConstructor)); break; - case V8ClassIndex::CANVASUNSIGNEDSHORTARRAY: - descriptor->SetCallHandler(USE_CALLBACK(CanvasUnsignedShortArrayConstructor)); - descriptor->InstanceTemplate()->SetIndexedPropertyHandler(USE_INDEXED_PROPERTY_GETTER(CanvasUnsignedShortArray), USE_INDEXED_PROPERTY_SETTER(CanvasUnsignedShortArray)); + case V8ClassIndex::WEBGLUNSIGNEDSHORTARRAY: + descriptor->SetCallHandler(USE_CALLBACK(WebGLUnsignedShortArrayConstructor)); break; #endif case V8ClassIndex::DOMPARSER: @@ -670,6 +723,8 @@ v8::Handle<v8::Value> V8DOMWrapper::convertToV8Object(V8ClassIndex::V8WrapperTyp return convertStyleSheetToV8Object(static_cast<StyleSheet*>(impl)); case V8ClassIndex::DOMWINDOW: return convertWindowToV8Object(static_cast<DOMWindow*>(impl)); + case V8ClassIndex::NAMEDNODEMAP: + return convertNamedNodeMapToV8Object(static_cast<NamedNodeMap*>(impl)); #if ENABLE(SVG) SVG_NONNODE_TYPES(MAKE_CASE) if (type == V8ClassIndex::SVGELEMENTINSTANCE) @@ -692,6 +747,27 @@ v8::Handle<v8::Value> V8DOMWrapper::convertToV8Object(V8ClassIndex::V8WrapperTyp // Non DOM node v8::Persistent<v8::Object> result = isActiveDomObject ? getActiveDOMObjectMap().get(impl) : getDOMObjectMap().get(impl); if (result.IsEmpty()) { +#if ENABLE(3D_CANVAS) + if (type == V8ClassIndex::WEBGLARRAY && impl) { + // Determine which subclass we are wrapping. + WebGLArray* array = reinterpret_cast<WebGLArray*>(impl); + if (array->isByteArray()) + type = V8ClassIndex::WEBGLBYTEARRAY; + else if (array->isFloatArray()) + type = V8ClassIndex::WEBGLFLOATARRAY; + else if (array->isIntArray()) + type = V8ClassIndex::WEBGLINTARRAY; + else if (array->isShortArray()) + type = V8ClassIndex::WEBGLSHORTARRAY; + else if (array->isUnsignedByteArray()) + type = V8ClassIndex::WEBGLUNSIGNEDBYTEARRAY; + else if (array->isUnsignedIntArray()) + type = V8ClassIndex::WEBGLUNSIGNEDINTARRAY; + else if (array->isUnsignedShortArray()) + type = V8ClassIndex::WEBGLUNSIGNEDSHORTARRAY; + } +#endif + v8::Local<v8::Object> v8Object = instantiateV8Object(type, type, impl); if (!v8Object.IsEmpty()) { // Go through big switch statement, it has some duplications @@ -715,6 +791,28 @@ v8::Handle<v8::Value> V8DOMWrapper::convertToV8Object(V8ClassIndex::V8WrapperTyp result->SetIndexedPropertiesToPixelData(pixels->data()->data(), pixels->length()); } +#if ENABLE(3D_CANVAS) + // Set up WebGLArray subclasses' accesses similarly. + switch (type) { + case V8ClassIndex::WEBGLBYTEARRAY: + case V8ClassIndex::WEBGLUNSIGNEDBYTEARRAY: + case V8ClassIndex::WEBGLSHORTARRAY: + case V8ClassIndex::WEBGLUNSIGNEDSHORTARRAY: + case V8ClassIndex::WEBGLINTARRAY: + case V8ClassIndex::WEBGLUNSIGNEDINTARRAY: + case V8ClassIndex::WEBGLFLOATARRAY: { + WebGLArray* array = reinterpret_cast<WebGLArray*>(impl); + setIndexedPropertiesToExternalArray(result, + V8ClassIndex::ToInt(type), + array->baseAddress(), + array->length()); + break; + } + default: + break; + } +#endif + // Special case for non-node objects associated with a // DOMWindow. Both Safari and FF let the JS wrappers for these // objects survive GC. To mimic their behavior, V8 creates @@ -849,13 +947,6 @@ v8::Local<v8::Object> V8DOMWrapper::instantiateV8Object(V8Proxy* proxy, V8ClassI return instance; } -void V8DOMWrapper::setDOMWrapper(v8::Handle<v8::Object> object, int type, void* cptr) -{ - ASSERT(object->InternalFieldCount() >= 2); - object->SetPointerInInternalField(V8Custom::kDOMWrapperObjectIndex, cptr); - object->SetInternalField(V8Custom::kDOMWrapperTypeIndex, v8::Integer::New(type)); -} - #ifndef NDEBUG bool V8DOMWrapper::maybeDOMWrapper(v8::Handle<v8::Value> value) { @@ -1034,7 +1125,7 @@ V8ClassIndex::V8WrapperType V8DOMWrapper::htmlElementType(HTMLElement* element) #define FOR_EACH_ANIMATION_TAG(macro) #endif -#if ENABLE(SVG_FILTERS) +#if ENABLE(SVG) && ENABLE(FILTERS) #define FOR_EACH_FILTERS_TAG(macro) \ macro(feBlend, FEBLEND) \ macro(feColorMatrix, FECOLORMATRIX) \ @@ -1179,6 +1270,8 @@ v8::Handle<v8::Value> V8DOMWrapper::convertEventToV8Object(Event* event) else if (event->isSVGZoomEvent()) type = V8ClassIndex::SVGZOOMEVENT; #endif + else if (event->isCompositionEvent()) + type = V8ClassIndex::COMPOSITIONEVENT; else type = V8ClassIndex::UIEVENT; } else if (event->isMutationEvent()) @@ -1260,6 +1353,23 @@ v8::Handle<v8::Value> V8DOMWrapper::convertDocumentToV8Object(Document* document return wrapper; } +v8::Handle<v8::Value> V8DOMWrapper::convertNodeToV8Object(Node* node) +{ + if (!node) + return v8::Null(); + + Document* document = node->document(); + if (node == document) + return convertDocumentToV8Object(document); + + DOMWrapperMap<Node>& domNodeMap = getDOMNodeMap(); + v8::Handle<v8::Object> wrapper = domNodeMap.get(node); + if (wrapper.IsEmpty()) + return convertNewNodeToV8Object(node, 0, domNodeMap); + + return wrapper; +} + // Caller checks node is not null. v8::Handle<v8::Value> V8DOMWrapper::convertNewNodeToV8Object(Node* node, V8Proxy* proxy, DOMWrapperMap<Node>& domNodeMap) { @@ -1358,6 +1468,12 @@ v8::Handle<v8::Value> V8DOMWrapper::convertEventTargetToV8Object(EventTarget* ta return convertToV8Object(V8ClassIndex::WORKER, worker); #endif // WORKERS +#if ENABLE(SHARED_WORKERS) + SharedWorker* sharedWorker = target->toSharedWorker(); + if (sharedWorker) + return convertToV8Object(V8ClassIndex::SHAREDWORKER, sharedWorker); +#endif // SHARED_WORKERS + #if ENABLE(NOTIFICATIONS) Notification* notification = target->toNotification(); if (notification) @@ -1422,30 +1538,23 @@ v8::Handle<v8::Value> V8DOMWrapper::convertEventListenerToV8Object(ScriptExecuti PassRefPtr<EventListener> V8DOMWrapper::getEventListener(Node* node, v8::Local<v8::Value> value, bool isAttribute, ListenerLookupType lookup) { - ScriptExecutionContext* context = node->scriptExecutionContext(); - if (!context) - return 0; - - V8Proxy* proxy = V8Proxy::retrieve(context); - // The document might be created using createDocument, which does - // not have a frame, use the active frame. - if (!proxy) - proxy = V8Proxy::retrieve(V8Proxy::retrieveFrameForEnteredContext()); - - if (proxy) - return (lookup == ListenerFindOnly) ? V8EventListenerList::findWrapper(value, isAttribute) : V8EventListenerList::findOrCreateWrapper<V8EventListener>(proxy->listenerGuard(), value, isAttribute); - - return 0; + return (lookup == ListenerFindOnly) ? V8EventListenerList::findWrapper(value, isAttribute) : V8EventListenerList::findOrCreateWrapper<V8EventListener>(value, isAttribute); } +<<<<<<< HEAD:WebCore/bindings/v8/V8DOMWrapper.cpp #if PLATFORM(ANDROID) +======= +>>>>>>> webkit.org at r51976:WebCore/bindings/v8/V8DOMWrapper.cpp #if ENABLE(SVG) PassRefPtr<EventListener> V8DOMWrapper::getEventListener(SVGElementInstance* element, v8::Local<v8::Value> value, bool isAttribute, ListenerLookupType lookup) { return getEventListener(element->correspondingElement(), value, isAttribute, lookup); } #endif +<<<<<<< HEAD:WebCore/bindings/v8/V8DOMWrapper.cpp #endif +======= +>>>>>>> webkit.org at r51976:WebCore/bindings/v8/V8DOMWrapper.cpp PassRefPtr<EventListener> V8DOMWrapper::getEventListener(AbstractWorker* worker, v8::Local<v8::Value> value, bool isAttribute, ListenerLookupType lookup) { @@ -1455,11 +1564,7 @@ PassRefPtr<EventListener> V8DOMWrapper::getEventListener(AbstractWorker* worker, return workerContextProxy->findOrCreateEventListener(value, isAttribute, lookup == ListenerFindOnly); } - V8Proxy* proxy = V8Proxy::retrieve(worker->scriptExecutionContext()); - if (proxy) - return (lookup == ListenerFindOnly) ? V8EventListenerList::findWrapper(value, isAttribute) : V8EventListenerList::findOrCreateWrapper<V8EventListener>(proxy->listenerGuard(), value, isAttribute); - - return 0; + return (lookup == ListenerFindOnly) ? V8EventListenerList::findWrapper(value, isAttribute) : V8EventListenerList::findOrCreateWrapper<V8EventListener>(value, isAttribute); } #if ENABLE(NOTIFICATIONS) @@ -1471,11 +1576,7 @@ PassRefPtr<EventListener> V8DOMWrapper::getEventListener(Notification* notificat return workerContextProxy->findOrCreateEventListener(value, isAttribute, lookup == ListenerFindOnly); } - V8Proxy* proxy = V8Proxy::retrieve(notification->scriptExecutionContext()); - if (proxy) - return (lookup == ListenerFindOnly) ? V8EventListenerList::findWrapper(value, isAttribute) : V8EventListenerList::findOrCreateWrapper<V8EventListener>(proxy->listenerGuard(), value, isAttribute); - - return 0; + return (lookup == ListenerFindOnly) ? V8EventListenerList::findWrapper(value, isAttribute) : V8EventListenerList::findOrCreateWrapper<V8EventListener>(value, isAttribute); } #endif @@ -1495,9 +1596,8 @@ PassRefPtr<EventListener> V8DOMWrapper::getEventListener(XMLHttpRequestUpload* u PassRefPtr<EventListener> V8DOMWrapper::getEventListener(EventTarget* eventTarget, v8::Local<v8::Value> value, bool isAttribute, ListenerLookupType lookup) { - V8Proxy* proxy = V8Proxy::retrieve(eventTarget->scriptExecutionContext()); - if (proxy) - return (lookup == ListenerFindOnly) ? V8EventListenerList::findWrapper(value, isAttribute) : V8EventListenerList::findOrCreateWrapper<V8EventListener>(proxy->listenerGuard(), value, isAttribute); + if (V8Proxy::retrieve(eventTarget->scriptExecutionContext())) + return (lookup == ListenerFindOnly) ? V8EventListenerList::findWrapper(value, isAttribute) : V8EventListenerList::findOrCreateWrapper<V8EventListener>(value, isAttribute); #if ENABLE(WORKERS) WorkerContextExecutionProxy* workerContextProxy = WorkerContextExecutionProxy::retrieve(); @@ -1510,10 +1610,7 @@ PassRefPtr<EventListener> V8DOMWrapper::getEventListener(EventTarget* eventTarge PassRefPtr<EventListener> V8DOMWrapper::getEventListener(V8Proxy* proxy, v8::Local<v8::Value> value, bool isAttribute, ListenerLookupType lookup) { - if (proxy) - return (lookup == ListenerFindOnly) ? V8EventListenerList::findWrapper(value, isAttribute) : V8EventListenerList::findOrCreateWrapper<V8EventListener>(proxy->listenerGuard(), value, isAttribute); - - return 0; + return (lookup == ListenerFindOnly) ? V8EventListenerList::findWrapper(value, isAttribute) : V8EventListenerList::findOrCreateWrapper<V8EventListener>(value, isAttribute); } v8::Handle<v8::Value> V8DOMWrapper::convertDOMImplementationToV8Object(DOMImplementation* impl) @@ -1679,4 +1776,30 @@ v8::Handle<v8::Value> V8DOMWrapper::convertWindowToV8Object(DOMWindow* window) return global; } +v8::Handle<v8::Value> V8DOMWrapper::convertNamedNodeMapToV8Object(NamedNodeMap* map) +{ + if (!map) + return v8::Null(); + + v8::Handle<v8::Object> wrapper = getDOMObjectMap().get(map); + if (!wrapper.IsEmpty()) + return wrapper; + + v8::Handle<v8::Object> result = instantiateV8Object(V8ClassIndex::NAMEDNODEMAP, V8ClassIndex::NAMEDNODEMAP, map); + if (result.IsEmpty()) + return result; + + // Only update the DOM object map if the result is non-empty. + map->ref(); + setJSWrapperForDOMObject(map, v8::Persistent<v8::Object>::New(result)); + + // Add a hidden reference from named node map to its owner node. + if (Element* element = map->element()) { + v8::Handle<v8::Object> owner = v8::Handle<v8::Object>::Cast(convertNodeToV8Object(element)); + result->SetInternalField(V8Custom::kNamedNodeMapOwnerNodeIndex, owner); + } + + return result; +} + } // namespace WebCore diff --git a/WebCore/bindings/v8/V8DOMWrapper.h b/WebCore/bindings/v8/V8DOMWrapper.h index 3d50af3..660b827 100644 --- a/WebCore/bindings/v8/V8DOMWrapper.h +++ b/WebCore/bindings/v8/V8DOMWrapper.h @@ -109,7 +109,12 @@ namespace WebCore { #endif // Sets contents of a DOM wrapper. - static void setDOMWrapper(v8::Handle<v8::Object>, int type, void* ptr); + static void setDOMWrapper(v8::Handle<v8::Object> object, int type, void* cptr) + { + ASSERT(object->InternalFieldCount() >= 2); + object->SetPointerInInternalField(V8Custom::kDOMWrapperObjectIndex, cptr); + object->SetInternalField(V8Custom::kDOMWrapperTypeIndex, v8::Integer::New(type)); + } static v8::Handle<v8::Object> lookupDOMWrapper(V8ClassIndex::V8WrapperType type, v8::Handle<v8::Object> object) { @@ -147,22 +152,7 @@ namespace WebCore { return convertNodeToV8Object(node.get()); } - static v8::Handle<v8::Value> convertNodeToV8Object(Node* node) - { - if (!node) - return v8::Null(); - - Document* document = node->document(); - if (node == document) - return convertDocumentToV8Object(document); - - DOMWrapperMap<Node>& domNodeMap = getDOMNodeMap(); - v8::Handle<v8::Object> wrapper = domNodeMap.get(node); - if (wrapper.IsEmpty()) - return convertNewNodeToV8Object(node, 0, domNodeMap); - - return wrapper; - } + static v8::Handle<v8::Value> convertNodeToV8Object(Node*); static v8::Handle<v8::Value> convertDocumentToV8Object(Document*); @@ -256,13 +246,13 @@ namespace WebCore { // TODO: upstream XPATH guard. #if ENABLE(XPATH) // XPath-related utilities - static RefPtr<XPathNSResolver> getXPathNSResolver(v8::Handle<v8::Value> value) + static RefPtr<XPathNSResolver> getXPathNSResolver(v8::Handle<v8::Value> value, V8Proxy* proxy = 0) { RefPtr<XPathNSResolver> resolver; if (V8XPathNSResolver::HasInstance(value)) resolver = convertToNativeObject<XPathNSResolver>(V8ClassIndex::XPATHNSRESOLVER, v8::Handle<v8::Object>::Cast(value)); else if (value->IsObject()) - resolver = V8CustomXPathNSResolver::create(value->ToObject()); + resolver = V8CustomXPathNSResolver::create(proxy, value->ToObject()); return resolver; } #endif @@ -284,6 +274,10 @@ namespace WebCore { // Checks whether a DOM object has a JS wrapper. static bool domObjectHasJSWrapper(void*); + // Get JS wrapper of an existing DOM object, assuming that the wrapper + // exists. + static v8::Persistent<v8::Object> jsWrapperForDOMObject(void*); + static v8::Persistent<v8::Object> jsWrapperForActiveDOMObject(void*); // Set JS wrapper of a DOM object, the caller in charge of increase ref. static void setJSWrapperForDOMObject(void*, v8::Persistent<v8::Object>); static void setJSWrapperForActiveDOMObject(void*, v8::Persistent<v8::Object>); @@ -303,12 +297,20 @@ namespace WebCore { // Returns the JS wrapper of a window object, initializes the environment // of the window frame if needed. static v8::Handle<v8::Value> convertWindowToV8Object(DOMWindow*); + static v8::Handle<v8::Value> convertNamedNodeMapToV8Object(NamedNodeMap*); #if ENABLE(SVG) static v8::Handle<v8::Value> convertSVGElementInstanceToV8Object(SVGElementInstance*); static v8::Handle<v8::Value> convertSVGObjectWithContextToV8Object(V8ClassIndex::V8WrapperType, void*); #endif +#if ENABLE(3D_CANVAS) + static void setIndexedPropertiesToExternalArray(v8::Handle<v8::Object>, + int, + void*, + int); +#endif + private: // Set hidden references in a DOMWindow object of a frame. static void setHiddenWindowReference(Frame*, const int internalIndex, v8::Handle<v8::Object>); diff --git a/WebCore/bindings/v8/V8EventListenerList.h b/WebCore/bindings/v8/V8EventListenerList.h index 29b4874..fdf211d 100644 --- a/WebCore/bindings/v8/V8EventListenerList.h +++ b/WebCore/bindings/v8/V8EventListenerList.h @@ -31,15 +31,14 @@ #ifndef V8EventListenerList_h #define V8EventListenerList_h -#include <v8.h> - -#include "PassRefPtr.h" #include "V8CustomEventListener.h" #include "V8HiddenPropertyName.h" +#include <v8.h> +#include <wtf/PassRefPtr.h> + namespace WebCore { class Frame; - class V8EventListener; // This is a container for V8EventListener objects that uses hidden properties of v8::Object to speed up lookups. class V8EventListenerList { @@ -55,7 +54,7 @@ namespace WebCore { } template<typename WrapperType> - static PassRefPtr<V8EventListener> findOrCreateWrapper(PassRefPtr<V8ListenerGuard>, v8::Local<v8::Value>, bool isAttribute); + static PassRefPtr<V8EventListener> findOrCreateWrapper(v8::Local<v8::Value>, bool isAttribute); static void clearWrapper(v8::Handle<v8::Object> listenerObject, bool isAttribute) { @@ -81,7 +80,7 @@ namespace WebCore { }; template<typename WrapperType> - PassRefPtr<V8EventListener> V8EventListenerList::findOrCreateWrapper(PassRefPtr<V8ListenerGuard> guard, v8::Local<v8::Value> value, bool isAttribute) + PassRefPtr<V8EventListener> V8EventListenerList::findOrCreateWrapper(v8::Local<v8::Value> value, bool isAttribute) { ASSERT(v8::Context::InContext()); if (!value->IsObject()) @@ -94,7 +93,7 @@ namespace WebCore { if (wrapper) return wrapper; - PassRefPtr<V8EventListener> wrapperPtr = WrapperType::create(guard, object, isAttribute); + PassRefPtr<V8EventListener> wrapperPtr = WrapperType::create(object, isAttribute, WorldContextHandle(UseCurrentWorld)); if (wrapperPtr) object->SetHiddenValue(wrapperProperty, v8::External::Wrap(wrapperPtr.get())); diff --git a/WebCore/bindings/v8/V8GCController.cpp b/WebCore/bindings/v8/V8GCController.cpp index 242954c..e08cf66 100644 --- a/WebCore/bindings/v8/V8GCController.cpp +++ b/WebCore/bindings/v8/V8GCController.cpp @@ -204,35 +204,11 @@ public: // has the drawback that the wrappers are "entangled/unentangled" for each // GC even though their entaglement most likely is still the same. if (type == V8ClassIndex::MESSAGEPORT) { - // Get the port and its entangled port. + // Mark each port as in-use if it's entangled. For simplicity's sake, we assume all ports are remotely entangled, + // since the Chromium port implementation can't tell the difference. MessagePort* port1 = static_cast<MessagePort*>(object); - MessagePort* port2 = port1->locallyEntangledPort(); - - // If we are remotely entangled, then mark this object as reachable - // (we can't determine reachability directly as the remote object is - // out-of-proc). - if (port1->isEntangled() && !port2) + if (port1->isEntangled()) wrapper.ClearWeak(); - - if (port2) { - // As ports are always entangled in pairs only perform the entanglement - // once for each pair (see ASSERT in MessagePort::unentangle()). - if (port1 < port2) { - v8::Handle<v8::Value> port1Wrapper = V8DOMWrapper::convertToV8Object(V8ClassIndex::MESSAGEPORT, port1); - v8::Handle<v8::Value> port2Wrapper = V8DOMWrapper::convertToV8Object(V8ClassIndex::MESSAGEPORT, port2); - ASSERT(port1Wrapper->IsObject()); - v8::Handle<v8::Object>::Cast(port1Wrapper)->SetInternalField(V8Custom::kMessagePortEntangledPortIndex, port2Wrapper); - ASSERT(port2Wrapper->IsObject()); - v8::Handle<v8::Object>::Cast(port2Wrapper)->SetInternalField(V8Custom::kMessagePortEntangledPortIndex, port1Wrapper); - } - } else { - // Remove the wrapper entanglement when a port is not entangled. - if (V8DOMWrapper::domObjectHasJSWrapper(port1)) { - v8::Handle<v8::Value> wrapper = V8DOMWrapper::convertToV8Object(V8ClassIndex::MESSAGEPORT, port1); - ASSERT(wrapper->IsObject()); - v8::Handle<v8::Object>::Cast(wrapper)->SetInternalField(V8Custom::kMessagePortEntangledPortIndex, v8::Undefined()); - } - } } } }; @@ -296,14 +272,21 @@ public: groupId = reinterpret_cast<uintptr_t>(node->document()); else { Node* root = node; - while (root->parent()) - root = root->parent(); - - // If the node is alone in its DOM tree (doesn't have a parent or any - // children) then the group will be filtered out later anyway. - if (root == node && !node->hasChildNodes()) - return; - + if (node->isAttributeNode()) { + root = static_cast<Attr*>(node)->ownerElement(); + // If the attribute has no element, no need to put it in the group, + // because it'll always be a group of 1. + if (!root) + return; + } else { + while (root->parent()) + root = root->parent(); + + // If the node is alone in its DOM tree (doesn't have a parent or any + // children) then the group will be filtered out later anyway. + if (root == node && !node->hasChildNodes() && !node->hasAttributes()) + return; + } groupId = reinterpret_cast<uintptr_t>(root); } m_grouper.append(GrouperItem(groupId, node, wrapper)); @@ -419,17 +402,30 @@ ACTIVE_DOM_OBJECT_TYPES(MAKE_CASE) if (type == V8ClassIndex::MESSAGEPORT) { MessagePort* port1 = static_cast<MessagePort*>(object); - MessagePort* port2 = port1->locallyEntangledPort(); - if (port1->isEntangled() && !port2) { - // We marked this port as reachable in GCPrologueVisitor. Undo this now since the - // port could be not reachable in the future if it gets disentangled (and also - // GCPrologueVisitor expects to see all handles marked as weak). + // We marked this port as reachable in GCPrologueVisitor. Undo this now since the + // port could be not reachable in the future if it gets disentangled (and also + // GCPrologueVisitor expects to see all handles marked as weak). + if (!wrapper.IsWeak() && !wrapper.IsNearDeath()) wrapper.MakeWeak(port1, &DOMDataStore::weakActiveDOMObjectCallback); - } } } }; +int V8GCController::workingSetEstimateMB = 0; + +namespace { + +int getMemoryUsageInMB() +{ +#if PLATFORM(CHROMIUM) + return ChromiumBridge::memoryUsageMB(); +#else + return 0; +#endif +} + +} // anonymous namespace + void V8GCController::gcEpilogue() { v8::HandleScope scope; @@ -439,6 +435,8 @@ void V8GCController::gcEpilogue() GCEpilogueVisitor epilogueVisitor; visitActiveDOMObjectsInCurrentThread(&epilogueVisitor); + workingSetEstimateMB = getMemoryUsageInMB(); + #ifndef NDEBUG // Check all survivals are weak. DOMObjectVisitor domObjectVisitor; @@ -452,4 +450,19 @@ void V8GCController::gcEpilogue() #endif } +void V8GCController::checkMemoryUsage() +{ +#if PLATFORM(CHROMIUM) + // These values are appropriate for Chromium only. + const int lowUsageMB = 256; // If memory usage is below this threshold, do not bother forcing GC. + const int highUsageMB = 1024; // If memory usage is above this threshold, force GC more aggresively. + const int highUsageDeltaMB = 128; // Delta of memory usage growth (vs. last workingSetEstimateMB) to force GC when memory usage is high. + + int memoryUsageMB = getMemoryUsageInMB(); + if ((memoryUsageMB > lowUsageMB && memoryUsageMB > 2 * workingSetEstimateMB) || (memoryUsageMB > highUsageMB && memoryUsageMB > workingSetEstimateMB + highUsageDeltaMB)) + v8::V8::LowMemoryNotification(); +#endif +} + + } // namespace WebCore diff --git a/WebCore/bindings/v8/V8GCController.h b/WebCore/bindings/v8/V8GCController.h index 7441bf0..484be24 100644 --- a/WebCore/bindings/v8/V8GCController.h +++ b/WebCore/bindings/v8/V8GCController.h @@ -78,6 +78,12 @@ namespace WebCore { static void gcPrologue(); static void gcEpilogue(); + + static void checkMemoryUsage(); + + private: + // Estimate of current working set. + static int workingSetEstimateMB; }; } diff --git a/WebCore/bindings/v8/V8HiddenPropertyName.h b/WebCore/bindings/v8/V8HiddenPropertyName.h index 5ef89cb..bb1ca4c 100644 --- a/WebCore/bindings/v8/V8HiddenPropertyName.h +++ b/WebCore/bindings/v8/V8HiddenPropertyName.h @@ -37,7 +37,6 @@ namespace WebCore { #define V8_HIDDEN_PROPERTIES(V) \ V(objectPrototype) \ - V(isolatedWorld) \ V(listener) \ V(attributeListener) \ V(sleepFunction) \ diff --git a/WebCore/bindings/v8/V8Index.cpp b/WebCore/bindings/v8/V8Index.cpp index c6369dd..7acaf89 100644 --- a/WebCore/bindings/v8/V8Index.cpp +++ b/WebCore/bindings/v8/V8Index.cpp @@ -34,7 +34,7 @@ #include "V8Attr.h" #include "V8BarInfo.h" #include "V8BeforeLoadEvent.h" -#include "V8CanvasActiveInfo.h" +#include "V8WebGLActiveInfo.h" #include "V8CanvasRenderingContext.h" #include "V8CanvasRenderingContext2D.h" #include "V8CanvasGradient.h" @@ -46,6 +46,7 @@ #include "V8ClientRectList.h" #include "V8Clipboard.h" #include "V8Comment.h" +#include "V8CompositionEvent.h" #include "V8Console.h" #include "V8Counter.h" #include "V8CSSStyleDeclaration.h" @@ -219,7 +220,7 @@ #include "V8SVGSetElement.h" #endif -#if ENABLE(SVG_FILTERS) +#if ENABLE(SVG) && ENABLE(FILTERS) #include "V8SVGComponentTransferFunctionElement.h" #include "V8SVGFEBlendElement.h" #include "V8SVGFEColorMatrixElement.h" @@ -237,6 +238,7 @@ #include "V8SVGFEImageElement.h" #include "V8SVGFEMergeElement.h" #include "V8SVGFEMergeNodeElement.h" +#include "V8SVGFEMorphologyElement.h" #include "V8SVGFEOffsetElement.h" #include "V8SVGFEPointLightElement.h" #include "V8SVGFESpecularLightingElement.h" @@ -393,22 +395,23 @@ #endif #if ENABLE(3D_CANVAS) -#include "V8CanvasRenderingContext3D.h" -#include "V8CanvasArrayBuffer.h" -#include "V8CanvasArray.h" -#include "V8CanvasByteArray.h" -#include "V8CanvasBuffer.h" -#include "V8CanvasFloatArray.h" -#include "V8CanvasFramebuffer.h" -#include "V8CanvasIntArray.h" -#include "V8CanvasProgram.h" -#include "V8CanvasRenderbuffer.h" -#include "V8CanvasShader.h" -#include "V8CanvasShortArray.h" -#include "V8CanvasTexture.h" -#include "V8CanvasUnsignedByteArray.h" -#include "V8CanvasUnsignedIntArray.h" -#include "V8CanvasUnsignedShortArray.h" +#include "V8WebGLRenderingContext.h" +#include "V8WebGLArrayBuffer.h" +#include "V8WebGLArray.h" +#include "V8WebGLByteArray.h" +#include "V8WebGLBuffer.h" +#include "V8WebGLFloatArray.h" +#include "V8WebGLFramebuffer.h" +#include "V8WebGLIntArray.h" +#include "V8WebGLProgram.h" +#include "V8WebGLRenderbuffer.h" +#include "V8WebGLShader.h" +#include "V8WebGLShortArray.h" +#include "V8WebGLTexture.h" +#include "V8WebGLUniformLocation.h" +#include "V8WebGLUnsignedByteArray.h" +#include "V8WebGLUnsignedIntArray.h" +#include "V8WebGLUnsignedShortArray.h" #endif #if ENABLE(DATABASE) @@ -432,7 +435,9 @@ #endif #if ENABLE(INSPECTOR) +#include "V8InjectedScriptHost.h" #include "V8InspectorBackend.h" +#include "V8InspectorFrontendHost.h" #endif // Geolocation @@ -441,6 +446,7 @@ #include "V8Geoposition.h" #include "V8PositionError.h" +<<<<<<< HEAD:WebCore/bindings/v8/V8Index.cpp #if PLATFORM(ANDROID) // TODO: Upstream these guards to webkit.org #if ENABLE(TOUCH_EVENTS) @@ -452,6 +458,8 @@ #include "V8VoidCallback.h" #endif // PLATFORM(ANDROID) +======= +>>>>>>> webkit.org at r51976:WebCore/bindings/v8/V8Index.cpp namespace WebCore { FunctionTemplateFactory V8ClassIndex::GetFactory(V8WrapperType type) diff --git a/WebCore/bindings/v8/V8Index.h b/WebCore/bindings/v8/V8Index.h index fb53948..6184f5a 100644 --- a/WebCore/bindings/v8/V8Index.h +++ b/WebCore/bindings/v8/V8Index.h @@ -197,7 +197,7 @@ typedef v8::Persistent<v8::FunctionTemplate> (*FunctionTemplateFactory)(); #define SVG_ANIMATION_ELEMENT_TYPES(V) #endif -#if ENABLE(SVG_FILTERS) +#if ENABLE(SVG) && ENABLE(FILTERS) #define SVG_FILTERS_ELEMENT_TYPES(V) \ V(SVGCOMPONENTTRANSFERFUNCTIONELEMENT, SVGComponentTransferFunctionElement)\ V(SVGFEBLENDELEMENT, SVGFEBlendElement) \ @@ -216,6 +216,7 @@ typedef v8::Persistent<v8::FunctionTemplate> (*FunctionTemplateFactory)(); V(SVGFEIMAGEELEMENT, SVGFEImageElement) \ V(SVGFEMERGEELEMENT, SVGFEMergeElement) \ V(SVGFEMERGENODEELEMENT, SVGFEMergeNodeElement) \ + V(SVGFEMORPHOLOGYELEMENT, SVGFEMorphologyElement) \ V(SVGFEOFFSETELEMENT, SVGFEOffsetElement) \ V(SVGFEPOINTLIGHTELEMENT, SVGFEPointLightElement) \ V(SVGFESPECULARLIGHTINGELEMENT, SVGFESpecularLightingElement) \ @@ -332,6 +333,7 @@ typedef v8::Persistent<v8::FunctionTemplate> (*FunctionTemplateFactory)(); V(CLIENTRECTLIST, ClientRectList) \ V(CLIPBOARD, Clipboard) \ V(CONSOLE, Console) \ + V(COMPOSITIONEVENT, CompositionEvent) \ V(COUNTER, Counter) \ V(CSSCHARSETRULE, CSSCharsetRule) \ V(CSSFONTFACERULE, CSSFontFaceRule) \ @@ -445,23 +447,24 @@ typedef v8::Persistent<v8::FunctionTemplate> (*FunctionTemplateFactory)(); #if ENABLE(3D_CANVAS) #define DOM_OBJECT_3D_CANVAS_TYPES(V) \ - V(CANVASACTIVEINFO, CanvasActiveInfo) \ - V(CANVASARRAY, CanvasArray) \ - V(CANVASARRAYBUFFER, CanvasArrayBuffer) \ - V(CANVASBUFFER, CanvasBuffer) \ - V(CANVASBYTEARRAY, CanvasByteArray) \ - V(CANVASFLOATARRAY, CanvasFloatArray) \ - V(CANVASFRAMEBUFFER, CanvasFramebuffer) \ - V(CANVASINTARRAY, CanvasIntArray) \ - V(CANVASPROGRAM, CanvasProgram) \ - V(CANVASRENDERBUFFER, CanvasRenderbuffer) \ - V(CANVASRENDERINGCONTEXT3D, CanvasRenderingContext3D) \ - V(CANVASSHADER, CanvasShader) \ - V(CANVASSHORTARRAY, CanvasShortArray) \ - V(CANVASTEXTURE, CanvasTexture) \ - V(CANVASUNSIGNEDBYTEARRAY, CanvasUnsignedByteArray) \ - V(CANVASUNSIGNEDINTARRAY, CanvasUnsignedIntArray) \ - V(CANVASUNSIGNEDSHORTARRAY, CanvasUnsignedShortArray) + V(WEBGLACTIVEINFO, WebGLActiveInfo) \ + V(WEBGLARRAY, WebGLArray) \ + V(WEBGLARRAYBUFFER, WebGLArrayBuffer) \ + V(WEBGLBUFFER, WebGLBuffer) \ + V(WEBGLBYTEARRAY, WebGLByteArray) \ + V(WEBGLFLOATARRAY, WebGLFloatArray) \ + V(WEBGLFRAMEBUFFER, WebGLFramebuffer) \ + V(WEBGLINTARRAY, WebGLIntArray) \ + V(WEBGLPROGRAM, WebGLProgram) \ + V(WEBGLRENDERBUFFER, WebGLRenderbuffer) \ + V(WEBGLRENDERINGCONTEXT, WebGLRenderingContext) \ + V(WEBGLSHADER, WebGLShader) \ + V(WEBGLSHORTARRAY, WebGLShortArray) \ + V(WEBGLTEXTURE, WebGLTexture) \ + V(WEBGLUNIFORMLOCATION, WebGLUniformLocation) \ + V(WEBGLUNSIGNEDBYTEARRAY, WebGLUnsignedByteArray) \ + V(WEBGLUNSIGNEDINTARRAY, WebGLUnsignedIntArray) \ + V(WEBGLUNSIGNEDSHORTARRAY, WebGLUnsignedShortArray) #else #define DOM_OBJECT_3D_CANVAS_TYPES(V) #endif @@ -486,7 +489,9 @@ typedef v8::Persistent<v8::FunctionTemplate> (*FunctionTemplateFactory)(); #if ENABLE(INSPECTOR) #define DOM_OBJECT_INSPECTOR_TYPES(V) \ - V(INSPECTORBACKEND, InspectorBackend) + V(INSPECTORBACKEND, InspectorBackend) \ + V(INSPECTORFRONTENDHOST, InspectorFrontendHost) \ + V(INJECTEDSCRIPTHOST, InjectedScriptHost) #else #define DOM_OBJECT_INSPECTOR_TYPES(V) #endif @@ -497,6 +502,7 @@ typedef v8::Persistent<v8::FunctionTemplate> (*FunctionTemplateFactory)(); V(GEOPOSITION, Geoposition) \ V(POSITIONERROR, PositionError) +<<<<<<< HEAD:WebCore/bindings/v8/V8Index.h #if PLATFORM(ANDROID) // TODO: Upstream this guard. #if ENABLE(TOUCH_EVENTS) @@ -518,6 +524,8 @@ typedef v8::Persistent<v8::FunctionTemplate> (*FunctionTemplateFactory)(); #if PLATFORM(ANDROID) // This block is modified, but is not Android-specific. +======= +>>>>>>> webkit.org at r51976:WebCore/bindings/v8/V8Index.h #define DOM_OBJECT_TYPES(V) \ DOM_OBJECT_TYPES_1(V) \ DOM_OBJECT_TYPES_2(V) \ @@ -528,10 +536,14 @@ typedef v8::Persistent<v8::FunctionTemplate> (*FunctionTemplateFactory)(); DOM_OBJECT_XPATH_TYPES(V) \ DOM_OBJECT_XSLT_TYPES(V) \ DOM_OBJECT_INSPECTOR_TYPES(V) \ +<<<<<<< HEAD:WebCore/bindings/v8/V8Index.h DOM_OBJECT_GEOLOCATION_TYPES(V) \ DOM_OBJECT_TOUCH_EVENT_TYPES(V) \ DOM_OBJECT_VOIDCALLBACK_TYPES(V) #endif +======= + DOM_OBJECT_GEOLOCATION_TYPES(V) +>>>>>>> webkit.org at r51976:WebCore/bindings/v8/V8Index.h #if ENABLE(SVG) // SVG_OBJECT_TYPES are svg non-node, non-pod types. diff --git a/WebCore/bindings/v8/V8IsolatedWorld.cpp b/WebCore/bindings/v8/V8IsolatedWorld.cpp index d4e4f52..cb65097 100644 --- a/WebCore/bindings/v8/V8IsolatedWorld.cpp +++ b/WebCore/bindings/v8/V8IsolatedWorld.cpp @@ -58,11 +58,13 @@ V8IsolatedWorld::V8IsolatedWorld(V8Proxy* proxy, int extensionGroup) v8::HandleScope scope; m_context = SharedPersistent<v8::Context>::create(proxy->createNewContext(v8::Handle<v8::Object>(), extensionGroup)); + if (m_context->get().IsEmpty()) + return; // Run code in the new context. v8::Context::Scope context_scope(m_context->get()); - m_context->get()->Global()->SetHiddenValue(V8HiddenPropertyName::isolatedWorld(), v8::External::Wrap(this)); + getGlobalObject(m_context->get())->SetPointerInInternalField(V8Custom::kDOMWindowEnteredIsolatedWorldIndex, this); V8Proxy::installHiddenObjectPrototype(m_context->get()); proxy->installDOMWindow(m_context->get(), proxy->frame()->domWindow()); @@ -89,17 +91,4 @@ V8IsolatedWorld::~V8IsolatedWorld() m_context->disposeHandle(); } -V8IsolatedWorld* V8IsolatedWorld::getEnteredImpl() -{ - if (!v8::Context::InContext()) - return 0; - v8::HandleScope scope; - - v8::Local<v8::Value> world = v8::Context::GetEntered()->Global()->GetHiddenValue(V8HiddenPropertyName::isolatedWorld()); - if (world.IsEmpty()) - return 0; - - return static_cast<V8IsolatedWorld*>(v8::External::Unwrap(world)); -} - } // namespace WebCore diff --git a/WebCore/bindings/v8/V8IsolatedWorld.h b/WebCore/bindings/v8/V8IsolatedWorld.h index 663f4bd..6313da8 100644 --- a/WebCore/bindings/v8/V8IsolatedWorld.h +++ b/WebCore/bindings/v8/V8IsolatedWorld.h @@ -61,6 +61,7 @@ namespace WebCore { // Creates an isolated world. To destroy it, call destroy(). // This will delete the isolated world when the context it owns is GC'd. V8IsolatedWorld(V8Proxy* proxy, int extensionGroup); + ~V8IsolatedWorld(); // Call this to destroy the isolated world. It will be deleted sometime // after this call, once all script references to the world's context @@ -84,7 +85,9 @@ namespace WebCore { // worlds at all. if (!isolatedWorldCount) return 0; - return getEnteredImpl(); + if (!v8::Context::InContext()) + return 0; + return reinterpret_cast<V8IsolatedWorld*>(getGlobalObject(v8::Context::GetEntered())->GetPointerFromInternalField(V8Custom::kDOMWindowEnteredIsolatedWorldIndex)); } v8::Handle<v8::Context> context() { return m_context->get(); } @@ -93,9 +96,10 @@ namespace WebCore { DOMDataStore* getDOMDataStore() const { return m_domDataStore.getStore(); } private: - ~V8IsolatedWorld(); - - static V8IsolatedWorld* getEnteredImpl(); + static v8::Handle<v8::Object> getGlobalObject(v8::Handle<v8::Context> context) + { + return v8::Handle<v8::Object>::Cast(context->Global()->GetPrototype()); + } // Called by the garbage collector when our JavaScript context is about // to be destroyed. diff --git a/WebCore/bindings/v8/V8LazyEventListener.cpp b/WebCore/bindings/v8/V8LazyEventListener.cpp index 54740a9..16b21d6 100644 --- a/WebCore/bindings/v8/V8LazyEventListener.cpp +++ b/WebCore/bindings/v8/V8LazyEventListener.cpp @@ -35,13 +35,14 @@ #include "V8Binding.h" #include "V8HiddenPropertyName.h" #include "V8Proxy.h" +#include "WorldContextHandle.h" #include <wtf/StdLibExtras.h> namespace WebCore { -V8LazyEventListener::V8LazyEventListener(const String& functionName, bool isSVGEvent, const String& code, const String sourceURL, int lineNumber, int columnNumber) - : V8AbstractEventListener(0, true) +V8LazyEventListener::V8LazyEventListener(const String& functionName, bool isSVGEvent, const String& code, const String sourceURL, int lineNumber, int columnNumber, const WorldContextHandle& worldContext) + : V8AbstractEventListener(true, worldContext) , m_functionName(functionName) , m_isSVGEvent(isSVGEvent) , m_code(code) @@ -83,7 +84,7 @@ void V8LazyEventListener::prepareListenerObject(ScriptExecutionContext* context) return; // Use the outer scope to hold context. - v8::Handle<v8::Context> v8Context = proxy->context(); + v8::Local<v8::Context> v8Context = worldContext().adjustedContext(proxy); // Bail out if we cannot get the context. if (v8Context.IsEmpty()) return; diff --git a/WebCore/bindings/v8/V8LazyEventListener.h b/WebCore/bindings/v8/V8LazyEventListener.h index 699460b..078dcf1 100644 --- a/WebCore/bindings/v8/V8LazyEventListener.h +++ b/WebCore/bindings/v8/V8LazyEventListener.h @@ -45,9 +45,9 @@ namespace WebCore { // A V8LazyEventListener is always a HTML event handler. class V8LazyEventListener : public V8AbstractEventListener { public: - static PassRefPtr<V8LazyEventListener> create(const String& functionName, bool isSVGEvent, const String& code, const String& sourceURL, int lineNumber, int columnNumber) + static PassRefPtr<V8LazyEventListener> create(const String& functionName, bool isSVGEvent, const String& code, const String& sourceURL, int lineNumber, int columnNumber, const WorldContextHandle& worldContext) { - return adoptRef(new V8LazyEventListener(functionName, isSVGEvent, code, sourceURL, lineNumber, columnNumber)); + return adoptRef(new V8LazyEventListener(functionName, isSVGEvent, code, sourceURL, lineNumber, columnNumber, worldContext)); } virtual bool isLazy() const { return true; } @@ -56,7 +56,7 @@ namespace WebCore { virtual void prepareListenerObject(ScriptExecutionContext*); private: - V8LazyEventListener(const String& functionName, bool isSVGEvent, const String& code, const String sourceURL, int lineNumber, int columnNumber); + V8LazyEventListener(const String& functionName, bool isSVGEvent, const String& code, const String sourceURL, int lineNumber, int columnNumber, const WorldContextHandle& worldContext); virtual v8::Local<v8::Value> callListenerFunction(ScriptExecutionContext*, v8::Handle<v8::Value> jsEvent, Event*); diff --git a/WebCore/bindings/v8/V8NPObject.cpp b/WebCore/bindings/v8/V8NPObject.cpp index 75163f1..bab3688 100644 --- a/WebCore/bindings/v8/V8NPObject.cpp +++ b/WebCore/bindings/v8/V8NPObject.cpp @@ -33,6 +33,7 @@ #include "V8NPObject.h" #include "HTMLPlugInElement.h" +#include "IdentifierRep.h" #include "NPV8Object.h" #include "V8CustomBinding.h" #include "V8DOMMap.h" @@ -44,7 +45,7 @@ #include "V8Proxy.h" #include "npruntime_impl.h" #include "npruntime_priv.h" -#include "wtf/OwnArrayPtr.h" +#include <wtf/OwnArrayPtr.h> using namespace WebCore; @@ -117,7 +118,7 @@ static v8::Handle<v8::Value> npObjectInvokeImpl(const v8::Arguments& args, Invok if (!retval) throwError("Error calling method on NPObject!", V8Proxy::GeneralError); - for (int i=0; i < numArgs; i++) + for (int i = 0; i < numArgs; i++) _NPN_ReleaseVariantValue(&npArgs[i]); // Unwrap return values. @@ -138,8 +139,8 @@ v8::Handle<v8::Value> npObjectInvokeDefaultHandler(const v8::Arguments& args) { if (args.IsConstructCall()) return npObjectInvokeImpl(args, InvokeConstruct); - else - return npObjectInvokeImpl(args, InvokeDefault); + + return npObjectInvokeImpl(args, InvokeDefault); } @@ -180,7 +181,9 @@ static v8::Handle<v8::Value> npObjectGetProperty(v8::Local<v8::Object> self, NPI _NPN_ReleaseVariantValue(&result); return returnValue; - } else if (key->IsString() && npObject->_class->hasMethod && npObject->_class->hasMethod(npObject, identifier)) { + } + + if (key->IsString() && npObject->_class->hasMethod && npObject->_class->hasMethod(npObject, identifier)) { PrivateIdentifier* id = static_cast<PrivateIdentifier*>(identifier); v8::Persistent<v8::FunctionTemplate> functionTemplate = staticTemplateMap.get(id); // Cache templates using identifier as the key. @@ -275,6 +278,44 @@ v8::Handle<v8::Value> npObjectSetIndexedProperty(v8::Local<v8::Object> self, uin return npObjectSetProperty(self, identifier, value); } +v8::Handle<v8::Array> npObjectPropertyEnumerator(const v8::AccessorInfo& info, bool namedProperty) +{ + NPObject* npObject = V8DOMWrapper::convertToNativeObject<NPObject>(V8ClassIndex::NPOBJECT, info.Holder()); + + // Verify that our wrapper wasn't using a NPObject which + // has already been deleted. + if (!npObject || !_NPN_IsAlive(npObject)) + throwError("NPObject deleted", V8Proxy::ReferenceError); + + if (NP_CLASS_STRUCT_VERSION_HAS_ENUM(npObject->_class) && npObject->_class->enumerate) { + uint32_t count; + NPIdentifier* identifiers; + if (npObject->_class->enumerate(npObject, &identifiers, &count)) { + v8::Handle<v8::Array> properties = v8::Array::New(count); + for (uint32_t i = 0; i < count; ++i) { + IdentifierRep* identifier = static_cast<IdentifierRep*>(identifiers[i]); + if (namedProperty) + properties->Set(v8::Integer::New(i), v8::String::New(identifier->string())); + else + properties->Set(v8::Integer::New(i), v8::Integer::New(identifier->number())); + } + + return properties; + } + } + + return v8::Handle<v8::Array>(); +} + +v8::Handle<v8::Array> npObjectNamedPropertyEnumerator(const v8::AccessorInfo& info) +{ + return npObjectPropertyEnumerator(info, true); +} + +v8::Handle<v8::Array> npObjectIndexedPropertyEnumerator(const v8::AccessorInfo& info) +{ + return npObjectPropertyEnumerator(info, false); +} static void weakNPObjectCallback(v8::Persistent<v8::Value>, void* parameter); @@ -317,8 +358,8 @@ v8::Local<v8::Object> createV8ObjectForNPObject(NPObject* object, NPObject* root if (npObjectDesc.IsEmpty()) { npObjectDesc = v8::Persistent<v8::FunctionTemplate>::New(v8::FunctionTemplate::New()); npObjectDesc->InstanceTemplate()->SetInternalFieldCount(V8Custom::kNPObjectInternalFieldCount); - npObjectDesc->InstanceTemplate()->SetNamedPropertyHandler(npObjectNamedPropertyGetter, npObjectNamedPropertySetter); - npObjectDesc->InstanceTemplate()->SetIndexedPropertyHandler(npObjectIndexedPropertyGetter, npObjectIndexedPropertySetter); + npObjectDesc->InstanceTemplate()->SetNamedPropertyHandler(npObjectNamedPropertyGetter, npObjectNamedPropertySetter, 0, 0, npObjectNamedPropertyEnumerator); + npObjectDesc->InstanceTemplate()->SetIndexedPropertyHandler(npObjectIndexedPropertyGetter, npObjectIndexedPropertySetter, 0, 0, npObjectIndexedPropertyEnumerator); npObjectDesc->InstanceTemplate()->SetCallAsFunctionHandler(npObjectInvokeDefaultHandler); } diff --git a/WebCore/bindings/v8/V8Proxy.cpp b/WebCore/bindings/v8/V8Proxy.cpp index 64424f3..c016d90 100644 --- a/WebCore/bindings/v8/V8Proxy.cpp +++ b/WebCore/bindings/v8/V8Proxy.cpp @@ -36,6 +36,7 @@ #include "DOMObjectsInclude.h" #include "DocumentLoader.h" #include "FrameLoaderClient.h" +#include "InspectorTimelineAgent.h" #include "Page.h" #include "PageGroup.h" #include "ScriptController.h" @@ -52,12 +53,14 @@ #include "WorkerContextExecutionProxy.h" #include <algorithm> +#include <stdio.h> #include <utility> #include <v8.h> #include <v8-debug.h> #include <wtf/Assertions.h> #include <wtf/OwnArrayPtr.h> #include <wtf/StdLibExtras.h> +#include <wtf/StringExtras.h> #include <wtf/UnusedParam.h> #if PLATFORM(CHROMIUM) @@ -79,16 +82,34 @@ v8::Persistent<v8::Context> V8Proxy::m_utilityContext; // Static list of registered extensions V8Extensions V8Proxy::m_extensions; -const char* V8Proxy::kContextDebugDataType = "type"; -const char* V8Proxy::kContextDebugDataValue = "value"; - -void batchConfigureAttributes(v8::Handle<v8::ObjectTemplate> instance, v8::Handle<v8::ObjectTemplate> proto, const BatchedAttribute* attributes, size_t attributeCount) +void batchConfigureAttributes(v8::Handle<v8::ObjectTemplate> instance, + v8::Handle<v8::ObjectTemplate> proto, + const BatchedAttribute* attributes, + size_t attributeCount) { for (size_t i = 0; i < attributeCount; ++i) configureAttribute(instance, proto, attributes[i]); } -void batchConfigureConstants(v8::Handle<v8::FunctionTemplate> functionDescriptor, v8::Handle<v8::ObjectTemplate> proto, const BatchedConstant* constants, size_t constantCount) +void batchConfigureCallbacks(v8::Handle<v8::ObjectTemplate> proto, + v8::Handle<v8::Signature> signature, + v8::PropertyAttribute attributes, + const BatchedCallback* callbacks, + size_t callbackCount) +{ + for (size_t i = 0; i < callbackCount; ++i) { + proto->Set(v8::String::New(callbacks[i].name), + v8::FunctionTemplate::New(callbacks[i].callback, + v8::Handle<v8::Value>(), + signature), + attributes); + } +} + +void batchConfigureConstants(v8::Handle<v8::FunctionTemplate> functionDescriptor, + v8::Handle<v8::ObjectTemplate> proto, + const BatchedConstant* constants, + size_t constantCount) { for (size_t i = 0; i < constantCount; ++i) { const BatchedConstant* constant = &constants[i]; @@ -218,7 +239,6 @@ static void reportFatalErrorInV8(const char* location, const char* message) V8Proxy::V8Proxy(Frame* frame) : m_frame(frame) - , m_listenerGuard(V8ListenerGuard::create()) , m_inlineCode(false) , m_timerCallback(false) , m_recursion(0) @@ -306,13 +326,26 @@ void V8Proxy::evaluateInIsolatedWorld(int worldID, const Vector<ScriptSourceCode world = iter->second; } else { world = new V8IsolatedWorld(this, extensionGroup); + if (world->context().IsEmpty()) { + delete world; + return; + } + m_isolatedWorlds.set(worldID, world); // Setup context id for JS debugger. - setInjectedScriptContextDebugId(world->context()); + if (!setInjectedScriptContextDebugId(world->context())) { + m_isolatedWorlds.take(worldID); + delete world; + return; + } } } else { world = new V8IsolatedWorld(this, extensionGroup); + if (world->context().IsEmpty()) { + delete world; + return; + } } v8::Local<v8::Context> context = v8::Local<v8::Context>::New(world->context()); @@ -338,10 +371,16 @@ void V8Proxy::evaluateInNewContext(const Vector<ScriptSourceCode>& sources, int ASSERT(V8DOMWrapper::convertDOMWrapperToNative<DOMWindow>(windowWrapper) == m_frame->domWindow()); v8::Persistent<v8::Context> context = createNewContext(v8::Handle<v8::Object>(), extensionGroup); + if (context.IsEmpty()) + return; + v8::Context::Scope contextScope(context); // Setup context id for JS debugger. - setInjectedScriptContextDebugId(context); + if (!setInjectedScriptContextDebugId(context)) { + context.Dispose(); + return; + } v8::Handle<v8::Object> global = context->Global(); @@ -367,25 +406,35 @@ void V8Proxy::evaluateInNewContext(const Vector<ScriptSourceCode>& sources, int context.Dispose(); } -void V8Proxy::setInjectedScriptContextDebugId(v8::Handle<v8::Context> targetContext) +bool V8Proxy::setInjectedScriptContextDebugId(v8::Handle<v8::Context> targetContext) { // Setup context id for JS debugger. v8::Context::Scope contextScope(targetContext); - v8::Handle<v8::Object> contextData = v8::Object::New(); + if (m_context.IsEmpty()) + return false; + int debugId = contextDebugId(m_context); - v8::Handle<v8::Value> windowContextData = m_context->GetData(); - if (windowContextData->IsObject()) { - v8::Handle<v8::String> propertyName = v8::String::New(kContextDebugDataValue); - contextData->Set(propertyName, v8::Object::Cast(*windowContextData)->Get(propertyName)); - } - contextData->Set(v8::String::New(kContextDebugDataType), v8::String::New("injected")); - targetContext->SetData(contextData); + char buffer[32]; + if (debugId == -1) + snprintf(buffer, sizeof(buffer), "injected"); + else + snprintf(buffer, sizeof(buffer), "injected,%d", debugId); + targetContext->SetData(v8::String::New(buffer)); + + return true; } v8::Local<v8::Value> V8Proxy::evaluate(const ScriptSourceCode& source, Node* node) { ASSERT(v8::Context::InContext()); + V8GCController::checkMemoryUsage(); + +#if ENABLE(INSPECTOR) + if (InspectorTimelineAgent* timelineAgent = m_frame->page() ? m_frame->page()->inspectorTimelineAgent() : 0) + timelineAgent->willEvaluateScript(source.url().isNull() ? String() : source.url().string(), source.startLine()); +#endif + v8::Local<v8::Value> result; { // Isolate exceptions that occur when compiling and executing @@ -419,7 +468,18 @@ v8::Local<v8::Value> V8Proxy::evaluate(const ScriptSourceCode& source, Node* nod #if PLATFORM(CHROMIUM) // TODO(andreip): ChromeBridge->BrowserBridge? ChromiumBridge::traceEventEnd("v8.run", node, ""); +<<<<<<< HEAD:WebCore/bindings/v8/V8Proxy.cpp +======= + +#if ENABLE(INSPECTOR) + if (InspectorTimelineAgent* timelineAgent = m_frame->page() ? m_frame->page()->inspectorTimelineAgent() : 0) + timelineAgent->didEvaluateScript(); +>>>>>>> webkit.org at r51976:WebCore/bindings/v8/V8Proxy.cpp #endif +<<<<<<< HEAD:WebCore/bindings/v8/V8Proxy.cpp +======= + +>>>>>>> webkit.org at r51976:WebCore/bindings/v8/V8Proxy.cpp return result; } @@ -438,6 +498,7 @@ v8::Local<v8::Value> V8Proxy::runScriptInternal(v8::Handle<v8::Script> script, b if (script.IsEmpty()) return notHandledByInterceptor(); + V8GCController::checkMemoryUsage(); // Compute the source string and prevent against infinite recursion. if (m_recursion >= kMaxRecursionDepth) { v8::Local<v8::String> code = v8ExternalString("throw RangeError('Recursion too deep')"); @@ -492,9 +553,13 @@ v8::Local<v8::Value> V8Proxy::runScriptInternal(v8::Handle<v8::Script> script, b v8::Local<v8::Value> V8Proxy::callFunction(v8::Handle<v8::Function> function, v8::Handle<v8::Object> receiver, int argc, v8::Handle<v8::Value> args[]) { +<<<<<<< HEAD:WebCore/bindings/v8/V8Proxy.cpp #ifdef ANDROID_INSTRUMENT android::TimeCounter::start(android::TimeCounter::JavaScriptExecuteTimeCounter); #endif +======= + V8GCController::checkMemoryUsage(); +>>>>>>> webkit.org at r51976:WebCore/bindings/v8/V8Proxy.cpp v8::Local<v8::Value> result; { V8ConsoleMessage::Scope scope; @@ -646,6 +711,7 @@ V8Proxy* V8Proxy::retrieve(ScriptExecutionContext* context) void V8Proxy::disconnectFrame() { +<<<<<<< HEAD:WebCore/bindings/v8/V8Proxy.cpp disconnectEventListeners(); } @@ -700,6 +766,8 @@ bool V8Proxy::isEnabled() } return false; // Other protocols fall through to here +======= +>>>>>>> webkit.org at r51976:WebCore/bindings/v8/V8Proxy.cpp } void V8Proxy::updateDocumentWrapper(v8::Handle<v8::Value> wrapper) @@ -789,12 +857,6 @@ void V8Proxy::releaseStorageMutex() page->group().localStorage()->unlock(); } -void V8Proxy::disconnectEventListeners() -{ - m_listenerGuard->disconnectListeners(); - m_listenerGuard = V8ListenerGuard::create(); -} - void V8Proxy::resetIsolatedWorlds() { for (IsolatedWorldMap::iterator iter = m_isolatedWorlds.begin(); @@ -818,7 +880,6 @@ void V8Proxy::clearForClose() void V8Proxy::clearForNavigation() { - disconnectEventListeners(); resetIsolatedWorlds(); if (!m_context.IsEmpty()) { @@ -942,14 +1003,20 @@ bool V8Proxy::canAccessPrivate(DOMWindow* targetWindow) String message; - DOMWindow* originWindow = retrieveWindow(currentContext()); - if (originWindow == targetWindow) + v8::Local<v8::Context> activeContext = v8::Context::GetCalling(); + if (activeContext.IsEmpty()) { + // There is a single activation record on the stack, so that must + // be the activeContext. + activeContext = v8::Context::GetCurrent(); + } + DOMWindow* activeWindow = retrieveWindow(activeContext); + if (activeWindow == targetWindow) return true; - if (!originWindow) + if (!activeWindow) return false; - const SecurityOrigin* activeSecurityOrigin = originWindow->securityOrigin(); + const SecurityOrigin* activeSecurityOrigin = activeWindow->securityOrigin(); const SecurityOrigin* targetSecurityOrigin = targetWindow->securityOrigin(); // We have seen crashes were the security origin of the target has not been @@ -962,7 +1029,7 @@ bool V8Proxy::canAccessPrivate(DOMWindow* targetWindow) // Allow access to a "about:blank" page if the dynamic context is a // detached context of the same frame as the blank page. - if (targetSecurityOrigin->isEmpty() && originWindow->frame() == targetWindow->frame()) + if (targetSecurityOrigin->isEmpty() && activeWindow->frame() == targetWindow->frame()) return true; return false; @@ -1171,10 +1238,17 @@ void V8Proxy::initContextIfNeeded() setSecurityToken(); m_frame->loader()->client()->didCreateScriptContextForFrame(); +<<<<<<< HEAD:WebCore/bindings/v8/V8Proxy.cpp m_frame->loader()->dispatchWindowObjectAvailable(); #ifdef ANDROID_INSTRUMENT android::TimeCounter::record(android::TimeCounter::JavaScriptInitTimeCounter, __FUNCTION__); #endif +======= + + // FIXME: This is wrong. We should actually do this for the proper world once + // we do isolated worlds the WebCore way. + m_frame->loader()->dispatchDidClearWindowObjectInWorld(0); +>>>>>>> webkit.org at r51976:WebCore/bindings/v8/V8Proxy.cpp } void V8Proxy::setDOMException(int exceptionCode) @@ -1257,8 +1331,13 @@ v8::Local<v8::Context> V8Proxy::context() return v8::Local<v8::Context>(); return v8::Local<v8::Context>::New(context->get()); } + return mainWorldContext(); +} + +v8::Local<v8::Context> V8Proxy::mainWorldContext() +{ initContextIfNeeded(); - return v8::Local<v8::Context>::New(m_context);; + return v8::Local<v8::Context>::New(m_context); } v8::Local<v8::Context> V8Proxy::mainWorldContext(Frame* frame) @@ -1267,8 +1346,7 @@ v8::Local<v8::Context> V8Proxy::mainWorldContext(Frame* frame) if (!proxy) return v8::Local<v8::Context>(); - proxy->initContextIfNeeded(); - return v8::Local<v8::Context>::New(proxy->m_context); + return proxy->mainWorldContext(); } v8::Local<v8::Context> V8Proxy::currentContext() @@ -1337,7 +1415,7 @@ void V8Proxy::createUtilityContext() v8::Script::Compile(v8::String::New(frameSourceNameSource))->Run(); } -int V8Proxy::sourceLineNumber() +bool V8Proxy::sourceLineNumber(int& result) { #if PLATFORM(ANDROID) // TODO(andreip): consider V8's DEBUG flag here, rather than PLATFORM(ANDROID) @@ -1347,20 +1425,29 @@ int V8Proxy::sourceLineNumber() v8::HandleScope scope; v8::Handle<v8::Context> v8UtilityContext = V8Proxy::utilityContext(); if (v8UtilityContext.IsEmpty()) - return 0; + return false; v8::Context::Scope contextScope(v8UtilityContext); v8::Handle<v8::Function> frameSourceLine; frameSourceLine = v8::Local<v8::Function>::Cast(v8UtilityContext->Global()->Get(v8::String::New("frameSourceLine"))); if (frameSourceLine.IsEmpty()) +<<<<<<< HEAD:WebCore/bindings/v8/V8Proxy.cpp return 0; v8::Handle<v8::Value> result = v8::Debug::Call(frameSourceLine); if (result.IsEmpty()) return 0; return result->Int32Value(); #endif +======= + return false; + v8::Handle<v8::Value> value = v8::Debug::Call(frameSourceLine); + if (value.IsEmpty()) + return false; + result = value->Int32Value(); + return true; +>>>>>>> webkit.org at r51976:WebCore/bindings/v8/V8Proxy.cpp } -String V8Proxy::sourceName() +bool V8Proxy::sourceName(String& result) { #if PLATFORM(ANDROID) return String(); @@ -1368,14 +1455,23 @@ String V8Proxy::sourceName() v8::HandleScope scope; v8::Handle<v8::Context> v8UtilityContext = utilityContext(); if (v8UtilityContext.IsEmpty()) - return String(); + return false; v8::Context::Scope contextScope(v8UtilityContext); v8::Handle<v8::Function> frameSourceName; frameSourceName = v8::Local<v8::Function>::Cast(v8UtilityContext->Global()->Get(v8::String::New("frameSourceName"))); if (frameSourceName.IsEmpty()) +<<<<<<< HEAD:WebCore/bindings/v8/V8Proxy.cpp return String(); return toWebCoreString(v8::Debug::Call(frameSourceName)); #endif +======= + return false; + v8::Handle<v8::Value> value = v8::Debug::Call(frameSourceName); + if (value.IsEmpty()) + return false; + result = toWebCoreString(value); + return true; +>>>>>>> webkit.org at r51976:WebCore/bindings/v8/V8Proxy.cpp } void V8Proxy::registerExtensionWithV8(v8::Extension* extension) @@ -1419,20 +1515,24 @@ bool V8Proxy::setContextDebugId(int debugId) return false; v8::Context::Scope contextScope(m_context); - v8::Handle<v8::Object> contextData = v8::Object::New(); - contextData->Set(v8::String::New(kContextDebugDataType), v8::String::New("page")); - contextData->Set(v8::String::New(kContextDebugDataValue), v8::Integer::New(debugId)); - m_context->SetData(contextData); + + char buffer[32]; + snprintf(buffer, sizeof(buffer), "page,%d", debugId); + m_context->SetData(v8::String::New(buffer)); + return true; } int V8Proxy::contextDebugId(v8::Handle<v8::Context> context) { v8::HandleScope scope; - if (!context->GetData()->IsObject()) + if (!context->GetData()->IsString()) return -1; - v8::Handle<v8::Value> data = context->GetData()->ToObject()->Get( v8::String::New(kContextDebugDataValue)); - return data->IsInt32() ? data->Int32Value() : -1; + v8::String::AsciiValue ascii(context->GetData()); + char* comma = strnstr(*ascii, ",", ascii.length()); + if (!comma) + return -1; + return atoi(comma + 1); } v8::Handle<v8::Value> V8Proxy::getHiddenObjectPrototype(v8::Handle<v8::Context> context) @@ -1455,11 +1555,11 @@ void V8Proxy::installHiddenObjectPrototype(v8::Handle<v8::Context> context) context->Global()->SetHiddenValue(hiddenObjectPrototypeString, objectPrototype); } -v8::Local<v8::Context> toV8Context(ScriptExecutionContext* context) +v8::Local<v8::Context> toV8Context(ScriptExecutionContext* context, const WorldContextHandle& worldContext) { if (context->isDocument()) { if (V8Proxy* proxy = V8Proxy::retrieve(context)) - return proxy->context(); + return worldContext.adjustedContext(proxy); } else if (context->isWorkerContext()) { if (WorkerContextExecutionProxy* proxy = static_cast<WorkerContext*>(context)->script()->proxy()) return proxy->context(); diff --git a/WebCore/bindings/v8/V8Proxy.h b/WebCore/bindings/v8/V8Proxy.h index 86d3b39..900ee18 100644 --- a/WebCore/bindings/v8/V8Proxy.h +++ b/WebCore/bindings/v8/V8Proxy.h @@ -59,6 +59,7 @@ namespace WebCore { class String; class V8EventListener; class V8IsolatedWorld; + class WorldContextHandle; // FIXME: use standard logging facilities in WebCore. void logInfo(Frame*, const String& message, const String& url); @@ -102,6 +103,17 @@ namespace WebCore { void batchConfigureConstants(v8::Handle<v8::FunctionTemplate>, v8::Handle<v8::ObjectTemplate>, const BatchedConstant*, size_t constantCount); + struct BatchedCallback { + const char* const name; + v8::InvocationCallback callback; + }; + + void batchConfigureCallbacks(v8::Handle<v8::ObjectTemplate>, + v8::Handle<v8::Signature>, + v8::PropertyAttribute, + const BatchedCallback*, + size_t callbackCount); + const int kMaxRecursionDepth = 20; // Information about an extension that is registered for use with V8. If @@ -163,11 +175,36 @@ namespace WebCore { // and clears all timeouts on the DOM window. void disconnectFrame(); - bool isEnabled(); - #if ENABLE(SVG) static void setSVGContext(void*, SVGElement*); static SVGElement* svgContext(void*); + + // These helper functions are required in case we are given a PassRefPtr + // to a (possibly) newly created object and must prevent its reference + // count from dropping to zero as would happen in code like + // + // V8Proxy::setSVGContext(imp->getNewlyCreatedObject().get(), context); + // foo(imp->getNewlyCreatedObject().get()); + // + // In the above two lines each time getNewlyCreatedObject() is called it + // creates a new object because we don't ref() it. (So our attemts to + // associate a context with it fail.) Such code should be rewritten to + // + // foo(V8Proxy::withSVGContext(imp->getNewlyCreatedObject(), context).get()); + // + // where PassRefPtr::~PassRefPtr() is invoked only after foo() is + // called. + template <typename T> + static PassRefPtr<T> withSVGContext(PassRefPtr<T> object, SVGElement* context) + { + setSVGContext(object.get(), context); + return object; + } + static void* withSVGContext(void* object, SVGElement* context) + { + setSVGContext(object, context); + return object; + } #endif void setEventHandlerLineNumber(int lineNumber) { m_handlerLineNumber = lineNumber; } @@ -302,15 +339,16 @@ namespace WebCore { // Function for retrieving the line number and source name for the top // JavaScript stack frame. - static int sourceLineNumber(); - static String sourceName(); + // + // It will return true if the line number was successfully retrieved and written + // into the |result| parameter, otherwise the function will return false. It may + // fail due to a stck overflow in the underlying JavaScript implentation, handling + // of such exception is up to the caller. + static bool sourceLineNumber(int& result); + static bool sourceName(String& result); v8::Local<v8::Context> context(); - - PassRefPtr<V8ListenerGuard> listenerGuard() - { - return m_listenerGuard; - } + v8::Local<v8::Context> mainWorldContext(); bool setContextDebugId(int id); static int contextDebugId(v8::Handle<v8::Context>); @@ -337,9 +375,6 @@ namespace WebCore { void updateDocumentWrapper(v8::Handle<v8::Value> wrapper); private: - static const char* kContextDebugDataType; - static const char* kContextDebugDataValue; - void setSecurityToken(); void clearDocumentWrapper(); @@ -357,11 +392,10 @@ namespace WebCore { // the storage mutex. void releaseStorageMutex(); - void disconnectEventListeners(); - void resetIsolatedWorlds(); - void setInjectedScriptContextDebugId(v8::Handle<v8::Context> targetContext); + // Returns false when we're out of memory in V8. + bool setInjectedScriptContextDebugId(v8::Handle<v8::Context> targetContext); static bool canAccessPrivate(DOMWindow*); @@ -397,8 +431,6 @@ namespace WebCore { v8::Persistent<v8::Context> m_context; - RefPtr<V8ListenerGuard> m_listenerGuard; - // For each possible type of wrapper, we keep a boilerplate object. // The boilerplate is used to create additional wrappers of the same // type. We keep a single persistent handle to an array of the @@ -456,7 +488,7 @@ namespace WebCore { } - v8::Local<v8::Context> toV8Context(ScriptExecutionContext*); + v8::Local<v8::Context> toV8Context(ScriptExecutionContext*, const WorldContextHandle& worldContext); // Used by an interceptor callback that it hasn't found anything to // intercept. diff --git a/WebCore/bindings/v8/V8Utilities.cpp b/WebCore/bindings/v8/V8Utilities.cpp index ecac358..c547cc7 100644 --- a/WebCore/bindings/v8/V8Utilities.cpp +++ b/WebCore/bindings/v8/V8Utilities.cpp @@ -76,6 +76,24 @@ void removeHiddenDependency(v8::Handle<v8::Object> object, v8::Local<v8::Value> } } } + +void transferHiddenDependency(v8::Handle<v8::Object> object, + EventListener* oldValue, + v8::Local<v8::Value> newValue, + int cacheIndex) +{ + if (oldValue) { + V8AbstractEventListener* oldListener = V8AbstractEventListener::cast(oldValue); + if (oldListener) { + v8::Local<v8::Object> oldListenerObject = oldListener->getExistingListenerObject(); + if (!oldListenerObject.IsEmpty()) + removeHiddenDependency(object, oldListenerObject, cacheIndex); + } + } + if (!newValue->IsNull() && !newValue->IsUndefined()) + createHiddenDependency(object, newValue, cacheIndex); +} + bool processingUserGesture() { @@ -147,7 +165,12 @@ void reportException(ScriptState* scriptState, v8::TryCatch& exceptionCatcher) sourceURL = toWebCoreString(message->GetScriptResourceName()); } - getScriptExecutionContext(scriptState)->reportException(errorMessage, lineNumber, sourceURL); + // Do not report the exception if the current execution context is Document because we do not want to lead to duplicate error messages in the console. + // FIXME (31171): need better design to solve the duplicate error message reporting problem. + ScriptExecutionContext* context = getScriptExecutionContext(scriptState); + // During the frame teardown, there may not be a valid context. + if (context && !context->isDocument()) + context->reportException(errorMessage, lineNumber, sourceURL); exceptionCatcher.Reset(); } diff --git a/WebCore/bindings/v8/V8Utilities.h b/WebCore/bindings/v8/V8Utilities.h index 36dce24..944823a 100644 --- a/WebCore/bindings/v8/V8Utilities.h +++ b/WebCore/bindings/v8/V8Utilities.h @@ -35,6 +35,7 @@ namespace WebCore { + class EventListener; class Frame; class KURL; class ScriptExecutionContext; @@ -44,7 +45,10 @@ namespace WebCore { // Use an array to hold dependents. It works like a ref-counted scheme. A value can be added more than once to the DOM object. void createHiddenDependency(v8::Handle<v8::Object>, v8::Local<v8::Value>, int cacheIndex); void removeHiddenDependency(v8::Handle<v8::Object>, v8::Local<v8::Value>, int cacheIndex); - + + // Combo create/remove, for generated event-handler-setter bindings: + void transferHiddenDependency(v8::Handle<v8::Object>, EventListener* oldValue, v8::Local<v8::Value> newValue, int cacheIndex); + bool processingUserGesture(); bool shouldAllowNavigation(Frame*); KURL completeURL(const String& relativeURL); diff --git a/WebCore/bindings/v8/V8WorkerContextEventListener.cpp b/WebCore/bindings/v8/V8WorkerContextEventListener.cpp index 8dc4b8d..e5356de 100644 --- a/WebCore/bindings/v8/V8WorkerContextEventListener.cpp +++ b/WebCore/bindings/v8/V8WorkerContextEventListener.cpp @@ -48,15 +48,14 @@ static WorkerContextExecutionProxy* workerProxy(ScriptExecutionContext* context) return workerContext->script()->proxy(); } -V8WorkerContextEventListener::V8WorkerContextEventListener(PassRefPtr<V8ListenerGuard> guard, v8::Local<v8::Object> listener, bool isInline) - : V8EventListener(guard, listener, isInline) +V8WorkerContextEventListener::V8WorkerContextEventListener(v8::Local<v8::Object> listener, bool isInline, const WorldContextHandle& worldContext) + : V8EventListener(listener, isInline, worldContext) { } void V8WorkerContextEventListener::handleEvent(ScriptExecutionContext* context, Event* event) { - // Is the EventListener disconnected? - if (disconnected()) + if (!context) return; // The callback function on XMLHttpRequest can clear the event listener and destroys 'this' object. Keep a local reference to it. @@ -84,8 +83,7 @@ void V8WorkerContextEventListener::handleEvent(ScriptExecutionContext* context, bool V8WorkerContextEventListener::reportError(ScriptExecutionContext* context, const String& message, const String& url, int lineNumber) { - // Is the EventListener disconnected? - if (disconnected()) + if (!context) return false; // The callback function can clear the event listener and destroy 'this' object. Keep a local reference to it. diff --git a/WebCore/bindings/v8/V8WorkerContextEventListener.h b/WebCore/bindings/v8/V8WorkerContextEventListener.h index 3f9f862..4487497 100644 --- a/WebCore/bindings/v8/V8WorkerContextEventListener.h +++ b/WebCore/bindings/v8/V8WorkerContextEventListener.h @@ -44,16 +44,16 @@ namespace WebCore { class V8WorkerContextEventListener : public V8EventListener { public: - static PassRefPtr<V8WorkerContextEventListener> create(PassRefPtr<V8ListenerGuard> guard, v8::Local<v8::Object> listener, bool isInline) + static PassRefPtr<V8WorkerContextEventListener> create(v8::Local<v8::Object> listener, bool isInline, const WorldContextHandle& worldContext) { - return adoptRef(new V8WorkerContextEventListener(guard, listener, isInline)); + return adoptRef(new V8WorkerContextEventListener(listener, isInline, worldContext)); } virtual void handleEvent(ScriptExecutionContext*, Event*); virtual bool reportError(ScriptExecutionContext*, const String& message, const String& url, int lineNumber); private: - V8WorkerContextEventListener(PassRefPtr<V8ListenerGuard>, v8::Local<v8::Object> listener, bool isInline); + V8WorkerContextEventListener(v8::Local<v8::Object> listener, bool isInline, const WorldContextHandle& worldContext); virtual v8::Local<v8::Value> callListenerFunction(ScriptExecutionContext*, v8::Handle<v8::Value> jsEvent, Event*); v8::Local<v8::Object> getReceiverObject(ScriptExecutionContext*, Event*); diff --git a/WebCore/bindings/v8/WorkerContextExecutionProxy.cpp b/WebCore/bindings/v8/WorkerContextExecutionProxy.cpp index 0fd0f8f..8c66d7b 100644 --- a/WebCore/bindings/v8/WorkerContextExecutionProxy.cpp +++ b/WebCore/bindings/v8/WorkerContextExecutionProxy.cpp @@ -72,7 +72,6 @@ static void reportFatalErrorInV8(const char* location, const char* message) WorkerContextExecutionProxy::WorkerContextExecutionProxy(WorkerContext* workerContext) : m_workerContext(workerContext) , m_recursion(0) - , m_listenerGuard(V8ListenerGuard::create()) { initV8IfNeeded(); } @@ -84,8 +83,6 @@ WorkerContextExecutionProxy::~WorkerContextExecutionProxy() void WorkerContextExecutionProxy::dispose() { - m_listenerGuard->disconnectListeners(); - // Detach all events from their JS wrappers. for (size_t eventIndex = 0; eventIndex < m_events.size(); ++eventIndex) { Event* event = m_events[eventIndex]; @@ -158,7 +155,12 @@ void WorkerContextExecutionProxy::initContextIfNeeded() v8::Handle<v8::String> implicitProtoString = v8::String::New("__proto__"); // Create a new JS object and use it as the prototype for the shadow global object. - v8::Handle<v8::Function> workerContextConstructor = V8DOMWrapper::getConstructorForContext(V8ClassIndex::DEDICATEDWORKERCONTEXT, context); + V8ClassIndex::V8WrapperType contextType = V8ClassIndex::DEDICATEDWORKERCONTEXT; +#if ENABLE(SHARED_WORKERS) + if (!m_workerContext->isDedicatedWorkerContext()) + contextType = V8ClassIndex::SHAREDWORKERCONTEXT; +#endif + v8::Handle<v8::Function> workerContextConstructor = V8DOMWrapper::getConstructorForContext(contextType, context); v8::Local<v8::Object> jsWorkerContext = SafeAllocation::newInstance(workerContextConstructor); // Bail out if allocation failed. if (jsWorkerContext.IsEmpty()) { @@ -167,7 +169,7 @@ void WorkerContextExecutionProxy::initContextIfNeeded() } // Wrap the object. - V8DOMWrapper::setDOMWrapper(jsWorkerContext, V8ClassIndex::ToInt(V8ClassIndex::DEDICATEDWORKERCONTEXT), m_workerContext); + V8DOMWrapper::setDOMWrapper(jsWorkerContext, V8ClassIndex::ToInt(contextType), m_workerContext); V8DOMWrapper::setJSWrapperForDOMObject(m_workerContext, v8::Persistent<v8::Object>::New(jsWorkerContext)); m_workerContext->ref(); @@ -182,7 +184,11 @@ v8::Handle<v8::Value> WorkerContextExecutionProxy::convertToV8Object(V8ClassInde if (!impl) return v8::Null(); - if (type == V8ClassIndex::DEDICATEDWORKERCONTEXT) + if (type == V8ClassIndex::DEDICATEDWORKERCONTEXT +#if ENABLE(SHARED_WORKERS) + || type == V8ClassIndex::SHAREDWORKERCONTEXT +#endif + ) return convertWorkerContextToV8Object(static_cast<WorkerContext*>(impl)); bool isActiveDomObject = false; @@ -294,10 +300,22 @@ v8::Handle<v8::Value> WorkerContextExecutionProxy::convertEventTargetToV8Object( if (workerContext) return convertWorkerContextToV8Object(workerContext); +#if ENABLE(SHARED_WORKERS) + SharedWorkerContext* sharedWorkerContext = target->toSharedWorkerContext(); + if (sharedWorkerContext) + return convertWorkerContextToV8Object(sharedWorkerContext); +#endif + Worker* worker = target->toWorker(); if (worker) return convertToV8Object(V8ClassIndex::WORKER, worker); +#if ENABLE(SHARED_WORKERS) + SharedWorker* sharedWorker = target->toSharedWorker(); + if (sharedWorker) + return convertToV8Object(V8ClassIndex::SHAREDWORKER, sharedWorker); +#endif + XMLHttpRequest* xhr = target->toXMLHttpRequest(); if (xhr) return convertToV8Object(V8ClassIndex::XMLHTTPREQUEST, xhr); @@ -411,7 +429,7 @@ v8::Local<v8::Value> WorkerContextExecutionProxy::runScript(v8::Handle<v8::Scrip PassRefPtr<V8EventListener> WorkerContextExecutionProxy::findOrCreateEventListener(v8::Local<v8::Value> object, bool isInline, bool findOnly) { - return findOnly ? V8EventListenerList::findWrapper(object, isInline) : V8EventListenerList::findOrCreateWrapper<V8WorkerContextEventListener>(m_listenerGuard, object, isInline); + return findOnly ? V8EventListenerList::findWrapper(object, isInline) : V8EventListenerList::findOrCreateWrapper<V8WorkerContextEventListener>(object, isInline); } void WorkerContextExecutionProxy::trackEvent(Event* event) diff --git a/WebCore/bindings/v8/WorkerContextExecutionProxy.h b/WebCore/bindings/v8/WorkerContextExecutionProxy.h index e723bc6..3b8ab9e 100644 --- a/WebCore/bindings/v8/WorkerContextExecutionProxy.h +++ b/WebCore/bindings/v8/WorkerContextExecutionProxy.h @@ -112,7 +112,6 @@ namespace WebCore { WorkerContext* m_workerContext; v8::Persistent<v8::Context> m_context; int m_recursion; - RefPtr<V8ListenerGuard> m_listenerGuard; Vector<Event*> m_events; }; diff --git a/WebCore/bindings/js/ScriptObjectQuarantine.h b/WebCore/bindings/v8/WorldContextHandle.cpp index df52379..eb83586 100644 --- a/WebCore/bindings/js/ScriptObjectQuarantine.h +++ b/WebCore/bindings/v8/WorldContextHandle.cpp @@ -28,31 +28,30 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef ScriptObjectQuarantine_h -#define ScriptObjectQuarantine_h +#include "config.h" +#include "WorldContextHandle.h" -#include "ScriptState.h" +#include "V8IsolatedWorld.h" namespace WebCore { - class Database; - class DOMWindow; - class Node; - class ScriptObject; - class ScriptValue; - class Storage; +WorldContextHandle::WorldContextHandle(WorldToUse worldToUse) + : m_worldToUse(worldToUse) +{ + if (worldToUse == UseMainWorld) + return; - ScriptValue quarantineValue(ScriptState*, const ScriptValue&); - -#if ENABLE(DATABASE) - bool getQuarantinedScriptObject(Database* database, ScriptObject& quarantinedObject); -#endif -#if ENABLE(DOM_STORAGE) - bool getQuarantinedScriptObject(Storage* storage, ScriptObject& quarantinedObject); -#endif - bool getQuarantinedScriptObject(Node* node, ScriptObject& quarantinedObject); - bool getQuarantinedScriptObject(DOMWindow* domWindow, ScriptObject& quarantinedObject); + if (V8IsolatedWorld* world = V8IsolatedWorld::getEntered()) + m_context = world->sharedContext(); +} +v8::Local<v8::Context> WorldContextHandle::adjustedContext(V8Proxy* proxy) const +{ + if (m_worldToUse == UseMainWorld) + return proxy->mainWorldContext(); + if (!m_context || m_context->get().IsEmpty()) + return proxy->context(); + return v8::Local<v8::Context>::New(m_context->get()); } -#endif // ScriptObjectQuarantine_h +} // namespace WebCore diff --git a/WebCore/bindings/v8/ScriptObjectQuarantine.h b/WebCore/bindings/v8/WorldContextHandle.h index 712dd9b..ad0983e 100644 --- a/WebCore/bindings/v8/ScriptObjectQuarantine.h +++ b/WebCore/bindings/v8/WorldContextHandle.h @@ -28,32 +28,30 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -// ScriptObjectQuarantine is used in JSC for wrapping DOM objects of the page -// before they are passed to Inspector's front-end. The wrapping prevents -// malicious scripts from gaining privileges. For V8, we are currently just -// passing the object itself, without any wrapping. +#ifndef WorldContextHandle_h +#define WorldContextHandle_h -#ifndef ScriptObjectQuarantine_h -#define ScriptObjectQuarantine_h +#include "SharedPersistent.h" -#include "ScriptState.h" +#include <v8.h> +#include <wtf/RefPtr.h> namespace WebCore { - class Database; - class DOMWindow; - class Node; - class ScriptObject; - class ScriptValue; - class Storage; +class V8Proxy; - ScriptValue quarantineValue(ScriptState*, const ScriptValue&); +enum WorldToUse { UseMainWorld, UseCurrentWorld }; - bool getQuarantinedScriptObject(Database* database, ScriptObject& quarantinedObject); - bool getQuarantinedScriptObject(Storage* storage, ScriptObject& quarantinedObject); - bool getQuarantinedScriptObject(Node* node, ScriptObject& quarantinedObject); - bool getQuarantinedScriptObject(DOMWindow* domWindow, ScriptObject& quarantinedObject); +class WorldContextHandle { +public: + WorldContextHandle(WorldToUse); + v8::Local<v8::Context> adjustedContext(V8Proxy*) const; -} +private: + WorldToUse m_worldToUse; + RefPtr<SharedPersistent<v8::Context> > m_context; +}; -#endif // ScriptObjectQuarantine_h +} // namespace WebCore + +#endif // WorldContextHandle_h diff --git a/WebCore/bindings/v8/custom/V8CanvasArrayCustom.h b/WebCore/bindings/v8/custom/V8CanvasArrayCustom.h deleted file mode 100644 index 311b838..0000000 --- a/WebCore/bindings/v8/custom/V8CanvasArrayCustom.h +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright (C) 2009 Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" - -#if ENABLE(3D_CANVAS) - -#include "CanvasArrayBuffer.h" - -#include "V8Binding.h" -#include "V8CanvasArrayBuffer.h" -#include "V8CustomBinding.h" -#include "V8Proxy.h" - -namespace WebCore { - - // Template function used by the CanvasArray*Constructor callbacks. - template<class ArrayClass> - v8::Handle<v8::Value> constructCanvasArray(const v8::Arguments& args, - int classIndex) - { - if (!args.IsConstructCall()) - return throwError("DOM object constructor cannot be called as a function."); - - int argLen = args.Length(); - // Supported constructors: - // Canvas<T>Array(n) where n is an integer: - // -- create an empty array of n elements - // Canvas<T>Array(arr) where arr is an array: - // -- create a Canvas<T>Array containing the contents of "arr" - // Canvas<T>Array(buf, offset, length) - // -- create a Canvas<T>Array pointing to the CanvasArrayBuffer - // "buf", starting at the specified offset, for the given - // length - - if (argLen == 0) - return throwError("No arguments specified to constructor"); - - // See whether the first argument is a CanvasArrayBuffer. - if (V8CanvasArrayBuffer::HasInstance(args[0])) { - if (argLen > 3) - return throwError("Wrong number of arguments to new Canvas<T>Array(CanvasArrayBuffer, int, int)"); - - CanvasArrayBuffer* buf = - V8DOMWrapper::convertToNativeObject<CanvasArrayBuffer>(V8ClassIndex::CANVASARRAYBUFFER, - args[0]->ToObject()); - if (buf == NULL) - return throwError("Could not convert argument 0 to a CanvasArrayBuffer"); - bool ok; - int offset = 0; - if (argLen > 1) { - offset = toInt32(args[1], ok); - if (!ok) - return throwError("Could not convert argument 1 to an integer"); - } - int length = buf->byteLength() - offset; - if (argLen > 2) { - length = toInt32(args[2], ok); - if (!ok) - return throwError("Could not convert argument 2 to an integer"); - } - if (length < 0) - return throwError("Length / offset out of range"); - - RefPtr<ArrayClass> array = ArrayClass::create(buf, offset, length); - if (array == NULL) - return throwError("Invalid arguments to new Canvas<T>Array(CanvasArrayBuffer, int, int)"); - // Transform the holder into a wrapper object for the array. - V8DOMWrapper::setDOMWrapper(args.Holder(), classIndex, array.get()); - return toV8(array.release(), args.Holder()); - } - - int len = 0; - v8::Handle<v8::Array> srcArray; - if (argLen != 1) - return throwError("Wrong number of arguments to new Canvas<T>Array(int / array)"); - - if (args[0]->IsInt32()) { - len = toInt32(args[0]); - } else if (args[0]->IsArray()) { - srcArray = v8::Local<v8::Array>::Cast(args[0]); - if (srcArray.IsEmpty()) - return throwError("Could not convert argument 0 to an array"); - len = srcArray->Length(); - } else - return throwError("Could not convert argument 0 to either an int32 or an array"); - - RefPtr<ArrayClass> array = ArrayClass::create(len); - if (!srcArray.IsEmpty()) { - // Need to copy the incoming array into the newly created CanvasArray. - for (int i = 0; i < len; i++) { - v8::Local<v8::Value> val = srcArray->Get(v8::Integer::New(i)); - if (!val->IsNumber()) { - char buf[256]; - sprintf(buf, "Could not convert array element %d to a number", i); - return throwError(buf); - } - array->set(i, val->NumberValue()); - } - } - - // Transform the holder into a wrapper object for the array. - V8DOMWrapper::setDOMWrapper(args.Holder(), classIndex, array.get()); - return toV8(array.release(), args.Holder()); - } - -} - -#endif // ENABLE(3D_CANVAS) diff --git a/WebCore/bindings/v8/custom/V8CanvasRenderingContext3DCustom.cpp b/WebCore/bindings/v8/custom/V8CanvasRenderingContext3DCustom.cpp deleted file mode 100644 index c109bb8..0000000 --- a/WebCore/bindings/v8/custom/V8CanvasRenderingContext3DCustom.cpp +++ /dev/null @@ -1,597 +0,0 @@ -/* - * Copyright (C) 2009 Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" - -#if ENABLE(3D_CANVAS) - -#include "CanvasRenderingContext3D.h" - -#include "ExceptionCode.h" - -#include "NotImplemented.h" - -#include <wtf/FastMalloc.h> - -#include "V8Binding.h" -#include "V8CanvasArray.h" -#include "V8CanvasByteArray.h" -#include "V8CanvasFloatArray.h" -#include "V8CanvasIntArray.h" -#include "V8CanvasShortArray.h" -#include "V8CanvasUnsignedByteArray.h" -#include "V8CanvasUnsignedIntArray.h" -#include "V8CanvasUnsignedShortArray.h" -#include "V8HTMLImageElement.h" -#include "V8Proxy.h" - -namespace WebCore { - -// Allocates new storage via tryFastMalloc. -// Returns NULL if array failed to convert for any reason. -static float* jsArrayToFloatArray(v8::Handle<v8::Array> array, uint32_t len) -{ - // Convert the data element-by-element. - float* data; - if (!tryFastMalloc(len * sizeof(float)).getValue(data)) - return 0; - for (uint32_t i = 0; i < len; i++) { - v8::Local<v8::Value> val = array->Get(v8::Integer::New(i)); - if (!val->IsNumber()) { - fastFree(data); - return 0; - } - data[i] = toFloat(val); - } - return data; -} - -// Allocates new storage via tryFastMalloc. -// Returns NULL if array failed to convert for any reason. -static int* jsArrayToIntArray(v8::Handle<v8::Array> array, uint32_t len) -{ - // Convert the data element-by-element. - int* data; - if (!tryFastMalloc(len * sizeof(int)).getValue(data)) - return 0; - for (uint32_t i = 0; i < len; i++) { - v8::Local<v8::Value> val = array->Get(v8::Integer::New(i)); - bool ok; - int ival = toInt32(val, ok); - if (!ok) { - fastFree(data); - return 0; - } - data[i] = ival; - } - return data; -} - -CALLBACK_FUNC_DECL(CanvasRenderingContext3DBufferData) -{ - INC_STATS("DOM.CanvasRenderingContext3D.bufferData()"); - - // Forms: - // * bufferData(GLenum target, CanvasArray data, GLenum usage); - // - Sets the buffer's data from the given CanvasArray - // * bufferData(GLenum target, GLsizeiptr size, GLenum usage); - // - Sets the size of the buffer to the given size in bytes - if (args.Length() != 3) { - V8Proxy::setDOMException(SYNTAX_ERR); - return notHandledByInterceptor(); - } - - CanvasRenderingContext3D* context = - V8DOMWrapper::convertDOMWrapperToNative<CanvasRenderingContext3D>(args.Holder()); - bool ok; - int target = toInt32(args[0], ok); - if (!ok) { - V8Proxy::setDOMException(SYNTAX_ERR); - return notHandledByInterceptor(); - } - int usage = toInt32(args[2], ok); - if (!ok) { - V8Proxy::setDOMException(SYNTAX_ERR); - return notHandledByInterceptor(); - } - if (args[1]->IsInt32()) { - int size = toInt32(args[1]); - context->bufferData(target, size, usage); - } else if (V8CanvasArray::HasInstance(args[1])) { - CanvasArray* array = V8DOMWrapper::convertToNativeObject<CanvasArray>(V8ClassIndex::CANVASARRAY, args[1]->ToObject()); - context->bufferData(target, array, usage); - } else { - V8Proxy::setDOMException(SYNTAX_ERR); - return notHandledByInterceptor(); - } - return v8::Undefined(); -} - -CALLBACK_FUNC_DECL(CanvasRenderingContext3DBufferSubData) -{ - INC_STATS("DOM.CanvasRenderingContext3D.bufferSubData()"); - - // Forms: - // * bufferSubData(GLenum target, GLintptr offset, CanvasArray data); - if (args.Length() != 3) { - V8Proxy::setDOMException(SYNTAX_ERR); - return notHandledByInterceptor(); - } - - CanvasRenderingContext3D* context = - V8DOMWrapper::convertDOMWrapperToNative<CanvasRenderingContext3D>(args.Holder()); - bool ok; - int target = toInt32(args[0], ok); - if (!ok) { - V8Proxy::setDOMException(SYNTAX_ERR); - return notHandledByInterceptor(); - } - int offset = toInt32(args[1], ok); - if (!ok) { - V8Proxy::setDOMException(SYNTAX_ERR); - return notHandledByInterceptor(); - } - if (!V8CanvasArray::HasInstance(args[2])) { - V8Proxy::setDOMException(SYNTAX_ERR); - return notHandledByInterceptor(); - } - CanvasArray* array = V8DOMWrapper::convertToNativeObject<CanvasArray>(V8ClassIndex::CANVASARRAY, args[2]->ToObject()); - context->bufferSubData(target, offset, array); - return v8::Undefined(); -} - -CALLBACK_FUNC_DECL(CanvasRenderingContext3DTexImage2D) -{ - INC_STATS("DOM.CanvasRenderingContext3D.texImage2D()"); - - // Currently supported forms: - // * void texImage2D(in GLenum target, in GLint level, - // in GLint internalformat, - // in GLsizei width, in GLsizei height, in GLint border, - // in GLenum format, in GLenum type, in CanvasArray pixels); - // * void texImage2D(in GLenum target, in GLint level, in HTMLImageElement image, - // [Optional] in GLboolean flipY, [Optional] in GLboolean premultiplyAlpha); - if (args.Length() != 3 && - args.Length() != 4 && - args.Length() != 5 && - args.Length() != 9) { - V8Proxy::setDOMException(SYNTAX_ERR); - return notHandledByInterceptor(); - } - - CanvasRenderingContext3D* context = - V8DOMWrapper::convertDOMWrapperToNative<CanvasRenderingContext3D>(args.Holder()); - bool ok; - int target = toInt32(args[0], ok); - if (!ok) { - V8Proxy::setDOMException(SYNTAX_ERR); - return notHandledByInterceptor(); - } - int level = toInt32(args[1], ok); - if (!ok) { - V8Proxy::setDOMException(SYNTAX_ERR); - return notHandledByInterceptor(); - } - - ExceptionCode ec = 0; - if (args.Length() == 3 || - args.Length() == 4 || - args.Length() == 5) { - v8::Handle<v8::Value> arg = args[2]; - if (V8HTMLImageElement::HasInstance(arg)) { - HTMLImageElement* image_element = V8DOMWrapper::convertDOMWrapperToNode<HTMLImageElement>(v8::Handle<v8::Object>::Cast(arg)); - bool flipY = false; - bool premultiplyAlpha = false; - if (args.Length() >= 4) - flipY = args[3]->BooleanValue(); - if (args.Length() >= 5) - premultiplyAlpha = args[4]->BooleanValue(); - context->texImage2D(target, level, image_element, flipY, premultiplyAlpha, ec); - } else { - // FIXME: consider different / better exception type. - V8Proxy::setDOMException(SYNTAX_ERR); - return notHandledByInterceptor(); - } - // Fall through - } else if (args.Length() == 9) { - int internalformat = toInt32(args[2], ok); - if (!ok) { - V8Proxy::setDOMException(SYNTAX_ERR); - return notHandledByInterceptor(); - } - int width = toInt32(args[3], ok); - if (!ok) { - V8Proxy::setDOMException(SYNTAX_ERR); - return notHandledByInterceptor(); - } - int height = toInt32(args[4], ok); - if (!ok) { - V8Proxy::setDOMException(SYNTAX_ERR); - return notHandledByInterceptor(); - } - int border = toInt32(args[5], ok); - if (!ok) { - V8Proxy::setDOMException(SYNTAX_ERR); - return notHandledByInterceptor(); - } - int format = toInt32(args[6], ok); - if (!ok) { - V8Proxy::setDOMException(SYNTAX_ERR); - return notHandledByInterceptor(); - } - int type = toInt32(args[7], ok); - if (!ok) { - V8Proxy::setDOMException(SYNTAX_ERR); - return notHandledByInterceptor(); - } - v8::Handle<v8::Value> arg = args[8]; - if (V8CanvasArray::HasInstance(arg)) { - CanvasArray* array = V8DOMWrapper::convertToNativeObject<CanvasArray>(V8ClassIndex::CANVASARRAY, arg->ToObject()); - // FIXME: must do validation similar to JOGL's to ensure that - // the incoming array is of the appropriate length and type - context->texImage2D(target, - level, - internalformat, - width, - height, - border, - format, - type, - array, - ec); - // Fall through - } else { - V8Proxy::setDOMException(SYNTAX_ERR); - return notHandledByInterceptor(); - } - } else { - ASSERT_NOT_REACHED(); - V8Proxy::setDOMException(SYNTAX_ERR); - return notHandledByInterceptor(); - } - if (ec) { - V8Proxy::setDOMException(ec); - return v8::Handle<v8::Value>(); - } - return v8::Undefined(); -} - -CALLBACK_FUNC_DECL(CanvasRenderingContext3DTexSubImage2D) -{ - INC_STATS("DOM.CanvasRenderingContext3D.texSubImage2D()"); - - // FIXME: implement - notImplemented(); - - return v8::Undefined(); -} - -enum FunctionToCall { - kUniform1v, kUniform2v, kUniform3v, kUniform4v, - kVertexAttrib1v, kVertexAttrib2v, kVertexAttrib3v, kVertexAttrib4v -}; - -static v8::Handle<v8::Value> vertexAttribAndUniformHelperf(const v8::Arguments& args, - FunctionToCall functionToCall) { - // Forms: - // * glUniform1fv(GLint location, Array data); - // * glUniform1fv(GLint location, CanvasFloatArray data); - // * glUniform2fv(GLint location, Array data); - // * glUniform2fv(GLint location, CanvasFloatArray data); - // * glUniform3fv(GLint location, Array data); - // * glUniform3fv(GLint location, CanvasFloatArray data); - // * glUniform4fv(GLint location, Array data); - // * glUniform4fv(GLint location, CanvasFloatArray data); - // * glVertexAttrib1fv(GLint location, Array data); - // * glVertexAttrib1fv(GLint location, CanvasFloatArray data); - // * glVertexAttrib2fv(GLint location, Array data); - // * glVertexAttrib2fv(GLint location, CanvasFloatArray data); - // * glVertexAttrib3fv(GLint location, Array data); - // * glVertexAttrib3fv(GLint location, CanvasFloatArray data); - // * glVertexAttrib4fv(GLint location, Array data); - // * glVertexAttrib4fv(GLint location, CanvasFloatArray data); - - if (args.Length() != 3) { - V8Proxy::setDOMException(SYNTAX_ERR); - return notHandledByInterceptor(); - } - - CanvasRenderingContext3D* context = - V8DOMWrapper::convertDOMWrapperToNative<CanvasRenderingContext3D>(args.Holder()); - bool ok; - int location = toInt32(args[0], ok); - if (!ok) { - V8Proxy::setDOMException(SYNTAX_ERR); - return notHandledByInterceptor(); - } - if (V8CanvasFloatArray::HasInstance(args[1])) { - CanvasFloatArray* array = - V8DOMWrapper::convertToNativeObject<CanvasFloatArray>(V8ClassIndex::CANVASFLOATARRAY, args[1]->ToObject()); - ASSERT(array != NULL); - switch (functionToCall) { - case kUniform1v: context->uniform1fv(location, array); break; - case kUniform2v: context->uniform2fv(location, array); break; - case kUniform3v: context->uniform3fv(location, array); break; - case kUniform4v: context->uniform4fv(location, array); break; - case kVertexAttrib1v: context->vertexAttrib1fv(location, array); break; - case kVertexAttrib2v: context->vertexAttrib2fv(location, array); break; - case kVertexAttrib3v: context->vertexAttrib3fv(location, array); break; - case kVertexAttrib4v: context->vertexAttrib4fv(location, array); break; - default: ASSERT_NOT_REACHED(); break; - } - return v8::Undefined(); - } - - v8::Handle<v8::Array> array = - v8::Local<v8::Array>::Cast(args[1]); - if (array.IsEmpty()) { - V8Proxy::setDOMException(SYNTAX_ERR); - return notHandledByInterceptor(); - } - uint32_t len = array->Length(); - float* data = jsArrayToFloatArray(array, len); - if (!data) { - // FIXME: consider different / better exception type. - V8Proxy::setDOMException(SYNTAX_ERR); - return notHandledByInterceptor(); - } - switch (functionToCall) { - case kUniform1v: context->uniform1fv(location, data, len); break; - case kUniform2v: context->uniform2fv(location, data, len); break; - case kUniform3v: context->uniform3fv(location, data, len); break; - case kUniform4v: context->uniform4fv(location, data, len); break; - case kVertexAttrib1v: context->vertexAttrib1fv(location, data, len); break; - case kVertexAttrib2v: context->vertexAttrib2fv(location, data, len); break; - case kVertexAttrib3v: context->vertexAttrib3fv(location, data, len); break; - case kVertexAttrib4v: context->vertexAttrib4fv(location, data, len); break; - default: ASSERT_NOT_REACHED(); break; - } - fastFree(data); - return v8::Undefined(); -} - -static v8::Handle<v8::Value> uniformHelperi(const v8::Arguments& args, - FunctionToCall functionToCall) { - // Forms: - // * glUniform1iv(GLint location, Array data); - // * glUniform1iv(GLint location, CanvasIntArray data); - // * glUniform2iv(GLint location, Array data); - // * glUniform2iv(GLint location, CanvasIntArray data); - // * glUniform3iv(GLint location, Array data); - // * glUniform3iv(GLint location, CanvasIntArray data); - // * glUniform4iv(GLint location, Array data); - // * glUniform4iv(GLint location, CanvasIntArray data); - - if (args.Length() != 3) { - V8Proxy::setDOMException(SYNTAX_ERR); - return notHandledByInterceptor(); - } - - CanvasRenderingContext3D* context = - V8DOMWrapper::convertDOMWrapperToNative<CanvasRenderingContext3D>(args.Holder()); - bool ok; - int location = toInt32(args[0], ok); - if (!ok) { - V8Proxy::setDOMException(SYNTAX_ERR); - return notHandledByInterceptor(); - } - if (V8CanvasIntArray::HasInstance(args[1])) { - CanvasIntArray* array = - V8DOMWrapper::convertToNativeObject<CanvasIntArray>(V8ClassIndex::CANVASINTARRAY, args[1]->ToObject()); - ASSERT(array != NULL); - switch (functionToCall) { - case kUniform1v: context->uniform1iv(location, array); break; - case kUniform2v: context->uniform2iv(location, array); break; - case kUniform3v: context->uniform3iv(location, array); break; - case kUniform4v: context->uniform4iv(location, array); break; - default: ASSERT_NOT_REACHED(); break; - } - return v8::Undefined(); - } - - v8::Handle<v8::Array> array = - v8::Local<v8::Array>::Cast(args[1]); - if (array.IsEmpty()) { - V8Proxy::setDOMException(SYNTAX_ERR); - return notHandledByInterceptor(); - } - uint32_t len = array->Length(); - int* data = jsArrayToIntArray(array, len); - if (!data) { - // FIXME: consider different / better exception type. - V8Proxy::setDOMException(SYNTAX_ERR); - return notHandledByInterceptor(); - } - switch (functionToCall) { - case kUniform1v: context->uniform1iv(location, data, len); break; - case kUniform2v: context->uniform2iv(location, data, len); break; - case kUniform3v: context->uniform3iv(location, data, len); break; - case kUniform4v: context->uniform4iv(location, data, len); break; - default: ASSERT_NOT_REACHED(); break; - } - fastFree(data); - return v8::Undefined(); -} - -CALLBACK_FUNC_DECL(CanvasRenderingContext3DUniform1fv) -{ - INC_STATS("DOM.CanvasRenderingContext3D.uniform1fv()"); - return vertexAttribAndUniformHelperf(args, kUniform1v); -} - -CALLBACK_FUNC_DECL(CanvasRenderingContext3DUniform1iv) -{ - INC_STATS("DOM.CanvasRenderingContext3D.uniform1iv()"); - return uniformHelperi(args, kUniform1v); -} - -CALLBACK_FUNC_DECL(CanvasRenderingContext3DUniform2fv) -{ - INC_STATS("DOM.CanvasRenderingContext3D.uniform2fv()"); - return vertexAttribAndUniformHelperf(args, kUniform2v); -} - -CALLBACK_FUNC_DECL(CanvasRenderingContext3DUniform2iv) -{ - INC_STATS("DOM.CanvasRenderingContext3D.uniform2iv()"); - return uniformHelperi(args, kUniform2v); -} - -CALLBACK_FUNC_DECL(CanvasRenderingContext3DUniform3fv) -{ - INC_STATS("DOM.CanvasRenderingContext3D.uniform3fv()"); - return vertexAttribAndUniformHelperf(args, kUniform3v); -} - -CALLBACK_FUNC_DECL(CanvasRenderingContext3DUniform3iv) -{ - INC_STATS("DOM.CanvasRenderingContext3D.uniform3iv()"); - return uniformHelperi(args, kUniform3v); -} - -CALLBACK_FUNC_DECL(CanvasRenderingContext3DUniform4fv) -{ - INC_STATS("DOM.CanvasRenderingContext3D.uniform4fv()"); - return vertexAttribAndUniformHelperf(args, kUniform4v); -} - -CALLBACK_FUNC_DECL(CanvasRenderingContext3DUniform4iv) -{ - INC_STATS("DOM.CanvasRenderingContext3D.uniform4iv()"); - return uniformHelperi(args, kUniform4v); -} - -static v8::Handle<v8::Value> uniformMatrixHelper(const v8::Arguments& args, - int matrixSize) -{ - // Forms: - // * glUniformMatrix2fv(GLint location, GLboolean transpose, Array data); - // * glUniformMatrix2fv(GLint location, GLboolean transpose, CanvasFloatArray data); - // * glUniformMatrix3fv(GLint location, GLboolean transpose, Array data); - // * glUniformMatrix3fv(GLint location, GLboolean transpose, CanvasFloatArray data); - // * glUniformMatrix4fv(GLint location, GLboolean transpose, Array data); - // * glUniformMatrix4fv(GLint location, GLboolean transpose, CanvasFloatArray data); - // - // FIXME: need to change to accept CanvasFloatArray as well. - if (args.Length() != 3) { - V8Proxy::setDOMException(SYNTAX_ERR); - return notHandledByInterceptor(); - } - - CanvasRenderingContext3D* context = - V8DOMWrapper::convertDOMWrapperToNative<CanvasRenderingContext3D>(args.Holder()); - bool ok; - int location = toInt32(args[0], ok); - if (!ok) { - V8Proxy::setDOMException(SYNTAX_ERR); - return notHandledByInterceptor(); - } - bool transpose = args[1]->BooleanValue(); - if (V8CanvasFloatArray::HasInstance(args[2])) { - CanvasFloatArray* array = - V8DOMWrapper::convertToNativeObject<CanvasFloatArray>(V8ClassIndex::CANVASFLOATARRAY, args[2]->ToObject()); - ASSERT(array != NULL); - switch (matrixSize) { - case 2: context->uniformMatrix2fv(location, transpose, array); break; - case 3: context->uniformMatrix3fv(location, transpose, array); break; - case 4: context->uniformMatrix4fv(location, transpose, array); break; - default: ASSERT_NOT_REACHED(); break; - } - return v8::Undefined(); - } - - v8::Handle<v8::Array> array = - v8::Local<v8::Array>::Cast(args[2]); - if (array.IsEmpty()) { - V8Proxy::setDOMException(SYNTAX_ERR); - return notHandledByInterceptor(); - } - uint32_t len = array->Length(); - float* data = jsArrayToFloatArray(array, len); - if (!data) { - // FIXME: consider different / better exception type. - V8Proxy::setDOMException(SYNTAX_ERR); - return notHandledByInterceptor(); - } - switch (matrixSize) { - case 2: context->uniformMatrix2fv(location, transpose, data, len); break; - case 3: context->uniformMatrix3fv(location, transpose, data, len); break; - case 4: context->uniformMatrix4fv(location, transpose, data, len); break; - default: ASSERT_NOT_REACHED(); break; - } - fastFree(data); - return v8::Undefined(); -} - -CALLBACK_FUNC_DECL(CanvasRenderingContext3DUniformMatrix2fv) -{ - INC_STATS("DOM.CanvasRenderingContext3D.uniformMatrix2fv()"); - return uniformMatrixHelper(args, 2); -} - -CALLBACK_FUNC_DECL(CanvasRenderingContext3DUniformMatrix3fv) -{ - INC_STATS("DOM.CanvasRenderingContext3D.uniformMatrix3fv()"); - return uniformMatrixHelper(args, 3); -} - -CALLBACK_FUNC_DECL(CanvasRenderingContext3DUniformMatrix4fv) -{ - INC_STATS("DOM.CanvasRenderingContext3D.uniformMatrix4fv()"); - return uniformMatrixHelper(args, 4); -} - -CALLBACK_FUNC_DECL(CanvasRenderingContext3DVertexAttrib1fv) -{ - INC_STATS("DOM.CanvasRenderingContext3D.vertexAttrib1fv()"); - return vertexAttribAndUniformHelperf(args, kVertexAttrib1v); -} - -CALLBACK_FUNC_DECL(CanvasRenderingContext3DVertexAttrib2fv) -{ - INC_STATS("DOM.CanvasRenderingContext3D.vertexAttrib2fv()"); - return vertexAttribAndUniformHelperf(args, kVertexAttrib2v); -} - -CALLBACK_FUNC_DECL(CanvasRenderingContext3DVertexAttrib3fv) -{ - INC_STATS("DOM.CanvasRenderingContext3D.vertexAttrib3fv()"); - return vertexAttribAndUniformHelperf(args, kVertexAttrib3v); -} - -CALLBACK_FUNC_DECL(CanvasRenderingContext3DVertexAttrib4fv) -{ - INC_STATS("DOM.CanvasRenderingContext3D.vertexAttrib4fv()"); - return vertexAttribAndUniformHelperf(args, kVertexAttrib4v); -} - -} // namespace WebCore - -#endif // ENABLE(3D_CANVAS) diff --git a/WebCore/bindings/v8/custom/V8CanvasPixelArrayCustom.cpp b/WebCore/bindings/v8/custom/V8ConsoleCustom.cpp index 5fe2710..b44e074 100644 --- a/WebCore/bindings/v8/custom/V8CanvasPixelArrayCustom.cpp +++ b/WebCore/bindings/v8/custom/V8ConsoleCustom.cpp @@ -29,37 +29,28 @@ */ #include "config.h" -#include "CanvasPixelArray.h" #include "V8Binding.h" #include "V8CustomBinding.h" #include "V8Proxy.h" +#include <v8.h> namespace WebCore { -// Get the specified value from the pixel buffer and return it wrapped as a JavaScript Number object to V8. Accesses outside the valid pixel buffer range return "undefined". -INDEXED_PROPERTY_GETTER(CanvasPixelArray) +CALLBACK_FUNC_DECL(ConsoleProfile) { - INC_STATS("DOM.CanvasPixelArray.IndexedPropertyGetter"); - CanvasPixelArray* pixelBuffer = V8DOMWrapper::convertToNativeObject<CanvasPixelArray>(V8ClassIndex::CANVASPIXELARRAY, info.Holder()); - - if ((index < 0) || (index >= pixelBuffer->length())) - return v8::Undefined(); - unsigned char result; - if (!pixelBuffer->get(index, result)) - return v8::Undefined(); - return v8::Number::New(result); + INC_STATS("console.profile()"); + v8::HandleScope scope; + v8::Context::Scope context_scope(v8::Context::GetCurrent()); + v8::V8::ResumeProfiler(); + return v8::Undefined(); } -// Set the specified value in the pixel buffer. Accesses outside the valid pixel buffer range are silently ignored. -INDEXED_PROPERTY_SETTER(CanvasPixelArray) +CALLBACK_FUNC_DECL(ConsoleProfileEnd) { - INC_STATS("DOM.CanvasPixelArray.IndexedPropertySetter"); - CanvasPixelArray* pixelBuffer = V8DOMWrapper::convertToNativeObject<CanvasPixelArray>(V8ClassIndex::CANVASPIXELARRAY, info.Holder()); - - if ((index >= 0) && (index < pixelBuffer->length())) - pixelBuffer->set(index, value->NumberValue()); - return value; + INC_STATS("console.profileEnd()"); + v8::V8::PauseProfiler(); + return v8::Undefined(); } } // namespace WebCore diff --git a/WebCore/bindings/v8/custom/V8CustomBinding.h b/WebCore/bindings/v8/custom/V8CustomBinding.h index 06182c9..e7670b7 100644 --- a/WebCore/bindings/v8/custom/V8CustomBinding.h +++ b/WebCore/bindings/v8/custom/V8CustomBinding.h @@ -120,8 +120,7 @@ namespace WebCore { static const int kMessageChannelInternalFieldCount = kDefaultWrapperInternalFieldCount + 2; static const int kMessagePortRequestCacheIndex = kDefaultWrapperInternalFieldCount + 0; - static const int kMessagePortEntangledPortIndex = kDefaultWrapperInternalFieldCount + 1; - static const int kMessagePortInternalFieldCount = kDefaultWrapperInternalFieldCount + 2; + static const int kMessagePortInternalFieldCount = kDefaultWrapperInternalFieldCount + 1; #if ENABLE(WORKERS) static const int kAbstractWorkerRequestCacheIndex = kDefaultWrapperInternalFieldCount + 0; @@ -169,10 +168,13 @@ namespace WebCore { static const int kDOMWindowLocationIndex = kDefaultWrapperInternalFieldCount + 11; static const int kDOMWindowDOMSelectionIndex = kDefaultWrapperInternalFieldCount + 12; static const int kDOMWindowEventListenerCacheIndex = kDefaultWrapperInternalFieldCount + 13; - static const int kDOMWindowInternalFieldCount = kDefaultWrapperInternalFieldCount + 14; + static const int kDOMWindowEnteredIsolatedWorldIndex = kDefaultWrapperInternalFieldCount + 14; + static const int kDOMWindowInternalFieldCount = kDefaultWrapperInternalFieldCount + 15; static const int kStyleSheetOwnerNodeIndex = kDefaultWrapperInternalFieldCount + 0; static const int kStyleSheetInternalFieldCount = kDefaultWrapperInternalFieldCount + 1; + static const int kNamedNodeMapOwnerNodeIndex = kDefaultWrapperInternalFieldCount + 0; + static const int kNamedNodeMapInternalFieldCount = kDefaultWrapperInternalFieldCount + 1; #if ENABLE(OFFLINE_WEB_APPLICATIONS) static const int kDOMApplicationCacheCacheIndex = kDefaultWrapperInternalFieldCount + 0; @@ -363,35 +365,43 @@ namespace WebCore { DECLARE_CALLBACK(CanvasRenderingContext2DPutImageData); #if ENABLE(3D_CANVAS) - DECLARE_CALLBACK(CanvasRenderingContext3DBufferData); - DECLARE_CALLBACK(CanvasRenderingContext3DBufferSubData); - DECLARE_CALLBACK(CanvasRenderingContext3DSizeof); - DECLARE_CALLBACK(CanvasRenderingContext3DTexImage2D); - DECLARE_CALLBACK(CanvasRenderingContext3DTexSubImage2D); - DECLARE_CALLBACK(CanvasRenderingContext3DUniform1fv); - DECLARE_CALLBACK(CanvasRenderingContext3DUniform1iv); - DECLARE_CALLBACK(CanvasRenderingContext3DUniform2fv); - DECLARE_CALLBACK(CanvasRenderingContext3DUniform2iv); - DECLARE_CALLBACK(CanvasRenderingContext3DUniform3fv); - DECLARE_CALLBACK(CanvasRenderingContext3DUniform3iv); - DECLARE_CALLBACK(CanvasRenderingContext3DUniform4fv); - DECLARE_CALLBACK(CanvasRenderingContext3DUniform4iv); - DECLARE_CALLBACK(CanvasRenderingContext3DUniformMatrix2fv); - DECLARE_CALLBACK(CanvasRenderingContext3DUniformMatrix3fv); - DECLARE_CALLBACK(CanvasRenderingContext3DUniformMatrix4fv); - DECLARE_CALLBACK(CanvasRenderingContext3DVertexAttrib1fv); - DECLARE_CALLBACK(CanvasRenderingContext3DVertexAttrib2fv); - DECLARE_CALLBACK(CanvasRenderingContext3DVertexAttrib3fv); - DECLARE_CALLBACK(CanvasRenderingContext3DVertexAttrib4fv); - - DECLARE_CALLBACK(CanvasArrayBufferConstructor); - DECLARE_CALLBACK(CanvasByteArrayConstructor); - DECLARE_CALLBACK(CanvasFloatArrayConstructor); - DECLARE_CALLBACK(CanvasIntArrayConstructor); - DECLARE_CALLBACK(CanvasShortArrayConstructor); - DECLARE_CALLBACK(CanvasUnsignedByteArrayConstructor); - DECLARE_CALLBACK(CanvasUnsignedIntArrayConstructor); - DECLARE_CALLBACK(CanvasUnsignedShortArrayConstructor); + DECLARE_CALLBACK(WebGLRenderingContextBufferData); + DECLARE_CALLBACK(WebGLRenderingContextBufferSubData); + DECLARE_CALLBACK(WebGLRenderingContextGetBufferParameter); + DECLARE_CALLBACK(WebGLRenderingContextGetFramebufferAttachmentParameter); + DECLARE_CALLBACK(WebGLRenderingContextGetParameter); + DECLARE_CALLBACK(WebGLRenderingContextGetProgramParameter); + DECLARE_CALLBACK(WebGLRenderingContextGetRenderbufferParameter); + DECLARE_CALLBACK(WebGLRenderingContextGetShaderParameter); + DECLARE_CALLBACK(WebGLRenderingContextGetTexParameter); + DECLARE_CALLBACK(WebGLRenderingContextGetUniform); + DECLARE_CALLBACK(WebGLRenderingContextGetVertexAttrib); + DECLARE_CALLBACK(WebGLRenderingContextTexImage2D); + DECLARE_CALLBACK(WebGLRenderingContextTexSubImage2D); + DECLARE_CALLBACK(WebGLRenderingContextUniform1fv); + DECLARE_CALLBACK(WebGLRenderingContextUniform1iv); + DECLARE_CALLBACK(WebGLRenderingContextUniform2fv); + DECLARE_CALLBACK(WebGLRenderingContextUniform2iv); + DECLARE_CALLBACK(WebGLRenderingContextUniform3fv); + DECLARE_CALLBACK(WebGLRenderingContextUniform3iv); + DECLARE_CALLBACK(WebGLRenderingContextUniform4fv); + DECLARE_CALLBACK(WebGLRenderingContextUniform4iv); + DECLARE_CALLBACK(WebGLRenderingContextUniformMatrix2fv); + DECLARE_CALLBACK(WebGLRenderingContextUniformMatrix3fv); + DECLARE_CALLBACK(WebGLRenderingContextUniformMatrix4fv); + DECLARE_CALLBACK(WebGLRenderingContextVertexAttrib1fv); + DECLARE_CALLBACK(WebGLRenderingContextVertexAttrib2fv); + DECLARE_CALLBACK(WebGLRenderingContextVertexAttrib3fv); + DECLARE_CALLBACK(WebGLRenderingContextVertexAttrib4fv); + + DECLARE_CALLBACK(WebGLArrayBufferConstructor); + DECLARE_CALLBACK(WebGLByteArrayConstructor); + DECLARE_CALLBACK(WebGLFloatArrayConstructor); + DECLARE_CALLBACK(WebGLIntArrayConstructor); + DECLARE_CALLBACK(WebGLShortArrayConstructor); + DECLARE_CALLBACK(WebGLUnsignedByteArrayConstructor); + DECLARE_CALLBACK(WebGLUnsignedIntArrayConstructor); + DECLARE_CALLBACK(WebGLUnsignedShortArrayConstructor); #endif DECLARE_PROPERTY_ACCESSOR_GETTER(ClipboardTypes); @@ -407,6 +417,9 @@ namespace WebCore { DECLARE_CALLBACK(ElementSetAttributeNS); DECLARE_CALLBACK(ElementSetAttributeNodeNS); + DECLARE_CALLBACK(HistoryPushState); + DECLARE_CALLBACK(HistoryReplaceState); + DECLARE_PROPERTY_ACCESSOR_SETTER(LocationProtocol); DECLARE_PROPERTY_ACCESSOR_SETTER(LocationHost); DECLARE_PROPERTY_ACCESSOR_SETTER(LocationHostname); @@ -423,7 +436,6 @@ namespace WebCore { DECLARE_CALLBACK(LocationReload); DECLARE_CALLBACK(LocationToString); DECLARE_CALLBACK(LocationValueOf); - DECLARE_CALLBACK(NodeAddEventListener); DECLARE_CALLBACK(NodeRemoveEventListener); DECLARE_CALLBACK(NodeInsertBefore); @@ -469,29 +481,25 @@ namespace WebCore { DECLARE_CALLBACK(TreeWalkerNextSibling); DECLARE_CALLBACK(TreeWalkerPreviousSibling); - DECLARE_CALLBACK(InspectorBackendHighlightDOMNode); - DECLARE_CALLBACK(InspectorBackendAddResourceSourceToFrame); - DECLARE_CALLBACK(InspectorBackendAddSourceToFrame); - DECLARE_CALLBACK(InspectorBackendSearch); - DECLARE_CALLBACK(InspectorBackendSetting); - DECLARE_CALLBACK(InspectorBackendDatabaseForId); - DECLARE_CALLBACK(InspectorBackendInspectedWindow); - DECLARE_CALLBACK(InspectorBackendSetSetting); - DECLARE_CALLBACK(InspectorBackendCurrentCallFrame); - DECLARE_CALLBACK(InspectorBackendDebuggerEnabled); - DECLARE_CALLBACK(InspectorBackendPauseOnExceptions); - DECLARE_CALLBACK(InspectorBackendProfilerEnabled); - DECLARE_CALLBACK(InspectorBackendNodeForId); - DECLARE_CALLBACK(InspectorBackendWrapObject); - DECLARE_CALLBACK(InspectorBackendUnwrapObject); - DECLARE_CALLBACK(InspectorBackendPushNodePathToFrontend); + DECLARE_CALLBACK(InjectedScriptHostInspectedWindow); + DECLARE_CALLBACK(InjectedScriptHostNodeForId); + DECLARE_CALLBACK(InjectedScriptHostWrapObject); + DECLARE_CALLBACK(InjectedScriptHostUnwrapObject); + DECLARE_CALLBACK(InjectedScriptHostPushNodePathToFrontend); + DECLARE_CALLBACK(InjectedScriptHostWrapCallback); #if ENABLE(DATABASE) - DECLARE_CALLBACK(InspectorBackendSelectDatabase); + DECLARE_CALLBACK(InjectedScriptHostSelectDatabase); + DECLARE_CALLBACK(InjectedScriptHostDatabaseForId); #endif #if ENABLE(DOM_STORAGE) - DECLARE_CALLBACK(InspectorBackendSelectDOMStorage); + DECLARE_CALLBACK(InjectedScriptHostSelectDOMStorage); #endif - DECLARE_CALLBACK(InspectorBackendWrapCallback); + + DECLARE_CALLBACK(InspectorFrontendHostSearch); + DECLARE_CALLBACK(InspectorFrontendHostShowContextMenu); + + DECLARE_CALLBACK(ConsoleProfile); + DECLARE_CALLBACK(ConsoleProfileEnd); DECLARE_CALLBACK(NodeIteratorNextNode); DECLARE_CALLBACK(NodeIteratorPreviousNode); @@ -529,31 +537,40 @@ namespace WebCore { DECLARE_NAMED_PROPERTY_GETTER(HTMLCollection); #if ENABLE(3D_CANVAS) - DECLARE_INDEXED_PROPERTY_GETTER(CanvasByteArray); - DECLARE_INDEXED_PROPERTY_SETTER(CanvasByteArray); - - DECLARE_INDEXED_PROPERTY_GETTER(CanvasFloatArray); - DECLARE_INDEXED_PROPERTY_SETTER(CanvasFloatArray); - - DECLARE_INDEXED_PROPERTY_GETTER(CanvasIntArray); - DECLARE_INDEXED_PROPERTY_SETTER(CanvasIntArray); -#endif - - DECLARE_INDEXED_PROPERTY_GETTER(CanvasPixelArray); - DECLARE_INDEXED_PROPERTY_SETTER(CanvasPixelArray); - -#if ENABLE(3D_CANVAS) - DECLARE_INDEXED_PROPERTY_GETTER(CanvasShortArray); - DECLARE_INDEXED_PROPERTY_SETTER(CanvasShortArray); - - DECLARE_INDEXED_PROPERTY_GETTER(CanvasUnsignedByteArray); - DECLARE_INDEXED_PROPERTY_SETTER(CanvasUnsignedByteArray); - - DECLARE_INDEXED_PROPERTY_GETTER(CanvasUnsignedIntArray); - DECLARE_INDEXED_PROPERTY_SETTER(CanvasUnsignedIntArray); - - DECLARE_INDEXED_PROPERTY_GETTER(CanvasUnsignedShortArray); - DECLARE_INDEXED_PROPERTY_SETTER(CanvasUnsignedShortArray); + DECLARE_CALLBACK(WebGLByteArrayGet); + DECLARE_CALLBACK(WebGLByteArraySet); + DECLARE_INDEXED_PROPERTY_GETTER(WebGLByteArray); + DECLARE_INDEXED_PROPERTY_SETTER(WebGLByteArray); + + DECLARE_CALLBACK(WebGLFloatArrayGet); + DECLARE_CALLBACK(WebGLFloatArraySet); + DECLARE_INDEXED_PROPERTY_GETTER(WebGLFloatArray); + DECLARE_INDEXED_PROPERTY_SETTER(WebGLFloatArray); + + DECLARE_CALLBACK(WebGLIntArrayGet); + DECLARE_CALLBACK(WebGLIntArraySet); + DECLARE_INDEXED_PROPERTY_GETTER(WebGLIntArray); + DECLARE_INDEXED_PROPERTY_SETTER(WebGLIntArray); + + DECLARE_CALLBACK(WebGLShortArrayGet); + DECLARE_CALLBACK(WebGLShortArraySet); + DECLARE_INDEXED_PROPERTY_GETTER(WebGLShortArray); + DECLARE_INDEXED_PROPERTY_SETTER(WebGLShortArray); + + DECLARE_CALLBACK(WebGLUnsignedByteArrayGet); + DECLARE_CALLBACK(WebGLUnsignedByteArraySet); + DECLARE_INDEXED_PROPERTY_GETTER(WebGLUnsignedByteArray); + DECLARE_INDEXED_PROPERTY_SETTER(WebGLUnsignedByteArray); + + DECLARE_CALLBACK(WebGLUnsignedIntArrayGet); + DECLARE_CALLBACK(WebGLUnsignedIntArraySet); + DECLARE_INDEXED_PROPERTY_GETTER(WebGLUnsignedIntArray); + DECLARE_INDEXED_PROPERTY_SETTER(WebGLUnsignedIntArray); + + DECLARE_CALLBACK(WebGLUnsignedShortArrayGet); + DECLARE_CALLBACK(WebGLUnsignedShortArraySet); + DECLARE_INDEXED_PROPERTY_GETTER(WebGLUnsignedShortArray); + DECLARE_INDEXED_PROPERTY_SETTER(WebGLUnsignedShortArray); #endif DECLARE_PROPERTY_ACCESSOR_GETTER(MessageEventPorts); @@ -600,6 +617,7 @@ namespace WebCore { #if ENABLE(SVG) DECLARE_PROPERTY_ACCESSOR_GETTER(SVGLengthValue); DECLARE_CALLBACK(SVGLengthConvertToSpecifiedUnits); + DECLARE_CALLBACK(SVGMatrixMultiply); DECLARE_CALLBACK(SVGMatrixInverse); DECLARE_CALLBACK(SVGMatrixRotateFromVector); DECLARE_CALLBACK(SVGElementInstanceAddEventListener); @@ -648,6 +666,7 @@ namespace WebCore { #endif // ENABLE(NOTIFICATIONS) #if ENABLE(OFFLINE_WEB_APPLICATIONS) + DECLARE_ACCESSOR_RUNTIME_ENABLER(DOMWindowApplicationCache); DECLARE_PROPERTY_ACCESSOR(DOMApplicationCacheEventHandler); DECLARE_CALLBACK(DOMApplicationCacheAddEventListener); DECLARE_CALLBACK(DOMApplicationCacheRemoveEventListener); diff --git a/WebCore/bindings/v8/custom/V8CustomEventListener.cpp b/WebCore/bindings/v8/custom/V8CustomEventListener.cpp index 17c86a3..24d752f 100644 --- a/WebCore/bindings/v8/custom/V8CustomEventListener.cpp +++ b/WebCore/bindings/v8/custom/V8CustomEventListener.cpp @@ -35,8 +35,8 @@ namespace WebCore { -V8EventListener::V8EventListener(PassRefPtr<V8ListenerGuard> guard, v8::Local<v8::Object> listener, bool isAttribute) - : V8AbstractEventListener(guard, isAttribute) +V8EventListener::V8EventListener(v8::Local<v8::Object> listener, bool isAttribute, const WorldContextHandle& worldContext) + : V8AbstractEventListener(isAttribute, worldContext) { setListenerObject(listener); } diff --git a/WebCore/bindings/v8/custom/V8CustomEventListener.h b/WebCore/bindings/v8/custom/V8CustomEventListener.h index dc9d33b..f9d5385 100644 --- a/WebCore/bindings/v8/custom/V8CustomEventListener.h +++ b/WebCore/bindings/v8/custom/V8CustomEventListener.h @@ -44,13 +44,13 @@ namespace WebCore { // that can handle the event. class V8EventListener : public V8AbstractEventListener { public: - static PassRefPtr<V8EventListener> create(PassRefPtr<V8ListenerGuard> guard, v8::Local<v8::Object> listener, bool isAttribute) + static PassRefPtr<V8EventListener> create(v8::Local<v8::Object> listener, bool isAttribute, const WorldContextHandle& worldContext) { - return adoptRef(new V8EventListener(guard, listener, isAttribute)); + return adoptRef(new V8EventListener(listener, isAttribute, worldContext)); } protected: - V8EventListener(PassRefPtr<V8ListenerGuard>, v8::Local<v8::Object> listener, bool isAttribute); + V8EventListener(v8::Local<v8::Object> listener, bool isAttribute, const WorldContextHandle& worldContext); v8::Local<v8::Function> getListenerFunction(ScriptExecutionContext*); diff --git a/WebCore/bindings/v8/custom/V8CustomXPathNSResolver.cpp b/WebCore/bindings/v8/custom/V8CustomXPathNSResolver.cpp index 3341924..e45cba0 100644 --- a/WebCore/bindings/v8/custom/V8CustomXPathNSResolver.cpp +++ b/WebCore/bindings/v8/custom/V8CustomXPathNSResolver.cpp @@ -38,13 +38,14 @@ namespace WebCore { -PassRefPtr<V8CustomXPathNSResolver> V8CustomXPathNSResolver::create(v8::Handle<v8::Object> resolver) +PassRefPtr<V8CustomXPathNSResolver> V8CustomXPathNSResolver::create(V8Proxy* proxy, v8::Handle<v8::Object> resolver) { - return adoptRef(new V8CustomXPathNSResolver(resolver)); + return adoptRef(new V8CustomXPathNSResolver(proxy, resolver)); } -V8CustomXPathNSResolver::V8CustomXPathNSResolver(v8::Handle<v8::Object> resolver) - : m_resolver(resolver) +V8CustomXPathNSResolver::V8CustomXPathNSResolver(V8Proxy* proxy, v8::Handle<v8::Object> resolver) + : m_proxy(proxy) + , m_resolver(resolver) { } @@ -54,6 +55,14 @@ V8CustomXPathNSResolver::~V8CustomXPathNSResolver() String V8CustomXPathNSResolver::lookupNamespaceURI(const String& prefix) { + V8Proxy* proxy = m_proxy; + + if (!proxy) { + proxy = V8Proxy::retrieve(); + if (!proxy) + return String(); + } + v8::Handle<v8::Function> lookupNamespaceURIFunc; v8::Handle<v8::String> lookupNamespaceURIName = v8::String::New("lookupNamespaceURI"); @@ -65,7 +74,7 @@ String V8CustomXPathNSResolver::lookupNamespaceURI(const String& prefix) } if (lookupNamespaceURIFunc.IsEmpty() && !m_resolver->IsFunction()) { - Frame* frame = V8Proxy::retrieveFrameForEnteredContext(); + Frame* frame = proxy->frame(); logInfo(frame, "XPathNSResolver does not have a lookupNamespaceURI method.", String()); return String(); } @@ -78,7 +87,6 @@ String V8CustomXPathNSResolver::lookupNamespaceURI(const String& prefix) v8::Handle<v8::Value> argv[argc] = { v8String(prefix) }; v8::Handle<v8::Function> function = lookupNamespaceURIFunc.IsEmpty() ? v8::Handle<v8::Function>::Cast(m_resolver) : lookupNamespaceURIFunc; - V8Proxy* proxy = V8Proxy::retrieve(); v8::Handle<v8::Value> retval = proxy->callFunction(function, m_resolver, argc, argv); // Eat exceptions from namespace resolver and return an empty string. This will most likely cause NAMESPACE_ERR. diff --git a/WebCore/bindings/v8/custom/V8CustomXPathNSResolver.h b/WebCore/bindings/v8/custom/V8CustomXPathNSResolver.h index f1dc65c..15ac27d 100644 --- a/WebCore/bindings/v8/custom/V8CustomXPathNSResolver.h +++ b/WebCore/bindings/v8/custom/V8CustomXPathNSResolver.h @@ -42,17 +42,22 @@ namespace WebCore { class String; +class V8Proxy; +// V8CustomXPathNSResolver does not create a persistent handle to the +// given resolver object. So the lifetime of V8CustomXPathNSResolver +// must not exceed the lifetime of the passed handle. class V8CustomXPathNSResolver : public XPathNSResolver { public: - static PassRefPtr<V8CustomXPathNSResolver> create(v8::Handle<v8::Object> resolver); + static PassRefPtr<V8CustomXPathNSResolver> create(V8Proxy* proxy, v8::Handle<v8::Object> resolver); virtual ~V8CustomXPathNSResolver(); virtual String lookupNamespaceURI(const String& prefix); private: - V8CustomXPathNSResolver(v8::Handle<v8::Object> resolver); + V8CustomXPathNSResolver(V8Proxy* proxy, v8::Handle<v8::Object> resolver); + V8Proxy* m_proxy; v8::Handle<v8::Object> m_resolver; // Handle to resolver object. }; diff --git a/WebCore/bindings/v8/custom/V8DOMWindowCustom.cpp b/WebCore/bindings/v8/custom/V8DOMWindowCustom.cpp index 25d5ccd..46c33b9 100644 --- a/WebCore/bindings/v8/custom/V8DOMWindowCustom.cpp +++ b/WebCore/bindings/v8/custom/V8DOMWindowCustom.cpp @@ -46,7 +46,6 @@ #include "FrameView.h" #include "HTMLCollection.h" #include "MediaPlayer.h" -#include "NotificationCenter.h" #include "Page.h" #include "PlatformScreen.h" #include "RuntimeEnabledFeatures.h" @@ -176,6 +175,9 @@ ACCESSOR_GETTER(DOMWindowEvent) return v8::Undefined(); v8::Local<v8::Context> context = V8Proxy::context(frame); + if (context.IsEmpty()) + return v8::Undefined(); + v8::Local<v8::String> eventSymbol = v8::String::NewSymbol("event"); v8::Handle<v8::Value> jsEvent = context->Global()->GetHiddenValue(eventSymbol); if (jsEvent.IsEmpty()) @@ -194,6 +196,9 @@ ACCESSOR_SETTER(DOMWindowEvent) return; v8::Local<v8::Context> context = V8Proxy::context(frame); + if (context.IsEmpty()) + return; + v8::Local<v8::String> eventSymbol = v8::String::NewSymbol("event"); context->Global()->SetHiddenValue(eventSymbol, value); } @@ -306,7 +311,14 @@ ACCESSOR_RUNTIME_ENABLER(DOMWindowSessionStorage) #if ENABLE(NOTIFICATIONS) ACCESSOR_RUNTIME_ENABLER(DOMWindowWebkitNotifications) { - return NotificationCenter::isAvailable(); + return RuntimeEnabledFeatures::notificationsEnabled(); +} +#endif + +#if ENABLE(OFFLINE_WEB_APPLICATIONS) +ACCESSOR_RUNTIME_ENABLER(DOMWindowApplicationCache) +{ + return RuntimeEnabledFeatures::applicationCacheEnabled(); } #endif @@ -538,6 +550,10 @@ static Frame* createWindow(Frame* callingFrame, ASSERT(callingFrame); ASSERT(enteredFrame); + // Sandboxed iframes cannot open new auxiliary browsing contexts. + if (callingFrame && callingFrame->loader()->isSandboxed(SandboxNavigation)) + return 0; + ResourceRequest request; // For whatever reason, Firefox uses the entered frame to determine @@ -696,14 +712,15 @@ CALLBACK_FUNC_DECL(DOMWindowOpen) if (!V8Proxy::canAccessFrame(frame, true)) return v8::Undefined(); - Frame* callingFrame = V8Proxy::retrieveFrameForCallingContext(); - if (!callingFrame) - return v8::Undefined(); - Frame* enteredFrame = V8Proxy::retrieveFrameForEnteredContext(); if (!enteredFrame) return v8::Undefined(); + Frame* callingFrame = V8Proxy::retrieveFrameForCallingContext(); + // We may not have a calling context if we are invoked by a plugin via NPAPI. + if (!callingFrame) + callingFrame = enteredFrame; + Page* page = frame->page(); if (!page) return v8::Undefined(); diff --git a/WebCore/bindings/v8/custom/V8DocumentCustom.cpp b/WebCore/bindings/v8/custom/V8DocumentCustom.cpp index 8b77a3a..ee68293 100644 --- a/WebCore/bindings/v8/custom/V8DocumentCustom.cpp +++ b/WebCore/bindings/v8/custom/V8DocumentCustom.cpp @@ -64,7 +64,7 @@ CALLBACK_FUNC_DECL(DocumentEvaluate) if (V8Node::HasInstance(args[1])) contextNode = V8DOMWrapper::convertDOMWrapperToNode<Node>(v8::Handle<v8::Object>::Cast(args[1])); - RefPtr<XPathNSResolver> resolver = V8DOMWrapper::getXPathNSResolver(args[2]); + RefPtr<XPathNSResolver> resolver = V8DOMWrapper::getXPathNSResolver(args[2], V8Proxy::retrieve(V8Proxy::retrieveFrameForCallingContext())); if (!resolver && !args[2]->IsNull() && !args[2]->IsUndefined()) return throwError(TYPE_MISMATCH_ERR); @@ -104,7 +104,7 @@ CALLBACK_FUNC_DECL(DocumentGetCSSCanvasContext) return V8DOMWrapper::convertToV8Object(V8ClassIndex::CANVASRENDERINGCONTEXT2D, result); #if ENABLE(3D_CANVAS) else if (result->is3d()) - return V8DOMWrapper::convertToV8Object(V8ClassIndex::CANVASRENDERINGCONTEXT3D, result); + return V8DOMWrapper::convertToV8Object(V8ClassIndex::WEBGLRENDERINGCONTEXT, result); #endif // ENABLE(3D_CANVAS) ASSERT_NOT_REACHED(); return v8::Undefined(); diff --git a/WebCore/bindings/v8/custom/V8HTMLCanvasElementCustom.cpp b/WebCore/bindings/v8/custom/V8HTMLCanvasElementCustom.cpp index 4116673..e51437e 100644 --- a/WebCore/bindings/v8/custom/V8HTMLCanvasElementCustom.cpp +++ b/WebCore/bindings/v8/custom/V8HTMLCanvasElementCustom.cpp @@ -53,7 +53,7 @@ CALLBACK_FUNC_DECL(HTMLCanvasElementGetContext) return V8DOMWrapper::convertToV8Object(V8ClassIndex::CANVASRENDERINGCONTEXT2D, result); #if ENABLE(3D_CANVAS) else if (result->is3d()) - return V8DOMWrapper::convertToV8Object(V8ClassIndex::CANVASRENDERINGCONTEXT3D, result); + return V8DOMWrapper::convertToV8Object(V8ClassIndex::WEBGLRENDERINGCONTEXT, result); #endif ASSERT_NOT_REACHED(); return v8::Undefined(); diff --git a/WebCore/bindings/v8/custom/V8HTMLDocumentCustom.cpp b/WebCore/bindings/v8/custom/V8HTMLDocumentCustom.cpp index afc9ed1..9cf2f3d 100644 --- a/WebCore/bindings/v8/custom/V8HTMLDocumentCustom.cpp +++ b/WebCore/bindings/v8/custom/V8HTMLDocumentCustom.cpp @@ -120,8 +120,7 @@ CALLBACK_FUNC_DECL(HTMLDocumentWrite) INC_STATS("DOM.HTMLDocument.write()"); HTMLDocument* htmlDocument = V8DOMWrapper::convertDOMWrapperToNode<HTMLDocument>(args.Holder()); Frame* frame = V8Proxy::retrieveFrameForCallingContext(); - ASSERT(frame); - htmlDocument->write(writeHelperGetString(args), frame->document()); + htmlDocument->write(writeHelperGetString(args), frame ? frame->document() : NULL); return v8::Undefined(); } @@ -130,8 +129,7 @@ CALLBACK_FUNC_DECL(HTMLDocumentWriteln) INC_STATS("DOM.HTMLDocument.writeln()"); HTMLDocument* htmlDocument = V8DOMWrapper::convertDOMWrapperToNode<HTMLDocument>(args.Holder()); Frame* frame = V8Proxy::retrieveFrameForCallingContext(); - ASSERT(frame); - htmlDocument->writeln(writeHelperGetString(args), frame->document()); + htmlDocument->writeln(writeHelperGetString(args), frame ? frame->document() : NULL); return v8::Undefined(); } @@ -170,7 +168,7 @@ CALLBACK_FUNC_DECL(HTMLDocumentOpen) } Frame* frame = V8Proxy::retrieveFrameForCallingContext(); - htmlDocument->open(frame->document()); + htmlDocument->open(frame ? frame->document() : NULL); // Return the document. return args.Holder(); } diff --git a/WebCore/bindings/v8/custom/V8HistoryCustom.cpp b/WebCore/bindings/v8/custom/V8HistoryCustom.cpp new file mode 100644 index 0000000..c884d15 --- /dev/null +++ b/WebCore/bindings/v8/custom/V8HistoryCustom.cpp @@ -0,0 +1,83 @@ +/* + * 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 "History.h" + +#include "ExceptionCode.h" +#include "SerializedScriptValue.h" +#include "V8Binding.h" +#include "V8CustomBinding.h" +#include "V8Proxy.h" + +namespace WebCore { +CALLBACK_FUNC_DECL(HistoryPushState) +{ + RefPtr<SerializedScriptValue> historyState = SerializedScriptValue::create(toWebCoreString(args[0])); + + v8::TryCatch tryCatch; + String title = toWebCoreStringWithNullOrUndefinedCheck(args[1]); + if (tryCatch.HasCaught()) + return v8::Undefined(); + String url; + if (args.Length() > 2) { + url = toWebCoreStringWithNullOrUndefinedCheck(args[2]); + if (tryCatch.HasCaught()) + return v8::Undefined(); + } + + ExceptionCode ec = 0; + History* history = V8DOMWrapper::convertToNativeObject<History>(V8ClassIndex::HISTORY, args.Holder()); + history->stateObjectAdded(historyState.release(), title, url, History::StateObjectPush, ec); + return throwError(ec); +} + +CALLBACK_FUNC_DECL(HistoryReplaceState) +{ + RefPtr<SerializedScriptValue> historyState = SerializedScriptValue::create(toWebCoreString(args[0])); + + v8::TryCatch tryCatch; + String title = toWebCoreStringWithNullOrUndefinedCheck(args[1]); + if (tryCatch.HasCaught()) + return v8::Undefined(); + String url; + if (args.Length() > 2) { + url = toWebCoreStringWithNullOrUndefinedCheck(args[2]); + if (tryCatch.HasCaught()) + return v8::Undefined(); + } + + ExceptionCode ec = 0; + History* history = V8DOMWrapper::convertToNativeObject<History>(V8ClassIndex::HISTORY, args.Holder()); + history->stateObjectAdded(historyState.release(), title, url, History::StateObjectReplace, ec); + return throwError(ec); +} + +} // namespace WebCore diff --git a/WebCore/bindings/v8/custom/V8InjectedScriptHostCustom.cpp b/WebCore/bindings/v8/custom/V8InjectedScriptHostCustom.cpp new file mode 100644 index 0000000..fac6733 --- /dev/null +++ b/WebCore/bindings/v8/custom/V8InjectedScriptHostCustom.cpp @@ -0,0 +1,163 @@ +/* + * Copyright (C) 2007-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 "InjectedScriptHost.h" + +#include "Database.h" +#include "DOMWindow.h" +#include "Frame.h" +#include "InspectorController.h" +#include "Node.h" +#include "Page.h" + +#include "V8Binding.h" +#include "V8CustomBinding.h" +#include "V8Proxy.h" + +namespace WebCore { + +CALLBACK_FUNC_DECL(InjectedScriptHostInspectedWindow) +{ + INC_STATS("InjectedScriptHost.inspectedWindow()"); + + InjectedScriptHost* host = V8DOMWrapper::convertToNativeObject<InjectedScriptHost>(V8ClassIndex::INJECTEDSCRIPTHOST, args.Holder()); + InspectorController* ic = host->inspectorController(); + if (!ic) + return v8::Undefined(); + return V8DOMWrapper::convertToV8Object<DOMWindow>(V8ClassIndex::DOMWINDOW, ic->inspectedPage()->mainFrame()->domWindow()); +} + +CALLBACK_FUNC_DECL(InjectedScriptHostWrapCallback) +{ + INC_STATS("InjectedScriptHost.wrapCallback()"); + return args[0]; +} + +CALLBACK_FUNC_DECL(InjectedScriptHostNodeForId) +{ + INC_STATS("InjectedScriptHost.nodeForId()"); + if (args.Length() < 1) + return v8::Undefined(); + + InjectedScriptHost* host = V8DOMWrapper::convertToNativeObject<InjectedScriptHost>(V8ClassIndex::INJECTEDSCRIPTHOST, args.Holder()); + + Node* node = host->nodeForId(args[0]->ToInt32()->Value()); + if (!node) + return v8::Undefined(); + + InspectorController* ic = host->inspectorController(); + if (!ic) + return v8::Undefined(); + + return V8DOMWrapper::convertToV8Object(V8ClassIndex::NODE, node); +} + +CALLBACK_FUNC_DECL(InjectedScriptHostWrapObject) +{ + INC_STATS("InjectedScriptHost.wrapObject()"); + if (args.Length() < 2) + return v8::Undefined(); + + InjectedScriptHost* host = V8DOMWrapper::convertToNativeObject<InjectedScriptHost>(V8ClassIndex::INJECTEDSCRIPTHOST, args.Holder()); + return host->wrapObject(ScriptValue(args[0]), toWebCoreStringWithNullCheck(args[1])).v8Value(); +} + +CALLBACK_FUNC_DECL(InjectedScriptHostUnwrapObject) +{ + INC_STATS("InjectedScriptHost.unwrapObject()"); + if (args.Length() < 1) + return v8::Undefined(); + + InjectedScriptHost* host = V8DOMWrapper::convertToNativeObject<InjectedScriptHost>(V8ClassIndex::INJECTEDSCRIPTHOST, args.Holder()); + return host->unwrapObject(toWebCoreStringWithNullCheck(args[0])).v8Value(); +} + +CALLBACK_FUNC_DECL(InjectedScriptHostPushNodePathToFrontend) +{ + INC_STATS("InjectedScriptHost.pushNodePathToFrontend()"); + if (args.Length() < 2) + return v8::Undefined(); + + InjectedScriptHost* host = V8DOMWrapper::convertToNativeObject<InjectedScriptHost>(V8ClassIndex::INJECTEDSCRIPTHOST, args.Holder()); + Node* node = V8DOMWrapper::convertDOMWrapperToNode<Node>(v8::Handle<v8::Object>::Cast(args[0])); + bool selectInUI = args[1]->ToBoolean()->Value(); + if (node) + return v8::Number::New(host->pushNodePathToFrontend(node, selectInUI)); + + return v8::Undefined(); +} + +#if ENABLE(DATABASE) +CALLBACK_FUNC_DECL(InjectedScriptHostDatabaseForId) +{ + INC_STATS("InjectedScriptHost.databaseForId()"); + if (args.Length() < 1) + return v8::Undefined(); + + InjectedScriptHost* host = V8DOMWrapper::convertToNativeObject<InjectedScriptHost>(V8ClassIndex::INJECTEDSCRIPTHOST, args.Holder()); + Database* database = host->databaseForId(args[0]->ToInt32()->Value()); + if (!database) + return v8::Undefined(); + return V8DOMWrapper::convertToV8Object<Database>(V8ClassIndex::DATABASE, database); +} + +CALLBACK_FUNC_DECL(InjectedScriptHostSelectDatabase) +{ + INC_STATS("InjectedScriptHost.selectDatabase()"); + if (args.Length() < 1) + return v8::Undefined(); + + InjectedScriptHost* host = V8DOMWrapper::convertToNativeObject<InjectedScriptHost>(V8ClassIndex::INJECTEDSCRIPTHOST, args.Holder()); + Database* database = V8DOMWrapper::convertToNativeObject<Database>(V8ClassIndex::DATABASE, v8::Handle<v8::Object>::Cast(args[0])); + if (database) + host->selectDatabase(database); + + return v8::Undefined(); +} +#endif + +#if ENABLE(DOM_STORAGE) +CALLBACK_FUNC_DECL(InjectedScriptHostSelectDOMStorage) +{ + INC_STATS("InjectedScriptHost.selectDOMStorage()"); + if (args.Length() < 1) + return v8::Undefined(); + + InjectedScriptHost* host = V8DOMWrapper::convertToNativeObject<InjectedScriptHost>(V8ClassIndex::INJECTEDSCRIPTHOST, args.Holder()); + Storage* storage = V8DOMWrapper::convertToNativeObject<Storage>(V8ClassIndex::STORAGE, v8::Handle<v8::Object>::Cast(args[0])); + if (storage) + host->selectDOMStorage(storage); + + return v8::Undefined(); +} +#endif + +} // namespace WebCore diff --git a/WebCore/bindings/v8/custom/V8InspectorBackendCustom.cpp b/WebCore/bindings/v8/custom/V8InspectorBackendCustom.cpp deleted file mode 100644 index ec9b034..0000000 --- a/WebCore/bindings/v8/custom/V8InspectorBackendCustom.cpp +++ /dev/null @@ -1,306 +0,0 @@ -/* - * Copyright (C) 2007-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 "InspectorBackend.h" - -#include "Database.h" -#include "DOMWindow.h" -#include "Frame.h" -#include "FrameLoader.h" -#include "ExceptionCode.h" -#include "InspectorController.h" -#include "InspectorResource.h" -#include "NotImplemented.h" -#include "Node.h" -#include "Range.h" -#include "Page.h" -#include "TextIterator.h" -#include "VisiblePosition.h" - -#include "V8Binding.h" -#include "V8CustomBinding.h" -#include "V8Proxy.h" - -namespace WebCore { - -CALLBACK_FUNC_DECL(InspectorBackendHighlightDOMNode) -{ - INC_STATS("InspectorBackend.highlightDOMNode()"); - - if (args.Length() < 1) - return v8::Undefined(); - - InspectorBackend* inspectorBackend = V8DOMWrapper::convertToNativeObject<InspectorBackend>(V8ClassIndex::INSPECTORBACKEND, args.Holder()); - inspectorBackend->highlight(args[0]->ToInt32()->Value()); - return v8::Undefined(); -} - -CALLBACK_FUNC_DECL(InspectorBackendSearch) -{ - INC_STATS("InspectorBackend.search()"); - - if (args.Length() < 2) - return v8::Undefined(); - - Node* node = V8DOMWrapper::convertDOMWrapperToNode<Node>(v8::Handle<v8::Object>::Cast(args[0])); - if (!node) - return v8::Undefined(); - - String target = toWebCoreStringWithNullCheck(args[1]); - if (target.isEmpty()) - return v8::Undefined(); - - v8::Local<v8::Array> result = v8::Array::New(); - RefPtr<Range> searchRange(rangeOfContents(node)); - - ExceptionCode ec = 0; - int index = 0; - do { - RefPtr<Range> resultRange(findPlainText(searchRange.get(), target, true, false)); - if (resultRange->collapsed(ec)) - break; - - // A non-collapsed result range can in some funky whitespace cases still not - // advance the range's start position (4509328). Break to avoid infinite loop. - VisiblePosition newStart = endVisiblePosition(resultRange.get(), DOWNSTREAM); - if (newStart == startVisiblePosition(searchRange.get(), DOWNSTREAM)) - break; - - result->Set(v8::Number::New(index++), V8DOMWrapper::convertToV8Object(V8ClassIndex::RANGE, resultRange.release())); - - setStart(searchRange.get(), newStart); - } while (true); - - return result; -} - -#if ENABLE(DATABASE) -CALLBACK_FUNC_DECL(InspectorBackendDatabaseForId) -{ - INC_STATS("InspectorBackend.databaseForId()"); - if (args.Length() < 1) - return v8::Undefined(); - - InspectorBackend* inspectorBackend = V8DOMWrapper::convertToNativeObject<InspectorBackend>(V8ClassIndex::INSPECTORBACKEND, args.Holder()); - Database* database = inspectorBackend->databaseForId(args[0]->ToInt32()->Value()); - if (!database) - return v8::Undefined(); - return V8DOMWrapper::convertToV8Object<Database>(V8ClassIndex::DATABASE, database); -} -#endif - -CALLBACK_FUNC_DECL(InspectorBackendInspectedWindow) -{ - INC_STATS("InspectorBackend.inspectedWindow()"); - - InspectorBackend* inspectorBackend = V8DOMWrapper::convertToNativeObject<InspectorBackend>(V8ClassIndex::INSPECTORBACKEND, args.Holder()); - InspectorController* ic = inspectorBackend->inspectorController(); - if (!ic) - return v8::Undefined(); - return V8DOMWrapper::convertToV8Object<DOMWindow>(V8ClassIndex::DOMWINDOW, ic->inspectedPage()->mainFrame()->domWindow()); -} - -CALLBACK_FUNC_DECL(InspectorBackendSetting) -{ - INC_STATS("InspectorBackend.setting()"); - - if (args.Length() < 1) - return v8::Undefined(); - - String key = toWebCoreStringWithNullCheck(args[0]); - if (key.isEmpty()) - return v8::Undefined(); - - InspectorBackend* inspectorBackend = V8DOMWrapper::convertToNativeObject<InspectorBackend>(V8ClassIndex::INSPECTORBACKEND, args.Holder()); - InspectorController* ic = inspectorBackend->inspectorController(); - if (!ic) - return v8::Undefined(); - const InspectorController::Setting& setting = ic->setting(key); - - switch (setting.type()) { - default: - case InspectorController::Setting::NoType: - return v8::Undefined(); - case InspectorController::Setting::StringType: - return v8String(setting.string()); - case InspectorController::Setting::DoubleType: - return v8::Number::New(setting.doubleValue()); - case InspectorController::Setting::IntegerType: - return v8::Number::New(setting.integerValue()); - case InspectorController::Setting::BooleanType: - return v8Boolean(setting.booleanValue()); - case InspectorController::Setting::StringVectorType: { - const Vector<String>& strings = setting.stringVector(); - v8::Local<v8::Array> stringsArray = v8::Array::New(strings.size()); - const unsigned length = strings.size(); - for (unsigned i = 0; i < length; ++i) - stringsArray->Set(v8::Number::New(i), v8String(strings[i])); - return stringsArray; - } - } -} - -CALLBACK_FUNC_DECL(InspectorBackendSetSetting) -{ - INC_STATS("InspectorBackend.setSetting()"); - if (args.Length() < 2) - return v8::Undefined(); - - String key = toWebCoreStringWithNullCheck(args[0]); - if (key.isEmpty()) - return v8::Undefined(); - - InspectorController::Setting setting; - - v8::Local<v8::Value> value = args[1]; - if (value->IsUndefined() || value->IsNull()) { - // Do nothing. The setting is already NoType. - ASSERT(setting.type() == InspectorController::Setting::NoType); - } else if (value->IsString()) - setting.set(toWebCoreStringWithNullCheck(value)); - else if (value->IsNumber()) - setting.set(value->NumberValue()); - else if (value->IsBoolean()) - setting.set(value->BooleanValue()); - else if (value->IsArray()) { - v8::Local<v8::Array> v8Array = v8::Local<v8::Array>::Cast(value); - Vector<String> strings; - for (unsigned i = 0; i < v8Array->Length(); ++i) { - String item = toWebCoreString(v8Array->Get(v8::Integer::New(i))); - if (item.isEmpty()) - return v8::Undefined(); - strings.append(item); - } - setting.set(strings); - } else - return v8::Undefined(); - - InspectorBackend* inspectorBackend = V8DOMWrapper::convertToNativeObject<InspectorBackend>(V8ClassIndex::INSPECTORBACKEND, args.Holder()); - InspectorController* ic = inspectorBackend->inspectorController(); - if (ic) - inspectorBackend->inspectorController()->setSetting(key, setting); - - return v8::Undefined(); -} - -CALLBACK_FUNC_DECL(InspectorBackendWrapCallback) -{ - INC_STATS("InspectorBackend.wrapCallback()"); - return args[0]; -} - -CALLBACK_FUNC_DECL(InspectorBackendNodeForId) -{ - INC_STATS("InspectorBackend.nodeForId()"); - if (args.Length() < 1) - return v8::Undefined(); - - InspectorBackend* inspectorBackend = V8DOMWrapper::convertToNativeObject<InspectorBackend>(V8ClassIndex::INSPECTORBACKEND, args.Holder()); - - Node* node = inspectorBackend->nodeForId(args[0]->ToInt32()->Value()); - if (!node) - return v8::Undefined(); - - InspectorController* ic = inspectorBackend->inspectorController(); - if (!ic) - return v8::Undefined(); - - return V8DOMWrapper::convertToV8Object(V8ClassIndex::NODE, node); -} - -CALLBACK_FUNC_DECL(InspectorBackendWrapObject) -{ - INC_STATS("InspectorBackend.wrapObject()"); - if (args.Length() < 2) - return v8::Undefined(); - - InspectorBackend* inspectorBackend = V8DOMWrapper::convertToNativeObject<InspectorBackend>(V8ClassIndex::INSPECTORBACKEND, args.Holder()); - return inspectorBackend->wrapObject(ScriptValue(args[0]), toWebCoreStringWithNullCheck(args[1])).v8Value(); -} - -CALLBACK_FUNC_DECL(InspectorBackendUnwrapObject) -{ - INC_STATS("InspectorBackend.unwrapObject()"); - if (args.Length() < 1) - return v8::Undefined(); - - InspectorBackend* inspectorBackend = V8DOMWrapper::convertToNativeObject<InspectorBackend>(V8ClassIndex::INSPECTORBACKEND, args.Holder()); - return inspectorBackend->unwrapObject(toWebCoreStringWithNullCheck(args[0])).v8Value(); -} - -CALLBACK_FUNC_DECL(InspectorBackendPushNodePathToFrontend) -{ - INC_STATS("InspectorBackend.pushNodePathToFrontend()"); - if (args.Length() < 2) - return v8::Undefined(); - - InspectorBackend* inspectorBackend = V8DOMWrapper::convertToNativeObject<InspectorBackend>(V8ClassIndex::INSPECTORBACKEND, args.Holder()); - Node* node = V8DOMWrapper::convertDOMWrapperToNode<Node>(v8::Handle<v8::Object>::Cast(args[0])); - bool selectInUI = args[1]->ToBoolean()->Value(); - if (node) - return v8::Number::New(inspectorBackend->pushNodePathToFrontend(node, selectInUI)); - - return v8::Undefined(); -} - -#if ENABLE(DATABASE) -CALLBACK_FUNC_DECL(InspectorBackendSelectDatabase) -{ - INC_STATS("InspectorBackend.selectDatabase()"); - if (args.Length() < 1) - return v8::Undefined(); - - InspectorBackend* inspectorBackend = V8DOMWrapper::convertToNativeObject<InspectorBackend>(V8ClassIndex::INSPECTORBACKEND, args.Holder()); - Database* database = V8DOMWrapper::convertToNativeObject<Database>(V8ClassIndex::DATABASE, v8::Handle<v8::Object>::Cast(args[0])); - if (database) - inspectorBackend->selectDatabase(database); - - return v8::Undefined(); -} -#endif - -#if ENABLE(DOM_STORAGE) -CALLBACK_FUNC_DECL(InspectorBackendSelectDOMStorage) -{ - INC_STATS("InspectorBackend.selectDOMStorage()"); - if (args.Length() < 1) - return v8::Undefined(); - - InspectorBackend* inspectorBackend = V8DOMWrapper::convertToNativeObject<InspectorBackend>(V8ClassIndex::INSPECTORBACKEND, args.Holder()); - Storage* storage = V8DOMWrapper::convertToNativeObject<Storage>(V8ClassIndex::STORAGE, v8::Handle<v8::Object>::Cast(args[0])); - if (storage) - inspectorBackend->selectDOMStorage(storage); - - return v8::Undefined(); -} -#endif - -} // namespace WebCore diff --git a/WebCore/bindings/v8/custom/V8InspectorFrontendHostCustom.cpp b/WebCore/bindings/v8/custom/V8InspectorFrontendHostCustom.cpp new file mode 100644 index 0000000..15b45e9 --- /dev/null +++ b/WebCore/bindings/v8/custom/V8InspectorFrontendHostCustom.cpp @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2007-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 "InspectorFrontendHost.h" + +#include "ExceptionCode.h" +#include "InspectorController.h" +#include "Node.h" +#include "Range.h" +#include "Page.h" +#include "TextIterator.h" +#include "VisiblePosition.h" + +#include "V8Binding.h" +#include "V8CustomBinding.h" +#include "V8Proxy.h" + +namespace WebCore { + +CALLBACK_FUNC_DECL(InspectorFrontendHostSearch) +{ + INC_STATS("InspectorFrontendHost.search()"); + + if (args.Length() < 2) + return v8::Undefined(); + + Node* node = V8DOMWrapper::convertDOMWrapperToNode<Node>(v8::Handle<v8::Object>::Cast(args[0])); + if (!node) + return v8::Undefined(); + + String target = toWebCoreStringWithNullCheck(args[1]); + if (target.isEmpty()) + return v8::Undefined(); + + v8::Local<v8::Array> result = v8::Array::New(); + RefPtr<Range> searchRange(rangeOfContents(node)); + + ExceptionCode ec = 0; + int index = 0; + do { + RefPtr<Range> resultRange(findPlainText(searchRange.get(), target, true, false)); + if (resultRange->collapsed(ec)) + break; + + // A non-collapsed result range can in some funky whitespace cases still not + // advance the range's start position (4509328). Break to avoid infinite loop. + VisiblePosition newStart = endVisiblePosition(resultRange.get(), DOWNSTREAM); + if (newStart == startVisiblePosition(searchRange.get(), DOWNSTREAM)) + break; + + result->Set(v8::Number::New(index++), V8DOMWrapper::convertToV8Object(V8ClassIndex::RANGE, resultRange.release())); + + setStart(searchRange.get(), newStart); + } while (true); + + return result; +} + +CALLBACK_FUNC_DECL(InspectorFrontendHostShowContextMenu) +{ + return v8::Undefined(); +} + +} // namespace WebCore diff --git a/WebCore/bindings/v8/custom/V8NotificationCenterCustom.cpp b/WebCore/bindings/v8/custom/V8NotificationCenterCustom.cpp index bd5fb4a..a1f20cc 100644 --- a/WebCore/bindings/v8/custom/V8NotificationCenterCustom.cpp +++ b/WebCore/bindings/v8/custom/V8NotificationCenterCustom.cpp @@ -82,15 +82,15 @@ CALLBACK_FUNC_DECL(NotificationCenterCreateHTMLNotification) { INC_STATS(L"DOM.NotificationCenter.CreateHTMLNotification()"); NotificationCenter* notificationCenter = V8DOMWrapper::convertToNativeObject<NotificationCenter>(V8ClassIndex::NOTIFICATIONCENTER, args.Holder()); - ScriptExecutionContext* context = notificationCenter->context(); + ExceptionCode ec = 0; String url = toWebCoreString(args[0]); - RefPtr<Notification> notification = Notification::create(url, context, ec, notificationCenter->presenter()); + RefPtr<Notification> notification = notificationCenter->createHTMLNotification(url, ec); if (ec) return throwError(ec); - if (context->isWorkerContext()) + if (notificationCenter->context()->isWorkerContext()) return WorkerContextExecutionProxy::convertToV8Object(V8ClassIndex::NOTIFICATION, notification.get()); return V8DOMWrapper::convertToV8Object(V8ClassIndex::NOTIFICATION, notification.get()); @@ -100,16 +100,14 @@ CALLBACK_FUNC_DECL(NotificationCenterCreateNotification) { INC_STATS(L"DOM.NotificationCenter.CreateNotification()"); NotificationCenter* notificationCenter = V8DOMWrapper::convertToNativeObject<NotificationCenter>(V8ClassIndex::NOTIFICATIONCENTER, args.Holder()); - NotificationContents contents(toWebCoreString(args[0]), toWebCoreString(args[1]), toWebCoreString(args[2])); - ScriptExecutionContext* context = notificationCenter->context(); ExceptionCode ec = 0; - RefPtr<Notification> notification = Notification::create(contents, context, ec, notificationCenter->presenter()); + RefPtr<Notification> notification = notificationCenter->createNotification(toWebCoreString(args[0]), toWebCoreString(args[1]), toWebCoreString(args[2]), ec); if (ec) return throwError(ec); - if (context->isWorkerContext()) + if (notificationCenter->context()->isWorkerContext()) return WorkerContextExecutionProxy::convertToV8Object(V8ClassIndex::NOTIFICATION, notification.get()); return V8DOMWrapper::convertToV8Object(V8ClassIndex::NOTIFICATION, notification.get()); diff --git a/WebCore/bindings/v8/custom/V8SVGMatrixCustom.cpp b/WebCore/bindings/v8/custom/V8SVGMatrixCustom.cpp index 3766397..690eac1 100644 --- a/WebCore/bindings/v8/custom/V8SVGMatrixCustom.cpp +++ b/WebCore/bindings/v8/custom/V8SVGMatrixCustom.cpp @@ -38,11 +38,27 @@ #include "V8Binding.h" #include "V8CustomBinding.h" +#include "V8SVGMatrix.h" #include "V8SVGPODTypeWrapper.h" #include "V8Proxy.h" namespace WebCore { +CALLBACK_FUNC_DECL(SVGMatrixMultiply) +{ + INC_STATS("DOM.SVGMatrix.multiply()"); + if (args.Length() < 1) + return throwError("Not enough arguments"); + + if (!V8SVGMatrix::HasInstance(args[0])) + return throwError("secondMatrix argument was not a SVGMatrix"); + + TransformationMatrix m1 = *V8DOMWrapper::convertToNativeObject<V8SVGPODTypeWrapper<TransformationMatrix> >(V8ClassIndex::SVGMATRIX, args.Holder()); + TransformationMatrix m2 = *V8DOMWrapper::convertToNativeObject<V8SVGPODTypeWrapper<TransformationMatrix> >(V8ClassIndex::SVGMATRIX, v8::Handle<v8::Object>::Cast(args[0])); + + return V8DOMWrapper::convertToV8Object(V8ClassIndex::SVGMATRIX, V8SVGStaticPODTypeWrapper<TransformationMatrix>::create(m1.multLeft(m2))); +} + CALLBACK_FUNC_DECL(SVGMatrixInverse) { INC_STATS("DOM.SVGMatrix.inverse()"); diff --git a/WebCore/bindings/v8/custom/V8StyleSheetListCustom.cpp b/WebCore/bindings/v8/custom/V8StyleSheetListCustom.cpp index ecd0153..32a48eb 100644 --- a/WebCore/bindings/v8/custom/V8StyleSheetListCustom.cpp +++ b/WebCore/bindings/v8/custom/V8StyleSheetListCustom.cpp @@ -29,6 +29,7 @@ */ #include "config.h" +#include "HTMLStyleElement.h" #include "StyleSheetList.h" #include "V8Binding.h" @@ -50,7 +51,7 @@ NAMED_PROPERTY_GETTER(StyleSheetList) if (!item) return notHandledByInterceptor(); - return V8DOMWrapper::convertToV8Object(V8ClassIndex::HTMLSTYLEELEMENT, item); + return V8DOMWrapper::convertToV8Object(V8ClassIndex::STYLESHEET, item->sheet()); } } // namespace WebCore diff --git a/WebCore/bindings/v8/custom/V8CanvasArrayBufferCustom.cpp b/WebCore/bindings/v8/custom/V8WebGLArrayBufferCustom.cpp index 4a85e82..16a1f51 100644 --- a/WebCore/bindings/v8/custom/V8CanvasArrayBufferCustom.cpp +++ b/WebCore/bindings/v8/custom/V8WebGLArrayBufferCustom.cpp @@ -32,37 +32,50 @@ #if ENABLE(3D_CANVAS) -#include "CanvasArrayBuffer.h" +#include "WebGLArrayBuffer.h" #include "V8Binding.h" -#include "V8CanvasArrayBuffer.h" +#include "V8WebGLArrayBuffer.h" #include "V8CustomBinding.h" #include "V8Proxy.h" namespace WebCore { -CALLBACK_FUNC_DECL(CanvasArrayBufferConstructor) +CALLBACK_FUNC_DECL(WebGLArrayBufferConstructor) { - INC_STATS("DOM.CanvasArrayBuffer.Contructor"); + INC_STATS("DOM.WebGLArrayBuffer.Constructor"); if (!args.IsConstructCall()) return throwError("DOM object constructor cannot be called as a function."); - int argLen = args.Length(); + // If we return a previously constructed WebGLArrayBuffer, + // e.g. from the call to WebGLArray.buffer, this code is called + // with a zero-length argument list. The V8DOMWrapper will then + // set the internal pointer in the newly-created object. + // Unfortunately it doesn't look like it's possible to distinguish + // between this case and that where the user calls "new + // WebGLArrayBuffer()" from JavaScript. To guard against problems, + // we always create at least a zero-length WebGLArrayBuffer, even + // if it is immediately overwritten by the V8DOMWrapper. + // Supported constructors: - // CanvasArrayBuffer(n) where n is an integer: + // WebGLArrayBuffer(n) where n is an integer: // -- create an empty buffer of n bytes - if (argLen != 1) + int argLen = args.Length(); + if (argLen > 1) return throwError("Wrong number of arguments specified to constructor (requires 1)"); int len = 0; - if (!args[0]->IsInt32()) - return throwError("Argument to CanvasArrayBuffer constructor was not an integer"); - len = toInt32(args[0]); - RefPtr<CanvasArrayBuffer> buffer = CanvasArrayBuffer::create(len); + if (argLen > 0) { + if (!args[0]->IsInt32()) + return throwError("Argument to WebGLArrayBuffer constructor was not an integer"); + len = toInt32(args[0]); + } + + RefPtr<WebGLArrayBuffer> buffer = WebGLArrayBuffer::create(len); // Transform the holder into a wrapper object for the array. - V8DOMWrapper::setDOMWrapper(args.Holder(), V8ClassIndex::ToInt(V8ClassIndex::CANVASARRAYBUFFER), buffer.get()); + V8DOMWrapper::setDOMWrapper(args.Holder(), V8ClassIndex::ToInt(V8ClassIndex::WEBGLARRAYBUFFER), buffer.get()); return toV8(buffer.release(), args.Holder()); } diff --git a/WebCore/bindings/v8/custom/V8WebGLArrayCustom.h b/WebCore/bindings/v8/custom/V8WebGLArrayCustom.h new file mode 100644 index 0000000..1a4b6a4 --- /dev/null +++ b/WebCore/bindings/v8/custom/V8WebGLArrayCustom.h @@ -0,0 +1,220 @@ +/* + * 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(3D_CANVAS) + +#include "WebGLArrayBuffer.h" + +#include "V8Binding.h" +#include "V8WebGLArrayBuffer.h" +#include "V8CustomBinding.h" +#include "V8Proxy.h" + +namespace WebCore { + +// Template function used by the WebGLArray*Constructor callbacks. +template<class ArrayClass> +v8::Handle<v8::Value> constructWebGLArray(const v8::Arguments& args, + int classIndex) +{ + if (!args.IsConstructCall()) + return throwError("DOM object constructor cannot be called as a function."); + + int argLen = args.Length(); + if (argLen == 0) { + // This happens when we return a previously constructed + // WebGLArray, e.g. from the call to WebGL<T>Array.slice(). + // The V8DOMWrapper will set the internal pointer in the + // created object. Unfortunately it doesn't look like it's + // possible to distinguish between this case and that where + // the user calls "new WebGL<T>Array()" from JavaScript. + return args.Holder(); + } + + // Supported constructors: + // WebGL<T>Array(n) where n is an integer: + // -- create an empty array of n elements + // WebGL<T>Array(arr) where arr is an array: + // -- create a WebGL<T>Array containing the contents of "arr" + // WebGL<T>Array(buf, offset, length) + // -- create a WebGL<T>Array pointing to the WebGLArrayBuffer + // "buf", starting at the specified offset, for the given + // length + + // See whether the first argument is a WebGLArrayBuffer. + if (V8WebGLArrayBuffer::HasInstance(args[0])) { + if (argLen > 3) + return throwError("Wrong number of arguments to new WebGL<T>Array(WebGLArrayBuffer, int, int)"); + + WebGLArrayBuffer* buf = + V8DOMWrapper::convertToNativeObject<WebGLArrayBuffer>(V8ClassIndex::WEBGLARRAYBUFFER, + args[0]->ToObject()); + if (buf == NULL) + return throwError("Could not convert argument 0 to a WebGLArrayBuffer"); + bool ok; + int offset = 0; + if (argLen > 1) { + offset = toInt32(args[1], ok); + if (!ok) + return throwError("Could not convert argument 1 to an integer"); + } + int length = buf->byteLength() - offset; + if (argLen > 2) { + length = toInt32(args[2], ok); + if (!ok) + return throwError("Could not convert argument 2 to an integer"); + } + if (length < 0) + return throwError("Length / offset out of range"); + + RefPtr<ArrayClass> array = ArrayClass::create(buf, offset, length); + if (array == NULL) + return throwError("Invalid arguments to new WebGL<T>Array(WebGLArrayBuffer, int, int)"); + // Transform the holder into a wrapper object for the array. + V8DOMWrapper::setDOMWrapper(args.Holder(), classIndex, array.get()); + V8DOMWrapper::setIndexedPropertiesToExternalArray(args.Holder(), + classIndex, + array.get()->baseAddress(), + array.get()->length()); + return toV8(array.release(), args.Holder()); + } + + int len = 0; + v8::Handle<v8::Object> srcArray; + if (argLen != 1) + return throwError("Wrong number of arguments to new WebGL<T>Array(int / array)"); + + if (args[0]->IsInt32()) { + len = toInt32(args[0]); + } else if (args[0]->IsObject()) { + srcArray = args[0]->ToObject(); + if (srcArray.IsEmpty()) + return throwError("Could not convert argument 0 to an object"); + len = toInt32(srcArray->Get(v8::String::New("length"))); + } else + return throwError("Could not convert argument 0 to either an int32 or an object"); + + RefPtr<ArrayClass> array = ArrayClass::create(len); + if (!srcArray.IsEmpty()) { + // Need to copy the incoming array into the newly created WebGLArray. + for (int i = 0; i < len; i++) { + v8::Local<v8::Value> val = srcArray->Get(v8::Integer::New(i)); + array->set(i, val->NumberValue()); + } + } + + // Transform the holder into a wrapper object for the array. + V8DOMWrapper::setDOMWrapper(args.Holder(), classIndex, array.get()); + V8DOMWrapper::setIndexedPropertiesToExternalArray(args.Holder(), + classIndex, + array.get()->baseAddress(), + array.get()->length()); + return toV8(array.release(), args.Holder()); +} + +template <class T, typename ElementType> +v8::Handle<v8::Value> getWebGLArrayElement(const v8::Arguments& args, + V8ClassIndex::V8WrapperType wrapperType) +{ + if (args.Length() != 1) { + V8Proxy::setDOMException(SYNTAX_ERR); + return notHandledByInterceptor(); + } + bool ok; + uint32_t index = toInt32(args[0], ok); + if (!ok) { + V8Proxy::setDOMException(SYNTAX_ERR); + return notHandledByInterceptor(); + } + T* array = V8DOMWrapper::convertToNativeObject<T>(wrapperType, args.Holder()); + if (index >= array->length()) + return v8::Undefined(); + ElementType result; + if (!array->get(index, result)) + return v8::Undefined(); + return v8::Number::New(result); +} + +template <class T> +v8::Handle<v8::Value> setWebGLArrayFromArray(T* webGLArray, const v8::Arguments& args) +{ + if (args[0]->IsObject()) { + // void set(in sequence<long> array, [Optional] in unsigned long offset); + v8::Local<v8::Object> array = args[0]->ToObject(); + uint32_t offset = 0; + if (args.Length() == 2) + offset = toInt32(args[1]); + uint32_t length = toInt32(array->Get(v8::String::New("length"))); + for (uint32_t i = 0; i < length; i++) { + webGLArray->set(offset + i, array->Get(v8::Integer::New(i))->NumberValue()); + } + } + + return v8::Undefined(); +} + +template <class CPlusPlusArrayType, class JavaScriptWrapperArrayType> +v8::Handle<v8::Value> setWebGLArray(const v8::Arguments& args, + V8ClassIndex::V8WrapperType wrapperType) +{ + if (args.Length() < 1 || args.Length() > 2) { + V8Proxy::setDOMException(SYNTAX_ERR); + return notHandledByInterceptor(); + } + + CPlusPlusArrayType* array = V8DOMWrapper::convertToNativeObject<CPlusPlusArrayType>(wrapperType, args.Holder()); + + if (args.Length() == 2 && args[0]->IsInt32()) { + // void set(in unsigned long index, in long value); + uint32_t index = toInt32(args[0]); + array->set(index, args[1]->NumberValue()); + return v8::Undefined(); + } + + if (JavaScriptWrapperArrayType::HasInstance(args[0])) { + // void set(in WebGL<T>Array array, [Optional] in unsigned long offset); + CPlusPlusArrayType* src = V8DOMWrapper::convertToNativeObject<CPlusPlusArrayType>(wrapperType, args[0]->ToObject()); + uint32_t offset = 0; + if (args.Length() == 2) + offset = toInt32(args[1]); + ExceptionCode ec = 0; + array->set(src, offset, ec); + V8Proxy::setDOMException(ec); + return v8::Undefined(); + } + + return setWebGLArrayFromArray(array, args); +} + +} + +#endif // ENABLE(3D_CANVAS) diff --git a/WebCore/bindings/v8/custom/V8CanvasByteArrayCustom.cpp b/WebCore/bindings/v8/custom/V8WebGLByteArrayCustom.cpp index 503e5e8..5719c8a 100644 --- a/WebCore/bindings/v8/custom/V8CanvasByteArrayCustom.cpp +++ b/WebCore/bindings/v8/custom/V8WebGLByteArrayCustom.cpp @@ -32,29 +32,30 @@ #if ENABLE(3D_CANVAS) -#include "CanvasArrayBuffer.h" -#include "CanvasByteArray.h" +#include "WebGLArrayBuffer.h" +#include "WebGLByteArray.h" #include "V8Binding.h" -#include "V8CanvasArrayBuffer.h" -#include "V8CanvasArrayCustom.h" +#include "V8WebGLArrayBuffer.h" +#include "V8WebGLArrayCustom.h" +#include "V8WebGLByteArray.h" #include "V8CustomBinding.h" #include "V8Proxy.h" namespace WebCore { -CALLBACK_FUNC_DECL(CanvasByteArrayConstructor) +CALLBACK_FUNC_DECL(WebGLByteArrayConstructor) { - INC_STATS("DOM.CanvasByteArray.Contructor"); + INC_STATS("DOM.WebGLByteArray.Contructor"); - return constructCanvasArray<CanvasByteArray>(args, V8ClassIndex::ToInt(V8ClassIndex::CANVASBYTEARRAY)); + return constructWebGLArray<WebGLByteArray>(args, V8ClassIndex::ToInt(V8ClassIndex::WEBGLBYTEARRAY)); } // Get the specified value from the byte buffer and return it wrapped as a JavaScript Number object to V8. Accesses outside the valid byte buffer range return "undefined". -INDEXED_PROPERTY_GETTER(CanvasByteArray) +INDEXED_PROPERTY_GETTER(WebGLByteArray) { - INC_STATS("DOM.CanvasByteArray.IndexedPropertyGetter"); - CanvasByteArray* byteBuffer = V8DOMWrapper::convertToNativeObject<CanvasByteArray>(V8ClassIndex::CANVASBYTEARRAY, info.Holder()); + INC_STATS("DOM.WebGLByteArray.IndexedPropertyGetter"); + WebGLByteArray* byteBuffer = V8DOMWrapper::convertToNativeObject<WebGLByteArray>(V8ClassIndex::WEBGLBYTEARRAY, info.Holder()); if ((index < 0) || (index >= byteBuffer->length())) return v8::Undefined(); @@ -65,10 +66,10 @@ INDEXED_PROPERTY_GETTER(CanvasByteArray) } // Set the specified value in the byte buffer. Accesses outside the valid byte buffer range are silently ignored. -INDEXED_PROPERTY_SETTER(CanvasByteArray) +INDEXED_PROPERTY_SETTER(WebGLByteArray) { - INC_STATS("DOM.CanvasByteArray.IndexedPropertySetter"); - CanvasByteArray* array = V8DOMWrapper::convertToNativeObject<CanvasByteArray>(V8ClassIndex::CANVASBYTEARRAY, info.Holder()); + INC_STATS("DOM.WebGLByteArray.IndexedPropertySetter"); + WebGLByteArray* array = V8DOMWrapper::convertToNativeObject<WebGLByteArray>(V8ClassIndex::WEBGLBYTEARRAY, info.Holder()); if ((index >= 0) && (index < array->length())) { if (!value->IsNumber()) @@ -78,6 +79,18 @@ INDEXED_PROPERTY_SETTER(CanvasByteArray) return value; } +CALLBACK_FUNC_DECL(WebGLByteArrayGet) +{ + INC_STATS("DOM.WebGLByteArray.get()"); + return getWebGLArrayElement<WebGLByteArray, signed char>(args, V8ClassIndex::WEBGLBYTEARRAY); +} + +CALLBACK_FUNC_DECL(WebGLByteArraySet) +{ + INC_STATS("DOM.WebGLByteArray.set()"); + return setWebGLArray<WebGLByteArray, V8WebGLByteArray>(args, V8ClassIndex::WEBGLBYTEARRAY); +} + } // namespace WebCore #endif // ENABLE(3D_CANVAS) diff --git a/WebCore/bindings/v8/custom/V8CanvasFloatArrayCustom.cpp b/WebCore/bindings/v8/custom/V8WebGLFloatArrayCustom.cpp index b3c1d62..6e56760 100644 --- a/WebCore/bindings/v8/custom/V8CanvasFloatArrayCustom.cpp +++ b/WebCore/bindings/v8/custom/V8WebGLFloatArrayCustom.cpp @@ -32,29 +32,30 @@ #if ENABLE(3D_CANVAS) -#include "CanvasArrayBuffer.h" -#include "CanvasFloatArray.h" +#include "WebGLArrayBuffer.h" +#include "WebGLFloatArray.h" #include "V8Binding.h" -#include "V8CanvasArrayBuffer.h" -#include "V8CanvasArrayCustom.h" +#include "V8WebGLArrayBuffer.h" +#include "V8WebGLArrayCustom.h" +#include "V8WebGLFloatArray.h" #include "V8CustomBinding.h" #include "V8Proxy.h" namespace WebCore { -CALLBACK_FUNC_DECL(CanvasFloatArrayConstructor) +CALLBACK_FUNC_DECL(WebGLFloatArrayConstructor) { - INC_STATS("DOM.CanvasFloatArray.Contructor"); + INC_STATS("DOM.WebGLFloatArray.Contructor"); - return constructCanvasArray<CanvasFloatArray>(args, V8ClassIndex::ToInt(V8ClassIndex::CANVASFLOATARRAY)); + return constructWebGLArray<WebGLFloatArray>(args, V8ClassIndex::ToInt(V8ClassIndex::WEBGLFLOATARRAY)); } // Get the specified value from the array and return it wrapped as a JavaScript Number object to V8. Accesses outside the valid array range return "undefined". -INDEXED_PROPERTY_GETTER(CanvasFloatArray) +INDEXED_PROPERTY_GETTER(WebGLFloatArray) { - INC_STATS("DOM.CanvasFloatArray.IndexedPropertyGetter"); - CanvasFloatArray* array = V8DOMWrapper::convertToNativeObject<CanvasFloatArray>(V8ClassIndex::CANVASFLOATARRAY, info.Holder()); + INC_STATS("DOM.WebGLFloatArray.IndexedPropertyGetter"); + WebGLFloatArray* array = V8DOMWrapper::convertToNativeObject<WebGLFloatArray>(V8ClassIndex::WEBGLFLOATARRAY, info.Holder()); if ((index < 0) || (index >= array->length())) return v8::Undefined(); @@ -65,16 +66,28 @@ INDEXED_PROPERTY_GETTER(CanvasFloatArray) } // Set the specified value in the array. Accesses outside the valid array range are silently ignored. -INDEXED_PROPERTY_SETTER(CanvasFloatArray) +INDEXED_PROPERTY_SETTER(WebGLFloatArray) { - INC_STATS("DOM.CanvasFloatArray.IndexedPropertySetter"); - CanvasFloatArray* array = V8DOMWrapper::convertToNativeObject<CanvasFloatArray>(V8ClassIndex::CANVASFLOATARRAY, info.Holder()); + INC_STATS("DOM.WebGLFloatArray.IndexedPropertySetter"); + WebGLFloatArray* array = V8DOMWrapper::convertToNativeObject<WebGLFloatArray>(V8ClassIndex::WEBGLFLOATARRAY, info.Holder()); if ((index >= 0) && (index < array->length())) array->set(index, value->NumberValue()); return value; } +CALLBACK_FUNC_DECL(WebGLFloatArrayGet) +{ + INC_STATS("DOM.WebGLFloatArray.get()"); + return getWebGLArrayElement<WebGLFloatArray, float>(args, V8ClassIndex::WEBGLFLOATARRAY); +} + +CALLBACK_FUNC_DECL(WebGLFloatArraySet) +{ + INC_STATS("DOM.WebGLFloatArray.set()"); + return setWebGLArray<WebGLFloatArray, V8WebGLFloatArray>(args, V8ClassIndex::WEBGLFLOATARRAY); +} + } // namespace WebCore #endif // ENABLE(3D_CANVAS) diff --git a/WebCore/bindings/v8/custom/V8CanvasIntArrayCustom.cpp b/WebCore/bindings/v8/custom/V8WebGLIntArrayCustom.cpp index 6f35db8..1bd30b2 100644 --- a/WebCore/bindings/v8/custom/V8CanvasIntArrayCustom.cpp +++ b/WebCore/bindings/v8/custom/V8WebGLIntArrayCustom.cpp @@ -32,29 +32,30 @@ #if ENABLE(3D_CANVAS) -#include "CanvasArrayBuffer.h" -#include "CanvasIntArray.h" +#include "WebGLArrayBuffer.h" +#include "WebGLIntArray.h" #include "V8Binding.h" -#include "V8CanvasArrayBuffer.h" -#include "V8CanvasArrayCustom.h" +#include "V8WebGLArrayBuffer.h" +#include "V8WebGLArrayCustom.h" +#include "V8WebGLIntArray.h" #include "V8CustomBinding.h" #include "V8Proxy.h" namespace WebCore { -CALLBACK_FUNC_DECL(CanvasIntArrayConstructor) +CALLBACK_FUNC_DECL(WebGLIntArrayConstructor) { - INC_STATS("DOM.CanvasIntArray.Contructor"); + INC_STATS("DOM.WebGLIntArray.Contructor"); - return constructCanvasArray<CanvasIntArray>(args, V8ClassIndex::ToInt(V8ClassIndex::CANVASINTARRAY)); + return constructWebGLArray<WebGLIntArray>(args, V8ClassIndex::ToInt(V8ClassIndex::WEBGLINTARRAY)); } // Get the specified value from the integer array and return it wrapped as a JavaScript Number object to V8. Accesses outside the valid pixel buffer range return "undefined". -INDEXED_PROPERTY_GETTER(CanvasIntArray) +INDEXED_PROPERTY_GETTER(WebGLIntArray) { - INC_STATS("DOM.CanvasIntArray.IndexedPropertyGetter"); - CanvasIntArray* array = V8DOMWrapper::convertToNativeObject<CanvasIntArray>(V8ClassIndex::CANVASINTARRAY, info.Holder()); + INC_STATS("DOM.WebGLIntArray.IndexedPropertyGetter"); + WebGLIntArray* array = V8DOMWrapper::convertToNativeObject<WebGLIntArray>(V8ClassIndex::WEBGLINTARRAY, info.Holder()); if ((index < 0) || (index >= array->length())) return v8::Undefined(); @@ -65,10 +66,10 @@ INDEXED_PROPERTY_GETTER(CanvasIntArray) } // Set the specified value in the integer array. Accesses outside the valid integer array range are silently ignored. -INDEXED_PROPERTY_SETTER(CanvasIntArray) +INDEXED_PROPERTY_SETTER(WebGLIntArray) { - INC_STATS("DOM.CanvasIntArray.IndexedPropertySetter"); - CanvasIntArray* array = V8DOMWrapper::convertToNativeObject<CanvasIntArray>(V8ClassIndex::CANVASINTARRAY, info.Holder()); + INC_STATS("DOM.WebGLIntArray.IndexedPropertySetter"); + WebGLIntArray* array = V8DOMWrapper::convertToNativeObject<WebGLIntArray>(V8ClassIndex::WEBGLINTARRAY, info.Holder()); if ((index >= 0) && (index < array->length())) { if (!value->IsNumber()) @@ -78,6 +79,18 @@ INDEXED_PROPERTY_SETTER(CanvasIntArray) return value; } +CALLBACK_FUNC_DECL(WebGLIntArrayGet) +{ + INC_STATS("DOM.WebGLIntArray.get()"); + return getWebGLArrayElement<WebGLIntArray, int>(args, V8ClassIndex::WEBGLINTARRAY); +} + +CALLBACK_FUNC_DECL(WebGLIntArraySet) +{ + INC_STATS("DOM.WebGLIntArray.set()"); + return setWebGLArray<WebGLIntArray, V8WebGLIntArray>(args, V8ClassIndex::WEBGLINTARRAY); +} + } // namespace WebCore #endif // ENABLE(3D_CANVAS) diff --git a/WebCore/bindings/v8/custom/V8WebGLRenderingContextCustom.cpp b/WebCore/bindings/v8/custom/V8WebGLRenderingContextCustom.cpp new file mode 100644 index 0000000..fd73a5b --- /dev/null +++ b/WebCore/bindings/v8/custom/V8WebGLRenderingContextCustom.cpp @@ -0,0 +1,928 @@ +/* + * 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 areV8ClassIndex::WEBGL + * 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(3D_CANVAS) + +#include "WebGLRenderingContext.h" + +#include "ExceptionCode.h" + +#include "NotImplemented.h" + +#include <wtf/FastMalloc.h> + +#include "V8Binding.h" +#include "V8WebGLArray.h" +#include "V8WebGLByteArray.h" +#include "V8WebGLFloatArray.h" +#include "V8WebGLIntArray.h" +#include "V8WebGLProgram.h" +#include "V8WebGLShader.h" +#include "V8WebGLShortArray.h" +#include "V8WebGLUniformLocation.h" +#include "V8WebGLUnsignedByteArray.h" +#include "V8WebGLUnsignedIntArray.h" +#include "V8WebGLUnsignedShortArray.h" +#include "V8HTMLCanvasElement.h" +#include "V8HTMLImageElement.h" +#include "V8Proxy.h" + +namespace WebCore { + +// Allocates new storage via tryFastMalloc. +// Returns NULL if array failed to convert for any reason. +static float* jsArrayToFloatArray(v8::Handle<v8::Array> array, uint32_t len) +{ + // Convert the data element-by-element. + float* data; + if (!tryFastMalloc(len * sizeof(float)).getValue(data)) + return 0; + for (uint32_t i = 0; i < len; i++) { + v8::Local<v8::Value> val = array->Get(v8::Integer::New(i)); + if (!val->IsNumber()) { + fastFree(data); + return 0; + } + data[i] = toFloat(val); + } + return data; +} + +// Allocates new storage via tryFastMalloc. +// Returns NULL if array failed to convert for any reason. +static int* jsArrayToIntArray(v8::Handle<v8::Array> array, uint32_t len) +{ + // Convert the data element-by-element. + int* data; + if (!tryFastMalloc(len * sizeof(int)).getValue(data)) + return 0; + for (uint32_t i = 0; i < len; i++) { + v8::Local<v8::Value> val = array->Get(v8::Integer::New(i)); + bool ok; + int ival = toInt32(val, ok); + if (!ok) { + fastFree(data); + return 0; + } + data[i] = ival; + } + return data; +} + +CALLBACK_FUNC_DECL(WebGLRenderingContextBufferData) +{ + INC_STATS("DOM.WebGLRenderingContext.bufferData()"); + + // Forms: + // * bufferData(GLenum target, WebGLArray data, GLenum usage); + // - Sets the buffer's data from the given WebGLArray + // * bufferData(GLenum target, GLsizeiptr size, GLenum usage); + // - Sets the size of the buffer to the given size in bytes + if (args.Length() != 3) { + V8Proxy::setDOMException(SYNTAX_ERR); + return notHandledByInterceptor(); + } + + WebGLRenderingContext* context = + V8DOMWrapper::convertDOMWrapperToNative<WebGLRenderingContext>(args.Holder()); + bool ok; + int target = toInt32(args[0], ok); + if (!ok) { + V8Proxy::setDOMException(SYNTAX_ERR); + return notHandledByInterceptor(); + } + int usage = toInt32(args[2], ok); + if (!ok) { + V8Proxy::setDOMException(SYNTAX_ERR); + return notHandledByInterceptor(); + } + if (args[1]->IsInt32()) { + int size = toInt32(args[1]); + ExceptionCode exceptionCode; + context->bufferData(target, size, usage, exceptionCode); + } else if (V8WebGLArray::HasInstance(args[1])) { + WebGLArray* array = V8DOMWrapper::convertToNativeObject<WebGLArray>(V8ClassIndex::WEBGLARRAY, args[1]->ToObject()); + ExceptionCode exceptionCode; + context->bufferData(target, array, usage, exceptionCode); + } else { + V8Proxy::setDOMException(SYNTAX_ERR); + return notHandledByInterceptor(); + } + return v8::Undefined(); +} + +CALLBACK_FUNC_DECL(WebGLRenderingContextBufferSubData) +{ + INC_STATS("DOM.WebGLRenderingContext.bufferSubData()"); + + // Forms: + // * bufferSubData(GLenum target, GLintptr offset, WebGLArray data); + if (args.Length() != 3) { + V8Proxy::setDOMException(SYNTAX_ERR); + return notHandledByInterceptor(); + } + + WebGLRenderingContext* context = + V8DOMWrapper::convertDOMWrapperToNative<WebGLRenderingContext>(args.Holder()); + bool ok; + int target = toInt32(args[0], ok); + if (!ok) { + V8Proxy::setDOMException(SYNTAX_ERR); + return notHandledByInterceptor(); + } + int offset = toInt32(args[1], ok); + if (!ok) { + V8Proxy::setDOMException(SYNTAX_ERR); + return notHandledByInterceptor(); + } + if (!V8WebGLArray::HasInstance(args[2])) { + V8Proxy::setDOMException(SYNTAX_ERR); + return notHandledByInterceptor(); + } + WebGLArray* array = V8DOMWrapper::convertToNativeObject<WebGLArray>(V8ClassIndex::WEBGLARRAY, args[2]->ToObject()); + ExceptionCode exceptionCode; + context->bufferSubData(target, offset, array, exceptionCode); + return v8::Undefined(); +} + +static v8::Handle<v8::Value> toV8(const WebGLGetInfo& info) +{ + switch (info.getType()) { + case WebGLGetInfo::kTypeBool: + return v8::Boolean::New(info.getBool()); + case WebGLGetInfo::kTypeFloat: + return v8::Number::New(info.getFloat()); + case WebGLGetInfo::kTypeLong: + return v8::Integer::New(info.getLong()); + case WebGLGetInfo::kTypeNull: + return v8::Null(); + case WebGLGetInfo::kTypeString: + return v8::String::New(fromWebCoreString(info.getString()), info.getString().length()); + case WebGLGetInfo::kTypeUnsignedLong: + return v8::Integer::NewFromUnsigned(info.getUnsignedLong()); + case WebGLGetInfo::kTypeWebGLBuffer: + return V8DOMWrapper::convertToV8Object(V8ClassIndex::WEBGLBUFFER, info.getWebGLBuffer()); + case WebGLGetInfo::kTypeWebGLFloatArray: + return V8DOMWrapper::convertToV8Object(V8ClassIndex::WEBGLFLOATARRAY, info.getWebGLFloatArray()); + case WebGLGetInfo::kTypeWebGLFramebuffer: + return V8DOMWrapper::convertToV8Object(V8ClassIndex::WEBGLFRAMEBUFFER, info.getWebGLFramebuffer()); + case WebGLGetInfo::kTypeWebGLIntArray: + return V8DOMWrapper::convertToV8Object(V8ClassIndex::WEBGLINTARRAY, info.getWebGLIntArray()); + // FIXME: implement WebGLObjectArray + // case WebGLGetInfo::kTypeWebGLObjectArray: + case WebGLGetInfo::kTypeWebGLProgram: + return V8DOMWrapper::convertToV8Object(V8ClassIndex::WEBGLPROGRAM, info.getWebGLProgram()); + case WebGLGetInfo::kTypeWebGLRenderbuffer: + return V8DOMWrapper::convertToV8Object(V8ClassIndex::WEBGLRENDERBUFFER, info.getWebGLRenderbuffer()); + case WebGLGetInfo::kTypeWebGLTexture: + return V8DOMWrapper::convertToV8Object(V8ClassIndex::WEBGLTEXTURE, info.getWebGLTexture()); + case WebGLGetInfo::kTypeWebGLUnsignedByteArray: + return V8DOMWrapper::convertToV8Object(V8ClassIndex::WEBGLUNSIGNEDBYTEARRAY, info.getWebGLUnsignedByteArray()); + default: + notImplemented(); + return v8::Undefined(); + } +} + +enum ObjectType { + kBuffer, kRenderbuffer, kTexture, kVertexAttrib +}; + +static v8::Handle<v8::Value> getObjectParameter(const v8::Arguments& args, ObjectType objectType) +{ + if (args.Length() != 2) { + V8Proxy::setDOMException(SYNTAX_ERR); + return notHandledByInterceptor(); + } + + ExceptionCode ec = 0; + WebGLRenderingContext* context = + V8DOMWrapper::convertDOMWrapperToNative<WebGLRenderingContext>(args.Holder()); + bool ok; + unsigned target = toInt32(args[0], ok); + if (!ok) { + V8Proxy::setDOMException(SYNTAX_ERR); + return notHandledByInterceptor(); + } + unsigned pname = toInt32(args[1], ok); + if (!ok) { + V8Proxy::setDOMException(SYNTAX_ERR); + return notHandledByInterceptor(); + } + WebGLGetInfo info; + switch (objectType) { + case kBuffer: + info = context->getBufferParameter(target, pname, ec); + break; + case kRenderbuffer: + info = context->getRenderbufferParameter(target, pname, ec); + break; + case kTexture: + info = context->getTexParameter(target, pname, ec); + break; + case kVertexAttrib: + // target => index + info = context->getVertexAttrib(target, pname, ec); + break; + default: + notImplemented(); + break; + } + if (ec) { + V8Proxy::setDOMException(ec); + return v8::Undefined(); + } + return toV8(info); +} + +static WebGLUniformLocation* toWebGLUniformLocation(v8::Handle<v8::Value> value, bool& ok) +{ + ok = false; + WebGLUniformLocation* location = 0; + if (V8WebGLUniformLocation::HasInstance(value)) { + location = V8DOMWrapper::convertToNativeObject<WebGLUniformLocation>( + V8ClassIndex::WEBGLUNIFORMLOCATION, value->ToObject()); + ok = true; + } + return location; +} + +enum WhichProgramCall { + kProgramParameter, kUniform +}; + +CALLBACK_FUNC_DECL(WebGLRenderingContextGetBufferParameter) +{ + INC_STATS("DOM.WebGLRenderingContext.getBufferParameter()"); + return getObjectParameter(args, kBuffer); +} + +CALLBACK_FUNC_DECL(WebGLRenderingContextGetFramebufferAttachmentParameter) +{ + INC_STATS("DOM.WebGLRenderingContext.getFramebufferAttachmentParameter()"); + + if (args.Length() != 3) { + V8Proxy::setDOMException(SYNTAX_ERR); + return notHandledByInterceptor(); + } + + ExceptionCode ec = 0; + WebGLRenderingContext* context = + V8DOMWrapper::convertDOMWrapperToNative<WebGLRenderingContext>(args.Holder()); + bool ok; + unsigned target = toInt32(args[0], ok); + if (!ok) { + V8Proxy::setDOMException(SYNTAX_ERR); + return notHandledByInterceptor(); + } + unsigned attachment = toInt32(args[1], ok); + if (!ok) { + V8Proxy::setDOMException(SYNTAX_ERR); + return notHandledByInterceptor(); + } + unsigned pname = toInt32(args[2], ok); + if (!ok) { + V8Proxy::setDOMException(SYNTAX_ERR); + return notHandledByInterceptor(); + } + WebGLGetInfo info = context->getFramebufferAttachmentParameter(target, attachment, pname, ec); + if (ec) { + V8Proxy::setDOMException(ec); + return v8::Undefined(); + } + return toV8(info); +} + +CALLBACK_FUNC_DECL(WebGLRenderingContextGetParameter) +{ + INC_STATS("DOM.WebGLRenderingContext.getParameter()"); + + if (args.Length() != 1) { + V8Proxy::setDOMException(SYNTAX_ERR); + return notHandledByInterceptor(); + } + + ExceptionCode ec = 0; + WebGLRenderingContext* context = + V8DOMWrapper::convertDOMWrapperToNative<WebGLRenderingContext>(args.Holder()); + bool ok; + unsigned pname = toInt32(args[0], ok); + if (!ok) { + V8Proxy::setDOMException(SYNTAX_ERR); + return notHandledByInterceptor(); + } + WebGLGetInfo info = context->getParameter(pname, ec); + if (ec) { + V8Proxy::setDOMException(ec); + return v8::Undefined(); + } + return toV8(info); +} + +CALLBACK_FUNC_DECL(WebGLRenderingContextGetProgramParameter) +{ + INC_STATS("DOM.WebGLRenderingContext.getProgramParameter()"); + + if (args.Length() != 2) { + V8Proxy::setDOMException(SYNTAX_ERR); + return notHandledByInterceptor(); + } + + ExceptionCode ec = 0; + WebGLRenderingContext* context = + V8DOMWrapper::convertDOMWrapperToNative<WebGLRenderingContext>(args.Holder()); + WebGLProgram* program = V8WebGLProgram::HasInstance(args[0]) ? v8DOMWrapperTo<WebGLProgram>(V8ClassIndex::WEBGLPROGRAM, v8::Handle<v8::Object>::Cast(args[0])) : 0; + bool ok; + unsigned pname = toInt32(args[1], ok); + if (!ok) { + V8Proxy::setDOMException(SYNTAX_ERR); + return notHandledByInterceptor(); + } + WebGLGetInfo info = context->getProgramParameter(program, pname, ec); + if (ec) { + V8Proxy::setDOMException(ec); + return v8::Undefined(); + } + return toV8(info); +} + +CALLBACK_FUNC_DECL(WebGLRenderingContextGetRenderbufferParameter) +{ + INC_STATS("DOM.WebGLRenderingContext.getRenderbufferParameter()"); + return getObjectParameter(args, kRenderbuffer); +} + +CALLBACK_FUNC_DECL(WebGLRenderingContextGetShaderParameter) +{ + INC_STATS("DOM.WebGLRenderingContext.getShaderParameter()"); + + if (args.Length() != 2) { + V8Proxy::setDOMException(SYNTAX_ERR); + return notHandledByInterceptor(); + } + + ExceptionCode ec = 0; + WebGLRenderingContext* context = + V8DOMWrapper::convertDOMWrapperToNative<WebGLRenderingContext>(args.Holder()); + WebGLShader* shader = V8WebGLShader::HasInstance(args[0]) ? v8DOMWrapperTo<WebGLShader>(V8ClassIndex::WEBGLSHADER, v8::Handle<v8::Object>::Cast(args[0])) : 0; + bool ok; + unsigned pname = toInt32(args[1], ok); + if (!ok) { + V8Proxy::setDOMException(SYNTAX_ERR); + return notHandledByInterceptor(); + } + WebGLGetInfo info = context->getShaderParameter(shader, pname, ec); + if (ec) { + V8Proxy::setDOMException(ec); + return v8::Undefined(); + } + return toV8(info); +} + +CALLBACK_FUNC_DECL(WebGLRenderingContextGetTexParameter) +{ + INC_STATS("DOM.WebGLRenderingContext.getTexParameter()"); + return getObjectParameter(args, kTexture); +} + +CALLBACK_FUNC_DECL(WebGLRenderingContextGetUniform) +{ + INC_STATS("DOM.WebGLRenderingContext.getUniform()"); + + if (args.Length() != 2) { + V8Proxy::setDOMException(SYNTAX_ERR); + return notHandledByInterceptor(); + } + + ExceptionCode ec = 0; + WebGLRenderingContext* context = + V8DOMWrapper::convertDOMWrapperToNative<WebGLRenderingContext>(args.Holder()); + WebGLProgram* program = V8WebGLProgram::HasInstance(args[0]) ? v8DOMWrapperTo<WebGLProgram>(V8ClassIndex::WEBGLPROGRAM, v8::Handle<v8::Object>::Cast(args[0])) : 0; + + bool ok = false; + WebGLUniformLocation* location = toWebGLUniformLocation(args[1], ok); + + if (!ok) { + V8Proxy::setDOMException(SYNTAX_ERR); + return notHandledByInterceptor(); + } + WebGLGetInfo info = context->getUniform(program, location, ec); + if (ec) { + V8Proxy::setDOMException(ec); + return v8::Undefined(); + } + return toV8(info); +} + +CALLBACK_FUNC_DECL(WebGLRenderingContextGetVertexAttrib) +{ + INC_STATS("DOM.WebGLRenderingContext.getVertexAttrib()"); + return getObjectParameter(args, kVertexAttrib); +} + +CALLBACK_FUNC_DECL(WebGLRenderingContextTexImage2D) +{ + INC_STATS("DOM.WebGLRenderingContext.texImage2D()"); + + // Currently supported forms: + // * void texImage2D(in GLenum target, in GLint level, + // in GLint internalformat, + // in GLsizei width, in GLsizei height, in GLint border, + // in GLenum format, in GLenum type, in WebGLArray pixels); + // * void texImage2D(in GLenum target, in GLint level, in HTMLImageElement image, + // [Optional] in GLboolean flipY, [Optional] in GLboolean premultiplyAlpha); + // * void texImage2D(in GLenum target, in GLint level, in HTMLCanvasElement image, + // [Optional] in GLboolean flipY, [Optional] in GLboolean premultiplyAlpha); + if (args.Length() != 3 && + args.Length() != 4 && + args.Length() != 5 && + args.Length() != 9) { + V8Proxy::setDOMException(SYNTAX_ERR); + return notHandledByInterceptor(); + } + + WebGLRenderingContext* context = + V8DOMWrapper::convertDOMWrapperToNative<WebGLRenderingContext>(args.Holder()); + bool ok; + int target = toInt32(args[0], ok); + if (!ok) { + V8Proxy::setDOMException(SYNTAX_ERR); + return notHandledByInterceptor(); + } + int level = toInt32(args[1], ok); + if (!ok) { + V8Proxy::setDOMException(SYNTAX_ERR); + return notHandledByInterceptor(); + } + + ExceptionCode ec = 0; + if (args.Length() == 3 || + args.Length() == 4 || + args.Length() == 5) { + v8::Handle<v8::Value> arg = args[2]; + bool flipY = false; + bool premultiplyAlpha = false; + if (args.Length() >= 4) + flipY = args[3]->BooleanValue(); + if (args.Length() >= 5) + premultiplyAlpha = args[4]->BooleanValue(); + if (V8HTMLImageElement::HasInstance(arg)) { + HTMLImageElement* element = V8DOMWrapper::convertDOMWrapperToNode<HTMLImageElement>(v8::Handle<v8::Object>::Cast(arg)); + context->texImage2D(target, level, element, flipY, premultiplyAlpha, ec); + } else if (V8HTMLCanvasElement::HasInstance(arg)) { + HTMLCanvasElement* element = V8DOMWrapper::convertDOMWrapperToNode<HTMLCanvasElement>(v8::Handle<v8::Object>::Cast(arg)); + context->texImage2D(target, level, element, flipY, premultiplyAlpha, ec); + } else { + // FIXME: support HTMLVideoElement and ImageData. + // FIXME: consider different / better exception type. + V8Proxy::setDOMException(SYNTAX_ERR); + return notHandledByInterceptor(); + } + // Fall through + } else if (args.Length() == 9) { + int internalformat = toInt32(args[2], ok); + if (!ok) { + V8Proxy::setDOMException(SYNTAX_ERR); + return notHandledByInterceptor(); + } + int width = toInt32(args[3], ok); + if (!ok) { + V8Proxy::setDOMException(SYNTAX_ERR); + return notHandledByInterceptor(); + } + int height = toInt32(args[4], ok); + if (!ok) { + V8Proxy::setDOMException(SYNTAX_ERR); + return notHandledByInterceptor(); + } + int border = toInt32(args[5], ok); + if (!ok) { + V8Proxy::setDOMException(SYNTAX_ERR); + return notHandledByInterceptor(); + } + int format = toInt32(args[6], ok); + if (!ok) { + V8Proxy::setDOMException(SYNTAX_ERR); + return notHandledByInterceptor(); + } + int type = toInt32(args[7], ok); + if (!ok) { + V8Proxy::setDOMException(SYNTAX_ERR); + return notHandledByInterceptor(); + } + v8::Handle<v8::Value> arg = args[8]; + if (V8WebGLArray::HasInstance(arg)) { + WebGLArray* array = V8DOMWrapper::convertToNativeObject<WebGLArray>(V8ClassIndex::WEBGLARRAY, arg->ToObject()); + // FIXME: must do validation similar to JOGL's to ensure that + // the incoming array is of the appropriate length and type + context->texImage2D(target, + level, + internalformat, + width, + height, + border, + format, + type, + array, + ec); + // Fall through + } else { + V8Proxy::setDOMException(SYNTAX_ERR); + return notHandledByInterceptor(); + } + } else { + ASSERT_NOT_REACHED(); + V8Proxy::setDOMException(SYNTAX_ERR); + return notHandledByInterceptor(); + } + if (ec) { + V8Proxy::setDOMException(ec); + return v8::Handle<v8::Value>(); + } + return v8::Undefined(); +} + +CALLBACK_FUNC_DECL(WebGLRenderingContextTexSubImage2D) +{ + INC_STATS("DOM.WebGLRenderingContext.texSubImage2D()"); + + // FIXME: implement + notImplemented(); + + return v8::Undefined(); +} + +enum FunctionToCall { + kUniform1v, kUniform2v, kUniform3v, kUniform4v, + kVertexAttrib1v, kVertexAttrib2v, kVertexAttrib3v, kVertexAttrib4v +}; + +bool isFunctionToCallForAttribute(FunctionToCall functionToCall) +{ + switch (functionToCall) { + case kVertexAttrib1v: + case kVertexAttrib2v: + case kVertexAttrib3v: + case kVertexAttrib4v: + return true; + default: + break; + } + return false; +} + +static v8::Handle<v8::Value> vertexAttribAndUniformHelperf(const v8::Arguments& args, + FunctionToCall functionToCall) { + // Forms: + // * glUniform1fv(WebGLUniformLocation location, Array data); + // * glUniform1fv(WebGLUniformLocation location, WebGLFloatArray data); + // * glUniform2fv(WebGLUniformLocation location, Array data); + // * glUniform2fv(WebGLUniformLocation location, WebGLFloatArray data); + // * glUniform3fv(WebGLUniformLocation location, Array data); + // * glUniform3fv(WebGLUniformLocation location, WebGLFloatArray data); + // * glUniform4fv(WebGLUniformLocation location, Array data); + // * glUniform4fv(WebGLUniformLocation location, WebGLFloatArray data); + // * glVertexAttrib1fv(GLint index, Array data); + // * glVertexAttrib1fv(GLint index, WebGLFloatArray data); + // * glVertexAttrib2fv(GLint index, Array data); + // * glVertexAttrib2fv(GLint index, WebGLFloatArray data); + // * glVertexAttrib3fv(GLint index, Array data); + // * glVertexAttrib3fv(GLint index, WebGLFloatArray data); + // * glVertexAttrib4fv(GLint index, Array data); + // * glVertexAttrib4fv(GLint index, WebGLFloatArray data); + + if (args.Length() != 2) { + V8Proxy::setDOMException(SYNTAX_ERR); + return notHandledByInterceptor(); + } + + bool ok = false; + int index = -1; + WebGLUniformLocation* location = 0; + + if (isFunctionToCallForAttribute(functionToCall)) + index = toInt32(args[0], ok); + else + location = toWebGLUniformLocation(args[0], ok); + + WebGLRenderingContext* context = + V8DOMWrapper::convertDOMWrapperToNative<WebGLRenderingContext>(args.Holder()); + + if (!ok) { + V8Proxy::setDOMException(SYNTAX_ERR); + return notHandledByInterceptor(); + } + if (V8WebGLFloatArray::HasInstance(args[1])) { + WebGLFloatArray* array = + V8DOMWrapper::convertToNativeObject<WebGLFloatArray>(V8ClassIndex::WEBGLFLOATARRAY, args[1]->ToObject()); + ASSERT(array != NULL); + ExceptionCode ec = 0; + switch (functionToCall) { + case kUniform1v: context->uniform1fv(location, array, ec); break; + case kUniform2v: context->uniform2fv(location, array, ec); break; + case kUniform3v: context->uniform3fv(location, array, ec); break; + case kUniform4v: context->uniform4fv(location, array, ec); break; + case kVertexAttrib1v: context->vertexAttrib1fv(index, array); break; + case kVertexAttrib2v: context->vertexAttrib2fv(index, array); break; + case kVertexAttrib3v: context->vertexAttrib3fv(index, array); break; + case kVertexAttrib4v: context->vertexAttrib4fv(index, array); break; + default: ASSERT_NOT_REACHED(); break; + } + if (ec) + V8Proxy::setDOMException(ec); + return v8::Undefined(); + } + + v8::Handle<v8::Array> array = + v8::Local<v8::Array>::Cast(args[1]); + if (array.IsEmpty()) { + V8Proxy::setDOMException(SYNTAX_ERR); + return notHandledByInterceptor(); + } + uint32_t len = array->Length(); + float* data = jsArrayToFloatArray(array, len); + if (!data) { + // FIXME: consider different / better exception type. + V8Proxy::setDOMException(SYNTAX_ERR); + return notHandledByInterceptor(); + } + ExceptionCode ec = 0; + switch (functionToCall) { + case kUniform1v: context->uniform1fv(location, data, len, ec); break; + case kUniform2v: context->uniform2fv(location, data, len, ec); break; + case kUniform3v: context->uniform3fv(location, data, len, ec); break; + case kUniform4v: context->uniform4fv(location, data, len, ec); break; + case kVertexAttrib1v: context->vertexAttrib1fv(index, data, len); break; + case kVertexAttrib2v: context->vertexAttrib2fv(index, data, len); break; + case kVertexAttrib3v: context->vertexAttrib3fv(index, data, len); break; + case kVertexAttrib4v: context->vertexAttrib4fv(index, data, len); break; + default: ASSERT_NOT_REACHED(); break; + } + fastFree(data); + if (ec) + V8Proxy::setDOMException(ec); + return v8::Undefined(); +} + +static v8::Handle<v8::Value> uniformHelperi(const v8::Arguments& args, + FunctionToCall functionToCall) { + // Forms: + // * glUniform1iv(GLUniformLocation location, Array data); + // * glUniform1iv(GLUniformLocation location, WebGLIntArray data); + // * glUniform2iv(GLUniformLocation location, Array data); + // * glUniform2iv(GLUniformLocation location, WebGLIntArray data); + // * glUniform3iv(GLUniformLocation location, Array data); + // * glUniform3iv(GLUniformLocation location, WebGLIntArray data); + // * glUniform4iv(GLUniformLocation location, Array data); + // * glUniform4iv(GLUniformLocation location, WebGLIntArray data); + + if (args.Length() != 2) { + V8Proxy::setDOMException(SYNTAX_ERR); + return notHandledByInterceptor(); + } + + WebGLRenderingContext* context = + V8DOMWrapper::convertDOMWrapperToNative<WebGLRenderingContext>(args.Holder()); + bool ok = false; + WebGLUniformLocation* location = toWebGLUniformLocation(args[0], ok); + + if (!ok) { + V8Proxy::setDOMException(SYNTAX_ERR); + return notHandledByInterceptor(); + } + if (V8WebGLIntArray::HasInstance(args[1])) { + WebGLIntArray* array = + V8DOMWrapper::convertToNativeObject<WebGLIntArray>(V8ClassIndex::WEBGLINTARRAY, args[1]->ToObject()); + ASSERT(array != NULL); + ExceptionCode ec = 0; + switch (functionToCall) { + case kUniform1v: context->uniform1iv(location, array, ec); break; + case kUniform2v: context->uniform2iv(location, array, ec); break; + case kUniform3v: context->uniform3iv(location, array, ec); break; + case kUniform4v: context->uniform4iv(location, array, ec); break; + default: ASSERT_NOT_REACHED(); break; + } + if (ec) + V8Proxy::setDOMException(ec); + return v8::Undefined(); + } + + v8::Handle<v8::Array> array = + v8::Local<v8::Array>::Cast(args[1]); + if (array.IsEmpty()) { + V8Proxy::setDOMException(SYNTAX_ERR); + return notHandledByInterceptor(); + } + uint32_t len = array->Length(); + int* data = jsArrayToIntArray(array, len); + if (!data) { + // FIXME: consider different / better exception type. + V8Proxy::setDOMException(SYNTAX_ERR); + return notHandledByInterceptor(); + } + ExceptionCode ec = 0; + switch (functionToCall) { + case kUniform1v: context->uniform1iv(location, data, len, ec); break; + case kUniform2v: context->uniform2iv(location, data, len, ec); break; + case kUniform3v: context->uniform3iv(location, data, len, ec); break; + case kUniform4v: context->uniform4iv(location, data, len, ec); break; + default: ASSERT_NOT_REACHED(); break; + } + fastFree(data); + if (ec) + V8Proxy::setDOMException(ec); + return v8::Undefined(); +} + +CALLBACK_FUNC_DECL(WebGLRenderingContextUniform1fv) +{ + INC_STATS("DOM.WebGLRenderingContext.uniform1fv()"); + return vertexAttribAndUniformHelperf(args, kUniform1v); +} + +CALLBACK_FUNC_DECL(WebGLRenderingContextUniform1iv) +{ + INC_STATS("DOM.WebGLRenderingContext.uniform1iv()"); + return uniformHelperi(args, kUniform1v); +} + +CALLBACK_FUNC_DECL(WebGLRenderingContextUniform2fv) +{ + INC_STATS("DOM.WebGLRenderingContext.uniform2fv()"); + return vertexAttribAndUniformHelperf(args, kUniform2v); +} + +CALLBACK_FUNC_DECL(WebGLRenderingContextUniform2iv) +{ + INC_STATS("DOM.WebGLRenderingContext.uniform2iv()"); + return uniformHelperi(args, kUniform2v); +} + +CALLBACK_FUNC_DECL(WebGLRenderingContextUniform3fv) +{ + INC_STATS("DOM.WebGLRenderingContext.uniform3fv()"); + return vertexAttribAndUniformHelperf(args, kUniform3v); +} + +CALLBACK_FUNC_DECL(WebGLRenderingContextUniform3iv) +{ + INC_STATS("DOM.WebGLRenderingContext.uniform3iv()"); + return uniformHelperi(args, kUniform3v); +} + +CALLBACK_FUNC_DECL(WebGLRenderingContextUniform4fv) +{ + INC_STATS("DOM.WebGLRenderingContext.uniform4fv()"); + return vertexAttribAndUniformHelperf(args, kUniform4v); +} + +CALLBACK_FUNC_DECL(WebGLRenderingContextUniform4iv) +{ + INC_STATS("DOM.WebGLRenderingContext.uniform4iv()"); + return uniformHelperi(args, kUniform4v); +} + +static v8::Handle<v8::Value> uniformMatrixHelper(const v8::Arguments& args, + int matrixSize) +{ + // Forms: + // * glUniformMatrix2fv(GLint location, GLboolean transpose, Array data); + // * glUniformMatrix2fv(GLint location, GLboolean transpose, WebGLFloatArray data); + // * glUniformMatrix3fv(GLint location, GLboolean transpose, Array data); + // * glUniformMatrix3fv(GLint location, GLboolean transpose, WebGLFloatArray data); + // * glUniformMatrix4fv(GLint location, GLboolean transpose, Array data); + // * glUniformMatrix4fv(GLint location, GLboolean transpose, WebGLFloatArray data); + // + // FIXME: need to change to accept WebGLFloatArray as well. + if (args.Length() != 3) { + V8Proxy::setDOMException(SYNTAX_ERR); + return notHandledByInterceptor(); + } + + WebGLRenderingContext* context = + V8DOMWrapper::convertDOMWrapperToNative<WebGLRenderingContext>(args.Holder()); + + bool ok = false; + WebGLUniformLocation* location = toWebGLUniformLocation(args[0], ok); + + if (!ok) { + V8Proxy::setDOMException(SYNTAX_ERR); + return notHandledByInterceptor(); + } + bool transpose = args[1]->BooleanValue(); + if (V8WebGLFloatArray::HasInstance(args[2])) { + WebGLFloatArray* array = + V8DOMWrapper::convertToNativeObject<WebGLFloatArray>(V8ClassIndex::WEBGLFLOATARRAY, args[2]->ToObject()); + ASSERT(array != NULL); + ExceptionCode ec = 0; + switch (matrixSize) { + case 2: context->uniformMatrix2fv(location, transpose, array, ec); break; + case 3: context->uniformMatrix3fv(location, transpose, array, ec); break; + case 4: context->uniformMatrix4fv(location, transpose, array, ec); break; + default: ASSERT_NOT_REACHED(); break; + } + if (ec) + V8Proxy::setDOMException(ec); + return v8::Undefined(); + } + + v8::Handle<v8::Array> array = + v8::Local<v8::Array>::Cast(args[2]); + if (array.IsEmpty()) { + V8Proxy::setDOMException(SYNTAX_ERR); + return notHandledByInterceptor(); + } + uint32_t len = array->Length(); + float* data = jsArrayToFloatArray(array, len); + if (!data) { + // FIXME: consider different / better exception type. + V8Proxy::setDOMException(SYNTAX_ERR); + return notHandledByInterceptor(); + } + ExceptionCode ec = 0; + switch (matrixSize) { + case 2: context->uniformMatrix2fv(location, transpose, data, len, ec); break; + case 3: context->uniformMatrix3fv(location, transpose, data, len, ec); break; + case 4: context->uniformMatrix4fv(location, transpose, data, len, ec); break; + default: ASSERT_NOT_REACHED(); break; + } + fastFree(data); + if (ec) + V8Proxy::setDOMException(ec); + return v8::Undefined(); +} + +CALLBACK_FUNC_DECL(WebGLRenderingContextUniformMatrix2fv) +{ + INC_STATS("DOM.WebGLRenderingContext.uniformMatrix2fv()"); + return uniformMatrixHelper(args, 2); +} + +CALLBACK_FUNC_DECL(WebGLRenderingContextUniformMatrix3fv) +{ + INC_STATS("DOM.WebGLRenderingContext.uniformMatrix3fv()"); + return uniformMatrixHelper(args, 3); +} + +CALLBACK_FUNC_DECL(WebGLRenderingContextUniformMatrix4fv) +{ + INC_STATS("DOM.WebGLRenderingContext.uniformMatrix4fv()"); + return uniformMatrixHelper(args, 4); +} + +CALLBACK_FUNC_DECL(WebGLRenderingContextVertexAttrib1fv) +{ + INC_STATS("DOM.WebGLRenderingContext.vertexAttrib1fv()"); + return vertexAttribAndUniformHelperf(args, kVertexAttrib1v); +} + +CALLBACK_FUNC_DECL(WebGLRenderingContextVertexAttrib2fv) +{ + INC_STATS("DOM.WebGLRenderingContext.vertexAttrib2fv()"); + return vertexAttribAndUniformHelperf(args, kVertexAttrib2v); +} + +CALLBACK_FUNC_DECL(WebGLRenderingContextVertexAttrib3fv) +{ + INC_STATS("DOM.WebGLRenderingContext.vertexAttrib3fv()"); + return vertexAttribAndUniformHelperf(args, kVertexAttrib3v); +} + +CALLBACK_FUNC_DECL(WebGLRenderingContextVertexAttrib4fv) +{ + INC_STATS("DOM.WebGLRenderingContext.vertexAttrib4fv()"); + return vertexAttribAndUniformHelperf(args, kVertexAttrib4v); +} + +} // namespace WebCore + +#endif // ENABLE(3D_CANVAS) diff --git a/WebCore/bindings/v8/custom/V8CanvasShortArrayCustom.cpp b/WebCore/bindings/v8/custom/V8WebGLShortArrayCustom.cpp index 8b83022..f8a26c3 100644 --- a/WebCore/bindings/v8/custom/V8CanvasShortArrayCustom.cpp +++ b/WebCore/bindings/v8/custom/V8WebGLShortArrayCustom.cpp @@ -32,29 +32,30 @@ #if ENABLE(3D_CANVAS) -#include "CanvasArrayBuffer.h" -#include "CanvasShortArray.h" +#include "WebGLArrayBuffer.h" +#include "WebGLShortArray.h" #include "V8Binding.h" -#include "V8CanvasArrayBuffer.h" -#include "V8CanvasArrayCustom.h" +#include "V8WebGLArrayBuffer.h" +#include "V8WebGLArrayCustom.h" +#include "V8WebGLShortArray.h" #include "V8CustomBinding.h" #include "V8Proxy.h" namespace WebCore { -CALLBACK_FUNC_DECL(CanvasShortArrayConstructor) +CALLBACK_FUNC_DECL(WebGLShortArrayConstructor) { - INC_STATS("DOM.CanvasShortArray.Contructor"); + INC_STATS("DOM.WebGLShortArray.Contructor"); - return constructCanvasArray<CanvasShortArray>(args, V8ClassIndex::ToInt(V8ClassIndex::CANVASSHORTARRAY)); + return constructWebGLArray<WebGLShortArray>(args, V8ClassIndex::ToInt(V8ClassIndex::WEBGLSHORTARRAY)); } // Get the specified value from the array and return it wrapped as a JavaScript Number object to V8. Accesses outside the valid array range return "undefined". -INDEXED_PROPERTY_GETTER(CanvasShortArray) +INDEXED_PROPERTY_GETTER(WebGLShortArray) { - INC_STATS("DOM.CanvasShortArray.IndexedPropertyGetter"); - CanvasShortArray* array = V8DOMWrapper::convertToNativeObject<CanvasShortArray>(V8ClassIndex::CANVASSHORTARRAY, info.Holder()); + INC_STATS("DOM.WebGLShortArray.IndexedPropertyGetter"); + WebGLShortArray* array = V8DOMWrapper::convertToNativeObject<WebGLShortArray>(V8ClassIndex::WEBGLSHORTARRAY, info.Holder()); if ((index < 0) || (index >= array->length())) return v8::Undefined(); @@ -65,10 +66,10 @@ INDEXED_PROPERTY_GETTER(CanvasShortArray) } // Set the specified value in the array. Accesses outside the valid array range are silently ignored. -INDEXED_PROPERTY_SETTER(CanvasShortArray) +INDEXED_PROPERTY_SETTER(WebGLShortArray) { - INC_STATS("DOM.CanvasShortArray.IndexedPropertySetter"); - CanvasShortArray* array = V8DOMWrapper::convertToNativeObject<CanvasShortArray>(V8ClassIndex::CANVASSHORTARRAY, info.Holder()); + INC_STATS("DOM.WebGLShortArray.IndexedPropertySetter"); + WebGLShortArray* array = V8DOMWrapper::convertToNativeObject<WebGLShortArray>(V8ClassIndex::WEBGLSHORTARRAY, info.Holder()); if ((index >= 0) && (index < array->length())) { if (!value->IsNumber()) @@ -78,6 +79,18 @@ INDEXED_PROPERTY_SETTER(CanvasShortArray) return value; } +CALLBACK_FUNC_DECL(WebGLShortArrayGet) +{ + INC_STATS("DOM.WebGLShortArray.get()"); + return getWebGLArrayElement<WebGLShortArray, short>(args, V8ClassIndex::WEBGLSHORTARRAY); +} + +CALLBACK_FUNC_DECL(WebGLShortArraySet) +{ + INC_STATS("DOM.WebGLShortArray.set()"); + return setWebGLArray<WebGLShortArray, V8WebGLShortArray>(args, V8ClassIndex::WEBGLSHORTARRAY); +} + } // namespace WebCore #endif // ENABLE(3D_CANVAS) diff --git a/WebCore/bindings/v8/custom/V8CanvasUnsignedByteArrayCustom.cpp b/WebCore/bindings/v8/custom/V8WebGLUnsignedByteArrayCustom.cpp index 62ab880..391f213 100644 --- a/WebCore/bindings/v8/custom/V8CanvasUnsignedByteArrayCustom.cpp +++ b/WebCore/bindings/v8/custom/V8WebGLUnsignedByteArrayCustom.cpp @@ -32,29 +32,30 @@ #if ENABLE(3D_CANVAS) -#include "CanvasArrayBuffer.h" -#include "CanvasUnsignedByteArray.h" +#include "WebGLArrayBuffer.h" +#include "WebGLUnsignedByteArray.h" #include "V8Binding.h" -#include "V8CanvasArrayBuffer.h" -#include "V8CanvasArrayCustom.h" +#include "V8WebGLArrayBuffer.h" +#include "V8WebGLArrayCustom.h" +#include "V8WebGLUnsignedByteArray.h" #include "V8CustomBinding.h" #include "V8Proxy.h" namespace WebCore { -CALLBACK_FUNC_DECL(CanvasUnsignedByteArrayConstructor) +CALLBACK_FUNC_DECL(WebGLUnsignedByteArrayConstructor) { - INC_STATS("DOM.CanvasUnsignedByteArray.Contructor"); + INC_STATS("DOM.WebGLUnsignedByteArray.Contructor"); - return constructCanvasArray<CanvasUnsignedByteArray>(args, V8ClassIndex::ToInt(V8ClassIndex::CANVASUNSIGNEDBYTEARRAY)); + return constructWebGLArray<WebGLUnsignedByteArray>(args, V8ClassIndex::ToInt(V8ClassIndex::WEBGLUNSIGNEDBYTEARRAY)); } // Get the specified value from the array and return it wrapped as a JavaScript Number object to V8. Accesses outside the valid array range return "undefined". -INDEXED_PROPERTY_GETTER(CanvasUnsignedByteArray) +INDEXED_PROPERTY_GETTER(WebGLUnsignedByteArray) { - INC_STATS("DOM.CanvasUnsignedByteArray.IndexedPropertyGetter"); - CanvasUnsignedByteArray* array = V8DOMWrapper::convertToNativeObject<CanvasUnsignedByteArray>(V8ClassIndex::CANVASUNSIGNEDBYTEARRAY, info.Holder()); + INC_STATS("DOM.WebGLUnsignedByteArray.IndexedPropertyGetter"); + WebGLUnsignedByteArray* array = V8DOMWrapper::convertToNativeObject<WebGLUnsignedByteArray>(V8ClassIndex::WEBGLUNSIGNEDBYTEARRAY, info.Holder()); if ((index < 0) || (index >= array->length())) return v8::Undefined(); @@ -65,10 +66,10 @@ INDEXED_PROPERTY_GETTER(CanvasUnsignedByteArray) } // Set the specified value in the array. Accesses outside the valid array range are silently ignored. -INDEXED_PROPERTY_SETTER(CanvasUnsignedByteArray) +INDEXED_PROPERTY_SETTER(WebGLUnsignedByteArray) { - INC_STATS("DOM.CanvasUnsignedByteArray.IndexedPropertySetter"); - CanvasUnsignedByteArray* array = V8DOMWrapper::convertToNativeObject<CanvasUnsignedByteArray>(V8ClassIndex::CANVASUNSIGNEDBYTEARRAY, info.Holder()); + INC_STATS("DOM.WebGLUnsignedByteArray.IndexedPropertySetter"); + WebGLUnsignedByteArray* array = V8DOMWrapper::convertToNativeObject<WebGLUnsignedByteArray>(V8ClassIndex::WEBGLUNSIGNEDBYTEARRAY, info.Holder()); if ((index >= 0) && (index < array->length())) { if (!value->IsNumber()) @@ -78,6 +79,18 @@ INDEXED_PROPERTY_SETTER(CanvasUnsignedByteArray) return value; } +CALLBACK_FUNC_DECL(WebGLUnsignedByteArrayGet) +{ + INC_STATS("DOM.WebGLUnsignedByteArray.get()"); + return getWebGLArrayElement<WebGLUnsignedByteArray, unsigned char>(args, V8ClassIndex::WEBGLUNSIGNEDBYTEARRAY); +} + +CALLBACK_FUNC_DECL(WebGLUnsignedByteArraySet) +{ + INC_STATS("DOM.WebGLUnsignedByteArray.set()"); + return setWebGLArray<WebGLUnsignedByteArray, V8WebGLUnsignedByteArray>(args, V8ClassIndex::WEBGLUNSIGNEDBYTEARRAY); +} + } // namespace WebCore #endif // ENABLE(3D_CANVAS) diff --git a/WebCore/bindings/v8/custom/V8CanvasUnsignedIntArrayCustom.cpp b/WebCore/bindings/v8/custom/V8WebGLUnsignedIntArrayCustom.cpp index 94ec7d0..92b9fe0 100644 --- a/WebCore/bindings/v8/custom/V8CanvasUnsignedIntArrayCustom.cpp +++ b/WebCore/bindings/v8/custom/V8WebGLUnsignedIntArrayCustom.cpp @@ -32,29 +32,30 @@ #if ENABLE(3D_CANVAS) -#include "CanvasArrayBuffer.h" -#include "CanvasUnsignedIntArray.h" +#include "WebGLArrayBuffer.h" +#include "WebGLUnsignedIntArray.h" #include "V8Binding.h" -#include "V8CanvasArrayBuffer.h" -#include "V8CanvasArrayCustom.h" +#include "V8WebGLArrayBuffer.h" +#include "V8WebGLArrayCustom.h" +#include "V8WebGLUnsignedIntArray.h" #include "V8CustomBinding.h" #include "V8Proxy.h" namespace WebCore { -CALLBACK_FUNC_DECL(CanvasUnsignedIntArrayConstructor) +CALLBACK_FUNC_DECL(WebGLUnsignedIntArrayConstructor) { - INC_STATS("DOM.CanvasUnsignedIntArray.Contructor"); + INC_STATS("DOM.WebGLUnsignedIntArray.Contructor"); - return constructCanvasArray<CanvasUnsignedIntArray>(args, V8ClassIndex::ToInt(V8ClassIndex::CANVASUNSIGNEDINTARRAY)); + return constructWebGLArray<WebGLUnsignedIntArray>(args, V8ClassIndex::ToInt(V8ClassIndex::WEBGLUNSIGNEDINTARRAY)); } // Get the specified value from the integer array and return it wrapped as a JavaScript Number object to V8. Accesses outside the valid pixel buffer range return "undefined". -INDEXED_PROPERTY_GETTER(CanvasUnsignedIntArray) +INDEXED_PROPERTY_GETTER(WebGLUnsignedIntArray) { - INC_STATS("DOM.CanvasUnsignedIntArray.IndexedPropertyGetter"); - CanvasUnsignedIntArray* array = V8DOMWrapper::convertToNativeObject<CanvasUnsignedIntArray>(V8ClassIndex::CANVASUNSIGNEDINTARRAY, info.Holder()); + INC_STATS("DOM.WebGLUnsignedIntArray.IndexedPropertyGetter"); + WebGLUnsignedIntArray* array = V8DOMWrapper::convertToNativeObject<WebGLUnsignedIntArray>(V8ClassIndex::WEBGLUNSIGNEDINTARRAY, info.Holder()); if ((index < 0) || (index >= array->length())) return v8::Undefined(); @@ -65,10 +66,10 @@ INDEXED_PROPERTY_GETTER(CanvasUnsignedIntArray) } // Set the specified value in the integer array. Accesses outside the valid integer array range are silently ignored. -INDEXED_PROPERTY_SETTER(CanvasUnsignedIntArray) +INDEXED_PROPERTY_SETTER(WebGLUnsignedIntArray) { - INC_STATS("DOM.CanvasUnsignedIntArray.IndexedPropertySetter"); - CanvasUnsignedIntArray* array = V8DOMWrapper::convertToNativeObject<CanvasUnsignedIntArray>(V8ClassIndex::CANVASUNSIGNEDINTARRAY, info.Holder()); + INC_STATS("DOM.WebGLUnsignedIntArray.IndexedPropertySetter"); + WebGLUnsignedIntArray* array = V8DOMWrapper::convertToNativeObject<WebGLUnsignedIntArray>(V8ClassIndex::WEBGLUNSIGNEDINTARRAY, info.Holder()); if ((index >= 0) && (index < array->length())) { if (!value->IsNumber()) @@ -78,6 +79,18 @@ INDEXED_PROPERTY_SETTER(CanvasUnsignedIntArray) return value; } +CALLBACK_FUNC_DECL(WebGLUnsignedIntArrayGet) +{ + INC_STATS("DOM.WebGLUnsignedIntArray.get()"); + return getWebGLArrayElement<WebGLUnsignedIntArray, unsigned int>(args, V8ClassIndex::WEBGLUNSIGNEDINTARRAY); +} + +CALLBACK_FUNC_DECL(WebGLUnsignedIntArraySet) +{ + INC_STATS("DOM.WebGLUnsignedIntArray.set()"); + return setWebGLArray<WebGLUnsignedIntArray, V8WebGLUnsignedIntArray>(args, V8ClassIndex::WEBGLUNSIGNEDINTARRAY); +} + } // namespace WebCore #endif // ENABLE(3D_CANVAS) diff --git a/WebCore/bindings/v8/custom/V8CanvasUnsignedShortArrayCustom.cpp b/WebCore/bindings/v8/custom/V8WebGLUnsignedShortArrayCustom.cpp index eeef82c..ce261e9 100644 --- a/WebCore/bindings/v8/custom/V8CanvasUnsignedShortArrayCustom.cpp +++ b/WebCore/bindings/v8/custom/V8WebGLUnsignedShortArrayCustom.cpp @@ -32,29 +32,30 @@ #if ENABLE(3D_CANVAS) -#include "CanvasArrayBuffer.h" -#include "CanvasUnsignedShortArray.h" +#include "WebGLArrayBuffer.h" +#include "WebGLUnsignedShortArray.h" #include "V8Binding.h" -#include "V8CanvasArrayBuffer.h" -#include "V8CanvasArrayCustom.h" +#include "V8WebGLArrayBuffer.h" +#include "V8WebGLArrayCustom.h" +#include "V8WebGLUnsignedShortArray.h" #include "V8CustomBinding.h" #include "V8Proxy.h" namespace WebCore { -CALLBACK_FUNC_DECL(CanvasUnsignedShortArrayConstructor) +CALLBACK_FUNC_DECL(WebGLUnsignedShortArrayConstructor) { - INC_STATS("DOM.CanvasUnsignedShortArray.Contructor"); + INC_STATS("DOM.WebGLUnsignedShortArray.Contructor"); - return constructCanvasArray<CanvasUnsignedShortArray>(args, V8ClassIndex::ToInt(V8ClassIndex::CANVASUNSIGNEDSHORTARRAY)); + return constructWebGLArray<WebGLUnsignedShortArray>(args, V8ClassIndex::ToInt(V8ClassIndex::WEBGLUNSIGNEDSHORTARRAY)); } // Get the specified value from the array and return it wrapped as a JavaScript Number object to V8. Accesses outside the valid array range return "undefined". -INDEXED_PROPERTY_GETTER(CanvasUnsignedShortArray) +INDEXED_PROPERTY_GETTER(WebGLUnsignedShortArray) { - INC_STATS("DOM.CanvasUnsignedShortArray.IndexedPropertyGetter"); - CanvasUnsignedShortArray* array = V8DOMWrapper::convertToNativeObject<CanvasUnsignedShortArray>(V8ClassIndex::CANVASUNSIGNEDSHORTARRAY, info.Holder()); + INC_STATS("DOM.WebGLUnsignedShortArray.IndexedPropertyGetter"); + WebGLUnsignedShortArray* array = V8DOMWrapper::convertToNativeObject<WebGLUnsignedShortArray>(V8ClassIndex::WEBGLUNSIGNEDSHORTARRAY, info.Holder()); if ((index < 0) || (index >= array->length())) return v8::Undefined(); @@ -65,10 +66,10 @@ INDEXED_PROPERTY_GETTER(CanvasUnsignedShortArray) } // Set the specified value in the array. Accesses outside the valid array range are silently ignored. -INDEXED_PROPERTY_SETTER(CanvasUnsignedShortArray) +INDEXED_PROPERTY_SETTER(WebGLUnsignedShortArray) { - INC_STATS("DOM.CanvasUnsignedShortArray.IndexedPropertySetter"); - CanvasUnsignedShortArray* array = V8DOMWrapper::convertToNativeObject<CanvasUnsignedShortArray>(V8ClassIndex::CANVASUNSIGNEDSHORTARRAY, info.Holder()); + INC_STATS("DOM.WebGLUnsignedShortArray.IndexedPropertySetter"); + WebGLUnsignedShortArray* array = V8DOMWrapper::convertToNativeObject<WebGLUnsignedShortArray>(V8ClassIndex::WEBGLUNSIGNEDSHORTARRAY, info.Holder()); if ((index >= 0) && (index < array->length())) { if (!value->IsNumber()) @@ -78,6 +79,18 @@ INDEXED_PROPERTY_SETTER(CanvasUnsignedShortArray) return value; } +CALLBACK_FUNC_DECL(WebGLUnsignedShortArrayGet) +{ + INC_STATS("DOM.WebGLUnsignedShortArray.get()"); + return getWebGLArrayElement<WebGLUnsignedShortArray, unsigned short>(args, V8ClassIndex::WEBGLUNSIGNEDSHORTARRAY); +} + +CALLBACK_FUNC_DECL(WebGLUnsignedShortArraySet) +{ + INC_STATS("DOM.WebGLUnsignedShortArray.set()"); + return setWebGLArray<WebGLUnsignedShortArray, V8WebGLUnsignedShortArray>(args, V8ClassIndex::WEBGLUNSIGNEDSHORTARRAY); +} + } // namespace WebCore #endif // ENABLE(3D_CANVAS) diff --git a/WebCore/bindings/v8/custom/V8WorkerContextCustom.cpp b/WebCore/bindings/v8/custom/V8WorkerContextCustom.cpp index 36c7001..9b68ac0 100755 --- a/WebCore/bindings/v8/custom/V8WorkerContextCustom.cpp +++ b/WebCore/bindings/v8/custom/V8WorkerContextCustom.cpp @@ -34,7 +34,7 @@ #include "DOMTimer.h" #include "ExceptionCode.h" -#include "NotificationCenter.h" +#include "RuntimeEnabledFeatures.h" #include "ScheduledAction.h" #include "V8Binding.h" #include "V8CustomBinding.h" @@ -49,7 +49,7 @@ namespace WebCore { #if ENABLE(NOTIFICATIONS) ACCESSOR_RUNTIME_ENABLER(WorkerContextWebkitNotifications) { - return NotificationCenter::isAvailable(); + return RuntimeEnabledFeatures::notificationsEnabled(); } #endif @@ -100,8 +100,13 @@ CALLBACK_FUNC_DECL(WorkerContextImportScripts) if (!args.Length()) return v8::Undefined(); - String callerURL = V8Proxy::sourceName(); - int callerLine = V8Proxy::sourceLineNumber() + 1; + String callerURL; + if (!V8Proxy::sourceName(callerURL)) + return v8::Undefined(); + int callerLine; + if (!V8Proxy::sourceLineNumber(callerLine)) + return v8::Undefined(); + callerLine += 1; Vector<String> urls; for (int i = 0; i < args.Length(); i++) { |