summaryrefslogtreecommitdiffstats
path: root/WebCore/bindings
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/bindings')
-rw-r--r--WebCore/bindings/ScriptControllerBase.cpp11
-rw-r--r--WebCore/bindings/generic/BindingDOMWindow.h6
-rw-r--r--WebCore/bindings/generic/RuntimeEnabledFeatures.cpp2
-rw-r--r--WebCore/bindings/generic/RuntimeEnabledFeatures.h19
-rw-r--r--WebCore/bindings/gobject/ConvertToUTF8String.cpp39
-rw-r--r--WebCore/bindings/gobject/ConvertToUTF8String.h34
-rw-r--r--WebCore/bindings/gobject/WebKitDOMBinding.cpp90
-rw-r--r--WebCore/bindings/gobject/WebKitDOMBinding.h44
-rw-r--r--WebCore/bindings/gobject/WebKitDOMObject.cpp23
-rw-r--r--WebCore/bindings/gobject/WebKitDOMObject.h58
-rw-r--r--WebCore/bindings/js/CachedScriptSourceProvider.h2
-rw-r--r--WebCore/bindings/js/DOMObjectHashTableMap.cpp37
-rw-r--r--WebCore/bindings/js/DOMObjectHashTableMap.h60
-rw-r--r--WebCore/bindings/js/DOMWrapperWorld.cpp85
-rw-r--r--WebCore/bindings/js/DOMWrapperWorld.h97
-rw-r--r--WebCore/bindings/js/GCController.cpp4
-rw-r--r--WebCore/bindings/js/JSAbstractWorkerCustom.cpp4
-rw-r--r--WebCore/bindings/js/JSAttrCustom.cpp10
-rw-r--r--WebCore/bindings/js/JSAudioConstructor.cpp2
-rw-r--r--WebCore/bindings/js/JSBindingsAllInOne.cpp3
-rw-r--r--WebCore/bindings/js/JSCSSStyleDeclarationCustom.cpp6
-rw-r--r--WebCore/bindings/js/JSCanvasRenderingContext2DCustom.cpp30
-rw-r--r--WebCore/bindings/js/JSClipboardCustom.cpp8
-rw-r--r--WebCore/bindings/js/JSConsoleCustom.cpp5
-rw-r--r--WebCore/bindings/js/JSCustomPositionCallback.cpp4
-rw-r--r--WebCore/bindings/js/JSCustomPositionErrorCallback.cpp4
-rw-r--r--WebCore/bindings/js/JSCustomSQLStatementCallback.cpp18
-rw-r--r--WebCore/bindings/js/JSCustomSQLStatementCallback.h5
-rw-r--r--WebCore/bindings/js/JSCustomSQLStatementErrorCallback.cpp24
-rw-r--r--WebCore/bindings/js/JSCustomSQLStatementErrorCallback.h13
-rw-r--r--WebCore/bindings/js/JSCustomSQLTransactionCallback.cpp22
-rw-r--r--WebCore/bindings/js/JSCustomSQLTransactionCallback.h12
-rw-r--r--WebCore/bindings/js/JSCustomSQLTransactionErrorCallback.cpp16
-rw-r--r--WebCore/bindings/js/JSCustomSQLTransactionErrorCallback.h10
-rw-r--r--WebCore/bindings/js/JSCustomXPathNSResolver.cpp2
-rw-r--r--WebCore/bindings/js/JSDOMApplicationCacheCustom.cpp4
-rw-r--r--WebCore/bindings/js/JSDOMBinding.cpp222
-rw-r--r--WebCore/bindings/js/JSDOMBinding.h174
-rw-r--r--WebCore/bindings/js/JSDOMFormDataCustom.cpp (renamed from WebCore/bindings/v8/custom/V8ScreenCustom.cpp)28
-rw-r--r--WebCore/bindings/js/JSDOMWindowBase.cpp10
-rw-r--r--WebCore/bindings/js/JSDOMWindowCustom.cpp114
-rw-r--r--WebCore/bindings/js/JSDOMWrapper.cpp51
-rw-r--r--WebCore/bindings/js/JSDOMWrapper.h46
-rw-r--r--WebCore/bindings/js/JSDataGridColumnListCustom.cpp4
-rw-r--r--WebCore/bindings/js/JSDatabaseCallback.cpp83
-rw-r--r--WebCore/bindings/js/JSDatabaseCallback.h66
-rw-r--r--WebCore/bindings/js/JSDatabaseCustom.cpp4
-rw-r--r--WebCore/bindings/js/JSDebugWrapperSet.cpp52
-rw-r--r--WebCore/bindings/js/JSDebugWrapperSet.h88
-rw-r--r--WebCore/bindings/js/JSDesktopNotificationsCustom.cpp6
-rw-r--r--WebCore/bindings/js/JSDocumentCustom.cpp2
-rw-r--r--WebCore/bindings/js/JSElementCustom.cpp19
-rw-r--r--WebCore/bindings/js/JSEventCustom.cpp4
-rw-r--r--WebCore/bindings/js/JSEventListener.cpp47
-rw-r--r--WebCore/bindings/js/JSEventListener.h1
-rw-r--r--WebCore/bindings/js/JSEventSourceConstructor.cpp2
-rw-r--r--WebCore/bindings/js/JSEventSourceCustom.cpp4
-rw-r--r--WebCore/bindings/js/JSGeolocationCustom.cpp4
-rw-r--r--WebCore/bindings/js/JSHTMLAllCollectionCustom.cpp10
-rw-r--r--WebCore/bindings/js/JSHTMLAppletElementCustom.cpp10
-rw-r--r--WebCore/bindings/js/JSHTMLCanvasElementCustom.cpp2
-rw-r--r--WebCore/bindings/js/JSHTMLCollectionCustom.cpp10
-rw-r--r--WebCore/bindings/js/JSHTMLDocumentCustom.cpp12
-rw-r--r--WebCore/bindings/js/JSHTMLEmbedElementCustom.cpp10
-rw-r--r--WebCore/bindings/js/JSHTMLFormElementCustom.cpp8
-rw-r--r--WebCore/bindings/js/JSHTMLFrameSetElementCustom.cpp8
-rw-r--r--WebCore/bindings/js/JSHTMLObjectElementCustom.cpp10
-rw-r--r--WebCore/bindings/js/JSHistoryCustom.cpp6
-rw-r--r--WebCore/bindings/js/JSInjectedScriptHostCustom.cpp36
-rw-r--r--WebCore/bindings/js/JSInspectorFrontendHostCustom.cpp35
-rw-r--r--WebCore/bindings/js/JSJavaScriptCallFrameCustom.cpp6
-rw-r--r--WebCore/bindings/js/JSLazyEventListener.cpp8
-rw-r--r--WebCore/bindings/js/JSLocationCustom.cpp24
-rw-r--r--WebCore/bindings/js/JSMessageEventCustom.cpp2
-rw-r--r--WebCore/bindings/js/JSMessagePortCustom.cpp4
-rw-r--r--WebCore/bindings/js/JSMimeTypeArrayCustom.cpp8
-rw-r--r--WebCore/bindings/js/JSNamedNodeMapCustom.cpp40
-rw-r--r--WebCore/bindings/js/JSNodeCustom.cpp100
-rw-r--r--WebCore/bindings/js/JSNodeCustom.h62
-rw-r--r--WebCore/bindings/js/JSNodeListCustom.cpp8
-rw-r--r--WebCore/bindings/js/JSOptionConstructor.cpp4
-rw-r--r--WebCore/bindings/js/JSPluginArrayCustom.cpp8
-rw-r--r--WebCore/bindings/js/JSPluginCustom.cpp8
-rw-r--r--WebCore/bindings/js/JSPluginElementFunctions.cpp24
-rw-r--r--WebCore/bindings/js/JSPluginElementFunctions.h10
-rw-r--r--WebCore/bindings/js/JSPopStateEventCustom.cpp2
-rw-r--r--WebCore/bindings/js/JSSQLResultSetRowListCustom.cpp2
-rw-r--r--WebCore/bindings/js/JSSQLTransactionCustom.cpp4
-rw-r--r--WebCore/bindings/js/JSSVGElementInstanceCustom.cpp4
-rw-r--r--WebCore/bindings/js/JSScriptProfileNodeCustom.cpp65
-rw-r--r--WebCore/bindings/js/JSSharedWorkerConstructor.cpp2
-rw-r--r--WebCore/bindings/js/JSStorageCustom.cpp16
-rw-r--r--WebCore/bindings/js/JSStyleSheetListCustom.cpp8
-rw-r--r--WebCore/bindings/js/JSWebGLArrayBufferConstructor.cpp8
-rw-r--r--WebCore/bindings/js/JSWebGLArrayBufferConstructor.h19
-rw-r--r--WebCore/bindings/js/JSWebGLArrayCustom.cpp21
-rw-r--r--WebCore/bindings/js/JSWebGLArrayHelper.h10
-rw-r--r--WebCore/bindings/js/JSWebGLByteArrayConstructor.cpp4
-rw-r--r--WebCore/bindings/js/JSWebGLFloatArrayConstructor.cpp4
-rw-r--r--WebCore/bindings/js/JSWebGLIntArrayConstructor.cpp4
-rw-r--r--WebCore/bindings/js/JSWebGLShortArrayConstructor.cpp4
-rw-r--r--WebCore/bindings/js/JSWebGLUnsignedByteArrayConstructor.cpp5
-rw-r--r--WebCore/bindings/js/JSWebGLUnsignedIntArrayConstructor.cpp4
-rw-r--r--WebCore/bindings/js/JSWebGLUnsignedShortArrayConstructor.cpp4
-rw-r--r--WebCore/bindings/js/JSWebKitCSSMatrixConstructor.cpp2
-rw-r--r--WebCore/bindings/js/JSWebSocketConstructor.cpp4
-rw-r--r--WebCore/bindings/js/JSWebSocketCustom.cpp6
-rw-r--r--WebCore/bindings/js/JSWorkerConstructor.cpp2
-rw-r--r--WebCore/bindings/js/JSWorkerContextCustom.cpp13
-rw-r--r--WebCore/bindings/js/JSWorkerContextErrorHandler.cpp116
-rw-r--r--WebCore/bindings/js/JSWorkerContextErrorHandler.h64
-rw-r--r--WebCore/bindings/js/JSXMLHttpRequestCustom.cpp46
-rw-r--r--WebCore/bindings/js/JSXMLHttpRequestUploadCustom.cpp4
-rw-r--r--WebCore/bindings/js/JSXSLTProcessorCustom.cpp14
-rw-r--r--WebCore/bindings/js/JavaScriptCallFrame.cpp115
-rw-r--r--WebCore/bindings/js/JavaScriptCallFrame.h89
-rw-r--r--WebCore/bindings/js/JavaScriptProfile.cpp183
-rw-r--r--WebCore/bindings/js/JavaScriptProfileNode.cpp236
-rw-r--r--WebCore/bindings/js/ScheduledAction.cpp5
-rw-r--r--WebCore/bindings/js/ScriptCallFrame.cpp2
-rw-r--r--WebCore/bindings/js/ScriptCallStack.cpp5
-rw-r--r--WebCore/bindings/js/ScriptCallStack.h1
-rw-r--r--WebCore/bindings/js/ScriptController.cpp59
-rw-r--r--WebCore/bindings/js/ScriptController.h10
-rw-r--r--WebCore/bindings/js/ScriptControllerBrew.cpp (renamed from WebCore/bindings/js/JavaScriptProfileNode.h)37
-rw-r--r--WebCore/bindings/js/ScriptControllerMac.mm2
-rw-r--r--WebCore/bindings/js/ScriptDebugServer.cpp585
-rw-r--r--WebCore/bindings/js/ScriptDebugServer.h149
-rw-r--r--WebCore/bindings/js/ScriptEventListener.cpp13
-rw-r--r--WebCore/bindings/js/ScriptFunctionCall.cpp6
-rw-r--r--WebCore/bindings/js/ScriptGCEvent.h (renamed from WebCore/bindings/v8/custom/V8IDBRequestCustom.cpp)28
-rw-r--r--WebCore/bindings/js/ScriptObject.cpp2
-rw-r--r--WebCore/bindings/js/ScriptProfileNode.h (renamed from WebCore/bindings/js/JavaScriptProfile.h)23
-rw-r--r--WebCore/bindings/js/ScriptProfiler.cpp5
-rw-r--r--WebCore/bindings/js/ScriptState.cpp2
-rw-r--r--WebCore/bindings/js/ScriptState.h40
-rw-r--r--WebCore/bindings/js/ScriptString.h6
-rw-r--r--WebCore/bindings/js/ScriptValue.cpp2
-rw-r--r--WebCore/bindings/js/ScriptValue.h7
-rw-r--r--WebCore/bindings/js/ScriptWrappable.h24
-rw-r--r--WebCore/bindings/js/SerializedScriptValue.cpp6
-rw-r--r--WebCore/bindings/js/StringSourceProvider.h3
-rw-r--r--WebCore/bindings/js/WebCoreJSClientData.h81
-rw-r--r--WebCore/bindings/js/WorkerScriptController.cpp15
-rw-r--r--WebCore/bindings/js/WorkerScriptController.h6
-rw-r--r--WebCore/bindings/objc/DOM.mm1
-rw-r--r--WebCore/bindings/objc/WebScriptObject.mm30
-rw-r--r--WebCore/bindings/scripts/CodeGenerator.pm2
-rw-r--r--WebCore/bindings/scripts/CodeGeneratorGObject.pm1086
-rw-r--r--WebCore/bindings/scripts/CodeGeneratorJS.pm128
-rw-r--r--WebCore/bindings/scripts/CodeGeneratorObjC.pm10
-rw-r--r--WebCore/bindings/scripts/CodeGeneratorV8.pm1124
-rw-r--r--WebCore/bindings/scripts/IDLParser.pm11
-rw-r--r--WebCore/bindings/scripts/IDLStructure.pm2
-rwxr-xr-xWebCore/bindings/scripts/generate-bindings.pl2
-rw-r--r--WebCore/bindings/scripts/gobject-generate-headers.pl77
-rw-r--r--WebCore/bindings/v8/DOMData.cpp71
-rw-r--r--WebCore/bindings/v8/DOMData.h34
-rw-r--r--WebCore/bindings/v8/DOMDataStore.cpp5
-rw-r--r--WebCore/bindings/v8/DOMDataStore.h41
-rw-r--r--WebCore/bindings/v8/DOMWrapperWorld.h1
-rw-r--r--WebCore/bindings/v8/DateExtension.cpp2
-rw-r--r--WebCore/bindings/v8/JavaScriptCallFrame.cpp120
-rw-r--r--WebCore/bindings/v8/JavaScriptCallFrame.h74
-rw-r--r--WebCore/bindings/v8/NPV8Object.cpp21
-rw-r--r--WebCore/bindings/v8/NPV8Object.h4
-rw-r--r--WebCore/bindings/v8/ScopedDOMDataStore.cpp10
-rw-r--r--WebCore/bindings/v8/ScriptCallStack.cpp26
-rw-r--r--WebCore/bindings/v8/ScriptCallStack.h4
-rw-r--r--WebCore/bindings/v8/ScriptController.cpp24
-rw-r--r--WebCore/bindings/v8/ScriptController.h7
-rw-r--r--WebCore/bindings/v8/ScriptDebugServer.cpp368
-rw-r--r--WebCore/bindings/v8/ScriptDebugServer.h107
-rw-r--r--WebCore/bindings/v8/ScriptEventListener.cpp4
-rw-r--r--WebCore/bindings/v8/ScriptGCEvent.cpp101
-rw-r--r--WebCore/bindings/v8/ScriptGCEvent.h63
-rw-r--r--WebCore/bindings/v8/ScriptProfile.cpp (renamed from WebCore/bindings/v8/custom/V8DOMSelectionCustom.cpp)31
-rw-r--r--WebCore/bindings/v8/ScriptProfile.h22
-rw-r--r--WebCore/bindings/v8/ScriptProfileNode.cpp92
-rw-r--r--WebCore/bindings/v8/ScriptProfileNode.h75
-rw-r--r--WebCore/bindings/v8/ScriptProfiler.cpp13
-rw-r--r--WebCore/bindings/v8/ScriptState.h112
-rw-r--r--WebCore/bindings/v8/ScriptValue.h2
-rw-r--r--WebCore/bindings/v8/SerializedScriptValue.cpp817
-rw-r--r--WebCore/bindings/v8/SerializedScriptValue.h36
-rw-r--r--WebCore/bindings/v8/StaticDOMDataStore.cpp8
-rw-r--r--WebCore/bindings/v8/StaticDOMDataStore.h8
-rw-r--r--WebCore/bindings/v8/V8AbstractEventListener.cpp9
-rw-r--r--WebCore/bindings/v8/V8Binding.cpp49
-rw-r--r--WebCore/bindings/v8/V8Binding.h11
-rw-r--r--WebCore/bindings/v8/V8Collection.h14
-rw-r--r--WebCore/bindings/v8/V8DOMMap.cpp17
-rw-r--r--WebCore/bindings/v8/V8DOMWindowShell.cpp97
-rw-r--r--WebCore/bindings/v8/V8DOMWindowShell.h21
-rw-r--r--WebCore/bindings/v8/V8DOMWrapper.cpp208
-rw-r--r--WebCore/bindings/v8/V8DOMWrapper.h99
-rw-r--r--WebCore/bindings/v8/V8GCController.cpp89
-rw-r--r--WebCore/bindings/v8/V8GCForContextDispose.cpp72
-rw-r--r--WebCore/bindings/v8/V8GCForContextDispose.h55
-rw-r--r--WebCore/bindings/v8/V8Helpers.cpp6
-rw-r--r--WebCore/bindings/v8/V8Helpers.h3
-rw-r--r--WebCore/bindings/v8/V8IsolatedContext.h1
-rw-r--r--WebCore/bindings/v8/V8LazyEventListener.h6
-rw-r--r--WebCore/bindings/v8/V8NPObject.cpp4
-rw-r--r--WebCore/bindings/v8/V8NodeFilterCondition.cpp5
-rw-r--r--WebCore/bindings/v8/V8Proxy.cpp140
-rw-r--r--WebCore/bindings/v8/V8Proxy.h55
-rw-r--r--WebCore/bindings/v8/V8SVGPODTypeWrapper.h6
-rw-r--r--WebCore/bindings/v8/V8Utilities.cpp45
-rw-r--r--WebCore/bindings/v8/V8Utilities.h7
-rw-r--r--WebCore/bindings/v8/V8WorkerContextErrorHandler.cpp66
-rw-r--r--WebCore/bindings/v8/V8WorkerContextErrorHandler.h59
-rw-r--r--WebCore/bindings/v8/V8WorkerContextEventListener.cpp50
-rw-r--r--WebCore/bindings/v8/V8WorkerContextEventListener.h4
-rw-r--r--WebCore/bindings/v8/WorkerContextExecutionProxy.cpp97
-rw-r--r--WebCore/bindings/v8/WorkerContextExecutionProxy.h15
-rw-r--r--WebCore/bindings/v8/WorkerScriptController.cpp22
-rw-r--r--WebCore/bindings/v8/WorkerScriptController.h9
-rw-r--r--WebCore/bindings/v8/WrapperTypeInfo.h86
-rw-r--r--WebCore/bindings/v8/custom/V8AbstractWorkerCustom.cpp81
-rw-r--r--WebCore/bindings/v8/custom/V8CSSStyleSheetCustom.cpp3
-rw-r--r--WebCore/bindings/v8/custom/V8CSSValueCustom.cpp5
-rw-r--r--WebCore/bindings/v8/custom/V8CanvasRenderingContext2DCustom.cpp358
-rw-r--r--WebCore/bindings/v8/custom/V8ConsoleCustom.cpp58
-rw-r--r--WebCore/bindings/v8/custom/V8CustomBinding.h0
-rw-r--r--WebCore/bindings/v8/custom/V8CustomIDBCallbacks.h123
-rw-r--r--WebCore/bindings/v8/custom/V8CustomSQLStatementCallback.cpp11
-rw-r--r--WebCore/bindings/v8/custom/V8CustomSQLStatementCallback.h7
-rw-r--r--WebCore/bindings/v8/custom/V8CustomSQLStatementErrorCallback.cpp12
-rw-r--r--WebCore/bindings/v8/custom/V8CustomSQLStatementErrorCallback.h6
-rw-r--r--WebCore/bindings/v8/custom/V8CustomSQLTransactionCallback.cpp11
-rw-r--r--WebCore/bindings/v8/custom/V8CustomSQLTransactionCallback.h7
-rw-r--r--WebCore/bindings/v8/custom/V8CustomSQLTransactionErrorCallback.cpp11
-rw-r--r--WebCore/bindings/v8/custom/V8CustomSQLTransactionErrorCallback.h7
-rw-r--r--WebCore/bindings/v8/custom/V8CustomVoidCallback.cpp26
-rw-r--r--WebCore/bindings/v8/custom/V8CustomVoidCallback.h1
-rw-r--r--WebCore/bindings/v8/custom/V8CustomXPathNSResolver.cpp25
-rw-r--r--WebCore/bindings/v8/custom/V8CustomXPathNSResolver.h5
-rw-r--r--WebCore/bindings/v8/custom/V8DOMApplicationCacheCustom.cpp80
-rw-r--r--WebCore/bindings/v8/custom/V8DOMFormDataCustom.cpp65
-rw-r--r--WebCore/bindings/v8/custom/V8DOMWindowCustom.cpp148
-rw-r--r--WebCore/bindings/v8/custom/V8DatabaseCallback.cpp79
-rw-r--r--WebCore/bindings/v8/custom/V8DatabaseCallback.h68
-rw-r--r--WebCore/bindings/v8/custom/V8DedicatedWorkerContextCustom.cpp5
-rw-r--r--WebCore/bindings/v8/custom/V8DocumentCustom.cpp9
-rw-r--r--WebCore/bindings/v8/custom/V8ElementCustom.cpp3
-rw-r--r--WebCore/bindings/v8/custom/V8EventCustom.cpp9
-rw-r--r--WebCore/bindings/v8/custom/V8EventSourceConstructor.cpp6
-rw-r--r--WebCore/bindings/v8/custom/V8EventSourceCustom.cpp73
-rw-r--r--WebCore/bindings/v8/custom/V8HTMLAudioElementConstructor.cpp4
-rwxr-xr-xWebCore/bindings/v8/custom/V8HTMLAudioElementConstructor.h3
-rw-r--r--WebCore/bindings/v8/custom/V8HTMLCanvasElementCustom.cpp4
-rw-r--r--WebCore/bindings/v8/custom/V8HTMLImageElementConstructor.cpp4
-rwxr-xr-xWebCore/bindings/v8/custom/V8HTMLImageElementConstructor.h3
-rw-r--r--WebCore/bindings/v8/custom/V8HTMLOptionElementConstructor.cpp4
-rwxr-xr-xWebCore/bindings/v8/custom/V8HTMLOptionElementConstructor.h3
-rw-r--r--WebCore/bindings/v8/custom/V8HistoryCustom.cpp29
-rw-r--r--WebCore/bindings/v8/custom/V8IndexedDatabaseRequestCustom.cpp29
-rw-r--r--WebCore/bindings/v8/custom/V8InjectedScriptHostCustom.cpp55
-rw-r--r--WebCore/bindings/v8/custom/V8InspectorFrontendHostCustom.cpp53
-rw-r--r--WebCore/bindings/v8/custom/V8JavaScriptCallFrameCustom.cpp79
-rw-r--r--WebCore/bindings/v8/custom/V8LocationCustom.cpp22
-rw-r--r--WebCore/bindings/v8/custom/V8MessageChannelConstructor.cpp6
-rw-r--r--WebCore/bindings/v8/custom/V8MessageEventCustom.cpp2
-rw-r--r--WebCore/bindings/v8/custom/V8MessagePortCustom.cpp36
-rw-r--r--WebCore/bindings/v8/custom/V8NamedNodeMapCustom.cpp50
-rw-r--r--WebCore/bindings/v8/custom/V8NodeCustom.cpp80
-rw-r--r--WebCore/bindings/v8/custom/V8NotificationCenterCustom.cpp32
-rw-r--r--WebCore/bindings/v8/custom/V8PopStateEventCustom.cpp8
-rw-r--r--WebCore/bindings/v8/custom/V8SVGDocumentCustom.cpp4
-rw-r--r--WebCore/bindings/v8/custom/V8SVGElementCustom.cpp2
-rw-r--r--WebCore/bindings/v8/custom/V8SVGElementInstanceCustom.cpp80
-rw-r--r--WebCore/bindings/v8/custom/V8SVGPathSegCustom.cpp4
-rw-r--r--WebCore/bindings/v8/custom/V8ScriptProfileCustom.cpp (renamed from WebCore/bindings/v8/custom/V8BarInfoCustom.cpp)50
-rw-r--r--WebCore/bindings/v8/custom/V8ScriptProfileNodeCustom.cpp81
-rw-r--r--WebCore/bindings/v8/custom/V8SharedWorkerCustom.cpp2
-rw-r--r--WebCore/bindings/v8/custom/V8StyleSheetCustom.cpp7
-rw-r--r--WebCore/bindings/v8/custom/V8WebGLArrayBufferCustom.cpp8
-rw-r--r--WebCore/bindings/v8/custom/V8WebGLArrayCustom.cpp26
-rw-r--r--WebCore/bindings/v8/custom/V8WebGLArrayCustom.h104
-rw-r--r--WebCore/bindings/v8/custom/V8WebGLByteArrayCustom.cpp10
-rw-r--r--WebCore/bindings/v8/custom/V8WebGLFloatArrayCustom.cpp10
-rw-r--r--WebCore/bindings/v8/custom/V8WebGLIntArrayCustom.cpp10
-rw-r--r--WebCore/bindings/v8/custom/V8WebGLRenderingContextCustom.cpp18
-rw-r--r--WebCore/bindings/v8/custom/V8WebGLShortArrayCustom.cpp10
-rw-r--r--WebCore/bindings/v8/custom/V8WebGLUnsignedByteArrayCustom.cpp10
-rw-r--r--WebCore/bindings/v8/custom/V8WebGLUnsignedIntArrayCustom.cpp10
-rw-r--r--WebCore/bindings/v8/custom/V8WebGLUnsignedShortArrayCustom.cpp10
-rw-r--r--WebCore/bindings/v8/custom/V8WebKitCSSMatrixConstructor.cpp2
-rwxr-xr-xWebCore/bindings/v8/custom/V8WebKitPointConstructor.cpp4
-rw-r--r--WebCore/bindings/v8/custom/V8WebSocketCustom.cpp33
-rwxr-xr-xWebCore/bindings/v8/custom/V8WorkerContextCustom.cpp54
-rwxr-xr-xWebCore/bindings/v8/custom/V8WorkerCustom.cpp7
-rw-r--r--WebCore/bindings/v8/custom/V8XMLHttpRequestConstructor.cpp2
-rw-r--r--WebCore/bindings/v8/custom/V8XMLHttpRequestCustom.cpp76
-rw-r--r--WebCore/bindings/v8/custom/V8XMLHttpRequestUploadCustom.cpp88
-rw-r--r--WebCore/bindings/v8/custom/V8XSLTProcessorCustom.cpp2
-rw-r--r--WebCore/bindings/v8/test/TestObj.idl71
-rw-r--r--WebCore/bindings/v8/test/V8TestObj.cpp459
-rw-r--r--WebCore/bindings/v8/test/V8TestObj.h53
-rw-r--r--WebCore/bindings/v8/test/run_tests.py58
301 files changed, 9432 insertions, 4469 deletions
diff --git a/WebCore/bindings/ScriptControllerBase.cpp b/WebCore/bindings/ScriptControllerBase.cpp
index abe96ee..41d2e0a 100644
--- a/WebCore/bindings/ScriptControllerBase.cpp
+++ b/WebCore/bindings/ScriptControllerBase.cpp
@@ -31,14 +31,17 @@
namespace WebCore {
-bool ScriptController::canExecuteScripts()
+bool ScriptController::canExecuteScripts(ReasonForCallingCanExecuteScripts reason)
{
// FIXME: We should get this information from the document instead of the frame.
if (m_frame->loader()->isSandboxed(SandboxScripts))
return false;
Settings* settings = m_frame->settings();
- return m_frame->loader()->client()->allowJavaScript(settings && settings->isJavaScriptEnabled());
+ const bool allowed = m_frame->loader()->client()->allowJavaScript(settings && settings->isJavaScriptEnabled());
+ if (!allowed && reason == AboutToExecuteScript)
+ m_frame->loader()->client()->didNotAllowScript();
+ return allowed;
}
ScriptValue ScriptController::executeScript(const String& script, bool forceUserGesture)
@@ -48,7 +51,7 @@ ScriptValue ScriptController::executeScript(const String& script, bool forceUser
ScriptValue ScriptController::executeScript(const ScriptSourceCode& sourceCode)
{
- if (!canExecuteScripts() || isPaused())
+ if (!canExecuteScripts(AboutToExecuteScript) || isPaused())
return ScriptValue();
bool wasInExecuteScript = m_inExecuteScript;
@@ -98,7 +101,7 @@ bool ScriptController::executeIfJavaScriptURL(const KURL& url, bool userGesture,
// synchronously can cause crashes:
// http://bugs.webkit.org/show_bug.cgi?id=16782
if (replaceDocument)
- m_frame->loader()->replaceDocument(scriptResult);
+ m_frame->loader()->writer()->replaceDocument(scriptResult);
return true;
}
diff --git a/WebCore/bindings/generic/BindingDOMWindow.h b/WebCore/bindings/generic/BindingDOMWindow.h
index d6d3087..b46bdf9 100644
--- a/WebCore/bindings/generic/BindingDOMWindow.h
+++ b/WebCore/bindings/generic/BindingDOMWindow.h
@@ -69,12 +69,6 @@ Frame* BindingDOMWindow<Binding>::createWindow(State<Binding>* state,
ASSERT(callingFrame);
ASSERT(enteredFrame);
- if (Document* callingDocument = callingFrame->document()) {
- // Sandboxed iframes cannot open new auxiliary browsing contexts.
- if (callingDocument->securityOrigin()->isSandboxed(SandboxNavigation))
- return 0;
- }
-
ResourceRequest request;
// For whatever reason, Firefox uses the entered frame to determine
diff --git a/WebCore/bindings/generic/RuntimeEnabledFeatures.cpp b/WebCore/bindings/generic/RuntimeEnabledFeatures.cpp
index 1b09518..6ba85da 100644
--- a/WebCore/bindings/generic/RuntimeEnabledFeatures.cpp
+++ b/WebCore/bindings/generic/RuntimeEnabledFeatures.cpp
@@ -44,6 +44,8 @@ bool RuntimeEnabledFeatures::isWebkitNotificationsEnabled = false;
bool RuntimeEnabledFeatures::isApplicationCacheEnabled = true;
bool RuntimeEnabledFeatures::isGeolocationEnabled = true;
bool RuntimeEnabledFeatures::isIndexedDBEnabled = false;
+bool RuntimeEnabledFeatures::isWebGLEnabled = false;
+bool RuntimeEnabledFeatures::isPushStateEnabled = false;
#if ENABLE(VIDEO)
diff --git a/WebCore/bindings/generic/RuntimeEnabledFeatures.h b/WebCore/bindings/generic/RuntimeEnabledFeatures.h
index 6f0f78f..37dceff 100644
--- a/WebCore/bindings/generic/RuntimeEnabledFeatures.h
+++ b/WebCore/bindings/generic/RuntimeEnabledFeatures.h
@@ -77,6 +77,23 @@ public:
static bool openDatabaseEnabled();
#endif
+#if ENABLE(3D_CANVAS)
+ static void setWebGLEnabled(bool isEnabled) { isWebGLEnabled = isEnabled; }
+ static bool webGLRenderingContextEnabled() { return isWebGLEnabled; }
+ static bool webGLArrayBufferEnabled() { return isWebGLEnabled; }
+ static bool webGLByteArrayEnabled() { return isWebGLEnabled; }
+ static bool webGLUnsignedByteArrayEnabled() { return isWebGLEnabled; }
+ static bool webGLShortArrayEnabled() { return isWebGLEnabled; }
+ static bool webGLUnsignedShortArrayEnabled() { return isWebGLEnabled; }
+ static bool webGLIntArrayEnabled() { return isWebGLEnabled; }
+ static bool webGLUnsignedIntArrayEnabled() { return isWebGLEnabled; }
+ static bool webGLFloatArrayEnabled() { return isWebGLEnabled; }
+#endif
+
+ static void setPushStateEnabled(bool isEnabled) { isPushStateEnabled = isEnabled; }
+ static bool pushStateEnabled() { return isPushStateEnabled; }
+ static bool replaceStateEnabled() { return isPushStateEnabled; }
+
private:
// Never instantiate.
RuntimeEnabledFeatures() { }
@@ -87,6 +104,8 @@ private:
static bool isApplicationCacheEnabled;
static bool isGeolocationEnabled;
static bool isIndexedDBEnabled;
+ static bool isWebGLEnabled;
+ static bool isPushStateEnabled;
};
} // namespace WebCore
diff --git a/WebCore/bindings/gobject/ConvertToUTF8String.cpp b/WebCore/bindings/gobject/ConvertToUTF8String.cpp
new file mode 100644
index 0000000..57010fa
--- /dev/null
+++ b/WebCore/bindings/gobject/ConvertToUTF8String.cpp
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2008 Luke Kenneth Casson Leighton <lkcl@lkcl.net>
+ * Copyright (C) 2010 Igalia S.L.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+#include "ConvertToUTF8String.h"
+
+#include "KURL.h"
+#include "PlatformString.h"
+#include <wtf/text/CString.h>
+
+#include <glib.h>
+
+gchar* convertToUTF8String(WebCore::String const& s)
+{
+ return g_strdup(s.utf8().data());
+}
+
+gchar* convertToUTF8String(WebCore::KURL const& s)
+{
+ return g_strdup(s.string().utf8().data());
+}
+
diff --git a/WebCore/bindings/gobject/ConvertToUTF8String.h b/WebCore/bindings/gobject/ConvertToUTF8String.h
new file mode 100644
index 0000000..02b6416
--- /dev/null
+++ b/WebCore/bindings/gobject/ConvertToUTF8String.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2008 Luke Kenneth Casson Leighton <lkcl@lkcl.net>
+ * Copyright (C) 2010 Igalia S.L.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef ConvertToUTF8String_h
+#define ConvertToUTF8String_h
+
+namespace WebCore {
+class String;
+class KURL;
+}
+
+typedef char gchar;
+
+gchar* convertToUTF8String(WebCore::String const& s);
+gchar* convertToUTF8String(WebCore::KURL const& s);
+
+#endif /* ConvertToUTF8String_h */
diff --git a/WebCore/bindings/gobject/WebKitDOMBinding.cpp b/WebCore/bindings/gobject/WebKitDOMBinding.cpp
new file mode 100644
index 0000000..1f900c3
--- /dev/null
+++ b/WebCore/bindings/gobject/WebKitDOMBinding.cpp
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
+ * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2007 Samuel Weinig <sam@webkit.org>
+ * Copyright (C) 2008 Luke Kenneth Casson Leighton <lkcl@lkcl.net>
+ * Copyright (C) 2008 Martin Soto <soto@freedesktop.org>
+ * Copyright (C) 2009, 2010 Igalia S.L.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+#include "WebKitDOMBinding.h"
+
+#include "Event.h"
+#include "EventException.h"
+#include "HTMLNames.h"
+#include "WebKitDOMNode.h"
+#include "WebKitDOMNodePrivate.h"
+
+namespace WebKit {
+
+using namespace WebCore;
+using namespace WebCore::HTMLNames;
+
+// DOMObjectCache
+
+typedef HashMap<void*, gpointer> DOMObjectMap;
+
+static DOMObjectMap& domObjects()
+{
+ static DOMObjectMap staticDOMObjects;
+ return staticDOMObjects;
+}
+
+gpointer DOMObjectCache::get(void* objectHandle)
+{
+ return domObjects().get(objectHandle);
+}
+
+gpointer DOMObjectCache::put(void* objectHandle, gpointer wrapper)
+{
+ domObjects().set(objectHandle, wrapper);
+ return wrapper;
+}
+
+void DOMObjectCache::forget(void* objectHandle)
+{
+ domObjects().take(objectHandle);
+}
+
+// kit methods
+
+static gpointer createWrapper(Node* node)
+{
+ ASSERT(node);
+
+ gpointer wrappedNode = 0;
+
+ if (node->nodeType())
+ wrappedNode = wrapNode(node);
+
+ return DOMObjectCache::put(node, wrappedNode);
+}
+
+gpointer kit(Node* node)
+{
+ if (!node)
+ return 0;
+
+ gpointer kitNode = DOMObjectCache::get(node);
+ if (kitNode)
+ return kitNode;
+
+ return createWrapper(node);
+}
+
+} // namespace WebKit
diff --git a/WebCore/bindings/gobject/WebKitDOMBinding.h b/WebCore/bindings/gobject/WebKitDOMBinding.h
new file mode 100644
index 0000000..f6efa46
--- /dev/null
+++ b/WebCore/bindings/gobject/WebKitDOMBinding.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
+ * Copyright (C) 2003, 2004, 2005, 2006, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2007 Samuel Weinig <sam@webkit.org>
+ * Copyright (C) 2008 Luke Kenneth Casson Leighton <lkcl@lkcl.net>
+ * Copyright (C) 2008 Martin Soto <soto@freedesktop.org>
+ * Copyright (C) 2009-2010 Igalia S.L.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef WebKitDOMBinding_h
+#define WebKitDOMBinding_h
+
+#include <glib.h>
+
+namespace WebCore {
+class Node;
+} // namespace WebCore
+
+namespace WebKit {
+gpointer kit(WebCore::Node* node);
+
+class DOMObjectCache {
+public:
+ static gpointer get(void* objectHandle);
+ static gpointer put(void* objectHandle, gpointer wrapper);
+ static void forget(void* objectHandle);
+};
+} // namespace WebKit
+
+#endif // WebKitDOMBinding_h
diff --git a/WebCore/bindings/gobject/WebKitDOMObject.cpp b/WebCore/bindings/gobject/WebKitDOMObject.cpp
new file mode 100644
index 0000000..fc8a874
--- /dev/null
+++ b/WebCore/bindings/gobject/WebKitDOMObject.cpp
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2008 Luke Kenneth Casson Leighton <lkcl@lkcl.net>
+ * Copyright (C) 2008 Martin Soto <soto@freedesktop.org>
+ * Copyright (C) 2008 Alp Toker <alp@atoker.com>
+ * Copyright (C) 2008 Apple Inc.
+ * Copyright (C) 2009 Igalia S.L.
+ */
+#include "config.h"
+#include "WebKitDOMObject.h"
+
+#include "glib-object.h"
+#include "WebKitDOMBinding.h"
+
+G_DEFINE_TYPE(WebKitDOMObject, webkit_dom_object, G_TYPE_OBJECT);
+
+static void webkit_dom_object_init(WebKitDOMObject* object)
+{
+}
+
+static void webkit_dom_object_class_init(WebKitDOMObjectClass* klass)
+{
+}
+
diff --git a/WebCore/bindings/gobject/WebKitDOMObject.h b/WebCore/bindings/gobject/WebKitDOMObject.h
new file mode 100644
index 0000000..b99c57c
--- /dev/null
+++ b/WebCore/bindings/gobject/WebKitDOMObject.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2008 Luke Kenneth Casson Leighton <lkcl@lkcl.net>
+ * Copyright (C) 2008 Martin Soto <soto@freedesktop.org>
+ * Copyright (C) 2008 Alp Toker <alp@atoker.com>
+ * Copyright (C) 2008 Apple Inc.
+ * Copyright (C) 2009 Igalia S.L.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+
+#ifndef WebKitDOMObject_h
+#define WebKitDOMObject_h
+
+#include "glib-object.h"
+#include "webkit/webkitdomdefines.h"
+#include <webkit/webkitdefines.h>
+
+G_BEGIN_DECLS
+
+#define WEBKIT_TYPE_DOM_OBJECT (webkit_dom_object_get_type())
+#define WEBKIT_DOM_OBJECT(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), WEBKIT_TYPE_DOM_OBJECT, WebKitDOMObject))
+#define WEBKIT_DOM_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), WEBKIT_TYPE_DOM_OBJECT, WebKitDOMObjectClass))
+#define WEBKIT_IS_DOM_OBJECT(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), WEBKIT_TYPE_DOM_OBJECT))
+#define WEBKIT_IS_DOM_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), WEBKIT_TYPE_DOM_OBJECT))
+#define WEBKIT_DOM_OBJECT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), WEBKIT_TYPE_DOM_OBJECT, WebKitDOMObjectClass))
+
+typedef struct _WebKitDOMObjectPrivate WebKitDOMObjectPrivate;
+
+struct _WebKitDOMObject {
+ GObject parentInstance;
+
+ gpointer coreObject;
+};
+
+struct _WebKitDOMObjectClass {
+ GObjectClass parentClass;
+};
+
+WEBKIT_API GType
+webkit_dom_object_get_type(void);
+
+G_END_DECLS
+
+#endif /* WebKitDOMObject_h */
diff --git a/WebCore/bindings/js/CachedScriptSourceProvider.h b/WebCore/bindings/js/CachedScriptSourceProvider.h
index 1cdd8aa..8e69b6b 100644
--- a/WebCore/bindings/js/CachedScriptSourceProvider.h
+++ b/WebCore/bindings/js/CachedScriptSourceProvider.h
@@ -50,7 +50,7 @@ namespace WebCore {
private:
CachedScriptSourceProvider(CachedScript* cachedScript)
- : ScriptSourceProvider(cachedScript->url())
+ : ScriptSourceProvider(stringToUString(cachedScript->url()))
, m_cachedScript(cachedScript)
{
m_cachedScript->addClient(this);
diff --git a/WebCore/bindings/js/DOMObjectHashTableMap.cpp b/WebCore/bindings/js/DOMObjectHashTableMap.cpp
new file mode 100644
index 0000000..bfcab0b
--- /dev/null
+++ b/WebCore/bindings/js/DOMObjectHashTableMap.cpp
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
+ * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2007 Samuel Weinig <sam@webkit.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+#include "DOMObjectHashTableMap.h"
+
+#include "WebCoreJSClientData.h"
+
+using namespace JSC;
+
+namespace WebCore{
+
+DOMObjectHashTableMap& DOMObjectHashTableMap::mapFor(JSGlobalData& globalData)
+{
+ JSGlobalData::ClientData* clientData = globalData.clientData;
+ ASSERT(clientData);
+ return static_cast<WebCoreJSClientData*>(clientData)->hashTableMap;
+}
+
+} // namespace WebCore
diff --git a/WebCore/bindings/js/DOMObjectHashTableMap.h b/WebCore/bindings/js/DOMObjectHashTableMap.h
new file mode 100644
index 0000000..4ddacb8
--- /dev/null
+++ b/WebCore/bindings/js/DOMObjectHashTableMap.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
+ * Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2007 Samuel Weinig <sam@webkit.org>
+ * Copyright (C) 2009 Google, Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef DOMObjectHashTableMap_h
+#define DOMObjectHashTableMap_h
+
+#include <runtime/Lookup.h>
+#include <wtf/HashMap.h>
+
+namespace JSC {
+ class JSGlobalData;
+}
+
+namespace WebCore {
+
+// Map from static HashTable instances to per-GlobalData ones.
+class DOMObjectHashTableMap {
+public:
+ static DOMObjectHashTableMap& mapFor(JSC::JSGlobalData&);
+
+ ~DOMObjectHashTableMap()
+ {
+ HashMap<const JSC::HashTable*, JSC::HashTable>::iterator mapEnd = m_map.end();
+ for (HashMap<const JSC::HashTable*, JSC::HashTable>::iterator iter = m_map.begin(); iter != m_map.end(); ++iter)
+ iter->second.deleteTable();
+ }
+
+ const JSC::HashTable* get(const JSC::HashTable* staticTable)
+ {
+ HashMap<const JSC::HashTable*, JSC::HashTable>::iterator iter = m_map.find(staticTable);
+ if (iter != m_map.end())
+ return &iter->second;
+ return &m_map.set(staticTable, JSC::HashTable(*staticTable)).first->second;
+ }
+
+private:
+ HashMap<const JSC::HashTable*, JSC::HashTable> m_map;
+};
+
+} // namespace WebCore
+
+#endif // DOMObjectHashTableMap_h
diff --git a/WebCore/bindings/js/DOMWrapperWorld.cpp b/WebCore/bindings/js/DOMWrapperWorld.cpp
new file mode 100644
index 0000000..10c3fdd
--- /dev/null
+++ b/WebCore/bindings/js/DOMWrapperWorld.cpp
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
+ * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2007 Samuel Weinig <sam@webkit.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+#include "DOMWrapperWorld.h"
+
+#include "JSDOMWindow.h"
+#include "ScriptController.h"
+#include "WebCoreJSClientData.h"
+
+using namespace JSC;
+
+namespace WebCore {
+
+DOMWrapperWorld::DOMWrapperWorld(JSC::JSGlobalData* globalData, bool isNormal)
+ : m_globalData(globalData)
+ , m_isNormal(isNormal)
+ , m_isRegistered(false)
+{
+ registerWorld();
+}
+
+DOMWrapperWorld::~DOMWrapperWorld()
+{
+ unregisterWorld();
+}
+
+void DOMWrapperWorld::registerWorld()
+{
+ JSGlobalData::ClientData* clientData = m_globalData->clientData;
+ ASSERT(clientData);
+ static_cast<WebCoreJSClientData*>(clientData)->rememberWorld(this);
+ m_isRegistered = true;
+}
+
+void DOMWrapperWorld::unregisterWorld()
+{
+ if (!m_isRegistered)
+ return;
+ m_isRegistered = false;
+
+ JSGlobalData::ClientData* clientData = m_globalData->clientData;
+ ASSERT(clientData);
+ static_cast<WebCoreJSClientData*>(clientData)->forgetWorld(this);
+
+ // These items are created lazily.
+ while (!m_documentsWithWrapperCaches.isEmpty())
+ (*m_documentsWithWrapperCaches.begin())->destroyWrapperCache(this);
+
+ while (!m_scriptControllersWithWindowShells.isEmpty())
+ (*m_scriptControllersWithWindowShells.begin())->destroyWindowShell(this);
+}
+
+DOMWrapperWorld* normalWorld(JSC::JSGlobalData& globalData)
+{
+ JSGlobalData::ClientData* clientData = globalData.clientData;
+ ASSERT(clientData);
+ return static_cast<WebCoreJSClientData*>(clientData)->normalWorld();
+}
+
+DOMWrapperWorld* mainThreadNormalWorld()
+{
+ ASSERT(isMainThread());
+ static DOMWrapperWorld* cachedNormalWorld = normalWorld(*JSDOMWindow::commonJSGlobalData());
+ return cachedNormalWorld;
+}
+
+} // namespace WebCore
diff --git a/WebCore/bindings/js/DOMWrapperWorld.h b/WebCore/bindings/js/DOMWrapperWorld.h
new file mode 100644
index 0000000..832c5e0
--- /dev/null
+++ b/WebCore/bindings/js/DOMWrapperWorld.h
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
+ * Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2007 Samuel Weinig <sam@webkit.org>
+ * Copyright (C) 2009 Google, Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef DOMWrapperWorld_h
+#define DOMWrapperWorld_h
+
+#include "Document.h"
+#include "JSDOMGlobalObject.h"
+#include "JSDOMWrapper.h"
+#include <runtime/WeakGCMap.h>
+
+namespace WebCore {
+
+class ScriptController;
+class StringImpl;
+
+typedef JSC::WeakGCMap<void*, DOMObject*> DOMObjectWrapperMap;
+typedef JSC::WeakGCMap<StringImpl*, JSC::JSString*> JSStringCache;
+
+class DOMWrapperWorld : public RefCounted<DOMWrapperWorld> {
+public:
+ static PassRefPtr<DOMWrapperWorld> create(JSC::JSGlobalData* globalData, bool isNormal = false)
+ {
+ return adoptRef(new DOMWrapperWorld(globalData, isNormal));
+ }
+ ~DOMWrapperWorld();
+
+ void registerWorld();
+ void unregisterWorld();
+
+ void didCreateWrapperCache(Document* document) { m_documentsWithWrapperCaches.add(document); }
+ void didDestroyWrapperCache(Document* document) { m_documentsWithWrapperCaches.remove(document); }
+
+ void didCreateWindowShell(ScriptController* scriptController) { m_scriptControllersWithWindowShells.add(scriptController); }
+ void didDestroyWindowShell(ScriptController* scriptController) { m_scriptControllersWithWindowShells.remove(scriptController); }
+
+ // FIXME: can we make this private?
+ DOMObjectWrapperMap m_wrappers;
+ JSStringCache m_stringCache;
+
+ bool isNormal() const { return m_isNormal; }
+
+protected:
+ DOMWrapperWorld(JSC::JSGlobalData*, bool isNormal);
+
+private:
+ JSC::JSGlobalData* m_globalData;
+ HashSet<Document*> m_documentsWithWrapperCaches;
+ HashSet<ScriptController*> m_scriptControllersWithWindowShells;
+ bool m_isNormal;
+ bool m_isRegistered;
+};
+
+DOMWrapperWorld* normalWorld(JSC::JSGlobalData&);
+DOMWrapperWorld* mainThreadNormalWorld();
+inline DOMWrapperWorld* debuggerWorld() { return mainThreadNormalWorld(); }
+inline DOMWrapperWorld* pluginWorld() { return mainThreadNormalWorld(); }
+
+inline DOMWrapperWorld* currentWorld(JSC::ExecState* exec)
+{
+ return static_cast<JSDOMGlobalObject*>(exec->lexicalGlobalObject())->world();
+}
+
+// From Document.h
+
+inline Document::JSWrapperCache* Document::getWrapperCache(DOMWrapperWorld* world)
+{
+ if (world->isNormal()) {
+ if (Document::JSWrapperCache* wrapperCache = m_normalWorldWrapperCache)
+ return wrapperCache;
+ ASSERT(!m_wrapperCacheMap.contains(world));
+ } else if (Document::JSWrapperCache* wrapperCache = m_wrapperCacheMap.get(world))
+ return wrapperCache;
+ return createWrapperCache(world);
+}
+
+} // namespace WebCore
+
+#endif // DOMWrapperWorld_h
diff --git a/WebCore/bindings/js/GCController.cpp b/WebCore/bindings/js/GCController.cpp
index 3e5645f..d5a1789 100644
--- a/WebCore/bindings/js/GCController.cpp
+++ b/WebCore/bindings/js/GCController.cpp
@@ -71,7 +71,9 @@ void GCController::gcTimerFired(Timer<GCController>*)
void GCController::garbageCollectNow()
{
- collect(0);
+ JSLock lock(SilenceAssertionsOnly);
+ if (!JSDOMWindow::commonJSGlobalData()->heap.isBusy())
+ collect(0);
}
void GCController::garbageCollectOnAlternateThreadForDebugging(bool waitUntilDone)
diff --git a/WebCore/bindings/js/JSAbstractWorkerCustom.cpp b/WebCore/bindings/js/JSAbstractWorkerCustom.cpp
index 61fcf98..1f843f9 100644
--- a/WebCore/bindings/js/JSAbstractWorkerCustom.cpp
+++ b/WebCore/bindings/js/JSAbstractWorkerCustom.cpp
@@ -50,7 +50,7 @@ JSValue JSAbstractWorker::addEventListener(ExecState* exec, const ArgList& args)
if (!listener.isObject())
return jsUndefined();
- impl()->addEventListener(args.at(0).toString(exec), JSEventListener::create(asObject(listener), this, false, currentWorld(exec)), args.at(2).toBoolean(exec));
+ impl()->addEventListener(ustringToAtomicString(args.at(0).toString(exec)), JSEventListener::create(asObject(listener), this, false, currentWorld(exec)), args.at(2).toBoolean(exec));
return jsUndefined();
}
@@ -60,7 +60,7 @@ JSValue JSAbstractWorker::removeEventListener(ExecState* exec, const ArgList& ar
if (!listener.isObject())
return jsUndefined();
- impl()->removeEventListener(args.at(0).toString(exec), JSEventListener::create(asObject(listener), this, false, currentWorld(exec)).get(), args.at(2).toBoolean(exec));
+ impl()->removeEventListener(ustringToAtomicString(args.at(0).toString(exec)), JSEventListener::create(asObject(listener), this, false, currentWorld(exec)).get(), args.at(2).toBoolean(exec));
return jsUndefined();
}
diff --git a/WebCore/bindings/js/JSAttrCustom.cpp b/WebCore/bindings/js/JSAttrCustom.cpp
index 3c01535..4cd40ac 100644
--- a/WebCore/bindings/js/JSAttrCustom.cpp
+++ b/WebCore/bindings/js/JSAttrCustom.cpp
@@ -33,6 +33,7 @@
#include "Document.h"
#include "HTMLFrameElementBase.h"
#include "HTMLNames.h"
+#include "JSDOMBinding.h"
using namespace JSC;
@@ -46,13 +47,8 @@ void JSAttr::setValue(ExecState* exec, JSValue value)
String attrValue = valueToStringWithNullCheck(exec, value);
Element* ownerElement = imp->ownerElement();
- if (ownerElement && (ownerElement->hasTagName(iframeTag) || ownerElement->hasTagName(frameTag))) {
- if (equalIgnoringCase(imp->name(), "src") && protocolIsJavaScript(deprecatedParseURL(attrValue))) {
- Document* contentDocument = static_cast<HTMLFrameElementBase*>(ownerElement)->contentDocument();
- if (contentDocument && !checkNodeSecurity(exec, contentDocument))
- return;
- }
- }
+ if (ownerElement && !allowSettingSrcToJavascriptURL(exec, ownerElement, imp->name(), attrValue))
+ return;
ExceptionCode ec = 0;
imp->setValue(attrValue, ec);
diff --git a/WebCore/bindings/js/JSAudioConstructor.cpp b/WebCore/bindings/js/JSAudioConstructor.cpp
index 77bb120..cc791d1 100644
--- a/WebCore/bindings/js/JSAudioConstructor.cpp
+++ b/WebCore/bindings/js/JSAudioConstructor.cpp
@@ -64,7 +64,7 @@ static JSObject* constructAudio(ExecState* exec, JSObject* constructor, const Ar
// rather than looking at args.size.
String src;
if (args.size() > 0)
- src = args.at(0).toString(exec);
+ src = ustringToString(args.at(0).toString(exec));
return asObject(toJS(exec, jsConstructor->globalObject(),
HTMLAudioElement::createForJSConstructor(document, src)));
}
diff --git a/WebCore/bindings/js/JSBindingsAllInOne.cpp b/WebCore/bindings/js/JSBindingsAllInOne.cpp
index 5a0820b..2e05350 100644
--- a/WebCore/bindings/js/JSBindingsAllInOne.cpp
+++ b/WebCore/bindings/js/JSBindingsAllInOne.cpp
@@ -113,6 +113,7 @@
#include "JSSVGMatrixCustom.cpp"
#include "JSSVGPathSegCustom.cpp"
#include "JSSVGPathSegListCustom.cpp"
+#include "JSScriptProfileNodeCustom.cpp"
#include "JSSharedWorkerConstructor.cpp"
#include "JSSharedWorkerCustom.cpp"
#include "JSStorageCustom.cpp"
@@ -127,12 +128,14 @@
#include "JSWorkerConstructor.cpp"
#include "JSWorkerContextBase.cpp"
#include "JSWorkerContextCustom.cpp"
+#include "JSWorkerContextErrorHandler.cpp"
#include "JSWorkerCustom.cpp"
#include "JSXMLHttpRequestConstructor.cpp"
#include "JSXMLHttpRequestCustom.cpp"
#include "JSXMLHttpRequestUploadCustom.cpp"
#include "JSXSLTProcessorConstructor.cpp"
#include "JSXSLTProcessorCustom.cpp"
+#include "JavaScriptCallFrame.cpp"
#include "ScheduledAction.cpp"
#include "ScriptArray.cpp"
#include "ScriptCachedFrameData.cpp"
diff --git a/WebCore/bindings/js/JSCSSStyleDeclarationCustom.cpp b/WebCore/bindings/js/JSCSSStyleDeclarationCustom.cpp
index 4a137d3..22bfee4 100644
--- a/WebCore/bindings/js/JSCSSStyleDeclarationCustom.cpp
+++ b/WebCore/bindings/js/JSCSSStyleDeclarationCustom.cpp
@@ -142,9 +142,9 @@ bool JSCSSStyleDeclaration::canGetItemsForName(ExecState*, CSSStyleDeclaration*,
// FIXME: You can get these properties, and set them (see putDelegate below),
// but you should also be able to enumerate them.
-JSValue JSCSSStyleDeclaration::nameGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot)
+JSValue JSCSSStyleDeclaration::nameGetter(ExecState* exec, JSValue slotBase, const Identifier& propertyName)
{
- JSCSSStyleDeclaration* thisObj = static_cast<JSCSSStyleDeclaration*>(asObject(slot.slotBase()));
+ JSCSSStyleDeclaration* thisObj = static_cast<JSCSSStyleDeclaration*>(asObject(slotBase));
// Set up pixelOrPos boolean to handle the fact that
// pixelTop returns "CSS Top" as number value in unit pixels
@@ -165,7 +165,7 @@ JSValue JSCSSStyleDeclaration::nameGetter(ExecState* exec, const Identifier& pro
// Make the SVG 'filter' attribute undetectable, to avoid confusion with the IE 'filter' attribute.
if (propertyName == "filter")
- return StringObjectThatMasqueradesAsUndefined::create(exec, thisObj->impl()->getPropertyValue(prop));
+ return StringObjectThatMasqueradesAsUndefined::create(exec, stringToUString(thisObj->impl()->getPropertyValue(prop)));
return jsString(exec, thisObj->impl()->getPropertyValue(prop));
}
diff --git a/WebCore/bindings/js/JSCanvasRenderingContext2DCustom.cpp b/WebCore/bindings/js/JSCanvasRenderingContext2DCustom.cpp
index a271923..7a776db 100644
--- a/WebCore/bindings/js/JSCanvasRenderingContext2DCustom.cpp
+++ b/WebCore/bindings/js/JSCanvasRenderingContext2DCustom.cpp
@@ -54,7 +54,7 @@ static JSValue toJS(ExecState* exec, CanvasStyle* style)
static PassRefPtr<CanvasStyle> toHTMLCanvasStyle(ExecState* exec, JSValue value)
{
if (value.isString())
- return CanvasStyle::create(asString(value)->value(exec));
+ return CanvasStyle::create(ustringToString(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(exec));
+ context->setFillColor(ustringToString(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(exec), args.at(1).toFloat(exec));
+ context->setFillColor(ustringToString(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(exec));
+ context->setStrokeColor(ustringToString(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(exec), args.at(1).toFloat(exec));
+ context->setStrokeColor(ustringToString(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;
@@ -198,7 +198,7 @@ JSValue JSCanvasRenderingContext2D::drawImage(ExecState* exec, const ArgList& ar
HTMLImageElement* imgElt = static_cast<HTMLImageElement*>(static_cast<JSHTMLElement*>(o)->impl());
switch (args.size()) {
case 3:
- context->drawImage(imgElt, args.at(1).toFloat(exec), args.at(2).toFloat(exec));
+ context->drawImage(imgElt, args.at(1).toFloat(exec), args.at(2).toFloat(exec), ec);
break;
case 5:
context->drawImage(imgElt, args.at(1).toFloat(exec), args.at(2).toFloat(exec),
@@ -219,7 +219,7 @@ JSValue JSCanvasRenderingContext2D::drawImage(ExecState* exec, const ArgList& ar
HTMLCanvasElement* canvas = static_cast<HTMLCanvasElement*>(static_cast<JSHTMLElement*>(o)->impl());
switch (args.size()) {
case 3:
- context->drawImage(canvas, args.at(1).toFloat(exec), args.at(2).toFloat(exec));
+ context->drawImage(canvas, args.at(1).toFloat(exec), args.at(2).toFloat(exec), ec);
break;
case 5:
context->drawImage(canvas, args.at(1).toFloat(exec), args.at(2).toFloat(exec),
@@ -241,7 +241,7 @@ JSValue JSCanvasRenderingContext2D::drawImage(ExecState* exec, const ArgList& ar
HTMLVideoElement* video = static_cast<HTMLVideoElement*>(static_cast<JSHTMLElement*>(o)->impl());
switch (args.size()) {
case 3:
- context->drawImage(video, args.at(1).toFloat(exec), args.at(2).toFloat(exec));
+ context->drawImage(video, args.at(1).toFloat(exec), args.at(2).toFloat(exec), ec);
break;
case 5:
context->drawImage(video, args.at(1).toFloat(exec), args.at(2).toFloat(exec),
@@ -282,7 +282,7 @@ JSValue JSCanvasRenderingContext2D::drawImageFromRect(ExecState* exec, const Arg
args.at(3).toFloat(exec), args.at(4).toFloat(exec),
args.at(5).toFloat(exec), args.at(6).toFloat(exec),
args.at(7).toFloat(exec), args.at(8).toFloat(exec),
- args.at(9).toString(exec));
+ ustringToString(args.at(9).toString(exec)));
return jsUndefined();
}
@@ -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(exec));
+ args.at(2).toFloat(exec), ustringToString(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(exec),
+ args.at(2).toFloat(exec), ustringToString(asString(args.at(3))->value(exec)),
args.at(4).toFloat(exec));
else
context->setShadow(args.at(0).toFloat(exec), args.at(1).toFloat(exec),
@@ -391,9 +391,9 @@ JSValue JSCanvasRenderingContext2D::fillText(ExecState* exec, const ArgList& arg
return throwError(exec, SyntaxError);
if (args.size() == 4)
- context->fillText(args.at(0).toString(exec), args.at(1).toFloat(exec), args.at(2).toFloat(exec), args.at(3).toFloat(exec));
+ context->fillText(ustringToString(args.at(0).toString(exec)), args.at(1).toFloat(exec), args.at(2).toFloat(exec), args.at(3).toFloat(exec));
else
- context->fillText(args.at(0).toString(exec), args.at(1).toFloat(exec), args.at(2).toFloat(exec));
+ context->fillText(ustringToString(args.at(0).toString(exec)), args.at(1).toFloat(exec), args.at(2).toFloat(exec));
return jsUndefined();
}
@@ -409,9 +409,9 @@ JSValue JSCanvasRenderingContext2D::strokeText(ExecState* exec, const ArgList& a
return throwError(exec, SyntaxError);
if (args.size() == 4)
- context->strokeText(args.at(0).toString(exec), args.at(1).toFloat(exec), args.at(2).toFloat(exec), args.at(3).toFloat(exec));
+ context->strokeText(ustringToString(args.at(0).toString(exec)), args.at(1).toFloat(exec), args.at(2).toFloat(exec), args.at(3).toFloat(exec));
else
- context->strokeText(args.at(0).toString(exec), args.at(1).toFloat(exec), args.at(2).toFloat(exec));
+ context->strokeText(ustringToString(args.at(0).toString(exec)), args.at(1).toFloat(exec), args.at(2).toFloat(exec));
return jsUndefined();
}
diff --git a/WebCore/bindings/js/JSClipboardCustom.cpp b/WebCore/bindings/js/JSClipboardCustom.cpp
index 78dca49..7efd2b0 100644
--- a/WebCore/bindings/js/JSClipboardCustom.cpp
+++ b/WebCore/bindings/js/JSClipboardCustom.cpp
@@ -59,7 +59,7 @@ JSValue JSClipboard::types(ExecState* exec) const
MarkedArgumentBuffer list;
HashSet<String>::const_iterator end = types.end();
for (HashSet<String>::const_iterator it = types.begin(); it != end; ++it)
- list.append(jsString(exec, UString(*it)));
+ list.append(jsString(exec, stringToUString(*it)));
return constructArray(exec, list);
}
@@ -73,7 +73,7 @@ JSValue JSClipboard::clearData(ExecState* exec, const ArgList& args)
}
if (args.size() == 1) {
- clipboard->clearData(args.at(0).toString(exec));
+ clipboard->clearData(ustringToString(args.at(0).toString(exec)));
return jsUndefined();
}
@@ -90,7 +90,7 @@ JSValue JSClipboard::getData(ExecState* exec, const ArgList& args)
Clipboard* clipboard = impl();
bool success;
- String result = clipboard->getData(args.at(0).toString(exec), success);
+ String result = clipboard->getData(ustringToString(args.at(0).toString(exec)), success);
if (!success)
return jsUndefined();
@@ -105,7 +105,7 @@ JSValue JSClipboard::setData(ExecState* exec, const ArgList& args)
if (args.size() != 2)
return throwError(exec, SyntaxError, "setData: Invalid number of arguments");
- return jsBoolean(clipboard->setData(args.at(0).toString(exec), args.at(1).toString(exec)));
+ return jsBoolean(clipboard->setData(ustringToString(args.at(0).toString(exec)), ustringToString(args.at(1).toString(exec))));
}
JSValue JSClipboard::setDragImage(ExecState* exec, const ArgList& args)
diff --git a/WebCore/bindings/js/JSConsoleCustom.cpp b/WebCore/bindings/js/JSConsoleCustom.cpp
index b631cdd..3ad34a3 100644
--- a/WebCore/bindings/js/JSConsoleCustom.cpp
+++ b/WebCore/bindings/js/JSConsoleCustom.cpp
@@ -28,8 +28,9 @@
#include "JSConsole.h"
#include "Console.h"
-#include "JavaScriptProfile.h"
+#include "JSScriptProfile.h"
#include "ScriptCallStack.h"
+#include "ScriptProfile.h"
#include <runtime/JSArray.h>
using namespace JSC;
@@ -38,7 +39,7 @@ namespace WebCore {
#if ENABLE(JAVASCRIPT_DEBUGGER)
-typedef Vector<RefPtr<JSC::Profile> > ProfilesArray;
+typedef Vector<RefPtr<ScriptProfile> > ProfilesArray;
JSValue JSConsole::profiles(ExecState* exec) const
{
diff --git a/WebCore/bindings/js/JSCustomPositionCallback.cpp b/WebCore/bindings/js/JSCustomPositionCallback.cpp
index e5f83aa..cc6d45c 100644
--- a/WebCore/bindings/js/JSCustomPositionCallback.cpp
+++ b/WebCore/bindings/js/JSCustomPositionCallback.cpp
@@ -26,6 +26,8 @@
#include "config.h"
#include "JSCustomPositionCallback.h"
+#if ENABLE(GEOLOCATION)
+
#include "Frame.h"
#include "JSGeoposition.h"
#include "ScriptController.h"
@@ -52,3 +54,5 @@ void JSCustomPositionCallback::handleEvent(Geoposition* geoposition)
}
} // namespace WebCore
+
+#endif // ENABLE(GEOLOCATION)
diff --git a/WebCore/bindings/js/JSCustomPositionErrorCallback.cpp b/WebCore/bindings/js/JSCustomPositionErrorCallback.cpp
index bd64deb..c94ae9a 100644
--- a/WebCore/bindings/js/JSCustomPositionErrorCallback.cpp
+++ b/WebCore/bindings/js/JSCustomPositionErrorCallback.cpp
@@ -26,6 +26,8 @@
#include "config.h"
#include "JSCustomPositionErrorCallback.h"
+#if ENABLE(GEOLOCATION)
+
#include "Frame.h"
#include "JSPositionError.h"
#include "ScriptController.h"
@@ -53,3 +55,5 @@ void JSCustomPositionErrorCallback::handleEvent(PositionError* positionError)
}
} // namespace WebCore
+
+#endif // ENABLE(GEOLOCATION)
diff --git a/WebCore/bindings/js/JSCustomSQLStatementCallback.cpp b/WebCore/bindings/js/JSCustomSQLStatementCallback.cpp
index 1f6bd95..46a7ae5 100644
--- a/WebCore/bindings/js/JSCustomSQLStatementCallback.cpp
+++ b/WebCore/bindings/js/JSCustomSQLStatementCallback.cpp
@@ -32,21 +32,22 @@
#if ENABLE(DATABASE)
#include "Frame.h"
-#include "ScriptController.h"
#include "JSSQLResultSet.h"
#include "JSSQLTransaction.h"
+#include "ScriptExecutionContext.h"
#include <runtime/JSLock.h>
#include <wtf/MainThread.h>
namespace WebCore {
-
+
using namespace JSC;
-
+
JSCustomSQLStatementCallback::JSCustomSQLStatementCallback(JSObject* callback, JSDOMGlobalObject* globalObject)
: m_data(new JSCallbackData(callback, globalObject))
+ , m_isolatedWorld(globalObject->world())
{
}
-
+
JSCustomSQLStatementCallback::~JSCustomSQLStatementCallback()
{
callOnMainThread(JSCallbackData::deleteData, m_data);
@@ -55,14 +56,19 @@ JSCustomSQLStatementCallback::~JSCustomSQLStatementCallback()
#endif
}
-void JSCustomSQLStatementCallback::handleEvent(SQLTransaction* transaction, SQLResultSet* resultSet, bool& raisedException)
+void JSCustomSQLStatementCallback::handleEvent(ScriptExecutionContext* context, SQLTransaction* transaction, SQLResultSet* resultSet, bool& raisedException)
{
ASSERT(m_data);
+ ASSERT(context);
RefPtr<JSCustomSQLStatementCallback> protect(this);
JSC::JSLock lock(SilenceAssertionsOnly);
- ExecState* exec = m_data->globalObject()->globalExec();
+ JSDOMGlobalObject* globalObject = toJSDOMGlobalObject(context, m_isolatedWorld.get());
+ if (!globalObject)
+ return;
+
+ ExecState* exec = globalObject->globalExec();
MarkedArgumentBuffer args;
args.append(toJS(exec, deprecatedGlobalObjectForPrototype(exec), transaction));
args.append(toJS(exec, deprecatedGlobalObjectForPrototype(exec), resultSet));
diff --git a/WebCore/bindings/js/JSCustomSQLStatementCallback.h b/WebCore/bindings/js/JSCustomSQLStatementCallback.h
index 259aecf..cb7b34d 100644
--- a/WebCore/bindings/js/JSCustomSQLStatementCallback.h
+++ b/WebCore/bindings/js/JSCustomSQLStatementCallback.h
@@ -45,15 +45,16 @@ public:
{
return adoptRef(new JSCustomSQLStatementCallback(callback, globalObject));
}
-
+
virtual ~JSCustomSQLStatementCallback();
- virtual void handleEvent(SQLTransaction*, SQLResultSet*, bool& raisedException);
+ virtual void handleEvent(ScriptExecutionContext*, SQLTransaction*, SQLResultSet*, bool& raisedException);
private:
JSCustomSQLStatementCallback(JSC::JSObject* callback, JSDOMGlobalObject*);
JSCallbackData* m_data;
+ RefPtr<DOMWrapperWorld> m_isolatedWorld;
};
}
diff --git a/WebCore/bindings/js/JSCustomSQLStatementErrorCallback.cpp b/WebCore/bindings/js/JSCustomSQLStatementErrorCallback.cpp
index 4d5de79..a2ba52a 100644
--- a/WebCore/bindings/js/JSCustomSQLStatementErrorCallback.cpp
+++ b/WebCore/bindings/js/JSCustomSQLStatementErrorCallback.cpp
@@ -35,16 +35,17 @@
#include "JSCallbackData.h"
#include "JSSQLError.h"
#include "JSSQLTransaction.h"
-#include "ScriptController.h"
+#include "ScriptExecutionContext.h"
#include <runtime/JSLock.h>
#include <wtf/MainThread.h>
namespace WebCore {
-
+
using namespace JSC;
-
+
JSCustomSQLStatementErrorCallback::JSCustomSQLStatementErrorCallback(JSObject* callback, JSDOMGlobalObject* globalObject)
: m_data(new JSCallbackData(callback, globalObject))
+ , m_isolatedWorld(globalObject->world())
{
}
@@ -56,18 +57,23 @@ JSCustomSQLStatementErrorCallback::~JSCustomSQLStatementErrorCallback()
#endif
}
-bool JSCustomSQLStatementErrorCallback::handleEvent(SQLTransaction* transaction, SQLError* error)
+bool JSCustomSQLStatementErrorCallback::handleEvent(ScriptExecutionContext* context, SQLTransaction* transaction, SQLError* error)
{
ASSERT(m_data);
-
+ ASSERT(context);
+
RefPtr<JSCustomSQLStatementErrorCallback> protect(this);
-
+
JSC::JSLock lock(SilenceAssertionsOnly);
- ExecState* exec = m_data->globalObject()->globalExec();
+ JSDOMGlobalObject* globalObject = toJSDOMGlobalObject(context, m_isolatedWorld.get());
+ if (!globalObject)
+ return true; // if we cannot invoke the callback, roll back the transaction
+
+ ExecState* exec = globalObject->globalExec();
MarkedArgumentBuffer args;
args.append(toJS(exec, deprecatedGlobalObjectForPrototype(exec), transaction));
args.append(toJS(exec, deprecatedGlobalObjectForPrototype(exec), error));
-
+
bool raisedException = false;
JSValue result = m_data->invokeCallback(args, &raisedException);
if (raisedException) {
@@ -77,7 +83,7 @@ bool JSCustomSQLStatementErrorCallback::handleEvent(SQLTransaction* transaction,
// Therefore an exception and returning true are the same thing - so, return true on an exception
return true;
}
- return !result.isFalse();
+ return result.toBoolean(exec);
}
}
diff --git a/WebCore/bindings/js/JSCustomSQLStatementErrorCallback.h b/WebCore/bindings/js/JSCustomSQLStatementErrorCallback.h
index ac4e45f..b1b0792 100644
--- a/WebCore/bindings/js/JSCustomSQLStatementErrorCallback.h
+++ b/WebCore/bindings/js/JSCustomSQLStatementErrorCallback.h
@@ -31,16 +31,15 @@
#if ENABLE(DATABASE)
-#include "JSDOMGlobalObject.h"
+#include "JSCallbackData.h"
#include "SQLStatementErrorCallback.h"
-#include <runtime/Protect.h>
#include <wtf/Forward.h>
namespace WebCore {
-class JSCallbackData;
+class JSCallbackData;
class SQLError;
-
+
class JSCustomSQLStatementErrorCallback : public SQLStatementErrorCallback {
public:
static PassRefPtr<JSCustomSQLStatementErrorCallback> create(JSC::JSObject* callback, JSDOMGlobalObject* globalObject)
@@ -50,17 +49,17 @@ public:
virtual ~JSCustomSQLStatementErrorCallback();
- virtual bool handleEvent(SQLTransaction*, SQLError*);
+ virtual bool handleEvent(ScriptExecutionContext*, SQLTransaction*, SQLError*);
private:
JSCustomSQLStatementErrorCallback(JSC::JSObject* callback, JSDOMGlobalObject*);
JSCallbackData* m_data;
+ RefPtr<DOMWrapperWorld> m_isolatedWorld;
};
-
+
}
#endif // ENABLE(DATABASE)
#endif // JSCustomSQLStatementErrorCallback_h
-
diff --git a/WebCore/bindings/js/JSCustomSQLTransactionCallback.cpp b/WebCore/bindings/js/JSCustomSQLTransactionCallback.cpp
index 456022f..d5e9754 100644
--- a/WebCore/bindings/js/JSCustomSQLTransactionCallback.cpp
+++ b/WebCore/bindings/js/JSCustomSQLTransactionCallback.cpp
@@ -33,24 +33,23 @@
#include "Frame.h"
#include "JSCallbackData.h"
-#include "JSDOMGlobalObject.h"
#include "JSSQLTransaction.h"
-#include "Page.h"
-#include "ScriptController.h"
+#include "ScriptExecutionContext.h"
#include <runtime/JSLock.h>
#include <wtf/MainThread.h>
#include <wtf/RefCountedLeakCounter.h>
namespace WebCore {
-
+
using namespace JSC;
-
+
#ifndef NDEBUG
static WTF::RefCountedLeakCounter counter("JSCustomSQLTransactionCallback");
#endif
JSCustomSQLTransactionCallback::JSCustomSQLTransactionCallback(JSObject* callback, JSDOMGlobalObject* globalObject)
: m_data(new JSCallbackData(callback, globalObject))
+ , m_isolatedWorld(globalObject->world())
{
#ifndef NDEBUG
counter.increment();
@@ -66,19 +65,24 @@ JSCustomSQLTransactionCallback::~JSCustomSQLTransactionCallback()
#endif
}
-void JSCustomSQLTransactionCallback::handleEvent(SQLTransaction* transaction, bool& raisedException)
+void JSCustomSQLTransactionCallback::handleEvent(ScriptExecutionContext* context, SQLTransaction* transaction, bool& raisedException)
{
ASSERT(m_data);
+ ASSERT(context);
RefPtr<JSCustomSQLTransactionCallback> protect(this);
-
+
JSC::JSLock lock(SilenceAssertionsOnly);
- ExecState* exec = m_data->globalObject()->globalExec();
+ JSDOMGlobalObject* globalObject = toJSDOMGlobalObject(context, m_isolatedWorld.get());
+ if (!globalObject)
+ return;
+
+ ExecState* exec = globalObject->globalExec();
MarkedArgumentBuffer args;
args.append(toJS(exec, deprecatedGlobalObjectForPrototype(exec), transaction));
m_data->invokeCallback(args, &raisedException);
}
-
+
}
#endif // ENABLE(DATABASE)
diff --git a/WebCore/bindings/js/JSCustomSQLTransactionCallback.h b/WebCore/bindings/js/JSCustomSQLTransactionCallback.h
index f142e59..bf2ae68 100644
--- a/WebCore/bindings/js/JSCustomSQLTransactionCallback.h
+++ b/WebCore/bindings/js/JSCustomSQLTransactionCallback.h
@@ -31,12 +31,9 @@
#if ENABLE(DATABASE)
+#include "JSDOMGlobalObject.h"
#include "SQLTransactionCallback.h"
-#include <wtf/PassRefPtr.h>
-
-namespace JSC {
- class JSObject;
-}
+#include <wtf/Forward.h>
namespace WebCore {
@@ -52,13 +49,14 @@ public:
}
virtual ~JSCustomSQLTransactionCallback();
-
- virtual void handleEvent(SQLTransaction*, bool& raisedException);
+
+ virtual void handleEvent(ScriptExecutionContext*, SQLTransaction*, bool& raisedException);
private:
JSCustomSQLTransactionCallback(JSC::JSObject* callback, JSDOMGlobalObject*);
JSCallbackData* m_data;
+ RefPtr<DOMWrapperWorld> m_isolatedWorld;
};
}
diff --git a/WebCore/bindings/js/JSCustomSQLTransactionErrorCallback.cpp b/WebCore/bindings/js/JSCustomSQLTransactionErrorCallback.cpp
index 331e014..09ff340 100644
--- a/WebCore/bindings/js/JSCustomSQLTransactionErrorCallback.cpp
+++ b/WebCore/bindings/js/JSCustomSQLTransactionErrorCallback.cpp
@@ -34,16 +34,17 @@
#include "Frame.h"
#include "JSCallbackData.h"
#include "JSSQLError.h"
-#include "ScriptController.h"
+#include "ScriptExecutionContext.h"
#include <runtime/JSLock.h>
#include <wtf/MainThread.h>
namespace WebCore {
-
+
using namespace JSC;
-
+
JSCustomSQLTransactionErrorCallback::JSCustomSQLTransactionErrorCallback(JSObject* callback, JSDOMGlobalObject* globalObject)
: m_data(new JSCallbackData(callback, globalObject))
+ , m_isolatedWorld(globalObject->world())
{
}
@@ -55,14 +56,19 @@ JSCustomSQLTransactionErrorCallback::~JSCustomSQLTransactionErrorCallback()
#endif
}
-void JSCustomSQLTransactionErrorCallback::handleEvent(SQLError* error)
+void JSCustomSQLTransactionErrorCallback::handleEvent(ScriptExecutionContext* context, SQLError* error)
{
ASSERT(m_data);
+ ASSERT(context);
RefPtr<JSCustomSQLTransactionErrorCallback> protect(this);
JSC::JSLock lock(SilenceAssertionsOnly);
- ExecState* exec = m_data->globalObject()->globalExec();
+ JSDOMGlobalObject* globalObject = toJSDOMGlobalObject(context, m_isolatedWorld.get());
+ if (!globalObject)
+ return;
+
+ ExecState* exec = globalObject->globalExec();
MarkedArgumentBuffer args;
args.append(toJS(exec, deprecatedGlobalObjectForPrototype(exec), error));
m_data->invokeCallback(args);
diff --git a/WebCore/bindings/js/JSCustomSQLTransactionErrorCallback.h b/WebCore/bindings/js/JSCustomSQLTransactionErrorCallback.h
index 54bf33b..bb92393 100644
--- a/WebCore/bindings/js/JSCustomSQLTransactionErrorCallback.h
+++ b/WebCore/bindings/js/JSCustomSQLTransactionErrorCallback.h
@@ -31,9 +31,8 @@
#if ENABLE(DATABASE)
+#include "JSCallbackData.h"
#include "SQLTransactionErrorCallback.h"
-#include "JSDOMGlobalObject.h"
-#include <runtime/Protect.h>
#include <wtf/Forward.h>
namespace WebCore {
@@ -47,15 +46,16 @@ public:
{
return adoptRef(new JSCustomSQLTransactionErrorCallback(callback, globalObject));
}
-
+
virtual ~JSCustomSQLTransactionErrorCallback();
-
- virtual void handleEvent(SQLError*);
+
+ virtual void handleEvent(ScriptExecutionContext*, SQLError*);
private:
JSCustomSQLTransactionErrorCallback(JSC::JSObject* callback, JSDOMGlobalObject* globalObject);
JSCallbackData* m_data;
+ RefPtr<DOMWrapperWorld> m_isolatedWorld;
};
}
diff --git a/WebCore/bindings/js/JSCustomXPathNSResolver.cpp b/WebCore/bindings/js/JSCustomXPathNSResolver.cpp
index 07cfc74..e7d174f 100644
--- a/WebCore/bindings/js/JSCustomXPathNSResolver.cpp
+++ b/WebCore/bindings/js/JSCustomXPathNSResolver.cpp
@@ -98,7 +98,7 @@ String JSCustomXPathNSResolver::lookupNamespaceURI(const String& prefix)
reportCurrentException(exec);
else {
if (!retval.isUndefinedOrNull())
- result = retval.toString(exec);
+ result = ustringToString(retval.toString(exec));
}
Document::updateStyleForAllDocuments();
diff --git a/WebCore/bindings/js/JSDOMApplicationCacheCustom.cpp b/WebCore/bindings/js/JSDOMApplicationCacheCustom.cpp
index 5637087..6198d6e 100644
--- a/WebCore/bindings/js/JSDOMApplicationCacheCustom.cpp
+++ b/WebCore/bindings/js/JSDOMApplicationCacheCustom.cpp
@@ -91,7 +91,7 @@ JSValue JSDOMApplicationCache::addEventListener(ExecState* exec, const ArgList&
if (!listener.isObject())
return jsUndefined();
- impl()->addEventListener(args.at(0).toString(exec), JSEventListener::create(asObject(listener), this, false, currentWorld(exec)), args.at(2).toBoolean(exec));
+ impl()->addEventListener(ustringToAtomicString(args.at(0).toString(exec)), JSEventListener::create(asObject(listener), this, false, currentWorld(exec)), args.at(2).toBoolean(exec));
return jsUndefined();
}
@@ -101,7 +101,7 @@ JSValue JSDOMApplicationCache::removeEventListener(ExecState* exec, const ArgLis
if (!listener.isObject())
return jsUndefined();
- impl()->removeEventListener(args.at(0).toString(exec), JSEventListener::create(asObject(listener), this, false, currentWorld(exec)).get(), args.at(2).toBoolean(exec));
+ impl()->removeEventListener(ustringToAtomicString(args.at(0).toString(exec)), JSEventListener::create(asObject(listener), this, false, currentWorld(exec)).get(), args.at(2).toBoolean(exec));
return jsUndefined();
}
diff --git a/WebCore/bindings/js/JSDOMBinding.cpp b/WebCore/bindings/js/JSDOMBinding.cpp
index abba405..a4c3d6a 100644
--- a/WebCore/bindings/js/JSDOMBinding.cpp
+++ b/WebCore/bindings/js/JSDOMBinding.cpp
@@ -24,7 +24,9 @@
#include "debugger/DebuggerCallFrame.h"
#include "ActiveDOMObject.h"
+#include "CSSHelper.h"
#include "DOMCoreException.h"
+#include "DOMObjectHashTableMap.h"
#include "Document.h"
#include "EventException.h"
#include "ExceptionBase.h"
@@ -32,11 +34,13 @@
#include "Frame.h"
#include "HTMLAudioElement.h"
#include "HTMLCanvasElement.h"
+#include "HTMLFrameElementBase.h"
#include "HTMLImageElement.h"
-#include "HTMLScriptElement.h"
#include "HTMLNames.h"
+#include "HTMLScriptElement.h"
#include "JSDOMCoreException.h"
#include "JSDOMWindowCustom.h"
+#include "JSDebugWrapperSet.h"
#include "JSEventException.h"
#include "JSExceptionBase.h"
#include "JSNode.h"
@@ -48,6 +52,7 @@
#include "ScriptCachedFrameData.h"
#include "ScriptController.h"
#include "Settings.h"
+#include "WebCoreJSClientData.h"
#include "XMLHttpRequestException.h"
#include <runtime/DateInstance.h>
#include <runtime/Error.h>
@@ -66,11 +71,6 @@
#include "XPathException.h"
#endif
-#if ENABLE(WORKERS)
-#include <wtf/ThreadSpecific.h>
-using namespace WTF;
-#endif
-
using namespace JSC;
namespace WebCore {
@@ -80,85 +80,6 @@ using namespace HTMLNames;
typedef Document::JSWrapperCache JSWrapperCache;
typedef Document::JSWrapperCacheMap JSWrapperCacheMap;
-inline JSWrapperCache* Document::getWrapperCache(DOMWrapperWorld* world)
-{
- if (world->isNormal()) {
- if (JSWrapperCache* wrapperCache = m_normalWorldWrapperCache)
- return wrapperCache;
- ASSERT(!m_wrapperCacheMap.contains(world));
- } else if (JSWrapperCache* wrapperCache = m_wrapperCacheMap.get(world))
- return wrapperCache;
- return createWrapperCache(world);
-}
-
-// For debugging, keep a set of wrappers currently cached, and check that
-// all are uncached before they are destroyed. This helps us catch bugs like:
-// - wrappers being deleted without being removed from the cache
-// - wrappers being cached twice
-
-static void willCacheWrapper(DOMObject* wrapper);
-static void didUncacheWrapper(DOMObject* wrapper);
-
-#ifdef NDEBUG
-
-static inline void willCacheWrapper(DOMObject*)
-{
-}
-
-static inline void didUncacheWrapper(DOMObject*)
-{
-}
-
-#else
-
-static HashSet<DOMObject*>& wrapperSet()
-{
-#if ENABLE(WORKERS)
- DEFINE_STATIC_LOCAL(ThreadSpecific<HashSet<DOMObject*> >, staticWrapperSet, ());
- return *staticWrapperSet;
-#else
- DEFINE_STATIC_LOCAL(HashSet<DOMObject*>, staticWrapperSet, ());
- return staticWrapperSet;
-#endif
-}
-
-static void willCacheWrapper(DOMObject* wrapper)
-{
- ASSERT(!wrapperSet().contains(wrapper));
- wrapperSet().add(wrapper);
-}
-
-static void didUncacheWrapper(DOMObject* wrapper)
-{
- if (!wrapper)
- return;
- ASSERT(wrapperSet().contains(wrapper));
- wrapperSet().remove(wrapper);
-}
-
-DOMObject::~DOMObject()
-{
- ASSERT(!wrapperSet().contains(this));
-}
-
-#endif
-
-DOMWrapperWorld::DOMWrapperWorld(JSC::JSGlobalData* globalData, bool isNormal)
- : m_globalData(globalData)
- , m_isNormal(isNormal)
-{
-}
-
-DOMWrapperWorld::~DOMWrapperWorld()
-{
- JSGlobalData::ClientData* clientData = m_globalData->clientData;
- ASSERT(clientData);
- static_cast<WebCoreJSClientData*>(clientData)->forgetWorld(this);
-
- for (HashSet<Document*>::iterator iter = documentsWithWrappers.begin(); iter != documentsWithWrappers.end(); ++iter)
- forgetWorldOfDOMNodesForDocument(*iter, this);
-}
-
class JSGlobalDataWorldIterator {
public:
JSGlobalDataWorldIterator(JSGlobalData* globalData)
@@ -195,37 +116,11 @@ private:
HashSet<DOMWrapperWorld*>::iterator m_end;
};
-DOMWrapperWorld* normalWorld(JSC::JSGlobalData& globalData)
-{
- JSGlobalData::ClientData* clientData = globalData.clientData;
- ASSERT(clientData);
- return static_cast<WebCoreJSClientData*>(clientData)->normalWorld();
-}
-
-DOMWrapperWorld* mainThreadNormalWorld()
-{
- ASSERT(isMainThread());
- static DOMWrapperWorld* cachedNormalWorld = normalWorld(*JSDOMWindow::commonJSGlobalData());
- return cachedNormalWorld;
-}
-
-DOMObjectHashTableMap& DOMObjectHashTableMap::mapFor(JSGlobalData& globalData)
-{
- JSGlobalData::ClientData* clientData = globalData.clientData;
- ASSERT(clientData);
- return static_cast<WebCoreJSClientData*>(clientData)->hashTableMap;
-}
-
const JSC::HashTable* getHashTableForGlobalData(JSGlobalData& globalData, const JSC::HashTable* staticTable)
{
return DOMObjectHashTableMap::mapFor(globalData).get(staticTable);
}
-static inline DOMObjectWrapperMap& DOMObjectWrapperMapFor(JSC::ExecState* exec)
-{
- return currentWorld(exec)->m_wrappers;
-}
-
bool hasCachedDOMObjectWrapperUnchecked(JSGlobalData* globalData, void* objectHandle)
{
for (JSGlobalDataWorldIterator worldIter(globalData); worldIter; ++worldIter) {
@@ -246,13 +141,13 @@ bool hasCachedDOMObjectWrapper(JSGlobalData* globalData, void* objectHandle)
DOMObject* getCachedDOMObjectWrapper(JSC::ExecState* exec, void* objectHandle)
{
- return DOMObjectWrapperMapFor(exec).get(objectHandle);
+ return domObjectWrapperMapFor(exec).get(objectHandle);
}
void cacheDOMObjectWrapper(JSC::ExecState* exec, void* objectHandle, DOMObject* wrapper)
{
- willCacheWrapper(wrapper);
- DOMObjectWrapperMapFor(exec).set(objectHandle, wrapper);
+ JSDebugWrapperSet::willCacheWrapper(wrapper);
+ domObjectWrapperMapFor(exec).set(objectHandle, wrapper);
}
bool hasCachedDOMNodeWrapperUnchecked(Document* document, Node* node)
@@ -268,13 +163,6 @@ bool hasCachedDOMNodeWrapperUnchecked(Document* document, Node* node)
return false;
}
-JSNode* getCachedDOMNodeWrapper(JSC::ExecState* exec, Document* document, Node* node)
-{
- if (document)
- return document->getWrapperCache(currentWorld(exec))->get(node);
- return static_cast<JSNode*>(DOMObjectWrapperMapFor(exec).get(node));
-}
-
void forgetDOMObject(DOMObject* wrapper, void* objectHandle)
{
JSC::JSGlobalData* globalData = Heap::heap(wrapper)->globalData();
@@ -284,7 +172,7 @@ void forgetDOMObject(DOMObject* wrapper, void* objectHandle)
ASSERT(clientData);
DOMObjectWrapperMap& wrappers = static_cast<WebCoreJSClientData*>(clientData)->normalWorld()->m_wrappers;
if (wrappers.uncheckedRemove(objectHandle, wrapper)) {
- didUncacheWrapper(wrapper);
+ JSDebugWrapperSet::didUncacheWrapper(wrapper);
return;
}
@@ -294,11 +182,13 @@ void forgetDOMObject(DOMObject* wrapper, void* objectHandle)
if (worldIter->m_wrappers.uncheckedRemove(objectHandle, wrapper))
break;
}
- didUncacheWrapper(wrapper);
+ JSDebugWrapperSet::didUncacheWrapper(wrapper);
}
void forgetDOMNode(JSNode* wrapper, Node* node, Document* document)
{
+ node->clearWrapper(wrapper);
+
if (!document) {
forgetDOMObject(wrapper, node);
return;
@@ -311,36 +201,20 @@ void forgetDOMNode(JSNode* wrapper, Node* node, Document* document)
if (wrappersIter->second->uncheckedRemove(node, wrapper))
break;
}
- didUncacheWrapper(wrapper);
+ JSDebugWrapperSet::didUncacheWrapper(wrapper);
}
void cacheDOMNodeWrapper(JSC::ExecState* exec, Document* document, Node* node, JSNode* wrapper)
{
- if (!document) {
- willCacheWrapper(wrapper);
- DOMObjectWrapperMapFor(exec).set(node, wrapper);
- return;
- }
- willCacheWrapper(wrapper);
- document->getWrapperCache(currentWorld(exec))->set(node, wrapper);
-}
+ JSDebugWrapperSet::willCacheWrapper(wrapper);
-void forgetAllDOMNodesForDocument(Document* document)
-{
- ASSERT(document);
- JSWrapperCacheMap& wrapperCacheMap = document->wrapperCacheMap();
- JSWrapperCacheMap::const_iterator wrappersMapEnd = wrapperCacheMap.end();
- for (JSWrapperCacheMap::const_iterator wrappersMapIter = wrapperCacheMap.begin(); wrappersMapIter != wrappersMapEnd; ++wrappersMapIter) {
- delete wrappersMapIter->second;
- wrappersMapIter->first->forgetDocument(document);
- }
-}
+ if (!document)
+ domObjectWrapperMapFor(exec).set(node, wrapper);
+ else
+ document->getWrapperCache(currentWorld(exec))->set(node, wrapper);
-void forgetWorldOfDOMNodesForDocument(Document* document, DOMWrapperWorld* world)
-{
- JSWrapperCache* wrappers = document->wrapperCacheMap().take(world);
- ASSERT(wrappers); // 'world' should only know about 'document' if 'document' knows about 'world'!
- delete wrappers;
+ if (currentWorld(exec)->isNormal())
+ node->setWrapper(wrapper);
}
static inline bool isObservableThroughDOM(JSNode* jsNode, DOMWrapperWorld* world)
@@ -464,7 +338,7 @@ static inline void takeWrappers(Node* node, Document* document, WrapperSet& wrap
JSWrapperCacheMap& wrapperCacheMap = document->wrapperCacheMap();
for (JSWrapperCacheMap::iterator iter = wrapperCacheMap.begin(); iter != wrapperCacheMap.end(); ++iter) {
if (JSNode* wrapper = iter->second->take(node)) {
- didUncacheWrapper(wrapper);
+ JSDebugWrapperSet::didUncacheWrapper(wrapper);
wrapperSet.append(WrapperAndWorld(wrapper, iter->first));
}
}
@@ -472,7 +346,7 @@ static inline void takeWrappers(Node* node, Document* document, WrapperSet& wrap
for (JSGlobalDataWorldIterator worldIter(JSDOMWindow::commonJSGlobalData()); worldIter; ++worldIter) {
DOMWrapperWorld* world = *worldIter;
if (JSNode* wrapper = static_cast<JSNode*>(world->m_wrappers.take(node))) {
- didUncacheWrapper(wrapper);
+ JSDebugWrapperSet::didUncacheWrapper(wrapper);
wrapperSet.append(WrapperAndWorld(wrapper, world));
}
}
@@ -488,7 +362,7 @@ void updateDOMNodeDocument(Node* node, Document* oldDocument, Document* newDocum
for (unsigned i = 0; i < wrapperSet.size(); ++i) {
JSNode* wrapper = wrapperSet[i].first;
- willCacheWrapper(wrapper);
+ JSDebugWrapperSet::willCacheWrapper(wrapper);
if (newDocument)
newDocument->getWrapperCache(wrapperSet[i].second)->set(node, wrapper);
else
@@ -556,7 +430,7 @@ JSValue jsStringSlowCase(ExecState* exec, JSStringCache& stringCache, StringImpl
if (JSString* wrapper = stringCache.uncheckedGet(stringImpl))
stringCache.uncheckedRemove(stringImpl, wrapper);
- JSString* wrapper = jsStringWithFinalizer(exec, stringImpl->ustring(), stringWrapperDestroyed, stringImpl);
+ JSString* wrapper = jsStringWithFinalizer(exec, UString(stringImpl), stringWrapperDestroyed, stringImpl);
stringCache.set(stringImpl, wrapper);
// ref explicitly instead of using a RefPtr-keyed hashtable because the wrapper can
// outlive the cache, so the stringImpl has to match the wrapper's lifetime.
@@ -618,18 +492,27 @@ JSValue jsStringOrFalse(ExecState* exec, const KURL& url)
return jsString(exec, url.string());
}
-UString valueToStringWithNullCheck(ExecState* exec, JSValue value)
+AtomicStringImpl* findAtomicString(const Identifier& identifier)
+{
+ if (identifier.isNull())
+ return 0;
+ UStringImpl* impl = identifier.ustring().rep();
+ ASSERT(impl->existingHash());
+ return AtomicString::find(impl->characters(), impl->length(), impl->existingHash());
+}
+
+String valueToStringWithNullCheck(ExecState* exec, JSValue value)
{
if (value.isNull())
- return UString();
- return value.toString(exec);
+ return String();
+ return ustringToString(value.toString(exec));
}
-UString valueToStringWithUndefinedOrNullCheck(ExecState* exec, JSValue value)
+String valueToStringWithUndefinedOrNullCheck(ExecState* exec, JSValue value)
{
if (value.isUndefinedOrNull())
- return UString();
- return value.toString(exec);
+ return String();
+ return ustringToString(value.toString(exec));
}
JSValue jsDateOrNull(ExecState* exec, double value)
@@ -650,6 +533,9 @@ double valueToDate(ExecState* exec, JSValue value)
void reportException(ExecState* exec, JSValue exception)
{
+ if (exception.isObject() && asObject(exception)->exceptionType() == Terminated)
+ return;
+
UString errorMessage = exception.toString(exec);
JSObject* exceptionObject = exception.toObject(exec);
int lineNumber = exceptionObject->get(exec, Identifier(exec, "line")).toInt32(exec);
@@ -657,7 +543,7 @@ void reportException(ExecState* exec, JSValue exception)
exec->clearException();
if (ExceptionBase* exceptionBase = toExceptionBase(exception))
- errorMessage = exceptionBase->message() + ": " + exceptionBase->description();
+ errorMessage = stringToUString(exceptionBase->message() + ": " + exceptionBase->description());
ScriptExecutionContext* scriptExecutionContext = static_cast<JSDOMGlobalObject*>(exec->lexicalGlobalObject())->scriptExecutionContext();
ASSERT(scriptExecutionContext);
@@ -667,7 +553,7 @@ void reportException(ExecState* exec, JSValue exception)
if (!scriptExecutionContext)
return;
- scriptExecutionContext->reportException(errorMessage, lineNumber, exceptionSourceURL);
+ scriptExecutionContext->reportException(ustringToString(errorMessage), lineNumber, ustringToString(exceptionSourceURL));
}
void reportCurrentException(ExecState* exec)
@@ -747,6 +633,16 @@ bool shouldAllowNavigation(ExecState* exec, Frame* frame)
return lexicalFrame && lexicalFrame->loader()->shouldAllowNavigation(frame);
}
+bool allowSettingSrcToJavascriptURL(ExecState* exec, Element* element, const String& name, const String& value)
+{
+ if ((element->hasTagName(iframeTag) || element->hasTagName(frameTag)) && equalIgnoringCase(name, "src") && protocolIsJavaScript(deprecatedParseURL(value))) {
+ Document* contentDocument = static_cast<HTMLFrameElementBase*>(element)->contentDocument();
+ if (contentDocument && !checkNodeSecurity(exec, contentDocument))
+ return false;
+ }
+ return true;
+}
+
void printErrorMessageForFrame(Frame* frame, const String& message)
{
if (!frame)
@@ -788,7 +684,7 @@ KURL completeURL(ExecState* exec, const String& relativeURL)
return frame->loader()->completeURL(relativeURL);
}
-JSValue objectToStringFunctionGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot&)
+JSValue objectToStringFunctionGetter(ExecState* exec, JSValue, const Identifier& propertyName)
{
return new (exec) NativeFunctionWrapper(exec, exec->lexicalGlobalObject()->prototypeFunctionStructure(), 0, propertyName, objectProtoFuncToString);
}
@@ -852,10 +748,4 @@ JSC::JSObject* toJSSequence(ExecState* exec, JSValue value, unsigned& length)
return object;
}
-bool DOMObject::defineOwnProperty(ExecState* exec, const Identifier&, PropertyDescriptor&, bool)
-{
- throwError(exec, TypeError, "defineProperty is not supported on DOM Objects");
- return false;
-}
-
} // namespace WebCore
diff --git a/WebCore/bindings/js/JSDOMBinding.h b/WebCore/bindings/js/JSDOMBinding.h
index 807bf82..209be3f 100644
--- a/WebCore/bindings/js/JSDOMBinding.h
+++ b/WebCore/bindings/js/JSDOMBinding.h
@@ -23,6 +23,8 @@
#define JSDOMBinding_h
#include "JSDOMGlobalObject.h"
+#include "JSDOMWrapper.h"
+#include "DOMWrapperWorld.h"
#include "JSSVGContextCache.h"
#include "Document.h"
#include <runtime/Completion.h>
@@ -52,21 +54,6 @@ namespace WebCore {
class SVGElement;
#endif
- // Base class for all objects in this binding except Window.
- class DOMObject : public JSC::JSObject {
- protected:
- explicit DOMObject(NonNullPassRefPtr<JSC::Structure> structure)
- : JSObject(structure)
- {
- }
-
- virtual bool defineOwnProperty(JSC::ExecState*, const JSC::Identifier&, JSC::PropertyDescriptor&, bool);
-
-#ifndef NDEBUG
- virtual ~DOMObject();
-#endif
- };
-
// FIXME: This class should collapse into DOMObject once all DOMObjects are
// updated to store a globalObject pointer.
class DOMObjectWithGlobalPointer : public DOMObject {
@@ -133,102 +120,6 @@ namespace WebCore {
}
};
- typedef JSC::WeakGCMap<void*, DOMObject*> DOMObjectWrapperMap;
- typedef JSC::WeakGCMap<StringImpl*, JSC::JSString*> JSStringCache;
-
- class DOMWrapperWorld : public RefCounted<DOMWrapperWorld> {
- public:
- static PassRefPtr<DOMWrapperWorld> create(JSC::JSGlobalData* globalData, bool isNormal)
- {
- return adoptRef(new DOMWrapperWorld(globalData, isNormal));
- }
- ~DOMWrapperWorld();
-
- void rememberDocument(Document* document) { documentsWithWrappers.add(document); }
- void forgetDocument(Document* document) { documentsWithWrappers.remove(document); }
-
- // FIXME: can we make this private?
- DOMObjectWrapperMap m_wrappers;
- JSStringCache m_stringCache;
-
- bool isNormal() const { return m_isNormal; }
-
- protected:
- DOMWrapperWorld(JSC::JSGlobalData*, bool isNormal);
-
- private:
- JSC::JSGlobalData* m_globalData;
- HashSet<Document*> documentsWithWrappers;
- bool m_isNormal;
- };
-
- // Map from static HashTable instances to per-GlobalData ones.
- class DOMObjectHashTableMap {
- public:
- static DOMObjectHashTableMap& mapFor(JSC::JSGlobalData&);
-
- ~DOMObjectHashTableMap()
- {
- HashMap<const JSC::HashTable*, JSC::HashTable>::iterator mapEnd = m_map.end();
- for (HashMap<const JSC::HashTable*, JSC::HashTable>::iterator iter = m_map.begin(); iter != m_map.end(); ++iter)
- iter->second.deleteTable();
- }
-
- const JSC::HashTable* get(const JSC::HashTable* staticTable)
- {
- HashMap<const JSC::HashTable*, JSC::HashTable>::iterator iter = m_map.find(staticTable);
- if (iter != m_map.end())
- return &iter->second;
- return &m_map.set(staticTable, JSC::HashTable(*staticTable)).first->second;
- }
-
- private:
- HashMap<const JSC::HashTable*, JSC::HashTable> m_map;
- };
-
- class WebCoreJSClientData : public JSC::JSGlobalData::ClientData, public Noncopyable {
- friend class JSGlobalDataWorldIterator;
-
- public:
- WebCoreJSClientData(JSC::JSGlobalData* globalData)
- : m_normalWorld(DOMWrapperWorld::create(globalData, true))
- {
- m_worldSet.add(m_normalWorld.get());
- }
-
- virtual ~WebCoreJSClientData()
- {
- ASSERT(m_worldSet.contains(m_normalWorld.get()));
- ASSERT(m_worldSet.size() == 1);
- ASSERT(m_normalWorld->hasOneRef());
- m_normalWorld.clear();
- ASSERT(m_worldSet.isEmpty());
- }
-
- DOMWrapperWorld* normalWorld() { return m_normalWorld.get(); }
-
- void getAllWorlds(Vector<DOMWrapperWorld*>& worlds)
- {
- copyToVector(m_worldSet, worlds);
- }
-
- void rememberWorld(DOMWrapperWorld* world)
- {
- ASSERT(!m_worldSet.contains(world));
- m_worldSet.add(world);
- }
- void forgetWorld(DOMWrapperWorld* world)
- {
- ASSERT(m_worldSet.contains(world));
- m_worldSet.remove(world);
- }
-
- DOMObjectHashTableMap hashTableMap;
- private:
- HashSet<DOMWrapperWorld*> m_worldSet;
- RefPtr<DOMWrapperWorld> m_normalWorld;
- };
-
DOMObject* getCachedDOMObjectWrapper(JSC::ExecState*, void* objectHandle);
bool hasCachedDOMObjectWrapper(JSC::JSGlobalData*, void* objectHandle);
void cacheDOMObjectWrapper(JSC::ExecState*, void* objectHandle, DOMObject* wrapper);
@@ -237,8 +128,6 @@ namespace WebCore {
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*);
@@ -253,12 +142,6 @@ namespace WebCore {
JSC::Structure* getCachedDOMStructure(JSC::ExecState*, const JSC::ClassInfo*);
JSC::Structure* cacheDOMStructure(JSC::ExecState*, NonNullPassRefPtr<JSC::Structure>, const JSC::ClassInfo*);
- DOMWrapperWorld* currentWorld(JSC::ExecState*);
- DOMWrapperWorld* normalWorld(JSC::JSGlobalData&);
- DOMWrapperWorld* mainThreadNormalWorld();
- inline DOMWrapperWorld* debuggerWorld() { return mainThreadNormalWorld(); }
- inline DOMWrapperWorld* pluginWorld() { return mainThreadNormalWorld(); }
-
JSC::JSObject* getCachedDOMConstructor(JSC::ExecState*, const JSC::ClassInfo*);
void cacheDOMConstructor(JSC::ExecState*, const JSC::ClassInfo*, JSC::JSObject* constructor);
@@ -375,8 +258,16 @@ namespace WebCore {
// object, to let the engine know that collecting the JSString wrapper is unlikely to save memory.
JSC::JSValue jsOwnedStringOrNull(JSC::ExecState*, const JSC::UString&);
- JSC::UString valueToStringWithNullCheck(JSC::ExecState*, JSC::JSValue); // null if the value is null
- JSC::UString valueToStringWithUndefinedOrNullCheck(JSC::ExecState*, JSC::JSValue); // null if the value is null or undefined
+ String identifierToString(const JSC::Identifier&);
+ String ustringToString(const JSC::UString&);
+ JSC::UString stringToUString(const String&);
+
+ AtomicString identifierToAtomicString(const JSC::Identifier&);
+ AtomicString ustringToAtomicString(const JSC::UString&);
+ AtomicStringImpl* findAtomicString(const JSC::Identifier&);
+
+ String valueToStringWithNullCheck(JSC::ExecState*, JSC::JSValue); // null if the value is null
+ String valueToStringWithUndefinedOrNullCheck(JSC::ExecState*, JSC::JSValue); // null if the value is null or undefined
// Returns a Date instance for the specified value, or null if the value is NaN or infinity.
JSC::JSValue jsDateOrNull(JSC::ExecState*, double);
@@ -417,18 +308,15 @@ namespace WebCore {
bool allowsAccessFromFrame(JSC::ExecState*, Frame*);
bool allowsAccessFromFrame(JSC::ExecState*, Frame*, String& message);
bool shouldAllowNavigation(JSC::ExecState*, Frame*);
+ bool allowSettingSrcToJavascriptURL(JSC::ExecState*, Element*, const String&, const String&);
+
void printErrorMessageForFrame(Frame*, const String& message);
- JSC::JSValue objectToStringFunctionGetter(JSC::ExecState*, const JSC::Identifier& propertyName, const JSC::PropertySlot&);
+ JSC::JSValue objectToStringFunctionGetter(JSC::ExecState*, JSC::JSValue, const JSC::Identifier& propertyName);
Frame* toLexicalFrame(JSC::ExecState*);
Frame* toDynamicFrame(JSC::ExecState*);
bool processingUserGesture(JSC::ExecState*);
KURL completeURL(JSC::ExecState*, const String& relativeURL);
-
- inline DOMWrapperWorld* currentWorld(JSC::ExecState* exec)
- {
- return static_cast<JSDOMGlobalObject*>(exec->lexicalGlobalObject())->world();
- }
inline JSC::JSValue jsString(JSC::ExecState* exec, const String& s)
{
@@ -437,7 +325,7 @@ namespace WebCore {
return jsEmptyString(exec);
if (stringImpl->length() == 1 && stringImpl->characters()[0] <= 0xFF)
- return jsString(exec, stringImpl->ustring());
+ return jsString(exec, stringToUString(s));
JSStringCache& stringCache = currentWorld(exec)->m_stringCache;
if (JSC::JSString* wrapper = stringCache.get(stringImpl))
@@ -446,6 +334,36 @@ namespace WebCore {
return jsStringSlowCase(exec, stringCache, stringImpl);
}
+ inline DOMObjectWrapperMap& domObjectWrapperMapFor(JSC::ExecState* exec)
+ {
+ return currentWorld(exec)->m_wrappers;
+ }
+
+ inline String ustringToString(const JSC::UString& u)
+ {
+ return u.rep();
+ }
+
+ inline JSC::UString stringToUString(const String& s)
+ {
+ return JSC::UString(s.impl());
+ }
+
+ inline String identifierToString(const JSC::Identifier& i)
+ {
+ return i.ustring().rep();
+ }
+
+ inline AtomicString ustringToAtomicString(const JSC::UString& u)
+ {
+ return AtomicString(u.rep());
+ }
+
+ inline AtomicString identifierToAtomicString(const JSC::Identifier& identifier)
+ {
+ return AtomicString(identifier.ustring().rep());
+ }
+
} // namespace WebCore
#endif // JSDOMBinding_h
diff --git a/WebCore/bindings/v8/custom/V8ScreenCustom.cpp b/WebCore/bindings/js/JSDOMFormDataCustom.cpp
index 98d9dd7..830db6b 100644
--- a/WebCore/bindings/v8/custom/V8ScreenCustom.cpp
+++ b/WebCore/bindings/js/JSDOMFormDataCustom.cpp
@@ -29,24 +29,28 @@
*/
#include "config.h"
-#include "V8Screen.h"
+#include "JSDOMFormData.h"
-#include "V8DOMWindow.h"
-#include "V8DOMWrapper.h"
+#include "DOMFormData.h"
+#include "JSBlob.h"
+#include <runtime/Error.h>
+
+using namespace JSC;
namespace WebCore {
-v8::Handle<v8::Value> toV8(Screen* impl)
+JSValue JSDOMFormData::append(ExecState* exec, const ArgList& args)
{
- if (!impl)
- return v8::Null();
- v8::Handle<v8::Object> wrapper = getDOMObjectMap().get(impl);
- if (wrapper.IsEmpty()) {
- wrapper = V8Screen::wrap(impl);
- if (!wrapper.IsEmpty())
- V8DOMWrapper::setHiddenWindowReference(impl->frame(), V8DOMWindow::screenIndex, wrapper);
+ if (args.size() >= 2) {
+ String name = ustringToString(args.at(0).toString(exec));
+ JSValue value = args.at(1);
+ if (value.inherits(&JSBlob::s_info))
+ impl()->append(name, toBlob(value));
+ else
+ impl()->append(name, ustringToString(value.toString(exec)));
}
- return wrapper;
+
+ return jsUndefined();
}
} // namespace WebCore
diff --git a/WebCore/bindings/js/JSDOMWindowBase.cpp b/WebCore/bindings/js/JSDOMWindowBase.cpp
index 4338cdd..82ac1ce 100644
--- a/WebCore/bindings/js/JSDOMWindowBase.cpp
+++ b/WebCore/bindings/js/JSDOMWindowBase.cpp
@@ -23,7 +23,6 @@
#include "config.h"
#include "JSDOMWindowBase.h"
-#include "CString.h"
#include "Chrome.h"
#include "Console.h"
#include "DOMWindow.h"
@@ -36,6 +35,9 @@
#include "ScriptController.h"
#include "SecurityOrigin.h"
#include "Settings.h"
+#include "WebCoreJSClientData.h"
+#include <wtf/Threading.h>
+#include <wtf/text/CString.h>
using namespace JSC;
@@ -155,12 +157,12 @@ JSGlobalData* JSDOMWindowBase::commonJSGlobalData()
static JSGlobalData* globalData = 0;
if (!globalData) {
- globalData = JSGlobalData::createLeaked().releaseRef();
+ globalData = JSGlobalData::createLeaked(ThreadStackTypeLarge).releaseRef();
globalData->timeoutChecker.setTimeoutInterval(10000); // 10 seconds
#ifndef NDEBUG
- globalData->mainThreadOnly = true;
+ globalData->exclusiveThread = currentThread();
#endif
- globalData->clientData = new WebCoreJSClientData(globalData);
+ initNormalWorldClientData(globalData);
}
return globalData;
diff --git a/WebCore/bindings/js/JSDOMWindowCustom.cpp b/WebCore/bindings/js/JSDOMWindowCustom.cpp
index bbd4a51..f5f2ae2 100644
--- a/WebCore/bindings/js/JSDOMWindowCustom.cpp
+++ b/WebCore/bindings/js/JSDOMWindowCustom.cpp
@@ -21,8 +21,8 @@
#include "JSDOMWindowCustom.h"
#include "AtomicString.h"
-#include "Base64.h"
#include "Chrome.h"
+#include "Database.h"
#include "DOMWindow.h"
#include "Document.h"
#include "ExceptionCode.h"
@@ -36,6 +36,8 @@
#include "HTMLDocument.h"
#include "History.h"
#include "JSAudioConstructor.h"
+#include "JSDatabase.h"
+#include "JSDatabaseCallback.h"
#include "JSDOMWindowShell.h"
#include "JSEvent.h"
#include "JSEventListener.h"
@@ -124,31 +126,31 @@ void JSDOMWindow::markChildren(MarkStack& markStack)
}
template<NativeFunction nativeFunction, int length>
-JSValue nonCachingStaticFunctionGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot&)
+JSValue nonCachingStaticFunctionGetter(ExecState* exec, JSValue, const Identifier& propertyName)
{
return new (exec) NativeFunctionWrapper(exec, exec->lexicalGlobalObject()->prototypeFunctionStructure(), length, propertyName, nativeFunction);
}
-static JSValue childFrameGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot)
+static JSValue childFrameGetter(ExecState* exec, JSValue slotBase, const Identifier& propertyName)
{
- return toJS(exec, static_cast<JSDOMWindow*>(asObject(slot.slotBase()))->impl()->frame()->tree()->child(AtomicString(propertyName))->domWindow());
+ return toJS(exec, static_cast<JSDOMWindow*>(asObject(slotBase))->impl()->frame()->tree()->child(identifierToAtomicString(propertyName))->domWindow());
}
-static JSValue indexGetter(ExecState* exec, const Identifier&, const PropertySlot& slot)
+static JSValue indexGetter(ExecState* exec, JSValue slotBase, unsigned index)
{
- return toJS(exec, static_cast<JSDOMWindow*>(asObject(slot.slotBase()))->impl()->frame()->tree()->child(slot.index())->domWindow());
+ return toJS(exec, static_cast<JSDOMWindow*>(asObject(slotBase))->impl()->frame()->tree()->child(index)->domWindow());
}
-static JSValue namedItemGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot)
+static JSValue namedItemGetter(ExecState* exec, JSValue slotBase, const Identifier& propertyName)
{
- JSDOMWindowBase* thisObj = static_cast<JSDOMWindow*>(asObject(slot.slotBase()));
+ JSDOMWindowBase* thisObj = static_cast<JSDOMWindow*>(asObject(slotBase));
Document* document = thisObj->impl()->frame()->document();
ASSERT(thisObj->allowsAccessFrom(exec));
ASSERT(document);
ASSERT(document->isHTMLDocument());
- RefPtr<HTMLCollection> collection = document->windowNamedItems(propertyName);
+ RefPtr<HTMLCollection> collection = document->windowNamedItems(identifierToString(propertyName));
if (collection->length() == 1)
return toJS(exec, collection->firstItem());
return toJS(exec, collection.get());
@@ -249,7 +251,7 @@ bool JSDOMWindow::getOwnPropertySlot(ExecState* exec, const Identifier& property
// naming frames things that conflict with window properties that
// are in Moz but not IE. Since we have some of these, we have to do
// it the Moz way.
- if (impl()->frame()->tree()->child(propertyName)) {
+ if (impl()->frame()->tree()->child(identifierToAtomicString(propertyName))) {
slot.setCustom(this, childFrameGetter);
return true;
}
@@ -287,7 +289,7 @@ bool JSDOMWindow::getOwnPropertySlot(ExecState* exec, const Identifier& property
// Allow shortcuts like 'Image1' instead of document.images.Image1
Document* document = impl()->frame()->document();
if (document->isHTMLDocument()) {
- AtomicStringImpl* atomicPropertyName = AtomicString::find(propertyName);
+ AtomicStringImpl* atomicPropertyName = findAtomicString(propertyName);
if (atomicPropertyName && (static_cast<HTMLDocument*>(document)->hasNamedItem(atomicPropertyName) || document->hasElementWithId(atomicPropertyName))) {
slot.setCustom(this, namedItemGetter);
return true;
@@ -338,7 +340,7 @@ bool JSDOMWindow::getOwnPropertyDescriptor(ExecState* exec, const Identifier& pr
// naming frames things that conflict with window properties that
// are in Moz but not IE. Since we have some of these, we have to do
// it the Moz way.
- if (impl()->frame()->tree()->child(propertyName)) {
+ if (impl()->frame()->tree()->child(identifierToAtomicString(propertyName))) {
PropertySlot slot;
slot.setCustom(this, childFrameGetter);
descriptor.setDescriptor(slot.getValue(exec, propertyName), ReadOnly | DontDelete | DontEnum);
@@ -357,7 +359,7 @@ bool JSDOMWindow::getOwnPropertyDescriptor(ExecState* exec, const Identifier& pr
// Allow shortcuts like 'Image1' instead of document.images.Image1
Document* document = impl()->frame()->document();
if (document->isHTMLDocument()) {
- AtomicStringImpl* atomicPropertyName = AtomicString::find(propertyName);
+ AtomicStringImpl* atomicPropertyName = findAtomicString(propertyName);
if (atomicPropertyName && (static_cast<HTMLDocument*>(document)->hasNamedItem(atomicPropertyName) || document->hasElementWithId(atomicPropertyName))) {
PropertySlot slot;
slot.setCustom(this, namedItemGetter);
@@ -504,7 +506,7 @@ void JSDOMWindow::setLocation(ExecState* exec, JSValue value)
Frame* frame = impl()->frame();
ASSERT(frame);
- KURL url = completeURL(exec, value.toString(exec));
+ KURL url = completeURL(exec, ustringToString(value.toString(exec)));
if (url.isNull())
return;
@@ -666,12 +668,6 @@ static Frame* createWindow(ExecState* exec, Frame* lexicalFrame, Frame* dynamicF
ASSERT(lexicalFrame);
ASSERT(dynamicFrame);
- if (Document* lexicalDocument = lexicalFrame->document()) {
- // Sandboxed iframes cannot open new auxiliary browsing contexts.
- if (lexicalDocument->securityOrigin()->isSandboxed(SandboxNavigation))
- return 0;
- }
-
ResourceRequest request;
// For whatever reason, Firefox uses the dynamicGlobalObject to determine
@@ -729,7 +725,7 @@ static bool domWindowAllowPopUp(Frame* activeFrame, ExecState* exec)
JSValue JSDOMWindow::open(ExecState* exec, const ArgList& args)
{
String urlString = valueToStringWithUndefinedOrNullCheck(exec, args.at(0));
- AtomicString frameName = args.at(1).isUndefinedOrNull() ? "_blank" : AtomicString(args.at(1).toString(exec));
+ AtomicString frameName = args.at(1).isUndefinedOrNull() ? "_blank" : ustringToAtomicString(args.at(1).toString(exec));
WindowFeatures windowFeatures(valueToStringWithUndefinedOrNullCheck(exec, args.at(2)));
Frame* frame = impl()->frame();
@@ -938,57 +934,6 @@ JSValue JSDOMWindow::setInterval(ExecState* exec, const ArgList& args)
return jsNumber(exec, result);
}
-JSValue JSDOMWindow::atob(ExecState* exec, const ArgList& args)
-{
- if (args.size() < 1)
- return throwError(exec, SyntaxError, "Not enough arguments");
-
- JSValue v = args.at(0);
- if (v.isNull())
- return jsEmptyString(exec);
-
- UString s = v.toString(exec);
- if (!s.is8Bit()) {
- setDOMException(exec, INVALID_CHARACTER_ERR);
- return jsUndefined();
- }
-
- Vector<char> in(s.size());
- for (unsigned i = 0; i < s.size(); ++i)
- in[i] = static_cast<char>(s.data()[i]);
- Vector<char> out;
-
- if (!base64Decode(in, out))
- return throwError(exec, GeneralError, "Cannot decode base64");
-
- return jsString(exec, String(out.data(), out.size()));
-}
-
-JSValue JSDOMWindow::btoa(ExecState* exec, const ArgList& args)
-{
- if (args.size() < 1)
- return throwError(exec, SyntaxError, "Not enough arguments");
-
- JSValue v = args.at(0);
- if (v.isNull())
- return jsEmptyString(exec);
-
- UString s = v.toString(exec);
- if (!s.is8Bit()) {
- setDOMException(exec, INVALID_CHARACTER_ERR);
- return jsUndefined();
- }
-
- Vector<char> in(s.size());
- for (unsigned i = 0; i < s.size(); ++i)
- in[i] = static_cast<char>(s.data()[i]);
- Vector<char> out;
-
- base64Encode(in, out);
-
- return jsString(exec, String(out.data(), out.size()));
-}
-
JSValue JSDOMWindow::addEventListener(ExecState* exec, const ArgList& args)
{
Frame* frame = impl()->frame();
@@ -999,7 +944,7 @@ JSValue JSDOMWindow::addEventListener(ExecState* exec, const ArgList& args)
if (!listener.isObject())
return jsUndefined();
- impl()->addEventListener(args.at(0).toString(exec), JSEventListener::create(asObject(listener), this, false, currentWorld(exec)), args.at(2).toBoolean(exec));
+ impl()->addEventListener(ustringToAtomicString(args.at(0).toString(exec)), JSEventListener::create(asObject(listener), this, false, currentWorld(exec)), args.at(2).toBoolean(exec));
return jsUndefined();
}
@@ -1013,10 +958,31 @@ JSValue JSDOMWindow::removeEventListener(ExecState* exec, const ArgList& args)
if (!listener.isObject())
return jsUndefined();
- impl()->removeEventListener(args.at(0).toString(exec), JSEventListener::create(asObject(listener), this, false, currentWorld(exec)).get(), args.at(2).toBoolean(exec));
+ impl()->removeEventListener(ustringToAtomicString(args.at(0).toString(exec)), JSEventListener::create(asObject(listener), this, false, currentWorld(exec)).get(), args.at(2).toBoolean(exec));
return jsUndefined();
}
+#if ENABLE(DATABASE)
+JSValue JSDOMWindow::openDatabase(ExecState* exec, const ArgList& args)
+{
+ if (!allowsAccessFrom(exec) || (args.size() < 4))
+ return jsUndefined();
+ ExceptionCode ec = 0;
+ const UString& name = args.at(0).toString(exec);
+ const UString& version = args.at(1).toString(exec);
+ const UString& displayName = args.at(2).toString(exec);
+ unsigned long estimatedSize = args.at(3).toInt32(exec);
+ RefPtr<DatabaseCallback> creationCallback;
+ if ((args.size() >= 5) && args.at(4).isObject())
+ creationCallback = JSDatabaseCallback::create(asObject(args.at(4)), globalObject());
+
+ JSValue result = toJS(exec, globalObject(), WTF::getPtr(impl()->openDatabase(ustringToString(name), ustringToString(version), ustringToString(displayName), estimatedSize, creationCallback.release(), ec)));
+
+ setDOMException(exec, ec);
+ return result;
+}
+#endif
+
DOMWindow* toDOMWindow(JSValue value)
{
if (!value.isObject())
diff --git a/WebCore/bindings/js/JSDOMWrapper.cpp b/WebCore/bindings/js/JSDOMWrapper.cpp
new file mode 100644
index 0000000..3fcdcc1
--- /dev/null
+++ b/WebCore/bindings/js/JSDOMWrapper.cpp
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "JSDOMWrapper.h"
+
+#include "JSDebugWrapperSet.h"
+#include <runtime/Error.h>
+
+using namespace JSC;
+
+namespace WebCore {
+
+#ifndef NDEBUG
+
+DOMObject::~DOMObject()
+{
+ ASSERT(!JSDebugWrapperSet::shared().contains(this));
+}
+
+#endif
+
+bool DOMObject::defineOwnProperty(ExecState* exec, const Identifier&, PropertyDescriptor&, bool)
+{
+ throwError(exec, TypeError, "defineProperty is not supported on DOM Objects");
+ return false;
+}
+
+} // namespace WebCore
diff --git a/WebCore/bindings/js/JSDOMWrapper.h b/WebCore/bindings/js/JSDOMWrapper.h
new file mode 100644
index 0000000..00594cf
--- /dev/null
+++ b/WebCore/bindings/js/JSDOMWrapper.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
+ * Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009, 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2007 Samuel Weinig <sam@webkit.org>
+ * Copyright (C) 2009 Google, Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef JSDOMWrapper_h
+#define JSDOMWrapper_h
+
+#include <runtime/JSObject.h>
+
+namespace WebCore {
+
+// Base class for all objects in this binding except Window.
+class DOMObject : public JSC::JSObject {
+protected:
+ explicit DOMObject(NonNullPassRefPtr<JSC::Structure> structure)
+ : JSObject(structure)
+ {
+ }
+
+ virtual bool defineOwnProperty(JSC::ExecState*, const JSC::Identifier&, JSC::PropertyDescriptor&, bool);
+
+#ifndef NDEBUG
+ virtual ~DOMObject();
+#endif
+};
+
+} // namespace WebCore
+
+#endif // JSDOMWrapper_h
diff --git a/WebCore/bindings/js/JSDataGridColumnListCustom.cpp b/WebCore/bindings/js/JSDataGridColumnListCustom.cpp
index 91b3d15..9a6982a 100644
--- a/WebCore/bindings/js/JSDataGridColumnListCustom.cpp
+++ b/WebCore/bindings/js/JSDataGridColumnListCustom.cpp
@@ -43,9 +43,9 @@ bool JSDataGridColumnList::canGetItemsForName(ExecState*, DataGridColumnList* im
return impl->itemWithName(propertyName);
}
-JSValue JSDataGridColumnList::nameGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot)
+JSValue JSDataGridColumnList::nameGetter(ExecState* exec, JSValue slotBase, const Identifier& propertyName)
{
- JSDataGridColumnList* thisObj = static_cast<JSDataGridColumnList*>(asObject(slot.slotBase()));
+ JSDataGridColumnList* thisObj = static_cast<JSDataGridColumnList*>(asObject(slotBase));
return toJS(exec, thisObj->globalObject(), thisObj->impl()->itemWithName(propertyName));
}
diff --git a/WebCore/bindings/js/JSDatabaseCallback.cpp b/WebCore/bindings/js/JSDatabaseCallback.cpp
new file mode 100644
index 0000000..6887c86
--- /dev/null
+++ b/WebCore/bindings/js/JSDatabaseCallback.cpp
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "JSDatabaseCallback.h"
+
+#if ENABLE(DATABASE)
+
+#include "Frame.h"
+#include "JSDatabase.h"
+#include "ScriptExecutionContext.h"
+#include <runtime/JSLock.h>
+#include <wtf/MainThread.h>
+
+namespace WebCore {
+
+using namespace JSC;
+
+JSDatabaseCallback::JSDatabaseCallback(JSObject* callback, JSDOMGlobalObject* globalObject)
+ : m_data(new JSCallbackData(callback, globalObject))
+ , m_isolatedWorld(globalObject->world())
+{
+}
+
+JSDatabaseCallback::~JSDatabaseCallback()
+{
+ callOnMainThread(JSCallbackData::deleteData, m_data);
+#ifndef NDEBUG
+ m_data = 0;
+#endif
+}
+
+void JSDatabaseCallback::handleEvent(ScriptExecutionContext* context, Database* database)
+{
+ ASSERT(m_data);
+ ASSERT(context);
+
+ RefPtr<JSDatabaseCallback> protect(this);
+
+ JSC::JSLock lock(SilenceAssertionsOnly);
+
+ JSDOMGlobalObject* globalObject = toJSDOMGlobalObject(context, m_isolatedWorld.get());
+ if (!globalObject)
+ return;
+
+ ExecState* exec = globalObject->globalExec();
+ MarkedArgumentBuffer args;
+ args.append(toJS(exec, database));
+
+ bool ignored;
+ m_data->invokeCallback(args, &ignored);
+}
+
+}
+
+#endif // ENABLE(DATABASE)
diff --git a/WebCore/bindings/js/JSDatabaseCallback.h b/WebCore/bindings/js/JSDatabaseCallback.h
new file mode 100644
index 0000000..752a2c3
--- /dev/null
+++ b/WebCore/bindings/js/JSDatabaseCallback.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef JSDatabaseCallback_h
+#define JSDatabaseCallback_h
+
+#if ENABLE(DATABASE)
+
+#include "DatabaseCallback.h"
+#include "JSCallbackData.h"
+#include <wtf/Forward.h>
+
+namespace WebCore {
+
+class ScriptExecutionContext;
+
+class JSDatabaseCallback : public DatabaseCallback {
+public:
+ static PassRefPtr<JSDatabaseCallback> create(JSC::JSObject* callback, JSDOMGlobalObject* globalObject)
+ {
+ return adoptRef(new JSDatabaseCallback(callback, globalObject));
+ }
+
+ virtual ~JSDatabaseCallback();
+
+ virtual void handleEvent(ScriptExecutionContext*, Database*);
+
+private:
+ JSDatabaseCallback(JSC::JSObject* callback, JSDOMGlobalObject*);
+
+ JSCallbackData* m_data;
+ RefPtr<DOMWrapperWorld> m_isolatedWorld;
+};
+
+}
+
+#endif // ENABLE(DATABASE)
+
+#endif // JSDatabaseCallback_h
diff --git a/WebCore/bindings/js/JSDatabaseCustom.cpp b/WebCore/bindings/js/JSDatabaseCustom.cpp
index 0932cca..50f1d17 100644
--- a/WebCore/bindings/js/JSDatabaseCustom.cpp
+++ b/WebCore/bindings/js/JSDatabaseCustom.cpp
@@ -49,8 +49,8 @@ using namespace JSC;
JSValue JSDatabase::changeVersion(ExecState* exec, const ArgList& args)
{
- String oldVersion = args.at(0).toString(exec);
- String newVersion = args.at(1).toString(exec);
+ String oldVersion = ustringToString(args.at(0).toString(exec));
+ String newVersion = ustringToString(args.at(1).toString(exec));
JSObject* object;
if (!(object = args.at(2).getObject())) {
diff --git a/WebCore/bindings/js/JSDebugWrapperSet.cpp b/WebCore/bindings/js/JSDebugWrapperSet.cpp
new file mode 100644
index 0000000..b0d6ca9
--- /dev/null
+++ b/WebCore/bindings/js/JSDebugWrapperSet.cpp
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "JSDebugWrapperSet.h"
+
+#include <wtf/StdLibExtras.h>
+
+#if ENABLE(WORKERS)
+#include <wtf/ThreadSpecific.h>
+#endif
+
+namespace WebCore {
+
+JSDebugWrapperSet& JSDebugWrapperSet::shared()
+{
+#if ENABLE(WORKERS)
+ DEFINE_STATIC_LOCAL(WTF::ThreadSpecific<JSDebugWrapperSet>, staticWrapperSet, ());
+ return *staticWrapperSet;
+#else
+ DEFINE_STATIC_LOCAL(JSDebugWrapperSet, staticWrapperSet, ());
+ return staticWrapperSet;
+#endif
+}
+
+JSDebugWrapperSet::JSDebugWrapperSet()
+{
+}
+
+} // namespace WebCore
diff --git a/WebCore/bindings/js/JSDebugWrapperSet.h b/WebCore/bindings/js/JSDebugWrapperSet.h
new file mode 100644
index 0000000..94b6f78
--- /dev/null
+++ b/WebCore/bindings/js/JSDebugWrapperSet.h
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef JSDebugWrapperSet_h
+#define JSDebugWrapperSet_h
+
+#include "JSDOMWrapper.h"
+#include <wtf/HashSet.h>
+#include <wtf/Noncopyable.h>
+
+namespace WebCore {
+
+// For debugging, keep a set of wrappers currently cached, and check that
+// all are uncached before they are destroyed. This helps us catch bugs like:
+// - wrappers being deleted without being removed from the cache
+// - wrappers being cached twice
+
+class JSDebugWrapperSet : public Noncopyable {
+ friend class WTF::ThreadSpecific<JSDebugWrapperSet>;
+public:
+ static JSDebugWrapperSet& shared();
+
+ void add(DOMObject* object) { m_wrapperSet.add(object); }
+ void remove(DOMObject* object) { m_wrapperSet.remove(object); }
+ bool contains(DOMObject* object) const { return m_wrapperSet.contains(object); }
+
+ static void willCacheWrapper(DOMObject*);
+ static void didUncacheWrapper(DOMObject*);
+
+private:
+ JSDebugWrapperSet();
+
+ HashSet<DOMObject*> m_wrapperSet;
+};
+
+#ifdef NDEBUG
+
+inline void JSDebugWrapperSet::willCacheWrapper(DOMObject*)
+{
+}
+
+inline void JSDebugWrapperSet::didUncacheWrapper(DOMObject*)
+{
+}
+
+#else
+
+inline void JSDebugWrapperSet::willCacheWrapper(DOMObject* wrapper)
+{
+ ASSERT(!JSDebugWrapperSet::shared().contains(wrapper));
+ JSDebugWrapperSet::shared().add(wrapper);
+}
+
+inline void JSDebugWrapperSet::didUncacheWrapper(DOMObject* wrapper)
+{
+ if (!wrapper)
+ return;
+ ASSERT(JSDebugWrapperSet::shared().contains(wrapper));
+ JSDebugWrapperSet::shared().remove(wrapper);
+}
+
+#endif
+
+} // namespace WebCore
+
+#endif // JSDebugWrapperSet_h
diff --git a/WebCore/bindings/js/JSDesktopNotificationsCustom.cpp b/WebCore/bindings/js/JSDesktopNotificationsCustom.cpp
index 7485c1f..f86bae5 100644
--- a/WebCore/bindings/js/JSDesktopNotificationsCustom.cpp
+++ b/WebCore/bindings/js/JSDesktopNotificationsCustom.cpp
@@ -55,7 +55,7 @@ JSValue JSNotificationCenter::requestPermission(ExecState* exec, const ArgList&
if (!args.at(0).isObject())
return throwError(exec, TypeError);
- PassRefPtr<JSCustomVoidCallback> callback = JSCustomVoidCallback::create(args.at(0).getObject(), static_cast<Document*>(context)->frame());
+ PassRefPtr<JSCustomVoidCallback> callback = JSCustomVoidCallback::create(args.at(0).getObject(), toJSDOMGlobalObject(static_cast<Document*>(context), exec));
impl()->requestPermission(callback);
return jsUndefined();
@@ -67,7 +67,7 @@ JSValue JSNotification::addEventListener(ExecState* exec, const ArgList& args)
if (!listener.isObject())
return jsUndefined();
- impl()->addEventListener(args.at(0).toString(exec), JSEventListener::create(asObject(listener)), false, currentWorld(exec)), args.at(2).toBoolean(exec));
+ impl()->addEventListener(ustringToAtomicString(args.at(0).toString(exec)), JSEventListener::create(asObject(listener), this, false, currentWorld(exec)), args.at(2).toBoolean(exec));
return jsUndefined();
}
@@ -77,7 +77,7 @@ JSValue JSNotification::removeEventListener(ExecState* exec, const ArgList& args
if (!listener.isObject())
return jsUndefined();
- impl()->removeEventListener(args.at(0).toString(exec), JSEventListener::create(asObject(listener), false, currentWorld(exec)).get(), args.at(2).toBoolean(exec));
+ impl()->removeEventListener(ustringToAtomicString(args.at(0).toString(exec)), JSEventListener::create(asObject(listener), this, false, currentWorld(exec)).get(), args.at(2).toBoolean(exec));
return jsUndefined();
}
diff --git a/WebCore/bindings/js/JSDocumentCustom.cpp b/WebCore/bindings/js/JSDocumentCustom.cpp
index eda153e..8abd8ce 100644
--- a/WebCore/bindings/js/JSDocumentCustom.cpp
+++ b/WebCore/bindings/js/JSDocumentCustom.cpp
@@ -79,7 +79,7 @@ void JSDocument::setLocation(ExecState* exec, JSValue value)
if (!frame)
return;
- String str = value.toString(exec);
+ String str = ustringToString(value.toString(exec));
// IE and Mozilla both resolve the URL relative to the source frame,
// not the target frame.
diff --git a/WebCore/bindings/js/JSElementCustom.cpp b/WebCore/bindings/js/JSElementCustom.cpp
index c725290..7e294bd 100644
--- a/WebCore/bindings/js/JSElementCustom.cpp
+++ b/WebCore/bindings/js/JSElementCustom.cpp
@@ -36,6 +36,7 @@
#include "HTMLFrameElementBase.h"
#include "HTMLNames.h"
#include "JSAttr.h"
+#include "JSDOMBinding.h"
#include "JSHTMLElementWrapperFactory.h"
#include "JSNodeList.h"
#include "NodeList.h"
@@ -63,21 +64,11 @@ void JSElement::markChildren(MarkStack& markStack)
markDOMObjectWrapper(markStack, globalData, static_cast<StyledElement*>(element)->inlineStyleDecl());
}
-static inline bool allowSettingSrcToJavascriptURL(ExecState* exec, Element* element, const String& name, const String& value)
-{
- if ((element->hasTagName(iframeTag) || element->hasTagName(frameTag)) && equalIgnoringCase(name, "src") && protocolIsJavaScript(deprecatedParseURL(value))) {
- Document* contentDocument = static_cast<HTMLFrameElementBase*>(element)->contentDocument();
- if (contentDocument && !checkNodeSecurity(exec, contentDocument))
- return false;
- }
- return true;
-}
-
JSValue JSElement::setAttribute(ExecState* exec, const ArgList& args)
{
ExceptionCode ec = 0;
- AtomicString name = args.at(0).toString(exec);
- AtomicString value = args.at(1).toString(exec);
+ AtomicString name = ustringToAtomicString(args.at(0).toString(exec));
+ AtomicString value = ustringToAtomicString(args.at(1).toString(exec));
Element* imp = impl();
if (!allowSettingSrcToJavascriptURL(exec, imp, name, value))
@@ -110,8 +101,8 @@ JSValue JSElement::setAttributeNS(ExecState* exec, const ArgList& args)
{
ExceptionCode ec = 0;
AtomicString namespaceURI = valueToStringWithNullCheck(exec, args.at(0));
- AtomicString qualifiedName = args.at(1).toString(exec);
- AtomicString value = args.at(2).toString(exec);
+ AtomicString qualifiedName = ustringToAtomicString(args.at(1).toString(exec));
+ AtomicString value = ustringToAtomicString(args.at(2).toString(exec));
Element* imp = impl();
if (!allowSettingSrcToJavascriptURL(exec, imp, qualifiedName, value))
diff --git a/WebCore/bindings/js/JSEventCustom.cpp b/WebCore/bindings/js/JSEventCustom.cpp
index 04ceec5..6686d7a 100644
--- a/WebCore/bindings/js/JSEventCustom.cpp
+++ b/WebCore/bindings/js/JSEventCustom.cpp
@@ -31,9 +31,11 @@
#include "Clipboard.h"
#include "CompositionEvent.h"
+#include "CustomEvent.h"
#include "Event.h"
#include "JSBeforeLoadEvent.h"
#include "JSClipboard.h"
+#include "JSCustomEvent.h"
#include "JSCompositionEvent.h"
#include "JSErrorEvent.h"
#include "JSKeyboardEvent.h"
@@ -153,6 +155,8 @@ JSValue toJS(ExecState* exec, JSDOMGlobalObject* globalObject, Event* event)
#endif
else if (event->isPopStateEvent())
wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, globalObject, PopStateEvent, event);
+ else if (event->isCustomEvent())
+ wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, globalObject, CustomEvent, event);
else
wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, globalObject, Event, event);
diff --git a/WebCore/bindings/js/JSEventListener.cpp b/WebCore/bindings/js/JSEventListener.cpp
index 61f21be..3853cfc 100644
--- a/WebCore/bindings/js/JSEventListener.cpp
+++ b/WebCore/bindings/js/JSEventListener.cpp
@@ -83,7 +83,7 @@ void JSEventListener::handleEvent(ScriptExecutionContext* scriptExecutionContext
return;
// FIXME: Is this check needed for other contexts?
ScriptController* script = frame->script();
- if (!script->canExecuteScripts() || script->isPaused())
+ if (!script->canExecuteScripts(AboutToExecuteScript) || script->isPaused())
return;
}
@@ -121,7 +121,7 @@ void JSEventListener::handleEvent(ScriptExecutionContext* scriptExecutionContext
reportCurrentException(exec);
else {
if (!retval.isUndefinedOrNull() && event->storesResultAsString())
- event->storeResult(retval.toString(exec));
+ event->storeResult(ustringToString(retval.toString(exec)));
if (m_isAttribute) {
bool retvalbool;
if (retval.getBoolean(retvalbool) && !retvalbool)
@@ -129,53 +129,10 @@ void JSEventListener::handleEvent(ScriptExecutionContext* scriptExecutionContext
}
}
- if (scriptExecutionContext->isDocument())
- Document::updateStyleForAllDocuments();
deref();
}
}
-bool JSEventListener::reportError(ScriptExecutionContext* context, const String& message, const String& url, int lineNumber)
-{
- JSLock lock(SilenceAssertionsOnly);
-
- JSObject* jsFunction = this->jsFunction(context);
- if (!jsFunction)
- return false;
-
- JSDOMGlobalObject* globalObject = toJSDOMGlobalObject(context, m_isolatedWorld.get());
- ExecState* exec = globalObject->globalExec();
-
- CallData callData;
- CallType callType = jsFunction->getCallData(callData);
-
- if (callType == CallTypeNone)
- return false;
-
- MarkedArgumentBuffer args;
- args.append(jsString(exec, message));
- args.append(jsString(exec, url));
- args.append(jsNumber(exec, lineNumber));
-
- JSGlobalData* globalData = globalObject->globalData();
- DynamicGlobalObjectScope globalObjectScope(exec, globalData->dynamicGlobalObject ? globalData->dynamicGlobalObject : globalObject);
-
- JSValue thisValue = globalObject->toThisObject(exec);
-
- globalData->timeoutChecker.start();
- 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.
- if (exec->hadException()) {
- exec->clearException();
- return false;
- }
-
- bool bubbleEvent;
- return returnValue.getBoolean(bubbleEvent) && !bubbleEvent;
-}
-
bool JSEventListener::virtualisAttribute() const
{
return m_isAttribute;
diff --git a/WebCore/bindings/js/JSEventListener.h b/WebCore/bindings/js/JSEventListener.h
index 569c192..b15c589 100644
--- a/WebCore/bindings/js/JSEventListener.h
+++ b/WebCore/bindings/js/JSEventListener.h
@@ -60,7 +60,6 @@ namespace WebCore {
virtual void markJSFunction(JSC::MarkStack&);
virtual void invalidateJSFunction(JSC::JSObject*);
virtual void handleEvent(ScriptExecutionContext*, Event*);
- virtual bool reportError(ScriptExecutionContext*, const String& message, const String& url, int lineNumber);
virtual bool virtualisAttribute() const;
protected:
diff --git a/WebCore/bindings/js/JSEventSourceConstructor.cpp b/WebCore/bindings/js/JSEventSourceConstructor.cpp
index c6e4825..e48489b 100644
--- a/WebCore/bindings/js/JSEventSourceConstructor.cpp
+++ b/WebCore/bindings/js/JSEventSourceConstructor.cpp
@@ -71,7 +71,7 @@ static JSObject* constructEventSource(ExecState* exec, JSObject* constructor, co
return throwError(exec, ReferenceError, "EventSource constructor associated document is unavailable");
ExceptionCode ec = 0;
- RefPtr<EventSource> eventSource = EventSource::create(url, context, ec);
+ RefPtr<EventSource> eventSource = EventSource::create(ustringToString(url), context, ec);
if (ec) {
setDOMException(exec, ec);
return 0;
diff --git a/WebCore/bindings/js/JSEventSourceCustom.cpp b/WebCore/bindings/js/JSEventSourceCustom.cpp
index dab3285..86db431 100644
--- a/WebCore/bindings/js/JSEventSourceCustom.cpp
+++ b/WebCore/bindings/js/JSEventSourceCustom.cpp
@@ -49,7 +49,7 @@ JSValue JSEventSource::addEventListener(ExecState* exec, const ArgList& args)
if (!listener.isObject())
return jsUndefined();
- impl()->addEventListener(args.at(0).toString(exec), JSEventListener::create(asObject(listener), this, false, currentWorld(exec)).get(), args.at(2).toBoolean(exec));
+ impl()->addEventListener(ustringToAtomicString(args.at(0).toString(exec)), JSEventListener::create(asObject(listener), this, false, currentWorld(exec)).get(), args.at(2).toBoolean(exec));
return jsUndefined();
}
@@ -59,7 +59,7 @@ JSValue JSEventSource::removeEventListener(ExecState* exec, const ArgList& args)
if (!listener.isObject())
return jsUndefined();
- impl()->removeEventListener(args.at(0).toString(exec), JSEventListener::create(asObject(listener), this, false, currentWorld(exec)).get(), args.at(2).toBoolean(exec));
+ impl()->removeEventListener(ustringToAtomicString(args.at(0).toString(exec)), JSEventListener::create(asObject(listener), this, false, currentWorld(exec)).get(), args.at(2).toBoolean(exec));
return jsUndefined();
}
diff --git a/WebCore/bindings/js/JSGeolocationCustom.cpp b/WebCore/bindings/js/JSGeolocationCustom.cpp
index 530b89b..8bc348c 100644
--- a/WebCore/bindings/js/JSGeolocationCustom.cpp
+++ b/WebCore/bindings/js/JSGeolocationCustom.cpp
@@ -26,6 +26,8 @@
#include "config.h"
#include "JSGeolocation.h"
+#if ENABLE(GEOLOCATION)
+
#include "DOMWindow.h"
#include "ExceptionCode.h"
#include "Geolocation.h"
@@ -178,3 +180,5 @@ JSValue JSGeolocation::watchPosition(ExecState* exec, const ArgList& args)
}
} // namespace WebCore
+
+#endif // ENABLE(GEOLOCATION)
diff --git a/WebCore/bindings/js/JSHTMLAllCollectionCustom.cpp b/WebCore/bindings/js/JSHTMLAllCollectionCustom.cpp
index fd1dd11..86d6fa2 100644
--- a/WebCore/bindings/js/JSHTMLAllCollectionCustom.cpp
+++ b/WebCore/bindings/js/JSHTMLAllCollectionCustom.cpp
@@ -43,7 +43,7 @@ namespace WebCore {
static JSValue getNamedItems(ExecState* exec, JSHTMLAllCollection* collection, const Identifier& propertyName)
{
Vector<RefPtr<Node> > namedItems;
- collection->impl()->namedItems(propertyName, namedItems);
+ collection->impl()->namedItems(identifierToAtomicString(propertyName), namedItems);
if (namedItems.isEmpty())
return jsUndefined();
@@ -86,7 +86,7 @@ static JSValue JSC_HOST_CALL callHTMLAllCollection(ExecState* exec, JSObject* fu
UString string = args.at(0).toString(exec);
unsigned index = args.at(1).toString(exec).toUInt32(&ok, false);
if (ok) {
- String pstr = string;
+ String pstr = ustringToString(string);
Node* node = collection->namedItem(pstr);
while (node) {
if (!index)
@@ -108,13 +108,13 @@ CallType JSHTMLAllCollection::getCallData(CallData& callData)
bool JSHTMLAllCollection::canGetItemsForName(ExecState*, HTMLAllCollection* collection, const Identifier& propertyName)
{
Vector<RefPtr<Node> > namedItems;
- collection->namedItems(propertyName, namedItems);
+ collection->namedItems(identifierToAtomicString(propertyName), namedItems);
return !namedItems.isEmpty();
}
-JSValue JSHTMLAllCollection::nameGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot)
+JSValue JSHTMLAllCollection::nameGetter(ExecState* exec, JSValue slotBase, const Identifier& propertyName)
{
- JSHTMLAllCollection* thisObj = static_cast<JSHTMLAllCollection*>(asObject(slot.slotBase()));
+ JSHTMLAllCollection* thisObj = static_cast<JSHTMLAllCollection*>(asObject(slotBase));
return getNamedItems(exec, thisObj, propertyName);
}
diff --git a/WebCore/bindings/js/JSHTMLAppletElementCustom.cpp b/WebCore/bindings/js/JSHTMLAppletElementCustom.cpp
index 30892e0..40d20cf 100644
--- a/WebCore/bindings/js/JSHTMLAppletElementCustom.cpp
+++ b/WebCore/bindings/js/JSHTMLAppletElementCustom.cpp
@@ -53,14 +53,4 @@ CallType JSHTMLAppletElement::getCallData(CallData& callData)
return runtimeObjectGetCallData(impl(), callData);
}
-bool JSHTMLAppletElement::canGetItemsForName(ExecState*, HTMLAppletElement*, const Identifier& propertyName)
-{
- return propertyName == "__apple_runtime_object";
-}
-
-JSValue JSHTMLAppletElement::nameGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot)
-{
- return runtimeObjectGetter(exec, propertyName, slot);
-}
-
} // namespace WebCore
diff --git a/WebCore/bindings/js/JSHTMLCanvasElementCustom.cpp b/WebCore/bindings/js/JSHTMLCanvasElementCustom.cpp
index 80634f7..89f62f8 100644
--- a/WebCore/bindings/js/JSHTMLCanvasElementCustom.cpp
+++ b/WebCore/bindings/js/JSHTMLCanvasElementCustom.cpp
@@ -78,7 +78,7 @@ JSValue JSHTMLCanvasElement::getContext(ExecState* exec, const ArgList& args)
}
}
#endif
- return toJS(exec, globalObject(), WTF::getPtr(canvas->getContext(contextId, attrs.get())));
+ return toJS(exec, globalObject(), WTF::getPtr(canvas->getContext(ustringToString(contextId), attrs.get())));
}
} // namespace WebCore
diff --git a/WebCore/bindings/js/JSHTMLCollectionCustom.cpp b/WebCore/bindings/js/JSHTMLCollectionCustom.cpp
index ba61922..c5eb41a 100644
--- a/WebCore/bindings/js/JSHTMLCollectionCustom.cpp
+++ b/WebCore/bindings/js/JSHTMLCollectionCustom.cpp
@@ -40,7 +40,7 @@ namespace WebCore {
static JSValue getNamedItems(ExecState* exec, JSHTMLCollection* collection, const Identifier& propertyName)
{
Vector<RefPtr<Node> > namedItems;
- collection->impl()->namedItems(propertyName, namedItems);
+ collection->impl()->namedItems(identifierToAtomicString(propertyName), namedItems);
if (namedItems.isEmpty())
return jsUndefined();
@@ -83,7 +83,7 @@ static JSValue JSC_HOST_CALL callHTMLCollection(ExecState* exec, JSObject* funct
UString string = args.at(0).toString(exec);
unsigned index = args.at(1).toString(exec).toUInt32(&ok, false);
if (ok) {
- String pstr = string;
+ String pstr = ustringToString(string);
Node* node = collection->namedItem(pstr);
while (node) {
if (!index)
@@ -105,13 +105,13 @@ CallType JSHTMLCollection::getCallData(CallData& callData)
bool JSHTMLCollection::canGetItemsForName(ExecState*, HTMLCollection* collection, const Identifier& propertyName)
{
Vector<RefPtr<Node> > namedItems;
- collection->namedItems(propertyName, namedItems);
+ collection->namedItems(identifierToAtomicString(propertyName), namedItems);
return !namedItems.isEmpty();
}
-JSValue JSHTMLCollection::nameGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot)
+JSValue JSHTMLCollection::nameGetter(ExecState* exec, JSValue slotBase, const Identifier& propertyName)
{
- JSHTMLCollection* thisObj = static_cast<JSHTMLCollection*>(asObject(slot.slotBase()));
+ JSHTMLCollection* thisObj = static_cast<JSHTMLCollection*>(asObject(slotBase));
return getNamedItems(exec, thisObj, propertyName);
}
diff --git a/WebCore/bindings/js/JSHTMLDocumentCustom.cpp b/WebCore/bindings/js/JSHTMLDocumentCustom.cpp
index 7fde002..de0e96f 100644
--- a/WebCore/bindings/js/JSHTMLDocumentCustom.cpp
+++ b/WebCore/bindings/js/JSHTMLDocumentCustom.cpp
@@ -51,16 +51,16 @@ using namespace HTMLNames;
bool JSHTMLDocument::canGetItemsForName(ExecState*, HTMLDocument* document, const Identifier& propertyName)
{
- AtomicStringImpl* atomicPropertyName = AtomicString::find(propertyName);
+ AtomicStringImpl* atomicPropertyName = findAtomicString(propertyName);
return atomicPropertyName && (document->hasNamedItem(atomicPropertyName) || document->hasExtraNamedItem(atomicPropertyName));
}
-JSValue JSHTMLDocument::nameGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot)
+JSValue JSHTMLDocument::nameGetter(ExecState* exec, JSValue slotBase, const Identifier& propertyName)
{
- JSHTMLDocument* thisObj = static_cast<JSHTMLDocument*>(asObject(slot.slotBase()));
+ JSHTMLDocument* thisObj = static_cast<JSHTMLDocument*>(asObject(slotBase));
HTMLDocument* document = static_cast<HTMLDocument*>(thisObj->impl());
- String name = propertyName;
+ String name = identifierToString(propertyName);
RefPtr<HTMLCollection> collection = document->documentNamedItems(name);
unsigned length = collection->length();
@@ -137,14 +137,14 @@ static inline void documentWrite(ExecState* exec, const ArgList& args, HTMLDocum
size_t size = args.size();
UString firstString = args.at(0).toString(exec);
- SegmentedString segmentedString = String(firstString);
+ SegmentedString segmentedString = ustringToString(firstString);
if (size != 1) {
if (!size)
segmentedString.clear();
else {
for (size_t i = 1; i < size; ++i) {
UString subsequentString = args.at(i).toString(exec);
- segmentedString.append(SegmentedString(String(subsequentString)));
+ segmentedString.append(SegmentedString(ustringToString(subsequentString)));
}
}
}
diff --git a/WebCore/bindings/js/JSHTMLEmbedElementCustom.cpp b/WebCore/bindings/js/JSHTMLEmbedElementCustom.cpp
index bce3ffb..b9f8c12 100644
--- a/WebCore/bindings/js/JSHTMLEmbedElementCustom.cpp
+++ b/WebCore/bindings/js/JSHTMLEmbedElementCustom.cpp
@@ -53,14 +53,4 @@ CallType JSHTMLEmbedElement::getCallData(CallData& callData)
return runtimeObjectGetCallData(impl(), callData);
}
-bool JSHTMLEmbedElement::canGetItemsForName(ExecState*, HTMLEmbedElement*, const Identifier& propertyName)
-{
- return propertyName == "__apple_runtime_object";
-}
-
-JSValue JSHTMLEmbedElement::nameGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot)
-{
- return runtimeObjectGetter(exec, propertyName, slot);
-}
-
} // namespace WebCore
diff --git a/WebCore/bindings/js/JSHTMLFormElementCustom.cpp b/WebCore/bindings/js/JSHTMLFormElementCustom.cpp
index c364c14..2e7522c 100644
--- a/WebCore/bindings/js/JSHTMLFormElementCustom.cpp
+++ b/WebCore/bindings/js/JSHTMLFormElementCustom.cpp
@@ -40,17 +40,17 @@ namespace WebCore {
bool JSHTMLFormElement::canGetItemsForName(ExecState*, HTMLFormElement* form, const Identifier& propertyName)
{
Vector<RefPtr<Node> > namedItems;
- form->getNamedElements(propertyName, namedItems);
+ form->getNamedElements(identifierToAtomicString(propertyName), namedItems);
return namedItems.size();
}
-JSValue JSHTMLFormElement::nameGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot)
+JSValue JSHTMLFormElement::nameGetter(ExecState* exec, JSValue slotBase, const Identifier& propertyName)
{
- JSHTMLElement* jsForm = static_cast<JSHTMLFormElement*>(asObject(slot.slotBase()));
+ JSHTMLElement* jsForm = static_cast<JSHTMLFormElement*>(asObject(slotBase));
HTMLFormElement* form = static_cast<HTMLFormElement*>(jsForm->impl());
Vector<RefPtr<Node> > namedItems;
- form->getNamedElements(propertyName, namedItems);
+ form->getNamedElements(identifierToAtomicString(propertyName), namedItems);
if (namedItems.isEmpty())
return jsUndefined();
diff --git a/WebCore/bindings/js/JSHTMLFrameSetElementCustom.cpp b/WebCore/bindings/js/JSHTMLFrameSetElementCustom.cpp
index 68769d6..617aaff 100644
--- a/WebCore/bindings/js/JSHTMLFrameSetElementCustom.cpp
+++ b/WebCore/bindings/js/JSHTMLFrameSetElementCustom.cpp
@@ -43,16 +43,16 @@ using namespace HTMLNames;
bool JSHTMLFrameSetElement::canGetItemsForName(ExecState*, HTMLFrameSetElement* frameSet, const Identifier& propertyName)
{
- Node* frame = frameSet->children()->namedItem(propertyName);
+ Node* frame = frameSet->children()->namedItem(identifierToAtomicString(propertyName));
return frame && frame->hasTagName(frameTag);
}
-JSValue JSHTMLFrameSetElement::nameGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot)
+JSValue JSHTMLFrameSetElement::nameGetter(ExecState* exec, JSValue slotBase, const Identifier& propertyName)
{
- JSHTMLElement* thisObj = static_cast<JSHTMLElement*>(asObject(slot.slotBase()));
+ JSHTMLElement* thisObj = static_cast<JSHTMLElement*>(asObject(slotBase));
HTMLElement* element = static_cast<HTMLElement*>(thisObj->impl());
- Node* frame = element->children()->namedItem(propertyName);
+ Node* frame = element->children()->namedItem(identifierToAtomicString(propertyName));
if (Document* doc = static_cast<HTMLFrameElement*>(frame)->contentDocument()) {
if (JSDOMWindowShell* window = toJSDOMWindowShell(doc->frame(), currentWorld(exec)))
return window;
diff --git a/WebCore/bindings/js/JSHTMLObjectElementCustom.cpp b/WebCore/bindings/js/JSHTMLObjectElementCustom.cpp
index 1bfb51f..68c9e59 100644
--- a/WebCore/bindings/js/JSHTMLObjectElementCustom.cpp
+++ b/WebCore/bindings/js/JSHTMLObjectElementCustom.cpp
@@ -53,14 +53,4 @@ CallType JSHTMLObjectElement::getCallData(CallData& callData)
return runtimeObjectGetCallData(impl(), callData);
}
-bool JSHTMLObjectElement::canGetItemsForName(ExecState*, HTMLObjectElement*, const Identifier& propertyName)
-{
- return propertyName == "__apple_runtime_object";
-}
-
-JSValue JSHTMLObjectElement::nameGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot)
-{
- return runtimeObjectGetter(exec, propertyName, slot);
-}
-
} // namespace WebCore
diff --git a/WebCore/bindings/js/JSHistoryCustom.cpp b/WebCore/bindings/js/JSHistoryCustom.cpp
index fff747f..c031b30 100644
--- a/WebCore/bindings/js/JSHistoryCustom.cpp
+++ b/WebCore/bindings/js/JSHistoryCustom.cpp
@@ -38,17 +38,17 @@ using namespace JSC;
namespace WebCore {
-static JSValue nonCachingStaticBackFunctionGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot&)
+static JSValue nonCachingStaticBackFunctionGetter(ExecState* exec, JSValue, const Identifier& propertyName)
{
return new (exec) NativeFunctionWrapper(exec, exec->lexicalGlobalObject()->prototypeFunctionStructure(), 0, propertyName, jsHistoryPrototypeFunctionBack);
}
-static JSValue nonCachingStaticForwardFunctionGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot&)
+static JSValue nonCachingStaticForwardFunctionGetter(ExecState* exec, JSValue, const Identifier& propertyName)
{
return new (exec) NativeFunctionWrapper(exec, exec->lexicalGlobalObject()->prototypeFunctionStructure(), 0, propertyName, jsHistoryPrototypeFunctionForward);
}
-static JSValue nonCachingStaticGoFunctionGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot&)
+static JSValue nonCachingStaticGoFunctionGetter(ExecState* exec, JSValue, const Identifier& propertyName)
{
return new (exec) NativeFunctionWrapper(exec, exec->lexicalGlobalObject()->prototypeFunctionStructure(), 1, propertyName, jsHistoryPrototypeFunctionGo);
}
diff --git a/WebCore/bindings/js/JSInjectedScriptHostCustom.cpp b/WebCore/bindings/js/JSInjectedScriptHostCustom.cpp
index 3db894d..8bfb8a3 100644
--- a/WebCore/bindings/js/JSInjectedScriptHostCustom.cpp
+++ b/WebCore/bindings/js/JSInjectedScriptHostCustom.cpp
@@ -1,7 +1,7 @@
/*
* 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.
+ * Copyright (C) 2010 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -48,6 +48,7 @@
#include "InspectorController.h"
#include "InspectorResource.h"
#include "JSDOMWindow.h"
+#include "JSDOMWindowCustom.h"
#include "JSNode.h"
#include "JSRange.h"
#include "Node.h"
@@ -67,17 +68,17 @@
#if ENABLE(JAVASCRIPT_DEBUGGER)
#include "JavaScriptCallFrame.h"
-#include "JavaScriptDebugServer.h"
#include "JSJavaScriptCallFrame.h"
+#include "ScriptDebugServer.h"
#endif
using namespace JSC;
namespace WebCore {
-static ScriptObject createInjectedScript(const String& source, InjectedScriptHost* injectedScriptHost, ScriptState* scriptState, long id)
+ScriptObject InjectedScriptHost::createInjectedScript(const String& source, ScriptState* scriptState, long id)
{
- SourceCode sourceCode = makeSource(source);
+ SourceCode sourceCode = makeSource(stringToUString(source));
JSLock lock(SilenceAssertionsOnly);
JSDOMGlobalObject* globalObject = static_cast<JSDOMGlobalObject*>(scriptState->lexicalGlobalObject());
JSValue globalThisValue = scriptState->globalThisValue();
@@ -91,9 +92,10 @@ static ScriptObject createInjectedScript(const String& source, InjectedScriptHos
return ScriptObject();
MarkedArgumentBuffer args;
- args.append(toJS(scriptState, globalObject, injectedScriptHost));
+ args.append(toJS(scriptState, globalObject, this));
args.append(globalThisValue);
args.append(jsNumber(scriptState, id));
+ args.append(jsString(scriptState, String("JSC")));
JSValue result = JSC::call(scriptState, functionValue, callType, callData, globalThisValue, args);
if (result.isObject())
return ScriptObject(scriptState, result.getObject());
@@ -118,10 +120,9 @@ JSValue JSInjectedScriptHost::databaseForId(ExecState* exec, const ArgList& args
#endif
#if ENABLE(JAVASCRIPT_DEBUGGER)
-
JSValue JSInjectedScriptHost::currentCallFrame(ExecState* exec, const ArgList&)
{
- JavaScriptCallFrame* callFrame = impl()->currentCallFrame();
+ JavaScriptCallFrame* callFrame = ScriptDebugServer::shared().currentCallFrame();
if (!callFrame || !callFrame->isValid())
return jsUndefined();
@@ -134,7 +135,6 @@ JSValue JSInjectedScriptHost::isActivation(ExecState*, const ArgList& args)
JSObject* object = args.at(0).getObject();
return jsBoolean(object && object->isActivationObject());
}
-
#endif
JSValue JSInjectedScriptHost::nodeForId(ExecState* exec, const ArgList& args)
@@ -223,15 +223,23 @@ InjectedScript InjectedScriptHost::injectedScriptFor(ScriptState* scriptState)
if (injectedScript)
return InjectedScript(ScriptObject(scriptState, injectedScript));
- ASSERT(!m_injectedScriptSource.isEmpty());
- ScriptObject injectedScriptObject = createInjectedScript(m_injectedScriptSource, this, scriptState, m_nextInjectedScriptId);
- globalObject->setInjectedScript(injectedScriptObject.jsObject());
- InjectedScript result(injectedScriptObject);
- m_idToInjectedScript.set(m_nextInjectedScriptId, result);
- m_nextInjectedScriptId++;
+ ASSERT(!m_injectedScriptSource.isEmpty());
+ pair<long, ScriptObject> injectedScriptObject = injectScript(m_injectedScriptSource, scriptState);
+ globalObject->setInjectedScript(injectedScriptObject.second.jsObject());
+ InjectedScript result(injectedScriptObject.second);
+ m_idToInjectedScript.set(injectedScriptObject.first, result);
return result;
}
+bool InjectedScriptHost::canAccessInspectedWindow(ScriptState* scriptState)
+{
+ JSLock lock(SilenceAssertionsOnly);
+ JSDOMWindow* inspectedWindow = toJSDOMWindow(scriptState->lexicalGlobalObject());
+ if (!inspectedWindow)
+ return false;
+ return inspectedWindow->allowsAccessFromNoErrorMessage(scriptState);
+}
+
} // namespace WebCore
#endif // ENABLE(INSPECTOR)
diff --git a/WebCore/bindings/js/JSInspectorFrontendHostCustom.cpp b/WebCore/bindings/js/JSInspectorFrontendHostCustom.cpp
index 7b06bac..d18260b 100644
--- a/WebCore/bindings/js/JSInspectorFrontendHostCustom.cpp
+++ b/WebCore/bindings/js/JSInspectorFrontendHostCustom.cpp
@@ -49,11 +49,39 @@ using namespace JSC;
namespace WebCore {
+JSValue JSInspectorFrontendHost::platform(ExecState* execState, const ArgList&)
+{
+#if PLATFORM(MAC)
+ DEFINE_STATIC_LOCAL(const String, platform, ("mac"));
+#elif OS(WINDOWS)
+ DEFINE_STATIC_LOCAL(const String, platform, ("windows"));
+#elif OS(LINUX)
+ DEFINE_STATIC_LOCAL(const String, platform, ("linux"));
+#else
+ DEFINE_STATIC_LOCAL(const String, platform, ("unknown"));
+#endif
+ return jsString(execState, platform);
+}
+
+JSValue JSInspectorFrontendHost::port(ExecState* execState, const ArgList&)
+{
+#if PLATFORM(QT)
+ DEFINE_STATIC_LOCAL(const String, port, ("qt"));
+#elif PLATFORM(GTK)
+ DEFINE_STATIC_LOCAL(const String, port, ("gtk"));
+#elif PLATFORM(WX)
+ DEFINE_STATIC_LOCAL(const String, port, ("wx"));
+#else
+ DEFINE_STATIC_LOCAL(const String, port, ("unknown"));
+#endif
+ return jsString(execState, port);
+}
+
JSValue JSInspectorFrontendHost::showContextMenu(ExecState* execState, const ArgList& args)
{
if (args.size() < 2)
return jsUndefined();
-
+#if ENABLE(CONTEXT_MENUS)
Event* event = toEvent(args.at(0));
JSArray* array = asArray(args.at(1));
@@ -67,11 +95,14 @@ JSValue JSInspectorFrontendHost::showContextMenu(ExecState* execState, const Arg
items.append(new ContextMenuItem(SeparatorType, ContextMenuItemTagNoAction, String()));
else {
ContextMenuAction typedId = static_cast<ContextMenuAction>(ContextMenuItemBaseCustomTag + id.toInt32(execState));
- items.append(new ContextMenuItem(ActionType, typedId, label.toString(execState)));
+ items.append(new ContextMenuItem(ActionType, typedId, ustringToString(label.toString(execState))));
}
}
impl()->showContextMenu(event, items);
+#else
+ UNUSED_PARAM(execState);
+#endif
return jsUndefined();
}
diff --git a/WebCore/bindings/js/JSJavaScriptCallFrameCustom.cpp b/WebCore/bindings/js/JSJavaScriptCallFrameCustom.cpp
index afbdf5d..080f730 100644
--- a/WebCore/bindings/js/JSJavaScriptCallFrameCustom.cpp
+++ b/WebCore/bindings/js/JSJavaScriptCallFrameCustom.cpp
@@ -85,6 +85,12 @@ JSValue JSJavaScriptCallFrame::scopeChain(ExecState* exec) const
return constructArray(exec, list);
}
+JSValue JSJavaScriptCallFrame::scopeType(ExecState*, const ArgList&)
+{
+ // FIXME(37663): implement this method the way it's done in the InjectedScipt.js
+ return jsNull();
+}
+
} // namespace WebCore
#endif // ENABLE(JAVASCRIPT_DEBUGGER)
diff --git a/WebCore/bindings/js/JSLazyEventListener.cpp b/WebCore/bindings/js/JSLazyEventListener.cpp
index 4fbdaa6..1aad7df 100644
--- a/WebCore/bindings/js/JSLazyEventListener.cpp
+++ b/WebCore/bindings/js/JSLazyEventListener.cpp
@@ -79,7 +79,7 @@ JSObject* JSLazyEventListener::initializeJSFunction(ScriptExecutionContext* exec
return 0;
ScriptController* scriptController = frame->script();
- if (!scriptController->canExecuteScripts())
+ if (!scriptController->canExecuteScripts(AboutToExecuteScript))
return 0;
JSDOMGlobalObject* globalObject = toJSDOMGlobalObject(executionContext, isolatedWorld());
@@ -93,17 +93,17 @@ JSObject* JSLazyEventListener::initializeJSFunction(ScriptExecutionContext* exec
return 0;
// FIXME: Is this check needed for non-Document contexts?
ScriptController* script = frame->script();
- if (!script->canExecuteScripts() || script->isPaused())
+ if (!script->canExecuteScripts(AboutToExecuteScript) || script->isPaused())
return 0;
}
ExecState* exec = globalObject->globalExec();
MarkedArgumentBuffer args;
- args.append(jsNontrivialString(exec, m_eventParameterName));
+ args.append(jsNontrivialString(exec, stringToUString(m_eventParameterName)));
args.append(jsString(exec, m_code));
- JSObject* jsFunction = constructFunction(exec, args, Identifier(exec, m_functionName), m_sourceURL, m_lineNumber); // FIXME: is globalExec ok?
+ JSObject* jsFunction = constructFunction(exec, args, Identifier(exec, stringToUString(m_functionName)), stringToUString(m_sourceURL), m_lineNumber); // FIXME: is globalExec ok?
if (exec->hadException()) {
exec->clearException();
return 0;
diff --git a/WebCore/bindings/js/JSLocationCustom.cpp b/WebCore/bindings/js/JSLocationCustom.cpp
index 8599242..e92a750 100644
--- a/WebCore/bindings/js/JSLocationCustom.cpp
+++ b/WebCore/bindings/js/JSLocationCustom.cpp
@@ -39,17 +39,17 @@ using namespace JSC;
namespace WebCore {
-static JSValue nonCachingStaticReplaceFunctionGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot&)
+static JSValue nonCachingStaticReplaceFunctionGetter(ExecState* exec, JSValue, const Identifier& propertyName)
{
return new (exec) NativeFunctionWrapper(exec, exec->lexicalGlobalObject()->prototypeFunctionStructure(), 1, propertyName, jsLocationPrototypeFunctionReplace);
}
-static JSValue nonCachingStaticReloadFunctionGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot&)
+static JSValue nonCachingStaticReloadFunctionGetter(ExecState* exec, JSValue, const Identifier& propertyName)
{
return new (exec) NativeFunctionWrapper(exec, exec->lexicalGlobalObject()->prototypeFunctionStructure(), 0, propertyName, jsLocationPrototypeFunctionReload);
}
-static JSValue nonCachingStaticAssignFunctionGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot&)
+static JSValue nonCachingStaticAssignFunctionGetter(ExecState* exec, JSValue, const Identifier& propertyName)
{
return new (exec) NativeFunctionWrapper(exec, exec->lexicalGlobalObject()->prototypeFunctionStructure(), 1, propertyName, jsLocationPrototypeFunctionAssign);
}
@@ -199,7 +199,7 @@ void JSLocation::setHref(ExecState* exec, JSValue value)
Frame* frame = impl()->frame();
ASSERT(frame);
- KURL url = completeURL(exec, value.toString(exec));
+ KURL url = completeURL(exec, ustringToString(value.toString(exec)));
if (url.isNull())
return;
@@ -215,7 +215,7 @@ void JSLocation::setProtocol(ExecState* exec, JSValue value)
ASSERT(frame);
KURL url = frame->loader()->url();
- if (!url.setProtocol(value.toString(exec))) {
+ if (!url.setProtocol(ustringToString(value.toString(exec)))) {
setDOMException(exec, SYNTAX_ERR);
return;
}
@@ -229,7 +229,7 @@ void JSLocation::setHost(ExecState* exec, JSValue value)
ASSERT(frame);
KURL url = frame->loader()->url();
- url.setHostAndPort(value.toString(exec));
+ url.setHostAndPort(ustringToString(value.toString(exec)));
navigateIfAllowed(exec, frame, url, !frame->script()->anyPageIsProcessingUserGesture(), false);
}
@@ -240,7 +240,7 @@ void JSLocation::setHostname(ExecState* exec, JSValue value)
ASSERT(frame);
KURL url = frame->loader()->url();
- url.setHost(value.toString(exec));
+ url.setHost(ustringToString(value.toString(exec)));
navigateIfAllowed(exec, frame, url, !frame->script()->anyPageIsProcessingUserGesture(), false);
}
@@ -268,7 +268,7 @@ void JSLocation::setPathname(ExecState* exec, JSValue value)
ASSERT(frame);
KURL url = frame->loader()->url();
- url.setPath(value.toString(exec));
+ url.setPath(ustringToString(value.toString(exec)));
navigateIfAllowed(exec, frame, url, !frame->script()->anyPageIsProcessingUserGesture(), false);
}
@@ -279,7 +279,7 @@ void JSLocation::setSearch(ExecState* exec, JSValue value)
ASSERT(frame);
KURL url = frame->loader()->url();
- url.setQuery(value.toString(exec));
+ url.setQuery(ustringToString(value.toString(exec)));
navigateIfAllowed(exec, frame, url, !frame->script()->anyPageIsProcessingUserGesture(), false);
}
@@ -291,7 +291,7 @@ void JSLocation::setHash(ExecState* exec, JSValue value)
KURL url = frame->loader()->url();
String oldFragmentIdentifier = url.fragmentIdentifier();
- String str = value.toString(exec);
+ String str = ustringToString(value.toString(exec));
if (str.startsWith("#"))
str = str.substring(1);
if (equalIgnoringNullity(oldFragmentIdentifier, str))
@@ -307,7 +307,7 @@ JSValue JSLocation::replace(ExecState* exec, const ArgList& args)
if (!frame)
return jsUndefined();
- KURL url = completeURL(exec, args.at(0).toString(exec));
+ KURL url = completeURL(exec, ustringToString(args.at(0).toString(exec)));
if (url.isNull())
return jsUndefined();
@@ -335,7 +335,7 @@ JSValue JSLocation::assign(ExecState* exec, const ArgList& args)
if (!frame)
return jsUndefined();
- KURL url = completeURL(exec, args.at(0).toString(exec));
+ KURL url = completeURL(exec, ustringToString(args.at(0).toString(exec)));
if (url.isNull())
return jsUndefined();
diff --git a/WebCore/bindings/js/JSMessageEventCustom.cpp b/WebCore/bindings/js/JSMessageEventCustom.cpp
index 2e7b2d0..fc1f542 100644
--- a/WebCore/bindings/js/JSMessageEventCustom.cpp
+++ b/WebCore/bindings/js/JSMessageEventCustom.cpp
@@ -72,7 +72,7 @@ JSC::JSValue JSMessageEvent::initMessageEvent(JSC::ExecState* exec, const JSC::A
}
MessageEvent* event = static_cast<MessageEvent*>(this->impl());
- event->initMessageEvent(typeArg, canBubbleArg, cancelableArg, dataArg, originArg, lastEventIdArg, sourceArg, messagePorts.release());
+ event->initMessageEvent(ustringToAtomicString(typeArg), canBubbleArg, cancelableArg, dataArg, ustringToString(originArg), ustringToString(lastEventIdArg), sourceArg, messagePorts.release());
return jsUndefined();
}
diff --git a/WebCore/bindings/js/JSMessagePortCustom.cpp b/WebCore/bindings/js/JSMessagePortCustom.cpp
index 2ee8125..f7c0160 100644
--- a/WebCore/bindings/js/JSMessagePortCustom.cpp
+++ b/WebCore/bindings/js/JSMessagePortCustom.cpp
@@ -58,7 +58,7 @@ JSValue JSMessagePort::addEventListener(ExecState* exec, const ArgList& args)
if (!listener.isObject())
return jsUndefined();
- impl()->addEventListener(args.at(0).toString(exec), JSEventListener::create(asObject(listener), this, false, currentWorld(exec)).get(), args.at(2).toBoolean(exec));
+ impl()->addEventListener(ustringToAtomicString(args.at(0).toString(exec)), JSEventListener::create(asObject(listener), this, false, currentWorld(exec)).get(), args.at(2).toBoolean(exec));
return jsUndefined();
}
@@ -68,7 +68,7 @@ JSValue JSMessagePort::removeEventListener(ExecState* exec, const ArgList& args)
if (!listener.isObject())
return jsUndefined();
- impl()->removeEventListener(args.at(0).toString(exec), JSEventListener::create(asObject(listener), this, false, currentWorld(exec)).get(), args.at(2).toBoolean(exec));
+ impl()->removeEventListener(ustringToAtomicString(args.at(0).toString(exec)), JSEventListener::create(asObject(listener), this, false, currentWorld(exec)).get(), args.at(2).toBoolean(exec));
return jsUndefined();
}
diff --git a/WebCore/bindings/js/JSMimeTypeArrayCustom.cpp b/WebCore/bindings/js/JSMimeTypeArrayCustom.cpp
index c90dadd..bdd6ddb 100644
--- a/WebCore/bindings/js/JSMimeTypeArrayCustom.cpp
+++ b/WebCore/bindings/js/JSMimeTypeArrayCustom.cpp
@@ -30,13 +30,13 @@ using namespace JSC;
bool JSMimeTypeArray::canGetItemsForName(ExecState*, MimeTypeArray* mimeTypeArray, const Identifier& propertyName)
{
- return mimeTypeArray->canGetItemsForName(propertyName);
+ return mimeTypeArray->canGetItemsForName(identifierToAtomicString(propertyName));
}
-JSValue JSMimeTypeArray::nameGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot)
+JSValue JSMimeTypeArray::nameGetter(ExecState* exec, JSValue slotBase, const Identifier& propertyName)
{
- JSMimeTypeArray* thisObj = static_cast<JSMimeTypeArray*>(asObject(slot.slotBase()));
- return toJS(exec, thisObj->impl()->namedItem(propertyName));
+ JSMimeTypeArray* thisObj = static_cast<JSMimeTypeArray*>(asObject(slotBase));
+ return toJS(exec, thisObj->impl()->namedItem(identifierToAtomicString(propertyName)));
}
} // namespace WebCore
diff --git a/WebCore/bindings/js/JSNamedNodeMapCustom.cpp b/WebCore/bindings/js/JSNamedNodeMapCustom.cpp
index d1bbeec..e1c490e 100644
--- a/WebCore/bindings/js/JSNamedNodeMapCustom.cpp
+++ b/WebCore/bindings/js/JSNamedNodeMapCustom.cpp
@@ -35,15 +35,47 @@ using namespace JSC;
namespace WebCore {
+JSValue JSNamedNodeMap::setNamedItem(ExecState* exec, const ArgList& args)
+{
+ NamedNodeMap* imp = static_cast<NamedNodeMap*>(impl());
+ ExceptionCode ec = 0;
+ Node* newNode = toNode(args.at(0));
+
+ if (newNode && newNode->nodeType() == Node::ATTRIBUTE_NODE && imp->element()) {
+ if (!allowSettingSrcToJavascriptURL(exec, imp->element(), newNode->nodeName(), newNode->nodeValue()))
+ return jsNull();
+ }
+
+ JSValue result = toJS(exec, globalObject(), WTF::getPtr(imp->setNamedItem(newNode, ec)));
+ setDOMException(exec, ec);
+ return result;
+}
+
+JSValue JSNamedNodeMap::setNamedItemNS(ExecState* exec, const ArgList& args)
+{
+ NamedNodeMap* imp = static_cast<NamedNodeMap*>(impl());
+ ExceptionCode ec = 0;
+ Node* newNode = toNode(args.at(0));
+
+ if (newNode && newNode->nodeType() == Node::ATTRIBUTE_NODE && imp->element()) {
+ if (!allowSettingSrcToJavascriptURL(exec, imp->element(), newNode->nodeName(), newNode->nodeValue()))
+ return jsNull();
+ }
+
+ JSValue result = toJS(exec, globalObject(), WTF::getPtr(imp->setNamedItemNS(newNode, ec)));
+ setDOMException(exec, ec);
+ return result;
+}
+
bool JSNamedNodeMap::canGetItemsForName(ExecState*, NamedNodeMap* impl, const Identifier& propertyName)
{
- return impl->getNamedItem(propertyName);
+ return impl->getNamedItem(identifierToString(propertyName));
}
-JSValue JSNamedNodeMap::nameGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot)
+JSValue JSNamedNodeMap::nameGetter(ExecState* exec, JSValue slotBase, const Identifier& propertyName)
{
- JSNamedNodeMap* thisObj = static_cast<JSNamedNodeMap*>(asObject(slot.slotBase()));
- return toJS(exec, thisObj->impl()->getNamedItem(propertyName));
+ JSNamedNodeMap* thisObj = static_cast<JSNamedNodeMap*>(asObject(slotBase));
+ return toJS(exec, thisObj->impl()->getNamedItem(identifierToString(propertyName)));
}
void JSNamedNodeMap::markChildren(MarkStack& markStack)
diff --git a/WebCore/bindings/js/JSNodeCustom.cpp b/WebCore/bindings/js/JSNodeCustom.cpp
index 46a30a4..3a07b29 100644
--- a/WebCore/bindings/js/JSNodeCustom.cpp
+++ b/WebCore/bindings/js/JSNodeCustom.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2007, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2007, 2009, 2010 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -34,10 +34,12 @@
#include "DocumentType.h"
#include "Entity.h"
#include "EntityReference.h"
+#include "ExceptionCode.h"
#include "HTMLElement.h"
#include "JSAttr.h"
#include "JSCDATASection.h"
#include "JSComment.h"
+#include "JSDOMBinding.h"
#include "JSDocument.h"
#include "JSDocumentFragment.h"
#include "JSDocumentType.h"
@@ -66,12 +68,53 @@ using namespace JSC;
namespace WebCore {
-typedef int ExpectionCode;
+static inline bool isAttrFrameSrc(Element *element, const String& name)
+{
+ return element && (element->hasTagName(HTMLNames::iframeTag) || element->hasTagName(HTMLNames::frameTag)) && equalIgnoringCase(name, "src");
+}
+
+void JSNode::setNodeValue(JSC::ExecState* exec, JSC::JSValue value)
+{
+ Node* imp = static_cast<Node*>(impl());
+ String nodeValue = valueToStringWithNullCheck(exec, value);
+
+ if (imp->nodeType() == Node::ATTRIBUTE_NODE) {
+ Element* ownerElement = static_cast<Attr*>(impl())->ownerElement();
+ if (ownerElement && !allowSettingSrcToJavascriptURL(exec, ownerElement, imp->nodeName(), nodeValue))
+ return;
+ }
+
+ ExceptionCode ec = 0;
+ imp->setNodeValue(nodeValue, ec);
+ setDOMException(exec, ec);
+}
+
+void JSNode::setTextContent(JSC::ExecState* exec, JSC::JSValue value)
+{
+ Node* imp = static_cast<Node*>(impl());
+ String nodeValue = valueToStringWithNullCheck(exec, value);
+
+ if (imp->nodeType() == Node::ATTRIBUTE_NODE) {
+ Element* ownerElement = static_cast<Attr*>(impl())->ownerElement();
+ if (ownerElement && !allowSettingSrcToJavascriptURL(exec, ownerElement, imp->nodeName(), nodeValue))
+ return;
+ }
+
+ ExceptionCode ec = 0;
+ imp->setTextContent(nodeValue, ec);
+ setDOMException(exec, ec);
+}
JSValue JSNode::insertBefore(ExecState* exec, const ArgList& args)
{
+ Node* imp = static_cast<Node*>(impl());
+ if (imp->nodeType() == Node::ATTRIBUTE_NODE && isAttrFrameSrc(static_cast<Attr*>(impl())->ownerElement(), imp->nodeName())) {
+ setDOMException(exec, NOT_SUPPORTED_ERR);
+ return jsNull();
+ }
+
ExceptionCode ec = 0;
- bool ok = impl()->insertBefore(toNode(args.at(0)), toNode(args.at(1)), ec, true);
+ bool ok = imp->insertBefore(toNode(args.at(0)), toNode(args.at(1)), ec, true);
setDOMException(exec, ec);
if (ok)
return args.at(0);
@@ -80,8 +123,14 @@ JSValue JSNode::insertBefore(ExecState* exec, const ArgList& args)
JSValue JSNode::replaceChild(ExecState* exec, const ArgList& args)
{
+ Node* imp = static_cast<Node*>(impl());
+ if (imp->nodeType() == Node::ATTRIBUTE_NODE && isAttrFrameSrc(static_cast<Attr*>(impl())->ownerElement(), imp->nodeName())) {
+ setDOMException(exec, NOT_SUPPORTED_ERR);
+ return jsNull();
+ }
+
ExceptionCode ec = 0;
- bool ok = impl()->replaceChild(toNode(args.at(0)), toNode(args.at(1)), ec, true);
+ bool ok = imp->replaceChild(toNode(args.at(0)), toNode(args.at(1)), ec, true);
setDOMException(exec, ec);
if (ok)
return args.at(1);
@@ -90,8 +139,14 @@ JSValue JSNode::replaceChild(ExecState* exec, const ArgList& args)
JSValue JSNode::removeChild(ExecState* exec, const ArgList& args)
{
+ Node* imp = static_cast<Node*>(impl());
+ if (imp->nodeType() == Node::ATTRIBUTE_NODE && isAttrFrameSrc(static_cast<Attr*>(impl())->ownerElement(), imp->nodeName())) {
+ setDOMException(exec, NOT_SUPPORTED_ERR);
+ return jsNull();
+ }
+
ExceptionCode ec = 0;
- bool ok = impl()->removeChild(toNode(args.at(0)), ec);
+ bool ok = imp->removeChild(toNode(args.at(0)), ec);
setDOMException(exec, ec);
if (ok)
return args.at(0);
@@ -100,8 +155,14 @@ JSValue JSNode::removeChild(ExecState* exec, const ArgList& args)
JSValue JSNode::appendChild(ExecState* exec, const ArgList& args)
{
+ Node* imp = static_cast<Node*>(impl());
+ if (imp->nodeType() == Node::ATTRIBUTE_NODE && isAttrFrameSrc(static_cast<Attr*>(impl())->ownerElement(), imp->nodeName())) {
+ setDOMException(exec, NOT_SUPPORTED_ERR);
+ return jsNull();
+ }
+
ExceptionCode ec = 0;
- bool ok = impl()->appendChild(toNode(args.at(0)), ec, true);
+ bool ok = imp->appendChild(toNode(args.at(0)), ec, true);
setDOMException(exec, ec);
if (ok)
return args.at(0);
@@ -114,7 +175,7 @@ JSValue JSNode::addEventListener(ExecState* exec, const ArgList& args)
if (!listener.isObject())
return jsUndefined();
- impl()->addEventListener(args.at(0).toString(exec), JSEventListener::create(asObject(listener), this, false, currentWorld(exec)), args.at(2).toBoolean(exec));
+ impl()->addEventListener(ustringToAtomicString(args.at(0).toString(exec)), JSEventListener::create(asObject(listener), this, false, currentWorld(exec)), args.at(2).toBoolean(exec));
return jsUndefined();
}
@@ -124,7 +185,7 @@ JSValue JSNode::removeEventListener(ExecState* exec, const ArgList& args)
if (!listener.isObject())
return jsUndefined();
- impl()->removeEventListener(args.at(0).toString(exec), JSEventListener::create(asObject(listener), this, false, currentWorld(exec)).get(), args.at(2).toBoolean(exec));
+ impl()->removeEventListener(ustringToAtomicString(args.at(0).toString(exec)), JSEventListener::create(asObject(listener), this, false, currentWorld(exec)).get(), args.at(2).toBoolean(exec));
return jsUndefined();
}
@@ -162,6 +223,8 @@ void JSNode::markChildren(MarkStack& markStack)
// 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.
+ // FIXME: In the non-common case of root not having a wrapper, this is still an O(n^2) algorithm,
+ // as we will traverse the whole tree as many times as there are nodes with wrappers in it.
if (node != outermostNodeWithWrapper) {
markDOMNodeWrapper(markStack, m_impl->document(), outermostNodeWithWrapper);
return;
@@ -172,7 +235,7 @@ void JSNode::markChildren(MarkStack& markStack)
markDOMNodeWrapper(markStack, m_impl->document(), nodeToMark);
}
-static ALWAYS_INLINE JSValue createWrapper(ExecState* exec, JSDOMGlobalObject* globalObject, Node* node)
+static ALWAYS_INLINE JSValue createWrapperInline(ExecState* exec, JSDOMGlobalObject* globalObject, Node* node)
{
ASSERT(node);
ASSERT(!getCachedDOMNodeWrapper(exec, node->document(), node));
@@ -228,25 +291,18 @@ static ALWAYS_INLINE JSValue createWrapper(ExecState* exec, JSDOMGlobalObject* g
return wrapper;
}
-
-JSValue toJSNewlyCreated(ExecState* exec, JSDOMGlobalObject* globalObject, Node* node)
+
+JSValue createWrapper(ExecState* exec, JSDOMGlobalObject* globalObject, Node* node)
{
- if (!node)
- return jsNull();
-
- return createWrapper(exec, globalObject, node);
+ return createWrapperInline(exec, globalObject, node);
}
-JSValue toJS(ExecState* exec, JSDOMGlobalObject* globalObject, Node* node)
+JSValue toJSNewlyCreated(ExecState* exec, JSDOMGlobalObject* globalObject, Node* node)
{
if (!node)
return jsNull();
-
- JSNode* wrapper = getCachedDOMNodeWrapper(exec, node->document(), node);
- if (wrapper)
- return wrapper;
-
- return createWrapper(exec, globalObject, node);
+
+ return createWrapperInline(exec, globalObject, node);
}
} // namespace WebCore
diff --git a/WebCore/bindings/js/JSNodeCustom.h b/WebCore/bindings/js/JSNodeCustom.h
new file mode 100644
index 0000000..9d06ae6
--- /dev/null
+++ b/WebCore/bindings/js/JSNodeCustom.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2007, 2009, 2010 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef JSNodeCustom_h
+#define JSNodeCustom_h
+
+#include "JSDOMBinding.h"
+#include <wtf/AlwaysInline.h>
+
+namespace WebCore {
+
+inline JSNode* getCachedDOMNodeWrapper(JSC::ExecState* exec, Document* document, Node* node)
+{
+ if (currentWorld(exec)->isNormal()) {
+ ASSERT(node->wrapper() == (document ? document->getWrapperCache(currentWorld(exec))->get(node) : domObjectWrapperMapFor(exec).get(node)));
+ return static_cast<JSNode*>(node->wrapper());
+ }
+
+ if (document)
+ return document->getWrapperCache(currentWorld(exec))->get(node);
+ return static_cast<JSNode*>(domObjectWrapperMapFor(exec).get(node));
+}
+
+JSC::JSValue createWrapper(JSC::ExecState*, JSDOMGlobalObject*, Node*);
+
+inline JSC::JSValue toJS(JSC::ExecState* exec, JSDOMGlobalObject* globalObject, Node* node)
+{
+ if (!node)
+ return JSC::jsNull();
+
+ JSNode* wrapper = getCachedDOMNodeWrapper(exec, node->document(), node);
+ if (wrapper)
+ return wrapper;
+
+ return createWrapper(exec, globalObject, node);
+}
+
+}
+
+#endif // JSDOMNodeCustom_h
diff --git a/WebCore/bindings/js/JSNodeListCustom.cpp b/WebCore/bindings/js/JSNodeListCustom.cpp
index 2821d01..d013e4f 100644
--- a/WebCore/bindings/js/JSNodeListCustom.cpp
+++ b/WebCore/bindings/js/JSNodeListCustom.cpp
@@ -53,13 +53,13 @@ CallType JSNodeList::getCallData(CallData& callData)
bool JSNodeList::canGetItemsForName(ExecState*, NodeList* impl, const Identifier& propertyName)
{
- return impl->itemWithName(propertyName);
+ return impl->itemWithName(identifierToAtomicString(propertyName));
}
-JSValue JSNodeList::nameGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot)
+JSValue JSNodeList::nameGetter(ExecState* exec, JSValue slotBase, const Identifier& propertyName)
{
- JSNodeList* thisObj = static_cast<JSNodeList*>(asObject(slot.slotBase()));
- return toJS(exec, thisObj->impl()->itemWithName(propertyName));
+ JSNodeList* thisObj = static_cast<JSNodeList*>(asObject(slotBase));
+ return toJS(exec, thisObj->impl()->itemWithName(identifierToAtomicString(propertyName)));
}
} // namespace WebCore
diff --git a/WebCore/bindings/js/JSOptionConstructor.cpp b/WebCore/bindings/js/JSOptionConstructor.cpp
index 995903e..8b29136 100644
--- a/WebCore/bindings/js/JSOptionConstructor.cpp
+++ b/WebCore/bindings/js/JSOptionConstructor.cpp
@@ -51,11 +51,11 @@ static JSObject* constructHTMLOptionElement(ExecState* exec, JSObject* construct
String data;
if (!args.at(0).isUndefined())
- data = args.at(0).toString(exec);
+ data = ustringToString(args.at(0).toString(exec));
String value;
if (!args.at(1).isUndefined())
- value = args.at(1).toString(exec);
+ value = ustringToString(args.at(1).toString(exec));
bool defaultSelected = args.at(2).toBoolean(exec);
bool selected = args.at(3).toBoolean(exec);
diff --git a/WebCore/bindings/js/JSPluginArrayCustom.cpp b/WebCore/bindings/js/JSPluginArrayCustom.cpp
index 81d4295..b232f4d 100644
--- a/WebCore/bindings/js/JSPluginArrayCustom.cpp
+++ b/WebCore/bindings/js/JSPluginArrayCustom.cpp
@@ -30,13 +30,13 @@ using namespace JSC;
bool JSPluginArray::canGetItemsForName(ExecState*, PluginArray* pluginArray, const Identifier& propertyName)
{
- return pluginArray->canGetItemsForName(propertyName);
+ return pluginArray->canGetItemsForName(identifierToAtomicString(propertyName));
}
-JSValue JSPluginArray::nameGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot)
+JSValue JSPluginArray::nameGetter(ExecState* exec, JSValue slotBase, const Identifier& propertyName)
{
- JSPluginArray* thisObj = static_cast<JSPluginArray*>(asObject(slot.slotBase()));
- return toJS(exec, thisObj->impl()->namedItem(propertyName));
+ JSPluginArray* thisObj = static_cast<JSPluginArray*>(asObject(slotBase));
+ return toJS(exec, thisObj->impl()->namedItem(identifierToAtomicString(propertyName)));
}
} // namespace WebCore
diff --git a/WebCore/bindings/js/JSPluginCustom.cpp b/WebCore/bindings/js/JSPluginCustom.cpp
index 555dd9e..9fa0b76 100644
--- a/WebCore/bindings/js/JSPluginCustom.cpp
+++ b/WebCore/bindings/js/JSPluginCustom.cpp
@@ -29,13 +29,13 @@ using namespace JSC;
bool JSPlugin::canGetItemsForName(ExecState*, Plugin* plugin, const Identifier& propertyName)
{
- return plugin->canGetItemsForName(propertyName);
+ return plugin->canGetItemsForName(identifierToAtomicString(propertyName));
}
-JSValue JSPlugin::nameGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot)
+JSValue JSPlugin::nameGetter(ExecState* exec, JSValue slotBase, const Identifier& propertyName)
{
- JSPlugin* thisObj = static_cast<JSPlugin*>(asObject(slot.slotBase()));
- return toJS(exec, thisObj->impl()->namedItem(propertyName));
+ JSPlugin* thisObj = static_cast<JSPlugin*>(asObject(slotBase));
+ return toJS(exec, thisObj->impl()->namedItem(identifierToAtomicString(propertyName)));
}
} // namespace WebCore
diff --git a/WebCore/bindings/js/JSPluginElementFunctions.cpp b/WebCore/bindings/js/JSPluginElementFunctions.cpp
index e927ef1..b20b9a7 100644
--- a/WebCore/bindings/js/JSPluginElementFunctions.cpp
+++ b/WebCore/bindings/js/JSPluginElementFunctions.cpp
@@ -35,7 +35,7 @@ using namespace HTMLNames;
// Runtime object support code for JSHTMLAppletElement, JSHTMLEmbedElement and JSHTMLObjectElement.
-static Instance* pluginInstance(Node* node)
+Instance* pluginInstance(Node* node)
{
if (!node)
return 0;
@@ -49,7 +49,7 @@ static Instance* pluginInstance(Node* node)
return instance;
}
-static RuntimeObjectImp* getRuntimeObject(ExecState* exec, Node* node)
+static RuntimeObject* getRuntimeObject(ExecState* exec, Node* node)
{
Instance* instance = pluginInstance(node);
if (!instance)
@@ -57,19 +57,11 @@ static RuntimeObjectImp* getRuntimeObject(ExecState* exec, Node* node)
return instance->createRuntimeObject(exec);
}
-JSValue runtimeObjectGetter(ExecState* exec, const Identifier&, const PropertySlot& slot)
+JSValue runtimeObjectPropertyGetter(ExecState* exec, JSValue slotBase, const Identifier& propertyName)
{
- JSHTMLElement* thisObj = static_cast<JSHTMLElement*>(asObject(slot.slotBase()));
+ JSHTMLElement* thisObj = static_cast<JSHTMLElement*>(asObject(slotBase));
HTMLElement* element = static_cast<HTMLElement*>(thisObj->impl());
- RuntimeObjectImp* runtimeObject = getRuntimeObject(exec, element);
- return runtimeObject ? runtimeObject : jsUndefined();
-}
-
-JSValue runtimeObjectPropertyGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot)
-{
- JSHTMLElement* thisObj = static_cast<JSHTMLElement*>(asObject(slot.slotBase()));
- HTMLElement* element = static_cast<HTMLElement*>(thisObj->impl());
- RuntimeObjectImp* runtimeObject = getRuntimeObject(exec, element);
+ RuntimeObject* runtimeObject = getRuntimeObject(exec, element);
if (!runtimeObject)
return jsUndefined();
return runtimeObject->get(exec, propertyName);
@@ -77,7 +69,7 @@ JSValue runtimeObjectPropertyGetter(ExecState* exec, const Identifier& propertyN
bool runtimeObjectCustomGetOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot, JSHTMLElement* element)
{
- RuntimeObjectImp* runtimeObject = getRuntimeObject(exec, element->impl());
+ RuntimeObject* runtimeObject = getRuntimeObject(exec, element->impl());
if (!runtimeObject)
return false;
if (!runtimeObject->hasProperty(exec, propertyName))
@@ -88,7 +80,7 @@ bool runtimeObjectCustomGetOwnPropertySlot(ExecState* exec, const Identifier& pr
bool runtimeObjectCustomGetOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor, JSHTMLElement* element)
{
- RuntimeObjectImp* runtimeObject = getRuntimeObject(exec, element->impl());
+ RuntimeObject* runtimeObject = getRuntimeObject(exec, element->impl());
if (!runtimeObject)
return false;
if (!runtimeObject->hasProperty(exec, propertyName))
@@ -104,7 +96,7 @@ bool runtimeObjectCustomGetOwnPropertyDescriptor(ExecState* exec, const Identifi
bool runtimeObjectCustomPut(ExecState* exec, const Identifier& propertyName, JSValue value, HTMLElement* element, PutPropertySlot& slot)
{
- RuntimeObjectImp* runtimeObject = getRuntimeObject(exec, element);
+ RuntimeObject* runtimeObject = getRuntimeObject(exec, element);
if (!runtimeObject)
return 0;
if (!runtimeObject->hasProperty(exec, propertyName))
diff --git a/WebCore/bindings/js/JSPluginElementFunctions.h b/WebCore/bindings/js/JSPluginElementFunctions.h
index a5a323a..736ace9 100644
--- a/WebCore/bindings/js/JSPluginElementFunctions.h
+++ b/WebCore/bindings/js/JSPluginElementFunctions.h
@@ -22,6 +22,12 @@
#include "JSDOMBinding.h"
+namespace JSC {
+namespace Bindings {
+class Instance;
+}
+}
+
namespace WebCore {
class HTMLElement;
@@ -29,9 +35,9 @@ namespace WebCore {
class Node;
// Runtime object support code for JSHTMLAppletElement, JSHTMLEmbedElement and JSHTMLObjectElement.
+ JSC::Bindings::Instance* pluginInstance(Node*);
- JSC::JSValue runtimeObjectGetter(JSC::ExecState*, const JSC::Identifier&, const JSC::PropertySlot&);
- JSC::JSValue runtimeObjectPropertyGetter(JSC::ExecState*, const JSC::Identifier&, const JSC::PropertySlot&);
+ JSC::JSValue runtimeObjectPropertyGetter(JSC::ExecState*, JSC::JSValue, const JSC::Identifier&);
bool runtimeObjectCustomGetOwnPropertySlot(JSC::ExecState*, const JSC::Identifier&, JSC::PropertySlot&, JSHTMLElement*);
bool runtimeObjectCustomGetOwnPropertyDescriptor(JSC::ExecState*, const JSC::Identifier&, JSC::PropertyDescriptor&, JSHTMLElement*);
bool runtimeObjectCustomPut(JSC::ExecState*, const JSC::Identifier&, JSC::JSValue, HTMLElement*, JSC::PutPropertySlot&);
diff --git a/WebCore/bindings/js/JSPopStateEventCustom.cpp b/WebCore/bindings/js/JSPopStateEventCustom.cpp
index 3f5fd7e..ce430ab 100644
--- a/WebCore/bindings/js/JSPopStateEventCustom.cpp
+++ b/WebCore/bindings/js/JSPopStateEventCustom.cpp
@@ -41,7 +41,7 @@ JSValue JSPopStateEvent::initPopStateEvent(ExecState* exec, const ArgList& args)
RefPtr<SerializedScriptValue> stateObjectArg = SerializedScriptValue::create(exec, args.at(3));
PopStateEvent* event = static_cast<PopStateEvent*>(impl());
- event->initPopStateEvent(typeArg, canBubbleArg, cancelableArg, stateObjectArg.release());
+ event->initPopStateEvent(ustringToAtomicString(typeArg), canBubbleArg, cancelableArg, stateObjectArg.release());
return jsUndefined();
}
diff --git a/WebCore/bindings/js/JSSQLResultSetRowListCustom.cpp b/WebCore/bindings/js/JSSQLResultSetRowListCustom.cpp
index f40956e..0039a05 100644
--- a/WebCore/bindings/js/JSSQLResultSetRowListCustom.cpp
+++ b/WebCore/bindings/js/JSSQLResultSetRowListCustom.cpp
@@ -74,7 +74,7 @@ JSValue JSSQLResultSetRowList::item(ExecState* exec, const ArgList& args)
ASSERT_NOT_REACHED();
}
- object->putDirect(Identifier(exec, m_impl->columnNames()[i]), jsValue, DontDelete | ReadOnly);
+ object->putDirect(Identifier(exec, stringToUString(m_impl->columnNames()[i])), jsValue, DontDelete | ReadOnly);
}
return object;
diff --git a/WebCore/bindings/js/JSSQLTransactionCustom.cpp b/WebCore/bindings/js/JSSQLTransactionCustom.cpp
index e022401..81e6c63 100644
--- a/WebCore/bindings/js/JSSQLTransactionCustom.cpp
+++ b/WebCore/bindings/js/JSSQLTransactionCustom.cpp
@@ -49,7 +49,7 @@ JSValue JSSQLTransaction::executeSql(ExecState* exec, const ArgList& args)
return jsUndefined();
}
- String sqlStatement = args.at(0).toString(exec);
+ String sqlStatement = ustringToString(args.at(0).toString(exec));
if (exec->hadException())
return jsUndefined();
@@ -80,7 +80,7 @@ JSValue JSSQLTransaction::executeSql(ExecState* exec, const ArgList& args)
sqlValues.append(value.uncheckedGetNumber());
else {
// Convert the argument to a string and append it
- sqlValues.append(value.toString(exec));
+ sqlValues.append(ustringToString(value.toString(exec)));
if (exec->hadException())
return jsUndefined();
}
diff --git a/WebCore/bindings/js/JSSVGElementInstanceCustom.cpp b/WebCore/bindings/js/JSSVGElementInstanceCustom.cpp
index b3bded5..fdcab06 100644
--- a/WebCore/bindings/js/JSSVGElementInstanceCustom.cpp
+++ b/WebCore/bindings/js/JSSVGElementInstanceCustom.cpp
@@ -52,7 +52,7 @@ JSValue JSSVGElementInstance::addEventListener(ExecState* exec, const ArgList& a
if (!listener.isObject())
return jsUndefined();
- impl()->addEventListener(args.at(0).toString(exec), JSEventListener::create(asObject(listener), this, false, currentWorld(exec)), args.at(2).toBoolean(exec));
+ impl()->addEventListener(ustringToAtomicString(args.at(0).toString(exec)), JSEventListener::create(asObject(listener), this, false, currentWorld(exec)), args.at(2).toBoolean(exec));
return jsUndefined();
}
@@ -62,7 +62,7 @@ JSValue JSSVGElementInstance::removeEventListener(ExecState* exec, const ArgList
if (!listener.isObject())
return jsUndefined();
- impl()->removeEventListener(args.at(0).toString(exec), JSEventListener::create(asObject(listener), this, false, currentWorld(exec)).get(), args.at(2).toBoolean(exec));
+ impl()->removeEventListener(ustringToAtomicString(args.at(0).toString(exec)), JSEventListener::create(asObject(listener), this, false, currentWorld(exec)).get(), args.at(2).toBoolean(exec));
return jsUndefined();
}
diff --git a/WebCore/bindings/js/JSScriptProfileNodeCustom.cpp b/WebCore/bindings/js/JSScriptProfileNodeCustom.cpp
new file mode 100644
index 0000000..127227e
--- /dev/null
+++ b/WebCore/bindings/js/JSScriptProfileNodeCustom.cpp
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include "JSScriptProfileNode.h"
+
+#if ENABLE(JAVASCRIPT_DEBUGGER)
+#include <profiler/ProfileNode.h>
+#endif
+
+#include <runtime/JSArray.h>
+
+using namespace JSC;
+
+namespace WebCore {
+
+#if ENABLE(JAVASCRIPT_DEBUGGER)
+
+JSValue JSScriptProfileNode::callUID(ExecState* exec) const
+{
+ JSValue result = jsNumber(exec, impl()->callIdentifier().hash());
+ return result;
+}
+
+typedef Vector<RefPtr<ProfileNode> > ProfileNodesList;
+
+JSValue JSScriptProfileNode::children(ExecState* exec) const
+{
+ const ProfileNodesList& children = impl()->children();
+ MarkedArgumentBuffer list;
+
+ ProfileNodesList::const_iterator end = children.end();
+ for (ProfileNodesList::const_iterator iter = children.begin(); iter != end; ++iter)
+ list.append(toJS(exec, iter->get()));
+
+ return constructArray(exec, list);
+}
+
+#endif
+
+} // namespace WebCore
diff --git a/WebCore/bindings/js/JSSharedWorkerConstructor.cpp b/WebCore/bindings/js/JSSharedWorkerConstructor.cpp
index c05b3d2..a66b1f7 100644
--- a/WebCore/bindings/js/JSSharedWorkerConstructor.cpp
+++ b/WebCore/bindings/js/JSSharedWorkerConstructor.cpp
@@ -71,7 +71,7 @@ static JSObject* constructSharedWorker(ExecState* exec, JSObject* constructor, c
// FIXME: We need to use both the dynamic scope and the lexical scope (dynamic scope for resolving the worker URL)
DOMWindow* window = asJSDOMWindow(exec->lexicalGlobalObject())->impl();
ExceptionCode ec = 0;
- RefPtr<SharedWorker> worker = SharedWorker::create(scriptURL, name, window->document(), ec);
+ RefPtr<SharedWorker> worker = SharedWorker::create(ustringToString(scriptURL), ustringToString(name), window->document(), ec);
setDOMException(exec, ec);
return asObject(toJS(exec, jsConstructor->globalObject(), worker.release()));
diff --git a/WebCore/bindings/js/JSStorageCustom.cpp b/WebCore/bindings/js/JSStorageCustom.cpp
index 3cfe22e..6a126b7 100644
--- a/WebCore/bindings/js/JSStorageCustom.cpp
+++ b/WebCore/bindings/js/JSStorageCustom.cpp
@@ -38,13 +38,13 @@ namespace WebCore {
bool JSStorage::canGetItemsForName(ExecState*, Storage* impl, const Identifier& propertyName)
{
- return impl->contains(propertyName);
+ return impl->contains(identifierToString(propertyName));
}
-JSValue JSStorage::nameGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot)
+JSValue JSStorage::nameGetter(ExecState* exec, JSValue slotBase, const Identifier& propertyName)
{
- JSStorage* thisObj = static_cast<JSStorage*>(asObject(slot.slotBase()));
- return jsStringOrNull(exec, thisObj->impl()->getItem(propertyName));
+ JSStorage* thisObj = static_cast<JSStorage*>(asObject(slotBase));
+ return jsStringOrNull(exec, thisObj->impl()->getItem(identifierToString(propertyName)));
}
bool JSStorage::deleteProperty(ExecState* exec, const Identifier& propertyName)
@@ -60,7 +60,7 @@ bool JSStorage::deleteProperty(ExecState* exec, const Identifier& propertyName)
if (prototype.isObject() && asObject(prototype)->hasProperty(exec, propertyName))
return false;
- m_impl->removeItem(propertyName);
+ m_impl->removeItem(identifierToString(propertyName));
return true;
}
@@ -68,7 +68,7 @@ void JSStorage::getOwnPropertyNames(ExecState* exec, PropertyNameArray& property
{
unsigned length = m_impl->length();
for (unsigned i = 0; i < length; ++i)
- propertyNames.add(Identifier(exec, m_impl->key(i)));
+ propertyNames.add(Identifier(exec, stringToUString(m_impl->key(i))));
Base::getOwnPropertyNames(exec, propertyNames, mode);
}
@@ -86,12 +86,12 @@ bool JSStorage::putDelegate(ExecState* exec, const Identifier& propertyName, JSV
if (prototype.isObject() && asObject(prototype)->hasProperty(exec, propertyName))
return false;
- String stringValue = value.toString(exec);
+ String stringValue = ustringToString(value.toString(exec));
if (exec->hadException())
return true;
ExceptionCode ec = 0;
- impl()->setItem(propertyName, stringValue, ec);
+ impl()->setItem(identifierToString(propertyName), stringValue, ec);
setDOMException(exec, ec);
return true;
diff --git a/WebCore/bindings/js/JSStyleSheetListCustom.cpp b/WebCore/bindings/js/JSStyleSheetListCustom.cpp
index 7bf9389..eb96a67 100644
--- a/WebCore/bindings/js/JSStyleSheetListCustom.cpp
+++ b/WebCore/bindings/js/JSStyleSheetListCustom.cpp
@@ -49,13 +49,13 @@ void JSStyleSheetList::markChildren(MarkStack& markStack)
bool JSStyleSheetList::canGetItemsForName(ExecState*, StyleSheetList* styleSheetList, const Identifier& propertyName)
{
- return styleSheetList->getNamedItem(propertyName);
+ return styleSheetList->getNamedItem(identifierToString(propertyName));
}
-JSValue JSStyleSheetList::nameGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot)
+JSValue JSStyleSheetList::nameGetter(ExecState* exec, JSValue slotBase, const Identifier& propertyName)
{
- JSStyleSheetList* thisObj = static_cast<JSStyleSheetList*>(asObject(slot.slotBase()));
- HTMLStyleElement* element = thisObj->impl()->getNamedItem(propertyName);
+ JSStyleSheetList* thisObj = static_cast<JSStyleSheetList*>(asObject(slotBase));
+ HTMLStyleElement* element = thisObj->impl()->getNamedItem(identifierToString(propertyName));
ASSERT(element);
return toJS(exec, element->sheet());
}
diff --git a/WebCore/bindings/js/JSWebGLArrayBufferConstructor.cpp b/WebCore/bindings/js/JSWebGLArrayBufferConstructor.cpp
index 9742db7..8671908 100644
--- a/WebCore/bindings/js/JSWebGLArrayBufferConstructor.cpp
+++ b/WebCore/bindings/js/JSWebGLArrayBufferConstructor.cpp
@@ -30,7 +30,6 @@
#include "JSWebGLArrayBufferConstructor.h"
#include "Document.h"
-#include "WebGLArrayBuffer.h"
#include "JSWebGLArrayBuffer.h"
namespace WebCore {
@@ -56,7 +55,12 @@ static JSObject* constructCanvasArrayBuffer(ExecState* exec, JSObject* construct
if (isnan(size))
size = 0;
}
- return asObject(toJS(exec, jsConstructor->globalObject(), WebGLArrayBuffer::create(size)));
+ RefPtr<WebGLArrayBuffer> buffer = WebGLArrayBuffer::create(size, 1);
+ if (!buffer.get()){
+ setDOMException(exec, INDEX_SIZE_ERR);
+ return 0;
+ }
+ return asObject(toJS(exec, jsConstructor->globalObject(), buffer.get()));
}
JSC::ConstructType JSWebGLArrayBufferConstructor::getConstructData(JSC::ConstructData& constructData)
diff --git a/WebCore/bindings/js/JSWebGLArrayBufferConstructor.h b/WebCore/bindings/js/JSWebGLArrayBufferConstructor.h
index 98e364b..c7a927e 100644
--- a/WebCore/bindings/js/JSWebGLArrayBufferConstructor.h
+++ b/WebCore/bindings/js/JSWebGLArrayBufferConstructor.h
@@ -30,6 +30,7 @@
#include "JSDocument.h"
#include "JSWebGLArrayBuffer.h"
#include <runtime/Error.h>
+#include "WebGLArrayBuffer.h"
namespace WebCore {
@@ -51,24 +52,30 @@ namespace WebCore {
if (args.size() < 1)
return C::create(0, 0, 0);
+ if (args.size() > 1 && !args.at(0).isObject())
+ // Invalid first argument
+ return 0;
+
if (args.at(0).isObject()) {
RefPtr<WebGLArrayBuffer> buffer = toWebGLArrayBuffer(args.at(0));
if (buffer) {
- int offset = (args.size() > 1) ? args.at(1).toInt32(exec) : 0;
- unsigned int length = (args.size() > 2) ? static_cast<unsigned int>(args.at(2).toInt32(exec)) : 0;
+ unsigned offset = (args.size() > 1) ? args.at(1).toUInt32(exec) : 0;
+ unsigned int length = (buffer->byteLength() - offset) / sizeof(T);
+ if (args.size() > 2)
+ length = args.at(2).toUInt32(exec);
return C::create(buffer, offset, length);
}
JSC::JSObject* array = asObject(args.at(0));
- int length = array->get(exec, JSC::Identifier(exec, "length")).toInt32(exec);
+ unsigned length = array->get(exec, JSC::Identifier(exec, "length")).toUInt32(exec);
void* tempValues;
- if (!tryFastMalloc(length * sizeof(T)).getValue(tempValues)) {
+ if (!tryFastCalloc(length, sizeof(T)).getValue(tempValues)) {
throwError(exec, JSC::GeneralError);
return 0;
}
OwnFastMallocPtr<T> values(static_cast<T*>(tempValues));
- for (int i = 0; i < length; ++i) {
+ for (unsigned i = 0; i < length; ++i) {
JSC::JSValue v = array->get(exec, i);
if (exec->hadException())
return 0;
@@ -78,7 +85,7 @@ namespace WebCore {
return C::create(values.get(), length);
}
- unsigned size = static_cast<unsigned>(args.at(0).toInt32(exec));
+ unsigned size = args.at(0).toUInt32(exec);
return C::create(size);
}
diff --git a/WebCore/bindings/js/JSWebGLArrayCustom.cpp b/WebCore/bindings/js/JSWebGLArrayCustom.cpp
index 9018544..d111d4e 100644
--- a/WebCore/bindings/js/JSWebGLArrayCustom.cpp
+++ b/WebCore/bindings/js/JSWebGLArrayCustom.cpp
@@ -67,6 +67,27 @@ JSC::JSValue toJS(JSC::ExecState* exec, JSDOMGlobalObject* globalObject, WebGLAr
return jsUndefined();
}
+JSValue JSWebGLArray::slice(ExecState* exec, const ArgList& args)
+{
+ WebGLArray* array = reinterpret_cast<WebGLArray*>(impl());
+
+ int start, end;
+ switch (args.size()) {
+ case 0:
+ start = 0;
+ end = array->length();
+ break;
+ case 1:
+ start = args.at(0).toInt32(exec);
+ end = array->length();
+ break;
+ default:
+ start = args.at(0).toInt32(exec);
+ end = args.at(1).toInt32(exec);
+ }
+ return toJS(exec, globalObject(), array->slice(start, end));
+}
+
} // namespace WebCore
#endif // ENABLE(3D_CANVAS)
diff --git a/WebCore/bindings/js/JSWebGLArrayHelper.h b/WebCore/bindings/js/JSWebGLArrayHelper.h
index 3326d76..481c68f 100644
--- a/WebCore/bindings/js/JSWebGLArrayHelper.h
+++ b/WebCore/bindings/js/JSWebGLArrayHelper.h
@@ -43,14 +43,16 @@ JSC::JSValue setWebGLArrayFromArray(JSC::ExecState* exec, T* webGLArray, JSC::Ar
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;
+ uint32_t offset = 0;
if (args.size() == 2)
offset = args.at(1).toInt32(exec);
- int length = array->get(exec, JSC::Identifier(exec, "length")).toInt32(exec);
- if (offset + length > webGLArray->length())
+ uint32_t length = array->get(exec, JSC::Identifier(exec, "length")).toInt32(exec);
+ if (offset > webGLArray->length() ||
+ offset + length > webGLArray->length() ||
+ offset + length < offset)
setDOMException(exec, INDEX_SIZE_ERR);
else {
- for (int i = 0; i < length; i++) {
+ for (uint32_t i = 0; i < length; i++) {
JSC::JSValue v = array->get(exec, i);
if (exec->hadException())
return JSC::jsUndefined();
diff --git a/WebCore/bindings/js/JSWebGLByteArrayConstructor.cpp b/WebCore/bindings/js/JSWebGLByteArrayConstructor.cpp
index 7db710f..f76fb1d 100644
--- a/WebCore/bindings/js/JSWebGLByteArrayConstructor.cpp
+++ b/WebCore/bindings/js/JSWebGLByteArrayConstructor.cpp
@@ -53,6 +53,10 @@ static JSObject* constructCanvasByteArray(ExecState* exec, JSObject* constructor
{
JSWebGLByteArrayConstructor* jsConstructor = static_cast<JSWebGLByteArrayConstructor*>(constructor);
RefPtr<WebGLByteArray> array = static_cast<WebGLByteArray*>(construct<WebGLByteArray, signed char>(exec, args).get());
+ if (!array.get()) {
+ setDOMException(exec, INDEX_SIZE_ERR);
+ return 0;
+ }
return asObject(toJS(exec, jsConstructor->globalObject(), array.get()));
}
diff --git a/WebCore/bindings/js/JSWebGLFloatArrayConstructor.cpp b/WebCore/bindings/js/JSWebGLFloatArrayConstructor.cpp
index 707fe56..e6375ac 100644
--- a/WebCore/bindings/js/JSWebGLFloatArrayConstructor.cpp
+++ b/WebCore/bindings/js/JSWebGLFloatArrayConstructor.cpp
@@ -53,6 +53,10 @@ static JSObject* constructCanvasFloatArray(ExecState* exec, JSObject* constructo
{
JSWebGLFloatArrayConstructor* jsConstructor = static_cast<JSWebGLFloatArrayConstructor*>(constructor);
RefPtr<WebGLFloatArray> array = static_cast<WebGLFloatArray*>(construct<WebGLFloatArray, float>(exec, args).get());
+ if (!array.get()) {
+ setDOMException(exec, INDEX_SIZE_ERR);
+ return 0;
+ }
return asObject(toJS(exec, jsConstructor->globalObject(), array.get()));
}
diff --git a/WebCore/bindings/js/JSWebGLIntArrayConstructor.cpp b/WebCore/bindings/js/JSWebGLIntArrayConstructor.cpp
index f2a0922..5b14803 100644
--- a/WebCore/bindings/js/JSWebGLIntArrayConstructor.cpp
+++ b/WebCore/bindings/js/JSWebGLIntArrayConstructor.cpp
@@ -53,6 +53,10 @@ static JSObject* constructCanvasIntArray(ExecState* exec, JSObject* constructor,
{
JSWebGLIntArrayConstructor* jsConstructor = static_cast<JSWebGLIntArrayConstructor*>(constructor);
RefPtr<WebGLIntArray> array = static_cast<WebGLIntArray*>(construct<WebGLIntArray, int>(exec, args).get());
+ if (!array.get()) {
+ setDOMException(exec, INDEX_SIZE_ERR);
+ return 0;
+ }
return asObject(toJS(exec, jsConstructor->globalObject(), array.get()));
}
diff --git a/WebCore/bindings/js/JSWebGLShortArrayConstructor.cpp b/WebCore/bindings/js/JSWebGLShortArrayConstructor.cpp
index 74bfe5c..a33779b 100644
--- a/WebCore/bindings/js/JSWebGLShortArrayConstructor.cpp
+++ b/WebCore/bindings/js/JSWebGLShortArrayConstructor.cpp
@@ -54,6 +54,10 @@ static JSObject* constructCanvasShortArray(ExecState* exec, JSObject* constructo
{
JSWebGLShortArrayConstructor* jsConstructor = static_cast<JSWebGLShortArrayConstructor*>(constructor);
RefPtr<WebGLShortArray> array = static_cast<WebGLShortArray*>(construct<WebGLShortArray, short>(exec, args).get());
+ if (!array.get()) {
+ setDOMException(exec, INDEX_SIZE_ERR);
+ return 0;
+ }
return asObject(toJS(exec, jsConstructor->globalObject(), array.get()));
}
diff --git a/WebCore/bindings/js/JSWebGLUnsignedByteArrayConstructor.cpp b/WebCore/bindings/js/JSWebGLUnsignedByteArrayConstructor.cpp
index d5597ce..dcb940e 100644
--- a/WebCore/bindings/js/JSWebGLUnsignedByteArrayConstructor.cpp
+++ b/WebCore/bindings/js/JSWebGLUnsignedByteArrayConstructor.cpp
@@ -30,6 +30,7 @@
#include "JSWebGLUnsignedByteArrayConstructor.h"
#include "Document.h"
+#include "ExceptionCode.h"
#include "WebGLUnsignedByteArray.h"
#include "JSWebGLArrayBuffer.h"
#include "JSWebGLArrayBufferConstructor.h"
@@ -53,6 +54,10 @@ static JSObject* constructCanvasUnsignedByteArray(ExecState* exec, JSObject* con
{
JSWebGLUnsignedByteArrayConstructor* jsConstructor = static_cast<JSWebGLUnsignedByteArrayConstructor*>(constructor);
RefPtr<WebGLUnsignedByteArray> array = static_cast<WebGLUnsignedByteArray*>(construct<WebGLUnsignedByteArray, unsigned char>(exec, args).get());
+ if (!array.get()) {
+ setDOMException(exec, INDEX_SIZE_ERR);
+ return 0;
+ }
return asObject(toJS(exec, jsConstructor->globalObject(), array.get()));
}
diff --git a/WebCore/bindings/js/JSWebGLUnsignedIntArrayConstructor.cpp b/WebCore/bindings/js/JSWebGLUnsignedIntArrayConstructor.cpp
index 6fafa81..23fccce 100644
--- a/WebCore/bindings/js/JSWebGLUnsignedIntArrayConstructor.cpp
+++ b/WebCore/bindings/js/JSWebGLUnsignedIntArrayConstructor.cpp
@@ -53,6 +53,10 @@ static JSObject* constructCanvasUnsignedIntArray(ExecState* exec, JSObject* cons
{
JSWebGLUnsignedIntArrayConstructor* jsConstructor = static_cast<JSWebGLUnsignedIntArrayConstructor*>(constructor);
RefPtr<WebGLUnsignedIntArray> array = static_cast<WebGLUnsignedIntArray*>(construct<WebGLUnsignedIntArray, unsigned int>(exec, args).get());
+ if (!array.get()) {
+ setDOMException(exec, INDEX_SIZE_ERR);
+ return 0;
+ }
return asObject(toJS(exec, jsConstructor->globalObject(), array.get()));
}
diff --git a/WebCore/bindings/js/JSWebGLUnsignedShortArrayConstructor.cpp b/WebCore/bindings/js/JSWebGLUnsignedShortArrayConstructor.cpp
index deaeffd..d8c2cfb 100644
--- a/WebCore/bindings/js/JSWebGLUnsignedShortArrayConstructor.cpp
+++ b/WebCore/bindings/js/JSWebGLUnsignedShortArrayConstructor.cpp
@@ -53,6 +53,10 @@ static JSObject* constructCanvasUnsignedShortArray(ExecState* exec, JSObject* co
{
JSWebGLUnsignedShortArrayConstructor* jsConstructor = static_cast<JSWebGLUnsignedShortArrayConstructor*>(constructor);
RefPtr<WebGLUnsignedShortArray> array = static_cast<WebGLUnsignedShortArray*>(construct<WebGLUnsignedShortArray, unsigned short>(exec, args).get());
+ if (!array.get()) {
+ setDOMException(exec, INDEX_SIZE_ERR);
+ return 0;
+ }
return asObject(toJS(exec, jsConstructor->globalObject(), array.get()));
}
diff --git a/WebCore/bindings/js/JSWebKitCSSMatrixConstructor.cpp b/WebCore/bindings/js/JSWebKitCSSMatrixConstructor.cpp
index bc05250..baf174e 100644
--- a/WebCore/bindings/js/JSWebKitCSSMatrixConstructor.cpp
+++ b/WebCore/bindings/js/JSWebKitCSSMatrixConstructor.cpp
@@ -47,7 +47,7 @@ static JSObject* constructWebKitCSSMatrix(ExecState* exec, JSObject* constructor
JSWebKitCSSMatrixConstructor* jsConstructor = static_cast<JSWebKitCSSMatrixConstructor*>(constructor);
String s;
if (args.size() >= 1)
- s = args.at(0).toString(exec);
+ s = ustringToString(args.at(0).toString(exec));
ExceptionCode ec = 0;
RefPtr<WebKitCSSMatrix> matrix = WebKitCSSMatrix::create(s, ec);
diff --git a/WebCore/bindings/js/JSWebSocketConstructor.cpp b/WebCore/bindings/js/JSWebSocketConstructor.cpp
index 5b34765..57b7477 100644
--- a/WebCore/bindings/js/JSWebSocketConstructor.cpp
+++ b/WebCore/bindings/js/JSWebSocketConstructor.cpp
@@ -64,7 +64,7 @@ static JSObject* constructWebSocket(ExecState* exec, JSObject* constructor, cons
if (args.size() == 0)
return throwError(exec, SyntaxError, "Not enough arguments");
- const String& urlString = args.at(0).toString(exec);
+ const String& urlString = ustringToString(args.at(0).toString(exec));
if (exec->hadException())
return throwError(exec, SyntaxError, "wrong URL");
const KURL& url = context->completeURL(urlString);
@@ -73,7 +73,7 @@ static JSObject* constructWebSocket(ExecState* exec, JSObject* constructor, cons
if (args.size() < 2)
webSocket->connect(url, ec);
else {
- const String& protocol = args.at(1).toString(exec);
+ const String& protocol = ustringToString(args.at(1).toString(exec));
if (exec->hadException())
return 0;
webSocket->connect(url, protocol, ec);
diff --git a/WebCore/bindings/js/JSWebSocketCustom.cpp b/WebCore/bindings/js/JSWebSocketCustom.cpp
index d610f01..18f4183 100644
--- a/WebCore/bindings/js/JSWebSocketCustom.cpp
+++ b/WebCore/bindings/js/JSWebSocketCustom.cpp
@@ -50,7 +50,7 @@ JSValue JSWebSocket::send(ExecState* exec, const ArgList& args)
if (args.size() < 1)
return throwError(exec, SyntaxError, "Not enough arguments");
- const String& msg = args.at(0).toString(exec);
+ const String& msg = ustringToString(args.at(0).toString(exec));
if (exec->hadException())
return throwError(exec, SyntaxError, "bad message data.");
ExceptionCode ec = 0;
@@ -65,7 +65,7 @@ JSValue JSWebSocket::addEventListener(ExecState* exec, const ArgList& args)
if (!listener.isObject())
return jsUndefined();
- impl()->addEventListener(args.at(0).toString(exec), JSEventListener::create(asObject(listener), this, false, currentWorld(exec)), args.at(2).toBoolean(exec));
+ impl()->addEventListener(ustringToAtomicString(args.at(0).toString(exec)), JSEventListener::create(asObject(listener), this, false, currentWorld(exec)), args.at(2).toBoolean(exec));
return jsUndefined();
}
@@ -75,7 +75,7 @@ JSValue JSWebSocket::removeEventListener(ExecState* exec, const ArgList& args)
if (!listener.isObject())
return jsUndefined();
- impl()->removeEventListener(args.at(0).toString(exec), JSEventListener::create(asObject(listener), this, false, currentWorld(exec)).get(), args.at(2).toBoolean(exec));
+ impl()->removeEventListener(ustringToAtomicString(args.at(0).toString(exec)), JSEventListener::create(asObject(listener), this, false, currentWorld(exec)).get(), args.at(2).toBoolean(exec));
return jsUndefined();
}
diff --git a/WebCore/bindings/js/JSWorkerConstructor.cpp b/WebCore/bindings/js/JSWorkerConstructor.cpp
index 69c05e7..43c685e 100644
--- a/WebCore/bindings/js/JSWorkerConstructor.cpp
+++ b/WebCore/bindings/js/JSWorkerConstructor.cpp
@@ -64,7 +64,7 @@ static JSObject* constructWorker(ExecState* exec, JSObject* constructor, const A
DOMWindow* window = asJSDOMWindow(exec->lexicalGlobalObject())->impl();
ExceptionCode ec = 0;
- RefPtr<Worker> worker = Worker::create(scriptURL, window->document(), ec);
+ RefPtr<Worker> worker = Worker::create(ustringToString(scriptURL), window->document(), ec);
if (ec) {
setDOMException(exec, ec);
return 0;
diff --git a/WebCore/bindings/js/JSWorkerContextCustom.cpp b/WebCore/bindings/js/JSWorkerContextCustom.cpp
index bf9409c..0a9489b 100644
--- a/WebCore/bindings/js/JSWorkerContextCustom.cpp
+++ b/WebCore/bindings/js/JSWorkerContextCustom.cpp
@@ -105,18 +105,13 @@ JSValue JSWorkerContext::importScripts(ExecState* exec, const ArgList& args)
Vector<String> urls;
for (unsigned i = 0; i < args.size(); i++) {
- urls.append(args.at(i).toString(exec));
+ urls.append(ustringToString(args.at(i).toString(exec)));
if (exec->hadException())
return jsUndefined();
}
ExceptionCode ec = 0;
- int signedLineNumber;
- intptr_t sourceID;
- UString sourceURL;
- JSValue function;
- exec->interpreter()->retrieveLastCaller(exec, signedLineNumber, sourceID, sourceURL, function);
- impl()->importScripts(urls, sourceURL, signedLineNumber >= 0 ? signedLineNumber : 0, ec);
+ impl()->importScripts(urls, ec);
setDOMException(exec, ec);
return jsUndefined();
}
@@ -127,7 +122,7 @@ JSValue JSWorkerContext::addEventListener(ExecState* exec, const ArgList& args)
if (!listener.isObject())
return jsUndefined();
- impl()->addEventListener(args.at(0).toString(exec), JSEventListener::create(asObject(listener), this, false, currentWorld(exec)), args.at(2).toBoolean(exec));
+ impl()->addEventListener(ustringToAtomicString(args.at(0).toString(exec)), JSEventListener::create(asObject(listener), this, false, currentWorld(exec)), args.at(2).toBoolean(exec));
return jsUndefined();
}
@@ -137,7 +132,7 @@ JSValue JSWorkerContext::removeEventListener(ExecState* exec, const ArgList& arg
if (!listener.isObject())
return jsUndefined();
- impl()->removeEventListener(args.at(0).toString(exec), JSEventListener::create(asObject(listener), this, false, currentWorld(exec)).get(), args.at(2).toBoolean(exec));
+ impl()->removeEventListener(ustringToAtomicString(args.at(0).toString(exec)), JSEventListener::create(asObject(listener), this, false, currentWorld(exec)).get(), args.at(2).toBoolean(exec));
return jsUndefined();
}
diff --git a/WebCore/bindings/js/JSWorkerContextErrorHandler.cpp b/WebCore/bindings/js/JSWorkerContextErrorHandler.cpp
new file mode 100644
index 0000000..ad3f5ec
--- /dev/null
+++ b/WebCore/bindings/js/JSWorkerContextErrorHandler.cpp
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if ENABLE(WORKERS)
+
+#include "JSWorkerContextErrorHandler.h"
+
+#include "ErrorEvent.h"
+#include "Event.h"
+#include "JSEvent.h"
+#include <runtime/JSLock.h>
+
+using namespace JSC;
+
+namespace WebCore {
+
+JSWorkerContextErrorHandler::JSWorkerContextErrorHandler(JSObject* function, JSObject* wrapper, bool isAttribute, DOMWrapperWorld* isolatedWorld)
+ : JSEventListener(function, wrapper, isAttribute, isolatedWorld)
+{
+}
+
+JSWorkerContextErrorHandler::~JSWorkerContextErrorHandler()
+{
+}
+
+void JSWorkerContextErrorHandler::handleEvent(ScriptExecutionContext* scriptExecutionContext, Event* event)
+{
+ ASSERT(scriptExecutionContext);
+ if (!scriptExecutionContext)
+ return;
+
+ JSLock lock(SilenceAssertionsOnly);
+
+ JSObject* jsFunction = this->jsFunction(scriptExecutionContext);
+ if (!jsFunction)
+ return;
+
+ JSDOMGlobalObject* globalObject = toJSDOMGlobalObject(scriptExecutionContext, isolatedWorld());
+ if (!globalObject)
+ return;
+
+ ExecState* exec = globalObject->globalExec();
+
+ CallData callData;
+ CallType callType = jsFunction->getCallData(callData);
+
+ if (callType != CallTypeNone) {
+
+ ref();
+
+ Event* savedEvent = globalObject->currentEvent();
+ globalObject->setCurrentEvent(event);
+
+ ASSERT(event->isErrorEvent());
+ ErrorEvent* errorEvent = static_cast<ErrorEvent*>(event);
+
+ MarkedArgumentBuffer args;
+ args.append(jsString(exec, errorEvent->message()));
+ args.append(jsString(exec, errorEvent->filename()));
+ args.append(jsNumber(exec, errorEvent->lineno()));
+
+ JSGlobalData* globalData = globalObject->globalData();
+ DynamicGlobalObjectScope globalObjectScope(exec, globalData->dynamicGlobalObject ? globalData->dynamicGlobalObject : globalObject);
+
+ JSValue thisValue = globalObject->toThisObject(exec);
+
+ globalData->timeoutChecker.start();
+ JSValue returnValue = JSC::call(exec, jsFunction, callType, callData, thisValue, args);
+ globalData->timeoutChecker.stop();
+
+ globalObject->setCurrentEvent(savedEvent);
+
+ if (exec->hadException())
+ reportCurrentException(exec);
+ else {
+ bool retvalbool;
+ if (returnValue.getBoolean(retvalbool) && !retvalbool)
+ event->preventDefault();
+ }
+
+ deref();
+ }
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(WORKERS)
diff --git a/WebCore/bindings/js/JSWorkerContextErrorHandler.h b/WebCore/bindings/js/JSWorkerContextErrorHandler.h
new file mode 100644
index 0000000..a188299
--- /dev/null
+++ b/WebCore/bindings/js/JSWorkerContextErrorHandler.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef JSWorkerContextErrorHandler_h
+#define JSWorkerContextErrorHandler_h
+
+#include "JSEventListener.h"
+
+namespace WebCore {
+
+class JSWorkerContextErrorHandler : public JSEventListener {
+public:
+ static PassRefPtr<JSWorkerContextErrorHandler> create(JSC::JSObject* listener, JSC::JSObject* wrapper, bool isAttribute, DOMWrapperWorld* isolatedWorld)
+ {
+ return adoptRef(new JSWorkerContextErrorHandler(listener, wrapper, isAttribute, isolatedWorld));
+ }
+
+ virtual ~JSWorkerContextErrorHandler();
+
+private:
+ JSWorkerContextErrorHandler(JSC::JSObject* function, JSC::JSObject* wrapper, bool isAttribute, DOMWrapperWorld* isolatedWorld);
+ virtual void handleEvent(ScriptExecutionContext*, Event*);
+};
+
+// Creates a JS EventListener for "onerror" event handler in worker context. It has custom implementation because
+// unlike other event listeners it accepts three parameters.
+inline PassRefPtr<JSWorkerContextErrorHandler> createJSWorkerContextErrorHandler(JSC::ExecState* exec, JSC::JSValue listener, JSC::JSObject* wrapper)
+{
+ if (!listener.isObject())
+ return 0;
+
+ return JSWorkerContextErrorHandler::create(asObject(listener), wrapper, true, currentWorld(exec));
+}
+
+} // namespace WebCore
+
+#endif // JSWorkerContextErrorHandler_h
diff --git a/WebCore/bindings/js/JSXMLHttpRequestCustom.cpp b/WebCore/bindings/js/JSXMLHttpRequestCustom.cpp
index e20b6d9..da83801 100644
--- a/WebCore/bindings/js/JSXMLHttpRequestCustom.cpp
+++ b/WebCore/bindings/js/JSXMLHttpRequestCustom.cpp
@@ -30,6 +30,7 @@
#include "JSXMLHttpRequest.h"
#include "Blob.h"
+#include "DOMFormData.h"
#include "DOMWindow.h"
#include "Document.h"
#include "Event.h"
@@ -37,6 +38,7 @@
#include "FrameLoader.h"
#include "HTMLDocument.h"
#include "JSBlob.h"
+#include "JSDOMFormData.h"
#include "JSDOMWindowCustom.h"
#include "JSDocument.h"
#include "JSEvent.h"
@@ -65,23 +67,25 @@ JSValue JSXMLHttpRequest::open(ExecState* exec, const ArgList& args)
if (args.size() < 2)
return throwError(exec, SyntaxError, "Not enough arguments");
- const KURL& url = impl()->scriptExecutionContext()->completeURL(args.at(1).toString(exec));
- String method = args.at(0).toString(exec);
- bool async = true;
- if (args.size() >= 3)
- async = args.at(2).toBoolean(exec);
+ const KURL& url = impl()->scriptExecutionContext()->completeURL(ustringToString(args.at(1).toString(exec)));
+ String method = ustringToString(args.at(0).toString(exec));
ExceptionCode ec = 0;
- if (args.size() >= 4 && !args.at(3).isUndefined()) {
- String user = valueToStringWithNullCheck(exec, args.at(3));
-
- if (args.size() >= 5 && !args.at(4).isUndefined()) {
- String password = valueToStringWithNullCheck(exec, args.at(4));
- impl()->open(method, url, async, user, password, ec);
+ if (args.size() >= 3) {
+ bool async = args.at(2).toBoolean(exec);
+
+ if (args.size() >= 4 && !args.at(3).isUndefined()) {
+ String user = valueToStringWithNullCheck(exec, args.at(3));
+
+ if (args.size() >= 5 && !args.at(4).isUndefined()) {
+ String password = valueToStringWithNullCheck(exec, args.at(4));
+ impl()->open(method, url, async, user, password, ec);
+ } else
+ impl()->open(method, url, async, user, ec);
} else
- impl()->open(method, url, async, user, ec);
+ impl()->open(method, url, async, ec);
} else
- impl()->open(method, url, async, ec);
+ impl()->open(method, url, ec);
setDOMException(exec, ec);
return jsUndefined();
@@ -93,7 +97,7 @@ JSValue JSXMLHttpRequest::setRequestHeader(ExecState* exec, const ArgList& args)
return throwError(exec, SyntaxError, "Not enough arguments");
ExceptionCode ec = 0;
- impl()->setRequestHeader(args.at(0).toString(exec), args.at(1).toString(exec), ec);
+ impl()->setRequestHeader(ustringToAtomicString(args.at(0).toString(exec)), ustringToString(args.at(1).toString(exec)), ec);
setDOMException(exec, ec);
return jsUndefined();
}
@@ -111,8 +115,10 @@ JSValue JSXMLHttpRequest::send(ExecState* exec, const ArgList& args)
impl()->send(toDocument(val), ec);
else if (val.inherits(&JSBlob::s_info))
impl()->send(toBlob(val), ec);
+ else if (val.inherits(&JSDOMFormData::s_info))
+ impl()->send(toDOMFormData(val), ec);
else
- impl()->send(val.toString(exec), ec);
+ impl()->send(ustringToString(val.toString(exec)), ec);
}
int signedLineNumber;
@@ -121,7 +127,7 @@ JSValue JSXMLHttpRequest::send(ExecState* exec, const ArgList& args)
JSValue function;
exec->interpreter()->retrieveLastCaller(exec, signedLineNumber, sourceID, sourceURL, function);
impl()->setLastSendLineNumber(signedLineNumber >= 0 ? signedLineNumber : 0);
- impl()->setLastSendURL(sourceURL);
+ impl()->setLastSendURL(ustringToString(sourceURL));
setDOMException(exec, ec);
return jsUndefined();
@@ -133,7 +139,7 @@ JSValue JSXMLHttpRequest::getResponseHeader(ExecState* exec, const ArgList& args
return throwError(exec, SyntaxError, "Not enough arguments");
ExceptionCode ec = 0;
- JSValue header = jsStringOrNull(exec, impl()->getResponseHeader(args.at(0).toString(exec), ec));
+ JSValue header = jsStringOrNull(exec, impl()->getResponseHeader(ustringToAtomicString(args.at(0).toString(exec)), ec));
setDOMException(exec, ec);
return header;
}
@@ -143,7 +149,7 @@ JSValue JSXMLHttpRequest::overrideMimeType(ExecState* exec, const ArgList& args)
if (args.size() < 1)
return throwError(exec, SyntaxError, "Not enough arguments");
- impl()->overrideMimeType(args.at(0).toString(exec));
+ impl()->overrideMimeType(ustringToString(args.at(0).toString(exec)));
return jsUndefined();
}
@@ -153,7 +159,7 @@ JSValue JSXMLHttpRequest::addEventListener(ExecState* exec, const ArgList& args)
if (!listener.isObject())
return jsUndefined();
- impl()->addEventListener(args.at(0).toString(exec), JSEventListener::create(asObject(listener), this, false, currentWorld(exec)), args.at(2).toBoolean(exec));
+ impl()->addEventListener(ustringToAtomicString(args.at(0).toString(exec)), JSEventListener::create(asObject(listener), this, false, currentWorld(exec)), args.at(2).toBoolean(exec));
return jsUndefined();
}
@@ -163,7 +169,7 @@ JSValue JSXMLHttpRequest::removeEventListener(ExecState* exec, const ArgList& ar
if (!listener.isObject())
return jsUndefined();
- impl()->removeEventListener(args.at(0).toString(exec), JSEventListener::create(asObject(listener), this, false, currentWorld(exec)).get(), args.at(2).toBoolean(exec));
+ impl()->removeEventListener(ustringToAtomicString(args.at(0).toString(exec)), JSEventListener::create(asObject(listener), this, false, currentWorld(exec)).get(), args.at(2).toBoolean(exec));
return jsUndefined();
}
diff --git a/WebCore/bindings/js/JSXMLHttpRequestUploadCustom.cpp b/WebCore/bindings/js/JSXMLHttpRequestUploadCustom.cpp
index 857c12d..42d4eb9 100644
--- a/WebCore/bindings/js/JSXMLHttpRequestUploadCustom.cpp
+++ b/WebCore/bindings/js/JSXMLHttpRequestUploadCustom.cpp
@@ -57,7 +57,7 @@ JSValue JSXMLHttpRequestUpload::addEventListener(ExecState* exec, const ArgList&
if (!listener.isObject())
return jsUndefined();
- impl()->addEventListener(args.at(0).toString(exec), JSEventListener::create(asObject(listener), this, false, currentWorld(exec)), args.at(2).toBoolean(exec));
+ impl()->addEventListener(ustringToAtomicString(args.at(0).toString(exec)), JSEventListener::create(asObject(listener), this, false, currentWorld(exec)), args.at(2).toBoolean(exec));
return jsUndefined();
}
@@ -67,7 +67,7 @@ JSValue JSXMLHttpRequestUpload::removeEventListener(ExecState* exec, const ArgLi
if (!listener.isObject())
return jsUndefined();
- impl()->removeEventListener(args.at(0).toString(exec), JSEventListener::create(asObject(listener), this, false, currentWorld(exec)).get(), args.at(2).toBoolean(exec));
+ impl()->removeEventListener(ustringToAtomicString(args.at(0).toString(exec)), JSEventListener::create(asObject(listener), this, false, currentWorld(exec)).get(), args.at(2).toBoolean(exec));
return jsUndefined();
}
diff --git a/WebCore/bindings/js/JSXSLTProcessorCustom.cpp b/WebCore/bindings/js/JSXSLTProcessorCustom.cpp
index 441bbc9..49ac234 100644
--- a/WebCore/bindings/js/JSXSLTProcessorCustom.cpp
+++ b/WebCore/bindings/js/JSXSLTProcessorCustom.cpp
@@ -89,9 +89,9 @@ JSValue JSXSLTProcessor::setParameter(ExecState* exec, const ArgList& args)
{
if (args.at(1).isUndefinedOrNull() || args.at(2).isUndefinedOrNull())
return jsUndefined(); // Throw exception?
- String namespaceURI = args.at(0).toString(exec);
- String localName = args.at(1).toString(exec);
- String value = args.at(2).toString(exec);
+ String namespaceURI = ustringToString(args.at(0).toString(exec));
+ String localName = ustringToString(args.at(1).toString(exec));
+ String value = ustringToString(args.at(2).toString(exec));
impl()->setParameter(namespaceURI, localName, value);
return jsUndefined();
}
@@ -100,8 +100,8 @@ JSValue JSXSLTProcessor::getParameter(ExecState* exec, const ArgList& args)
{
if (args.at(1).isUndefinedOrNull())
return jsUndefined();
- String namespaceURI = args.at(0).toString(exec);
- String localName = args.at(1).toString(exec);
+ String namespaceURI = ustringToString(args.at(0).toString(exec));
+ String localName = ustringToString(args.at(1).toString(exec));
String value = impl()->getParameter(namespaceURI, localName);
return jsStringOrUndefined(exec, value);
}
@@ -110,8 +110,8 @@ JSValue JSXSLTProcessor::removeParameter(ExecState* exec, const ArgList& args)
{
if (args.at(1).isUndefinedOrNull())
return jsUndefined();
- String namespaceURI = args.at(0).toString(exec);
- String localName = args.at(1).toString(exec);
+ String namespaceURI = ustringToString(args.at(0).toString(exec));
+ String localName = ustringToString(args.at(1).toString(exec));
impl()->removeParameter(namespaceURI, localName);
return jsUndefined();
}
diff --git a/WebCore/bindings/js/JavaScriptCallFrame.cpp b/WebCore/bindings/js/JavaScriptCallFrame.cpp
new file mode 100644
index 0000000..c280d98
--- /dev/null
+++ b/WebCore/bindings/js/JavaScriptCallFrame.cpp
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "JavaScriptCallFrame.h"
+
+#include "JSDOMBinding.h"
+
+#if ENABLE(JAVASCRIPT_DEBUGGER) && USE(JSC)
+
+#include "PlatformString.h"
+#include <debugger/DebuggerCallFrame.h>
+#include <runtime/Completion.h>
+#include <runtime/JSGlobalObject.h>
+#include <runtime/JSLock.h>
+#include <runtime/JSObject.h>
+#include <runtime/JSValue.h>
+
+using namespace JSC;
+
+namespace WebCore {
+
+JavaScriptCallFrame::JavaScriptCallFrame(const DebuggerCallFrame& debuggerCallFrame, PassRefPtr<JavaScriptCallFrame> caller, intptr_t sourceID, int line)
+ : m_debuggerCallFrame(debuggerCallFrame)
+ , m_caller(caller)
+ , m_sourceID(sourceID)
+ , m_line(line)
+ , m_isValid(true)
+{
+}
+
+JavaScriptCallFrame* JavaScriptCallFrame::caller()
+{
+ return m_caller.get();
+}
+
+const JSC::ScopeChainNode* JavaScriptCallFrame::scopeChain() const
+{
+ ASSERT(m_isValid);
+ if (!m_isValid)
+ return 0;
+ return m_debuggerCallFrame.scopeChain();
+}
+
+JSC::JSGlobalObject* JavaScriptCallFrame::dynamicGlobalObject() const
+{
+ ASSERT(m_isValid);
+ if (!m_isValid)
+ return 0;
+ return m_debuggerCallFrame.dynamicGlobalObject();
+}
+
+String JavaScriptCallFrame::functionName() const
+{
+ ASSERT(m_isValid);
+ if (!m_isValid)
+ return String();
+ UString functionName = m_debuggerCallFrame.calculatedFunctionName();
+ if (functionName.isEmpty())
+ return String();
+ return ustringToString(functionName);
+}
+
+DebuggerCallFrame::Type JavaScriptCallFrame::type() const
+{
+ ASSERT(m_isValid);
+ if (!m_isValid)
+ return DebuggerCallFrame::ProgramType;
+ return m_debuggerCallFrame.type();
+}
+
+JSObject* JavaScriptCallFrame::thisObject() const
+{
+ ASSERT(m_isValid);
+ if (!m_isValid)
+ return 0;
+ return m_debuggerCallFrame.thisObject();
+}
+
+// Evaluate some JavaScript code in the scope of this frame.
+JSValue JavaScriptCallFrame::evaluate(const UString& script, JSValue& exception) const
+{
+ ASSERT(m_isValid);
+ if (!m_isValid)
+ return jsNull();
+
+ JSLock lock(SilenceAssertionsOnly);
+ return m_debuggerCallFrame.evaluate(script, exception);
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(JAVASCRIPT_DEBUGGER)
diff --git a/WebCore/bindings/js/JavaScriptCallFrame.h b/WebCore/bindings/js/JavaScriptCallFrame.h
new file mode 100644
index 0000000..574c782
--- /dev/null
+++ b/WebCore/bindings/js/JavaScriptCallFrame.h
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef JavaScriptCallFrame_h
+#define JavaScriptCallFrame_h
+
+#if ENABLE(JAVASCRIPT_DEBUGGER) && USE(JSC)
+
+#include <debugger/DebuggerCallFrame.h>
+#include <interpreter/CallFrame.h>
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+
+namespace WebCore {
+
+class String;
+
+class JavaScriptCallFrame : public RefCounted<JavaScriptCallFrame> {
+public:
+ static PassRefPtr<JavaScriptCallFrame> create(const JSC::DebuggerCallFrame& debuggerCallFrame, PassRefPtr<JavaScriptCallFrame> caller, intptr_t sourceID, int line)
+ {
+ return adoptRef(new JavaScriptCallFrame(debuggerCallFrame, caller, sourceID, line));
+ }
+
+ void invalidate()
+ {
+ m_isValid = false;
+ m_debuggerCallFrame = 0;
+ }
+
+ bool isValid() const { return m_isValid; }
+
+ JavaScriptCallFrame* caller();
+
+ intptr_t sourceID() const { return m_sourceID; }
+ int line() const { return m_line; }
+ void update(const JSC::DebuggerCallFrame& debuggerCallFrame, intptr_t sourceID, int line)
+ {
+ m_debuggerCallFrame = debuggerCallFrame;
+ m_line = line;
+ m_sourceID = sourceID;
+ m_isValid = true;
+ }
+
+ String functionName() const;
+ JSC::DebuggerCallFrame::Type type() const;
+ const JSC::ScopeChainNode* scopeChain() const;
+ JSC::JSGlobalObject* dynamicGlobalObject() const;
+
+ JSC::JSObject* thisObject() const;
+ JSC::JSValue evaluate(const JSC::UString& script, JSC::JSValue& exception) const;
+
+private:
+ JavaScriptCallFrame(const JSC::DebuggerCallFrame&, PassRefPtr<JavaScriptCallFrame> caller, intptr_t sourceID, int line);
+
+ JSC::DebuggerCallFrame m_debuggerCallFrame;
+ RefPtr<JavaScriptCallFrame> m_caller;
+ intptr_t m_sourceID;
+ int m_line;
+ bool m_isValid;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(JAVASCRIPT_DEBUGGER)
+
+#endif // JavaScriptCallFrame_h
diff --git a/WebCore/bindings/js/JavaScriptProfile.cpp b/WebCore/bindings/js/JavaScriptProfile.cpp
deleted file mode 100644
index 8e56ed8..0000000
--- a/WebCore/bindings/js/JavaScriptProfile.cpp
+++ /dev/null
@@ -1,183 +0,0 @@
-/*
- * Copyright (C) 2008 Apple Inc. All Rights Reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "JavaScriptProfile.h"
-
-#if ENABLE(JAVASCRIPT_DEBUGGER)
-
-#include "JavaScriptProfileNode.h"
-#include <JavaScriptCore/APICast.h>
-#include <JavaScriptCore/JSObjectRef.h>
-#include <JavaScriptCore/JSStringRef.h>
-#include <JavaScriptCore/OpaqueJSString.h>
-#include <profiler/Profile.h>
-#include <runtime/JSObject.h>
-#include <runtime/JSValue.h>
-#include <wtf/StdLibExtras.h>
-
-using namespace JSC;
-
-namespace WebCore {
-
-// Cache
-
-typedef HashMap<Profile*, JSObject*> ProfileMap;
-
-static ProfileMap& profileCache()
-{
- DEFINE_STATIC_LOCAL(ProfileMap, staticProfiles, ());
- return staticProfiles;
-}
-
-// Static Values
-
-static JSClassRef ProfileClass();
-
-static JSValueRef getTitleCallback(JSContextRef ctx, JSObjectRef thisObject, JSStringRef, JSValueRef*)
-{
- if (!JSValueIsObjectOfClass(ctx, thisObject, ProfileClass()))
- return JSValueMakeUndefined(ctx);
-
- Profile* profile = static_cast<Profile*>(JSObjectGetPrivate(thisObject));
- return JSValueMakeString(ctx, OpaqueJSString::create(profile->title()).get());
-}
-
-static JSValueRef getHeadCallback(JSContextRef ctx, JSObjectRef thisObject, JSStringRef, JSValueRef*)
-{
- if (!JSValueIsObjectOfClass(ctx, thisObject, ProfileClass()))
- return JSValueMakeUndefined(ctx);
-
- ExecState* exec = toJS(ctx);
- Profile* profile = static_cast<Profile*>(JSObjectGetPrivate(thisObject));
- return toRef(exec, toJS(exec, profile->head()));
-}
-
-static JSValueRef getUniqueIdCallback(JSContextRef ctx, JSObjectRef thisObject, JSStringRef, JSValueRef*)
-{
- if (!JSValueIsObjectOfClass(ctx, thisObject, ProfileClass()))
- return JSValueMakeUndefined(ctx);
-
- Profile* profile = static_cast<Profile*>(JSObjectGetPrivate(thisObject));
- return JSValueMakeNumber(ctx, profile->uid());
-}
-
-// Static Functions
-
-static JSValueRef focus(JSContextRef ctx, JSObjectRef /*function*/, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* /*exception*/)
-{
- if (!JSValueIsObjectOfClass(ctx, thisObject, ProfileClass()))
- return JSValueMakeUndefined(ctx);
-
- if (argumentCount < 1)
- return JSValueMakeUndefined(ctx);
-
- if (!JSValueIsObjectOfClass(ctx, arguments[0], ProfileNodeClass()))
- return JSValueMakeUndefined(ctx);
-
- Profile* profile = static_cast<Profile*>(JSObjectGetPrivate(thisObject));
- profile->focus(static_cast<ProfileNode*>(JSObjectGetPrivate(const_cast<JSObjectRef>(arguments[0]))));
-
- return JSValueMakeUndefined(ctx);
-}
-
-static JSValueRef exclude(JSContextRef ctx, JSObjectRef /*function*/, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* /*exception*/)
-{
- if (!JSValueIsObjectOfClass(ctx, thisObject, ProfileClass()))
- return JSValueMakeUndefined(ctx);
-
- if (argumentCount < 1)
- return JSValueMakeUndefined(ctx);
-
- if (!JSValueIsObjectOfClass(ctx, arguments[0], ProfileNodeClass()))
- return JSValueMakeUndefined(ctx);
-
- Profile* profile = static_cast<Profile*>(JSObjectGetPrivate(thisObject));
- profile->exclude(static_cast<ProfileNode*>(JSObjectGetPrivate(const_cast<JSObjectRef>(arguments[0]))));
-
- return JSValueMakeUndefined(ctx);
-}
-
-static JSValueRef restoreAll(JSContextRef ctx, JSObjectRef /*function*/, JSObjectRef thisObject, size_t /*argumentCount*/, const JSValueRef[] /*arguments*/, JSValueRef* /*exception*/)
-{
- if (!JSValueIsObjectOfClass(ctx, thisObject, ProfileClass()))
- return JSValueMakeUndefined(ctx);
-
- Profile* profile = static_cast<Profile*>(JSObjectGetPrivate(thisObject));
- profile->restoreAll();
-
- return JSValueMakeUndefined(ctx);
-}
-
-static void finalize(JSObjectRef object)
-{
- Profile* profile = static_cast<Profile*>(JSObjectGetPrivate(object));
- profileCache().remove(profile);
- profile->deref();
-}
-
-JSClassRef ProfileClass()
-{
- static JSStaticValue staticValues[] = {
- { "title", getTitleCallback, 0, kJSPropertyAttributeNone },
- { "head", getHeadCallback, 0, kJSPropertyAttributeNone },
- { "uid", getUniqueIdCallback, 0, kJSPropertyAttributeNone },
- { 0, 0, 0, 0 }
- };
-
- static JSStaticFunction staticFunctions[] = {
- { "focus", focus, kJSPropertyAttributeNone },
- { "exclude", exclude, kJSPropertyAttributeNone },
- { "restoreAll", restoreAll, kJSPropertyAttributeNone },
- { 0, 0, 0 }
- };
-
- static JSClassDefinition classDefinition = {
- 0, kJSClassAttributeNone, "Profile", 0, staticValues, staticFunctions,
- 0, finalize, 0, 0, 0, 0, 0, 0, 0, 0, 0
- };
-
- static JSClassRef profileClass = JSClassCreate(&classDefinition);
- return profileClass;
-}
-
-JSValue toJS(ExecState* exec, Profile* profile)
-{
- if (!profile)
- return jsNull();
-
- JSObject* profileWrapper = profileCache().get(profile);
- if (profileWrapper)
- return profileWrapper;
-
- profile->ref();
- profileWrapper = toJS(JSObjectMake(toRef(exec), ProfileClass(), static_cast<void*>(profile)));
- profileCache().set(profile, profileWrapper);
- return profileWrapper;
-}
-
-} // namespace WebCore
-
-#endif // ENABLE(JAVASCRIPT_DEBUGGER)
diff --git a/WebCore/bindings/js/JavaScriptProfileNode.cpp b/WebCore/bindings/js/JavaScriptProfileNode.cpp
deleted file mode 100644
index 7d60b24..0000000
--- a/WebCore/bindings/js/JavaScriptProfileNode.cpp
+++ /dev/null
@@ -1,236 +0,0 @@
-/*
- * Copyright (C) 2008 Apple Inc. All Rights Reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "JavaScriptProfileNode.h"
-
-#if ENABLE(JAVASCRIPT_DEBUGGER)
-
-#include "JSDOMBinding.h"
-#include <JavaScriptCore/APICast.h>
-#include <JavaScriptCore/JSContextRef.h>
-#include <JavaScriptCore/JSObjectRef.h>
-#include <JavaScriptCore/JSRetainPtr.h>
-#include <JavaScriptCore/JSStringRef.h>
-#include <profiler/ProfileNode.h>
-#include <runtime/JSLock.h>
-#include <runtime/JSValue.h>
-#include <wtf/StdLibExtras.h>
-
-using namespace JSC;
-
-namespace WebCore {
-
-// Cache
-
-typedef HashMap<ProfileNode*, JSObject*> ProfileNodeMap;
-
-static ProfileNodeMap& profileNodeCache()
-{
- DEFINE_STATIC_LOCAL(ProfileNodeMap, staticProfileNodes, ());
- return staticProfileNodes;
-}
-
-static JSValueRef getFunctionName(JSContextRef ctx, JSObjectRef thisObject, JSStringRef, JSValueRef*)
-{
- if (!JSValueIsObjectOfClass(ctx, thisObject, ProfileNodeClass()))
- return JSValueMakeUndefined(ctx);
-
- ProfileNode* profileNode = static_cast<ProfileNode*>(JSObjectGetPrivate(thisObject));
- JSRetainPtr<JSStringRef> functionNameString(Adopt, JSStringCreateWithCharacters(profileNode->functionName().data(), profileNode->functionName().size()));
- return JSValueMakeString(ctx, functionNameString.get());
-}
-
-static JSValueRef getURL(JSContextRef ctx, JSObjectRef thisObject, JSStringRef, JSValueRef*)
-{
- if (!JSValueIsObjectOfClass(ctx, thisObject, ProfileNodeClass()))
- return JSValueMakeUndefined(ctx);
-
- ProfileNode* profileNode = static_cast<ProfileNode*>(JSObjectGetPrivate(thisObject));
- JSRetainPtr<JSStringRef> urlString(Adopt, JSStringCreateWithCharacters(profileNode->url().data(), profileNode->url().size()));
- return JSValueMakeString(ctx, urlString.get());
-}
-
-static JSValueRef getLineNumber(JSContextRef ctx, JSObjectRef thisObject, JSStringRef, JSValueRef*)
-{
- if (!JSValueIsObjectOfClass(ctx, thisObject, ProfileNodeClass()))
- return JSValueMakeUndefined(ctx);
-
- ProfileNode* profileNode = static_cast<ProfileNode*>(JSObjectGetPrivate(thisObject));
- return JSValueMakeNumber(ctx, profileNode->lineNumber());
-}
-
-static JSValueRef getTotalTime(JSContextRef ctx, JSObjectRef thisObject, JSStringRef, JSValueRef*)
-{
- JSC::JSLock lock(SilenceAssertionsOnly);
-
- if (!JSValueIsObjectOfClass(ctx, thisObject, ProfileNodeClass()))
- return JSValueMakeUndefined(ctx);
-
- ProfileNode* profileNode = static_cast<ProfileNode*>(JSObjectGetPrivate(thisObject));
- return JSValueMakeNumber(ctx, profileNode->totalTime());
-}
-
-static JSValueRef getSelfTime(JSContextRef ctx, JSObjectRef thisObject, JSStringRef, JSValueRef*)
-{
- JSC::JSLock lock(SilenceAssertionsOnly);
-
- if (!JSValueIsObjectOfClass(ctx, thisObject, ProfileNodeClass()))
- return JSValueMakeUndefined(ctx);
-
- ProfileNode* profileNode = static_cast<ProfileNode*>(JSObjectGetPrivate(thisObject));
- return JSValueMakeNumber(ctx, profileNode->selfTime());
-}
-
-static JSValueRef getNumberOfCalls(JSContextRef ctx, JSObjectRef thisObject, JSStringRef, JSValueRef*)
-{
- JSC::JSLock lock(SilenceAssertionsOnly);
-
- if (!JSValueIsObjectOfClass(ctx, thisObject, ProfileNodeClass()))
- return JSValueMakeUndefined(ctx);
-
- ProfileNode* profileNode = static_cast<ProfileNode*>(JSObjectGetPrivate(thisObject));
- return JSValueMakeNumber(ctx, profileNode->numberOfCalls());
-}
-
-static JSValueRef getChildren(JSContextRef ctx, JSObjectRef thisObject, JSStringRef, JSValueRef* exception)
-{
- JSC::JSLock lock(SilenceAssertionsOnly);
-
- if (!JSValueIsObjectOfClass(ctx, thisObject, ProfileNodeClass()))
- return JSValueMakeUndefined(ctx);
-
- ProfileNode* profileNode = static_cast<ProfileNode*>(JSObjectGetPrivate(thisObject));
- const Vector<RefPtr<ProfileNode> >& children = profileNode->children();
-
- JSObjectRef global = JSContextGetGlobalObject(ctx);
-
- JSRetainPtr<JSStringRef> arrayString(Adopt, JSStringCreateWithUTF8CString("Array"));
-
- JSValueRef arrayProperty = JSObjectGetProperty(ctx, global, arrayString.get(), exception);
- if (exception && *exception)
- return JSValueMakeUndefined(ctx);
-
- JSObjectRef arrayConstructor = JSValueToObject(ctx, arrayProperty, exception);
- if (exception && *exception)
- return JSValueMakeUndefined(ctx);
-
- JSObjectRef result = JSObjectCallAsConstructor(ctx, arrayConstructor, 0, 0, exception);
- if (exception && *exception)
- return JSValueMakeUndefined(ctx);
-
- JSRetainPtr<JSStringRef> pushString(Adopt, JSStringCreateWithUTF8CString("push"));
-
- JSValueRef pushProperty = JSObjectGetProperty(ctx, result, pushString.get(), exception);
- if (exception && *exception)
- return JSValueMakeUndefined(ctx);
-
- JSObjectRef pushFunction = JSValueToObject(ctx, pushProperty, exception);
- if (exception && *exception)
- return JSValueMakeUndefined(ctx);
-
- ExecState* exec = toJS(ctx);
- for (Vector<RefPtr<ProfileNode> >::const_iterator it = children.begin(); it != children.end(); ++it) {
- JSValueRef arg0 = toRef(exec, toJS(exec, (*it).get() ));
- JSObjectCallAsFunction(ctx, pushFunction, result, 1, &arg0, exception);
- if (exception && *exception)
- return JSValueMakeUndefined(ctx);
- }
-
- return result;
-}
-
-static JSValueRef getVisible(JSContextRef ctx, JSObjectRef thisObject, JSStringRef, JSValueRef*)
-{
- JSC::JSLock lock(SilenceAssertionsOnly);
-
- if (!JSValueIsObjectOfClass(ctx, thisObject, ProfileNodeClass()))
- return JSValueMakeUndefined(ctx);
-
- ProfileNode* profileNode = static_cast<ProfileNode*>(JSObjectGetPrivate(thisObject));
- return JSValueMakeBoolean(ctx, profileNode->visible());
-}
-
-static JSValueRef getCallUID(JSContextRef ctx, JSObjectRef thisObject, JSStringRef, JSValueRef*)
-{
- JSC::JSLock lock(SilenceAssertionsOnly);
-
- if (!JSValueIsObjectOfClass(ctx, thisObject, ProfileNodeClass()))
- return JSValueMakeUndefined(ctx);
-
- ProfileNode* profileNode = static_cast<ProfileNode*>(JSObjectGetPrivate(thisObject));
- return JSValueMakeNumber(ctx, profileNode->callIdentifier().hash());
-}
-
-static void finalize(JSObjectRef object)
-{
- ProfileNode* profileNode = static_cast<ProfileNode*>(JSObjectGetPrivate(object));
- profileNodeCache().remove(profileNode);
- profileNode->deref();
-}
-
-JSClassRef ProfileNodeClass()
-{
- static JSStaticValue staticValues[] = {
- { "functionName", getFunctionName, 0, kJSPropertyAttributeNone },
- { "url", getURL, 0, kJSPropertyAttributeNone },
- { "lineNumber", getLineNumber, 0, kJSPropertyAttributeNone },
- { "totalTime", getTotalTime, 0, kJSPropertyAttributeNone },
- { "selfTime", getSelfTime, 0, kJSPropertyAttributeNone },
- { "numberOfCalls", getNumberOfCalls, 0, kJSPropertyAttributeNone },
- { "children", getChildren, 0, kJSPropertyAttributeNone },
- { "visible", getVisible, 0, kJSPropertyAttributeNone },
- { "callUID", getCallUID, 0, kJSPropertyAttributeNone },
- { 0, 0, 0, 0 }
- };
-
- static JSClassDefinition classDefinition = {
- 0, kJSClassAttributeNone, "ProfileNode", 0, staticValues, 0,
- 0, finalize, 0, 0, 0, 0, 0, 0, 0, 0, 0
- };
-
- static JSClassRef profileNodeClass = JSClassCreate(&classDefinition);
- return profileNodeClass;
-}
-
-JSValue toJS(ExecState* exec, ProfileNode* profileNode)
-{
- if (!profileNode)
- return jsNull();
-
- JSObject* profileNodeWrapper = profileNodeCache().get(profileNode);
- if (profileNodeWrapper)
- return profileNodeWrapper;
-
- profileNode->ref();
-
- profileNodeWrapper = toJS(JSObjectMake(toRef(exec), ProfileNodeClass(), static_cast<void*>(profileNode)));
- profileNodeCache().set(profileNode, profileNodeWrapper);
- return profileNodeWrapper;
-}
-
-} // namespace WebCore
-
-#endif // ENABLE(JAVASCRIPT_DEBUGGER)
diff --git a/WebCore/bindings/js/ScheduledAction.cpp b/WebCore/bindings/js/ScheduledAction.cpp
index be62bb8..8fc860b 100644
--- a/WebCore/bindings/js/ScheduledAction.cpp
+++ b/WebCore/bindings/js/ScheduledAction.cpp
@@ -24,7 +24,6 @@
#include "config.h"
#include "ScheduledAction.h"
-#include "CString.h"
#include "DOMWindow.h"
#include "Document.h"
#include "Frame.h"
@@ -55,7 +54,7 @@ PassOwnPtr<ScheduledAction> ScheduledAction::create(ExecState* exec, const ArgLi
UString string = v.toString(exec);
if (exec->hadException())
return 0;
- return new ScheduledAction(string, isolatedWorld);
+ return new ScheduledAction(ustringToString(string), isolatedWorld);
}
ArgList argsTail;
args.getSlice(2, argsTail);
@@ -117,7 +116,7 @@ void ScheduledAction::execute(Document* document)
return;
RefPtr<Frame> frame = window->impl()->frame();
- if (!frame || !frame->script()->canExecuteScripts())
+ if (!frame || !frame->script()->canExecuteScripts(AboutToExecuteScript))
return;
frame->script()->setProcessingTimerCallback(true);
diff --git a/WebCore/bindings/js/ScriptCallFrame.cpp b/WebCore/bindings/js/ScriptCallFrame.cpp
index 09752d1..19ed1ea 100644
--- a/WebCore/bindings/js/ScriptCallFrame.cpp
+++ b/WebCore/bindings/js/ScriptCallFrame.cpp
@@ -40,7 +40,7 @@ namespace WebCore {
ScriptCallFrame::ScriptCallFrame(const UString& functionName, const UString& urlString, int lineNumber, const ArgList& args, unsigned skipArgumentCount)
: m_functionName(functionName)
- , m_sourceURL(ParsedURLString, urlString)
+ , m_sourceURL(ParsedURLString, ustringToString(urlString))
, m_lineNumber(lineNumber)
{
size_t argumentCount = args.size();
diff --git a/WebCore/bindings/js/ScriptCallStack.cpp b/WebCore/bindings/js/ScriptCallStack.cpp
index a435588..771141d 100644
--- a/WebCore/bindings/js/ScriptCallStack.cpp
+++ b/WebCore/bindings/js/ScriptCallStack.cpp
@@ -101,4 +101,9 @@ void ScriptCallStack::initialize()
m_initialized = true;
}
+bool ScriptCallStack::callLocation(String*, int*, String*)
+{
+ return false;
+}
+
} // namespace WebCore
diff --git a/WebCore/bindings/js/ScriptCallStack.h b/WebCore/bindings/js/ScriptCallStack.h
index 52362ea..e51d97a 100644
--- a/WebCore/bindings/js/ScriptCallStack.h
+++ b/WebCore/bindings/js/ScriptCallStack.h
@@ -53,6 +53,7 @@ namespace WebCore {
// frame retrieval methods
const ScriptCallFrame &at(unsigned);
unsigned size();
+ static bool callLocation(String*, int*, String*);
private:
void initialize();
diff --git a/WebCore/bindings/js/ScriptController.cpp b/WebCore/bindings/js/ScriptController.cpp
index 171d4dd..b3695b4 100644
--- a/WebCore/bindings/js/ScriptController.cpp
+++ b/WebCore/bindings/js/ScriptController.cpp
@@ -21,7 +21,6 @@
#include "config.h"
#include "ScriptController.h"
-#include "CString.h"
#include "Event.h"
#include "EventNames.h"
#include "Frame.h"
@@ -37,6 +36,7 @@
#include "ScriptValue.h"
#include "Settings.h"
#include "StorageNamespace.h"
+#include "WebCoreJSClientData.h"
#include "XSSAuditor.h"
#include "npruntime_impl.h"
#include "runtime_root.h"
@@ -81,20 +81,36 @@ ScriptController::ScriptController(Frame* frame)
ScriptController::~ScriptController()
{
+ disconnectPlatformScriptObjects();
+
+ // It's likely that destroying m_windowShells will create a lot of garbage.
if (!m_windowShells.isEmpty()) {
- m_windowShells.clear();
-
- // It's likely that releasing the global object has created a lot of garbage.
+ while (!m_windowShells.isEmpty())
+ destroyWindowShell(m_windowShells.begin()->first.get());
gcController().garbageCollectSoon();
}
+}
- disconnectPlatformScriptObjects();
+void ScriptController::destroyWindowShell(DOMWrapperWorld* world)
+{
+ ASSERT(m_windowShells.contains(world));
+ m_windowShells.remove(world);
+ world->didDestroyWindowShell(this);
+}
+
+JSDOMWindowShell* ScriptController::createWindowShell(DOMWrapperWorld* world)
+{
+ ASSERT(!m_windowShells.contains(world));
+ JSDOMWindowShell* windowShell = new JSDOMWindowShell(m_frame->domWindow(), world);
+ m_windowShells.add(world, windowShell);
+ world->didCreateWindowShell(this);
+ return windowShell;
}
ScriptValue ScriptController::evaluateInWorld(const ScriptSourceCode& sourceCode, DOMWrapperWorld* world)
{
const SourceCode& jsSourceCode = sourceCode.jsSourceCode();
- String sourceURL = jsSourceCode.provider()->url();
+ String sourceURL = ustringToString(jsSourceCode.provider()->url());
if (!m_XSSAuditor->canEvaluate(sourceCode.source())) {
// This script is not safe to be evaluated.
@@ -152,24 +168,9 @@ ScriptValue ScriptController::evaluate(const ScriptSourceCode& sourceCode)
return evaluateInWorld(sourceCode, mainThreadNormalWorld());
}
-// An DOMWrapperWorld other than the thread's normal world.
-class IsolatedWorld : public DOMWrapperWorld {
-public:
- static PassRefPtr<IsolatedWorld> create(JSGlobalData* globalData) { return adoptRef(new IsolatedWorld(globalData)); }
-
-protected:
- IsolatedWorld(JSGlobalData* globalData)
- : DOMWrapperWorld(globalData, false)
- {
- JSGlobalData::ClientData* clientData = globalData->clientData;
- ASSERT(clientData);
- static_cast<WebCoreJSClientData*>(clientData)->rememberWorld(this);
- }
-};
-
PassRefPtr<DOMWrapperWorld> ScriptController::createWorld()
{
- return IsolatedWorld::create(JSDOMWindow::commonJSGlobalData());
+ return DOMWrapperWorld::create(JSDOMWindow::commonJSGlobalData());
}
void ScriptController::getAllWorlds(Vector<DOMWrapperWorld*>& worlds)
@@ -199,7 +200,7 @@ void ScriptController::clearWindowShell()
}
}
- // There is likely to be a lot of garbage now.
+ // It's likely that resetting our windows created a lot of garbage.
gcController().garbageCollectSoon();
}
@@ -209,8 +210,8 @@ JSDOMWindowShell* ScriptController::initScript(DOMWrapperWorld* world)
JSLock lock(SilenceAssertionsOnly);
- JSDOMWindowShell* windowShell = new JSDOMWindowShell(m_frame->domWindow(), world);
- m_windowShells.add(world, windowShell);
+ JSDOMWindowShell* windowShell = createWindowShell(world);
+
windowShell->window()->updateDocument();
if (Page* page = m_frame->page()) {
@@ -317,7 +318,7 @@ void ScriptController::updateSecurityOrigin()
Bindings::RootObject* ScriptController::bindingRootObject()
{
- if (!canExecuteScripts())
+ if (!canExecuteScripts(NotAboutToExecuteScript))
return 0;
if (!m_bindingRootObject) {
@@ -344,7 +345,7 @@ PassRefPtr<Bindings::RootObject> ScriptController::createRootObject(void* native
NPObject* ScriptController::windowScriptNPObject()
{
if (!m_windowScriptNPObject) {
- if (canExecuteScripts()) {
+ if (canExecuteScripts(NotAboutToExecuteScript)) {
// JavaScript is enabled, so there is a JavaScript window object.
// Return an NPObject bound to the window object.
JSC::JSLock lock(SilenceAssertionsOnly);
@@ -377,7 +378,7 @@ NPObject* ScriptController::createScriptObjectForPluginElement(HTMLPlugInElement
JSObject* ScriptController::jsObjectForPluginElement(HTMLPlugInElement* plugin)
{
// Can't create JSObjects when JavaScript is disabled
- if (!canExecuteScripts())
+ if (!canExecuteScripts(NotAboutToExecuteScript))
return 0;
// Create a JSObject bound to this element
@@ -444,7 +445,7 @@ ScriptValue ScriptController::executeScriptInWorld(DOMWrapperWorld* world, const
{
ScriptSourceCode sourceCode(script, forceUserGesture ? KURL() : m_frame->loader()->url());
- if (!canExecuteScripts() || isPaused())
+ if (!canExecuteScripts(AboutToExecuteScript) || isPaused())
return ScriptValue();
bool wasInExecuteScript = m_inExecuteScript;
diff --git a/WebCore/bindings/js/ScriptController.h b/WebCore/bindings/js/ScriptController.h
index 1cbb56d..d096c2e 100644
--- a/WebCore/bindings/js/ScriptController.h
+++ b/WebCore/bindings/js/ScriptController.h
@@ -62,6 +62,11 @@ class XSSAuditor;
typedef HashMap<void*, RefPtr<JSC::Bindings::RootObject> > RootObjectMap;
+enum ReasonForCallingCanExecuteScripts {
+ AboutToExecuteScript,
+ NotAboutToExecuteScript
+};
+
class ScriptController {
friend class ScriptCachedFrameData;
typedef WTF::HashMap< RefPtr<DOMWrapperWorld>, JSC::ProtectedPtr<JSDOMWindowShell> > ShellMap;
@@ -72,6 +77,9 @@ public:
static PassRefPtr<DOMWrapperWorld> createWorld();
+ JSDOMWindowShell* createWindowShell(DOMWrapperWorld*);
+ void destroyWindowShell(DOMWrapperWorld*);
+
JSDOMWindowShell* windowShell(DOMWrapperWorld* world)
{
ShellMap::iterator iter = m_windowShells.find(world);
@@ -110,7 +118,7 @@ public:
bool processingUserGesture(DOMWrapperWorld*) const;
bool anyPageIsProcessingUserGesture() const;
- bool canExecuteScripts();
+ bool canExecuteScripts(ReasonForCallingCanExecuteScripts);
// Debugger can be 0 to detach any existing Debugger.
void attachDebugger(JSC::Debugger*); // Attaches/detaches in all worlds/window shells.
diff --git a/WebCore/bindings/js/JavaScriptProfileNode.h b/WebCore/bindings/js/ScriptControllerBrew.cpp
index f01be19..d8d345a 100644
--- a/WebCore/bindings/js/JavaScriptProfileNode.h
+++ b/WebCore/bindings/js/ScriptControllerBrew.cpp
@@ -1,5 +1,8 @@
/*
- * Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ * Copyright (C) 2008 Apple Computer, Inc.
+ * Copyright (C) 2009 Company 100, Inc.
+ *
+ * All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -10,10 +13,10 @@
* 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
+ * 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 INC. OR
+ * 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
@@ -23,26 +26,22 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef JavaScriptProfileNode_h
-#define JavaScriptProfileNode_h
-
-#if ENABLE(JAVASCRIPT_DEBUGGER)
+#include "config.h"
+#include "ScriptController.h"
-#include <JavaScriptCore/JSBase.h>
-#include <runtime/JSValue.h>
-
-namespace JSC {
-class ExecState;
-class ProfileNode;
-}
+#include "Bridge.h"
+#include "PluginView.h"
+#include "runtime_root.h"
namespace WebCore {
-JSClassRef ProfileNodeClass();
-JSC::JSValue toJS(JSC::ExecState*, JSC::ProfileNode*);
+PassRefPtr<JSC::Bindings::Instance> ScriptController::createScriptInstanceForWidget(WebCore::Widget* widget)
+{
+ if (!widget->isPluginView())
+ return 0;
-} // namespace WebCore
+ return static_cast<PluginView*>(widget)->bindingInstance();
-#endif // ENABLE(JAVASCRIPT_DEBUGGER)
+}
-#endif
+} // namespace WebCore
diff --git a/WebCore/bindings/js/ScriptControllerMac.mm b/WebCore/bindings/js/ScriptControllerMac.mm
index 208aae8..a895489 100644
--- a/WebCore/bindings/js/ScriptControllerMac.mm
+++ b/WebCore/bindings/js/ScriptControllerMac.mm
@@ -107,7 +107,7 @@ PassScriptInstance ScriptController::createScriptInstanceForWidget(Widget* widge
WebScriptObject* ScriptController::windowScriptObject()
{
- if (!canExecuteScripts())
+ if (!canExecuteScripts(NotAboutToExecuteScript))
return 0;
if (!m_windowScriptObject) {
diff --git a/WebCore/bindings/js/ScriptDebugServer.cpp b/WebCore/bindings/js/ScriptDebugServer.cpp
index 9869775..8f476b4 100644
--- a/WebCore/bindings/js/ScriptDebugServer.cpp
+++ b/WebCore/bindings/js/ScriptDebugServer.cpp
@@ -1,47 +1,588 @@
/*
- * Copyright (C) 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2009 Apple Inc. All rights reserved.
* Copyright (C) 2010 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
*
- * 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.
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
+#include "ScriptDebugServer.h"
#if ENABLE(JAVASCRIPT_DEBUGGER)
-#include "ScriptDebugServer.h"
+#include "DOMWindow.h"
+#include "EventLoop.h"
+#include "Frame.h"
+#include "FrameTree.h"
+#include "FrameView.h"
+#include "JSDOMWindowCustom.h"
+#include "JavaScriptCallFrame.h"
+#include "Page.h"
+#include "PageGroup.h"
+#include "PluginView.h"
+#include "ScriptBreakpoint.h"
+#include "ScriptController.h"
+#include "ScriptDebugListener.h"
+#include "ScrollView.h"
+#include "Widget.h"
+#include <debugger/DebuggerCallFrame.h>
+#include <parser/SourceCode.h>
+#include <runtime/JSLock.h>
+#include <wtf/MainThread.h>
+#include <wtf/StdLibExtras.h>
+#include <wtf/UnusedParam.h>
-#include "JavaScriptDebugServer.h"
+using namespace JSC;
namespace WebCore {
-void ScriptDebugServer::recompileAllJSFunctions()
+ScriptDebugServer& ScriptDebugServer::shared()
+{
+ DEFINE_STATIC_LOCAL(ScriptDebugServer, server, ());
+ return server;
+}
+
+ScriptDebugServer::ScriptDebugServer()
+ : m_callingListeners(false)
+ , m_pauseOnExceptionsState(DontPauseOnExceptions)
+ , m_pauseOnNextStatement(false)
+ , m_paused(false)
+ , m_doneProcessingDebuggerEvents(true)
+ , m_breakpointsActivated(true)
+ , m_pauseOnCallFrame(0)
+ , m_recompileTimer(this, &ScriptDebugServer::recompileAllJSFunctions)
+{
+}
+
+ScriptDebugServer::~ScriptDebugServer()
+{
+ deleteAllValues(m_pageListenersMap);
+}
+
+void ScriptDebugServer::addListener(ScriptDebugListener* listener, Page* page)
+{
+ ASSERT_ARG(listener, listener);
+ ASSERT_ARG(page, page);
+
+ pair<PageListenersMap::iterator, bool> result = m_pageListenersMap.add(page, 0);
+ if (result.second)
+ result.first->second = new ListenerSet;
+
+ ListenerSet* listeners = result.first->second;
+ listeners->add(listener);
+
+ didAddListener(page);
+}
+
+void ScriptDebugServer::removeListener(ScriptDebugListener* listener, Page* page)
+{
+ ASSERT_ARG(listener, listener);
+ ASSERT_ARG(page, page);
+
+ PageListenersMap::iterator it = m_pageListenersMap.find(page);
+ if (it == m_pageListenersMap.end())
+ return;
+
+ ListenerSet* listeners = it->second;
+ listeners->remove(listener);
+ if (listeners->isEmpty()) {
+ m_pageListenersMap.remove(it);
+ delete listeners;
+ }
+
+ didRemoveListener(page);
+ if (!hasListeners())
+ didRemoveLastListener();
+}
+
+void ScriptDebugServer::pageCreated(Page* page)
+{
+ ASSERT_ARG(page, page);
+
+ if (!hasListenersInterestedInPage(page))
+ return;
+ page->setDebugger(this);
+}
+
+bool ScriptDebugServer::hasListenersInterestedInPage(Page* page)
{
- JavaScriptDebugServer::shared().recompileAllJSFunctions();
+ ASSERT_ARG(page, page);
+
+ if (hasGlobalListeners())
+ return true;
+
+ return m_pageListenersMap.contains(page);
+}
+
+void ScriptDebugServer::setBreakpoint(const String& sourceID, unsigned lineNumber, ScriptBreakpoint breakpoint)
+{
+ intptr_t sourceIDValue = sourceID.toIntPtr();
+ if (!sourceIDValue)
+ return;
+ BreakpointsMap::iterator it = m_breakpoints.find(sourceIDValue);
+ if (it == m_breakpoints.end())
+ it = m_breakpoints.set(sourceIDValue, SourceBreakpoints()).first;
+ it->second.set(lineNumber, breakpoint);
+}
+
+void ScriptDebugServer::removeBreakpoint(const String& sourceID, unsigned lineNumber)
+{
+ intptr_t sourceIDValue = sourceID.toIntPtr();
+ if (!sourceIDValue)
+ return;
+ BreakpointsMap::iterator it = m_breakpoints.find(sourceIDValue);
+ if (it != m_breakpoints.end())
+ it->second.remove(lineNumber);
+}
+
+bool ScriptDebugServer::hasBreakpoint(intptr_t sourceID, unsigned lineNumber) const
+{
+ if (!m_breakpointsActivated)
+ return false;
+
+ BreakpointsMap::const_iterator it = m_breakpoints.find(sourceID);
+ if (it == m_breakpoints.end())
+ return false;
+ SourceBreakpoints::const_iterator breakIt = it->second.find(lineNumber);
+ if (breakIt == it->second.end() || !breakIt->second.enabled)
+ return false;
+
+ // An empty condition counts as no condition which is equivalent to "true".
+ if (breakIt->second.condition.isEmpty())
+ return true;
+
+ JSValue exception;
+ JSValue result = m_currentCallFrame->evaluate(stringToUString(breakIt->second.condition), exception);
+ if (exception) {
+ // An erroneous condition counts as "false".
+ return false;
+ }
+ return result.toBoolean(m_currentCallFrame->scopeChain()->globalObject->globalExec());
+}
+
+void ScriptDebugServer::clearBreakpoints()
+{
+ m_breakpoints.clear();
+}
+
+void ScriptDebugServer::setBreakpointsActivated(bool activated)
+{
+ m_breakpointsActivated = activated;
+}
+
+void ScriptDebugServer::setPauseOnExceptionsState(PauseOnExceptionsState pause)
+{
+ m_pauseOnExceptionsState = pause;
+}
+
+void ScriptDebugServer::pauseProgram()
+{
+ m_pauseOnNextStatement = true;
+}
+
+void ScriptDebugServer::continueProgram()
+{
+ if (!m_paused)
+ return;
+
+ m_pauseOnNextStatement = false;
+ m_doneProcessingDebuggerEvents = true;
+}
+
+void ScriptDebugServer::stepIntoStatement()
+{
+ if (!m_paused)
+ return;
+
+ m_pauseOnNextStatement = true;
+ m_doneProcessingDebuggerEvents = true;
+}
+
+void ScriptDebugServer::stepOverStatement()
+{
+ if (!m_paused)
+ return;
+
+ m_pauseOnCallFrame = m_currentCallFrame.get();
+ m_doneProcessingDebuggerEvents = true;
+}
+
+void ScriptDebugServer::stepOutOfFunction()
+{
+ if (!m_paused)
+ return;
+
+ m_pauseOnCallFrame = m_currentCallFrame ? m_currentCallFrame->caller() : 0;
+ m_doneProcessingDebuggerEvents = true;
+}
+
+JavaScriptCallFrame* ScriptDebugServer::currentCallFrame()
+{
+ if (!m_paused)
+ return 0;
+ return m_currentCallFrame.get();
+}
+
+ScriptState* ScriptDebugServer::currentCallFrameState()
+{
+ if (!m_paused)
+ return 0;
+ return m_currentCallFrame->scopeChain()->globalObject->globalExec();
+}
+
+void ScriptDebugServer::dispatchDidParseSource(const ListenerSet& listeners, const JSC::SourceCode& source)
+{
+ String sourceID = ustringToString(JSC::UString::from(source.provider()->asID()));
+ String url = ustringToString(source.provider()->url());
+ String data = ustringToString(JSC::UString(source.data(), source.length()));
+ int firstLine = source.firstLine();
+
+ Vector<ScriptDebugListener*> copy;
+ copyToVector(listeners, copy);
+ for (size_t i = 0; i < copy.size(); ++i)
+ copy[i]->didParseSource(sourceID, url, data, firstLine);
+}
+
+void ScriptDebugServer::dispatchFailedToParseSource(const ListenerSet& listeners, const SourceCode& source, int errorLine, const String& errorMessage)
+{
+ String url = ustringToString(source.provider()->url());
+ String data = ustringToString(JSC::UString(source.data(), source.length()));
+ int firstLine = source.firstLine();
+
+ Vector<ScriptDebugListener*> copy;
+ copyToVector(listeners, copy);
+ for (size_t i = 0; i < copy.size(); ++i)
+ copy[i]->failedToParseSource(url, data, firstLine, errorLine, errorMessage);
+}
+
+static Page* toPage(JSGlobalObject* globalObject)
+{
+ ASSERT_ARG(globalObject, globalObject);
+
+ JSDOMWindow* window = asJSDOMWindow(globalObject);
+ Frame* frame = window->impl()->frame();
+ return frame ? frame->page() : 0;
+}
+
+void ScriptDebugServer::detach(JSGlobalObject* globalObject)
+{
+ // If we're detaching from the currently executing global object, manually tear down our
+ // stack, since we won't get further debugger callbacks to do so. Also, resume execution,
+ // since there's no point in staying paused once a window closes.
+ if (m_currentCallFrame && m_currentCallFrame->dynamicGlobalObject() == globalObject) {
+ m_currentCallFrame = 0;
+ m_pauseOnCallFrame = 0;
+ continueProgram();
+ }
+ Debugger::detach(globalObject);
+}
+
+void ScriptDebugServer::sourceParsed(ExecState* exec, const SourceCode& source, int errorLine, const UString& errorMessage)
+{
+ if (m_callingListeners)
+ return;
+
+ Page* page = toPage(exec->dynamicGlobalObject());
+ if (!page)
+ return;
+
+ m_callingListeners = true;
+
+ bool isError = errorLine != -1;
+
+ if (hasGlobalListeners()) {
+ if (isError)
+ dispatchFailedToParseSource(m_listeners, source, errorLine, ustringToString(errorMessage));
+ else
+ dispatchDidParseSource(m_listeners, source);
+ }
+
+ if (ListenerSet* pageListeners = m_pageListenersMap.get(page)) {
+ ASSERT(!pageListeners->isEmpty());
+ if (isError)
+ dispatchFailedToParseSource(*pageListeners, source, errorLine, ustringToString(errorMessage));
+ else
+ dispatchDidParseSource(*pageListeners, source);
+ }
+
+ m_callingListeners = false;
+}
+
+void ScriptDebugServer::dispatchFunctionToListeners(const ListenerSet& listeners, JavaScriptExecutionCallback callback)
+{
+ Vector<ScriptDebugListener*> copy;
+ copyToVector(listeners, copy);
+ for (size_t i = 0; i < copy.size(); ++i)
+ (copy[i]->*callback)();
+}
+
+void ScriptDebugServer::dispatchFunctionToListeners(JavaScriptExecutionCallback callback, Page* page)
+{
+ if (m_callingListeners)
+ return;
+
+ m_callingListeners = true;
+
+ ASSERT(hasListeners());
+
+ dispatchFunctionToListeners(m_listeners, callback);
+
+ if (ListenerSet* pageListeners = m_pageListenersMap.get(page)) {
+ ASSERT(!pageListeners->isEmpty());
+ dispatchFunctionToListeners(*pageListeners, callback);
+ }
+
+ m_callingListeners = false;
+}
+
+void ScriptDebugServer::setJavaScriptPaused(const PageGroup& pageGroup, bool paused)
+{
+ setMainThreadCallbacksPaused(paused);
+
+ const HashSet<Page*>& pages = pageGroup.pages();
+
+ HashSet<Page*>::const_iterator end = pages.end();
+ for (HashSet<Page*>::const_iterator it = pages.begin(); it != end; ++it)
+ setJavaScriptPaused(*it, paused);
+}
+
+void ScriptDebugServer::setJavaScriptPaused(Page* page, bool paused)
+{
+ ASSERT_ARG(page, page);
+
+ page->setDefersLoading(paused);
+
+ for (Frame* frame = page->mainFrame(); frame; frame = frame->tree()->traverseNext())
+ setJavaScriptPaused(frame, paused);
+}
+
+void ScriptDebugServer::setJavaScriptPaused(Frame* frame, bool paused)
+{
+ ASSERT_ARG(frame, frame);
+
+ if (!frame->script()->canExecuteScripts(NotAboutToExecuteScript))
+ return;
+
+ frame->script()->setPaused(paused);
+
+ Document* document = frame->document();
+ if (paused)
+ document->suspendActiveDOMObjects();
+ else
+ document->resumeActiveDOMObjects();
+
+ setJavaScriptPaused(frame->view(), paused);
+}
+
+void ScriptDebugServer::setJavaScriptPaused(FrameView* view, bool paused)
+{
+ if (!view)
+ return;
+
+ const HashSet<RefPtr<Widget> >* children = view->children();
+ ASSERT(children);
+
+ HashSet<RefPtr<Widget> >::const_iterator end = children->end();
+ for (HashSet<RefPtr<Widget> >::const_iterator it = children->begin(); it != end; ++it) {
+ Widget* widget = (*it).get();
+ if (!widget->isPluginView())
+ continue;
+ static_cast<PluginView*>(widget)->setJavaScriptPaused(paused);
+ }
+}
+
+void ScriptDebugServer::pauseIfNeeded(Page* page)
+{
+ if (m_paused)
+ return;
+
+ if (!page || !hasListenersInterestedInPage(page))
+ return;
+
+ bool pauseNow = m_pauseOnNextStatement;
+ pauseNow |= (m_pauseOnCallFrame == m_currentCallFrame);
+ pauseNow |= (m_currentCallFrame->line() > 0 && hasBreakpoint(m_currentCallFrame->sourceID(), m_currentCallFrame->line()));
+ if (!pauseNow)
+ return;
+
+ m_pauseOnCallFrame = 0;
+ m_pauseOnNextStatement = false;
+ m_paused = true;
+
+ dispatchFunctionToListeners(&ScriptDebugListener::didPause, page);
+
+ setJavaScriptPaused(page->group(), true);
+
+ TimerBase::fireTimersInNestedEventLoop();
+
+ EventLoop loop;
+ m_doneProcessingDebuggerEvents = false;
+ while (!m_doneProcessingDebuggerEvents && !loop.ended())
+ loop.cycle();
+
+ setJavaScriptPaused(page->group(), false);
+
+ m_paused = false;
+
+ dispatchFunctionToListeners(&ScriptDebugListener::didContinue, page);
+}
+
+void ScriptDebugServer::callEvent(const DebuggerCallFrame& debuggerCallFrame, intptr_t sourceID, int lineNumber)
+{
+ if (m_paused)
+ return;
+
+ m_currentCallFrame = JavaScriptCallFrame::create(debuggerCallFrame, m_currentCallFrame, sourceID, lineNumber);
+ pauseIfNeeded(toPage(debuggerCallFrame.dynamicGlobalObject()));
+}
+
+void ScriptDebugServer::atStatement(const DebuggerCallFrame& debuggerCallFrame, intptr_t sourceID, int lineNumber)
+{
+ if (m_paused)
+ return;
+
+ ASSERT(m_currentCallFrame);
+ if (!m_currentCallFrame)
+ return;
+
+ m_currentCallFrame->update(debuggerCallFrame, sourceID, lineNumber);
+ pauseIfNeeded(toPage(debuggerCallFrame.dynamicGlobalObject()));
+}
+
+void ScriptDebugServer::returnEvent(const DebuggerCallFrame& debuggerCallFrame, intptr_t sourceID, int lineNumber)
+{
+ if (m_paused)
+ return;
+
+ ASSERT(m_currentCallFrame);
+ if (!m_currentCallFrame)
+ return;
+
+ m_currentCallFrame->update(debuggerCallFrame, sourceID, lineNumber);
+ pauseIfNeeded(toPage(debuggerCallFrame.dynamicGlobalObject()));
+
+ // Treat stepping over a return statement like stepping out.
+ if (m_currentCallFrame == m_pauseOnCallFrame)
+ m_pauseOnCallFrame = m_currentCallFrame->caller();
+ m_currentCallFrame = m_currentCallFrame->caller();
+}
+
+void ScriptDebugServer::exception(const DebuggerCallFrame& debuggerCallFrame, intptr_t sourceID, int lineNumber, bool hasHandler)
+{
+ if (m_paused)
+ return;
+
+ ASSERT(m_currentCallFrame);
+ if (!m_currentCallFrame)
+ return;
+
+ if (m_pauseOnExceptionsState == PauseOnAllExceptions || (m_pauseOnExceptionsState == PauseOnUncaughtExceptions && !hasHandler))
+ m_pauseOnNextStatement = true;
+
+ m_currentCallFrame->update(debuggerCallFrame, sourceID, lineNumber);
+ pauseIfNeeded(toPage(debuggerCallFrame.dynamicGlobalObject()));
+}
+
+void ScriptDebugServer::willExecuteProgram(const DebuggerCallFrame& debuggerCallFrame, intptr_t sourceID, int lineNumber)
+{
+ if (m_paused)
+ return;
+
+ m_currentCallFrame = JavaScriptCallFrame::create(debuggerCallFrame, m_currentCallFrame, sourceID, lineNumber);
+ pauseIfNeeded(toPage(debuggerCallFrame.dynamicGlobalObject()));
+}
+
+void ScriptDebugServer::didExecuteProgram(const DebuggerCallFrame& debuggerCallFrame, intptr_t sourceID, int lineNumber)
+{
+ if (m_paused)
+ return;
+
+ ASSERT(m_currentCallFrame);
+ if (!m_currentCallFrame)
+ return;
+
+ m_currentCallFrame->update(debuggerCallFrame, sourceID, lineNumber);
+ pauseIfNeeded(toPage(debuggerCallFrame.dynamicGlobalObject()));
+
+ // Treat stepping over the end of a program like stepping out.
+ if (m_currentCallFrame == m_pauseOnCallFrame)
+ m_pauseOnCallFrame = m_currentCallFrame->caller();
+ m_currentCallFrame = m_currentCallFrame->caller();
+}
+
+void ScriptDebugServer::didReachBreakpoint(const DebuggerCallFrame& debuggerCallFrame, intptr_t sourceID, int lineNumber)
+{
+ if (m_paused)
+ return;
+
+ ASSERT(m_currentCallFrame);
+ if (!m_currentCallFrame)
+ return;
+
+ m_pauseOnNextStatement = true;
+ m_currentCallFrame->update(debuggerCallFrame, sourceID, lineNumber);
+ pauseIfNeeded(toPage(debuggerCallFrame.dynamicGlobalObject()));
}
void ScriptDebugServer::recompileAllJSFunctionsSoon()
{
- JavaScriptDebugServer::shared().recompileAllJSFunctionsSoon();
+ m_recompileTimer.startOneShot(0);
+}
+
+void ScriptDebugServer::recompileAllJSFunctions(Timer<ScriptDebugServer>*)
+{
+ JSLock lock(SilenceAssertionsOnly);
+ Debugger::recompileAllJSFunctions(JSDOMWindow::commonJSGlobalData());
+}
+
+void ScriptDebugServer::didAddListener(Page* page)
+{
+ recompileAllJSFunctionsSoon();
+
+ if (page)
+ page->setDebugger(this);
+ else
+ Page::setDebuggerForAllPages(this);
+}
+
+void ScriptDebugServer::didRemoveListener(Page* page)
+{
+ if (hasGlobalListeners() || (page && hasListenersInterestedInPage(page)))
+ return;
+
+ recompileAllJSFunctionsSoon();
+
+ if (page)
+ page->setDebugger(0);
+ else
+ Page::setDebuggerForAllPages(0);
+}
+
+void ScriptDebugServer::didRemoveLastListener()
+{
+ m_doneProcessingDebuggerEvents = true;
}
} // namespace WebCore
diff --git a/WebCore/bindings/js/ScriptDebugServer.h b/WebCore/bindings/js/ScriptDebugServer.h
index 027ffa5..4740585 100644
--- a/WebCore/bindings/js/ScriptDebugServer.h
+++ b/WebCore/bindings/js/ScriptDebugServer.h
@@ -1,27 +1,30 @@
/*
- * Copyright (C) 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
* Copyright (C) 2010 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
*
- * 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.
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef ScriptDebugServer_h
@@ -29,14 +32,118 @@
#if ENABLE(JAVASCRIPT_DEBUGGER)
-#include <wtf/Noncopyable.h>
+#include "PlatformString.h"
+#include "ScriptBreakpoint.h"
+#include "ScriptState.h"
+#include "Timer.h"
+
+#include <debugger/Debugger.h>
+#include <runtime/UString.h>
+#include <wtf/HashMap.h>
+#include <wtf/HashSet.h>
+#include <wtf/RefPtr.h>
+namespace JSC {
+class DebuggerCallFrame;
+class JSGlobalObject;
+}
namespace WebCore {
-class ScriptDebugServer : public Noncopyable {
+class Frame;
+class FrameView;
+class Page;
+class PageGroup;
+class ScriptDebugListener;
+class JavaScriptCallFrame;
+
+class ScriptDebugServer : JSC::Debugger, public Noncopyable {
public:
- static void recompileAllJSFunctions();
- static void recompileAllJSFunctionsSoon();
+ static ScriptDebugServer& shared();
+
+ void addListener(ScriptDebugListener*, Page*);
+ void removeListener(ScriptDebugListener*, Page*);
+
+ void setBreakpoint(const String& sourceID, unsigned lineNumber, ScriptBreakpoint breakpoint);
+ void removeBreakpoint(const String& sourceID, unsigned lineNumber);
+ void clearBreakpoints();
+ void setBreakpointsActivated(bool activated);
+
+ enum PauseOnExceptionsState {
+ DontPauseOnExceptions,
+ PauseOnAllExceptions,
+ PauseOnUncaughtExceptions
+ };
+ PauseOnExceptionsState pauseOnExceptionsState() const { return m_pauseOnExceptionsState; }
+ void setPauseOnExceptionsState(PauseOnExceptionsState);
+
+ void pauseProgram();
+ void continueProgram();
+ void stepIntoStatement();
+ void stepOverStatement();
+ void stepOutOfFunction();
+
+ void recompileAllJSFunctionsSoon();
+ void recompileAllJSFunctions(Timer<ScriptDebugServer>* = 0);
+
+ JavaScriptCallFrame* currentCallFrame();
+ ScriptState* currentCallFrameState();
+
+ void pageCreated(Page*);
+
+private:
+ typedef HashSet<ScriptDebugListener*> ListenerSet;
+ typedef void (ScriptDebugListener::*JavaScriptExecutionCallback)();
+
+ ScriptDebugServer();
+ ~ScriptDebugServer();
+
+ bool hasBreakpoint(intptr_t sourceID, unsigned lineNumber) const;
+ bool hasListeners() const { return !m_listeners.isEmpty() || !m_pageListenersMap.isEmpty(); }
+ bool hasGlobalListeners() const { return !m_listeners.isEmpty(); }
+ bool hasListenersInterestedInPage(Page*);
+
+ void setJavaScriptPaused(const PageGroup&, bool paused);
+ void setJavaScriptPaused(Page*, bool paused);
+ void setJavaScriptPaused(Frame*, bool paused);
+ void setJavaScriptPaused(FrameView*, bool paused);
+
+ void dispatchFunctionToListeners(JavaScriptExecutionCallback, Page*);
+ void dispatchFunctionToListeners(const ListenerSet& listeners, JavaScriptExecutionCallback callback);
+ void dispatchDidParseSource(const ListenerSet& listeners, const JSC::SourceCode& source);
+ void dispatchFailedToParseSource(const ListenerSet& listeners, const JSC::SourceCode& source, int errorLine, const String& errorMessage);
+
+ void pauseIfNeeded(Page*);
+
+ virtual void detach(JSC::JSGlobalObject*);
+
+ virtual void sourceParsed(JSC::ExecState*, const JSC::SourceCode&, int errorLine, const JSC::UString& errorMsg);
+ virtual void callEvent(const JSC::DebuggerCallFrame&, intptr_t sourceID, int lineNumber);
+ virtual void atStatement(const JSC::DebuggerCallFrame&, intptr_t sourceID, int firstLine);
+ virtual void returnEvent(const JSC::DebuggerCallFrame&, intptr_t sourceID, int lineNumber);
+ virtual void exception(const JSC::DebuggerCallFrame&, intptr_t sourceID, int lineNumber, bool hasHandler);
+ virtual void willExecuteProgram(const JSC::DebuggerCallFrame&, intptr_t sourceID, int lineno);
+ virtual void didExecuteProgram(const JSC::DebuggerCallFrame&, intptr_t sourceID, int lineno);
+ virtual void didReachBreakpoint(const JSC::DebuggerCallFrame&, intptr_t sourceID, int lineno);
+
+ void didAddListener(Page*);
+ void didRemoveListener(Page*);
+ void didRemoveLastListener();
+
+ typedef HashMap<Page*, ListenerSet*> PageListenersMap;
+ typedef HashMap<intptr_t, SourceBreakpoints> BreakpointsMap;
+
+ PageListenersMap m_pageListenersMap;
+ ListenerSet m_listeners;
+ bool m_callingListeners;
+ PauseOnExceptionsState m_pauseOnExceptionsState;
+ bool m_pauseOnNextStatement;
+ bool m_paused;
+ bool m_doneProcessingDebuggerEvents;
+ bool m_breakpointsActivated;
+ JavaScriptCallFrame* m_pauseOnCallFrame;
+ RefPtr<JavaScriptCallFrame> m_currentCallFrame;
+ BreakpointsMap m_breakpoints;
+ Timer<ScriptDebugServer> m_recompileTimer;
};
} // namespace WebCore
diff --git a/WebCore/bindings/js/ScriptEventListener.cpp b/WebCore/bindings/js/ScriptEventListener.cpp
index fd45546..01b9060 100644
--- a/WebCore/bindings/js/ScriptEventListener.cpp
+++ b/WebCore/bindings/js/ScriptEventListener.cpp
@@ -59,12 +59,11 @@ PassRefPtr<JSLazyEventListener> createAttributeEventListener(Node* node, Attribu
int lineNumber = 1;
String sourceURL;
- JSObject* wrapper = 0;
// FIXME: We should be able to provide accurate source information for frameless documents, too (e.g. for importing nodes from XMLHttpRequest.responseXML).
if (Frame* frame = node->document()->frame()) {
ScriptController* scriptController = frame->script();
- if (!scriptController->canExecuteScripts())
+ if (!scriptController->canExecuteScripts(AboutToExecuteScript))
return 0;
if (!scriptController->xssAuditor()->canCreateInlineEventListener(attr->localName().string(), attr->value())) {
@@ -74,13 +73,9 @@ PassRefPtr<JSLazyEventListener> createAttributeEventListener(Node* node, Attribu
lineNumber = scriptController->eventHandlerLineNumber();
sourceURL = node->document()->url().string();
-
- JSC::JSLock lock(SilenceAssertionsOnly);
- JSDOMGlobalObject* globalObject = toJSDOMGlobalObject(node->document(), mainThreadNormalWorld());
- wrapper = asObject(toJS(globalObject->globalExec(), globalObject, node));
}
- return JSLazyEventListener::create(attr->localName().string(), eventParameterName(node->isSVGElement()), attr->value(), node, sourceURL, lineNumber, wrapper, mainThreadNormalWorld());
+ return JSLazyEventListener::create(attr->localName().string(), eventParameterName(node->isSVGElement()), attr->value(), node, sourceURL, lineNumber, 0, mainThreadNormalWorld());
}
PassRefPtr<JSLazyEventListener> createAttributeEventListener(Frame* frame, Attribute* attr)
@@ -96,7 +91,7 @@ PassRefPtr<JSLazyEventListener> createAttributeEventListener(Frame* frame, Attri
String sourceURL;
ScriptController* scriptController = frame->script();
- if (!scriptController->canExecuteScripts())
+ if (!scriptController->canExecuteScripts(AboutToExecuteScript))
return 0;
if (!scriptController->xssAuditor()->canCreateInlineEventListener(attr->localName().string(), attr->value())) {
@@ -118,7 +113,7 @@ String getEventListenerHandlerBody(ScriptExecutionContext* context, ScriptState*
JSC::JSObject* jsFunction = jsListener->jsFunction(context);
if (!jsFunction)
return "";
- return jsFunction->toString(scriptState);
+ return ustringToString(jsFunction->toString(scriptState));
}
} // namespace WebCore
diff --git a/WebCore/bindings/js/ScriptFunctionCall.cpp b/WebCore/bindings/js/ScriptFunctionCall.cpp
index 5001d3c..e9073b5 100644
--- a/WebCore/bindings/js/ScriptFunctionCall.cpp
+++ b/WebCore/bindings/js/ScriptFunctionCall.cpp
@@ -60,7 +60,7 @@ void ScriptFunctionCall::appendArgument(const ScriptObject& argument)
void ScriptFunctionCall::appendArgument(const ScriptString& argument)
{
- m_arguments.append(jsString(m_exec, argument));
+ m_arguments.append(jsString(m_exec, argument.ustring()));
}
void ScriptFunctionCall::appendArgument(const ScriptValue& argument)
@@ -132,7 +132,7 @@ ScriptValue ScriptFunctionCall::call(bool& hadException, bool reportExceptions)
JSLock lock(SilenceAssertionsOnly);
- JSValue function = thisObject->get(m_exec, Identifier(m_exec, m_name));
+ JSValue function = thisObject->get(m_exec, Identifier(m_exec, stringToUString(m_name)));
if (m_exec->hadException()) {
if (reportExceptions)
reportException(m_exec, m_exec->exception());
@@ -170,7 +170,7 @@ ScriptObject ScriptFunctionCall::construct(bool& hadException, bool reportExcept
JSLock lock(SilenceAssertionsOnly);
- JSObject* constructor = asObject(thisObject->get(m_exec, Identifier(m_exec, m_name)));
+ JSObject* constructor = asObject(thisObject->get(m_exec, Identifier(m_exec, stringToUString(m_name))));
if (m_exec->hadException()) {
if (reportExceptions)
reportException(m_exec, m_exec->exception());
diff --git a/WebCore/bindings/v8/custom/V8IDBRequestCustom.cpp b/WebCore/bindings/js/ScriptGCEvent.h
index ccf4d0e..57892e7 100644
--- a/WebCore/bindings/v8/custom/V8IDBRequestCustom.cpp
+++ b/WebCore/bindings/js/ScriptGCEvent.h
@@ -28,26 +28,24 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include "config.h"
+#ifndef ScriptGCEvent_h
+#define ScriptGCEvent_h
-#if ENABLE(INDEXED_DATABASE)
-#include "V8IDBRequest.h"
-
-#include "SerializedScriptValue.h"
-#include "V8Proxy.h"
+#if ENABLE(INSPECTOR)
namespace WebCore {
-v8::Handle<v8::Value> V8IDBRequest::resultAccessorGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info)
-{
- IDBRequest* request = V8IDBRequest::toNative(info.Holder());
- SerializedScriptValue* result = request->result();
- if (!result)
- return v8::Null();
+class ScriptGCEventListener;
- return result->deserialize();
-}
+class ScriptGCEvent
+{
+public:
+ static void addEventListener(ScriptGCEventListener*) { }
+ static void removeEventListener(ScriptGCEventListener*) { }
+ static void getHeapSize(size_t&, size_t&) { }
+};
} // namespace WebCore
-#endif
+#endif // !ENABLE(INSPECTOR)
+#endif // !defined(ScriptGCEvent_h)
diff --git a/WebCore/bindings/js/ScriptObject.cpp b/WebCore/bindings/js/ScriptObject.cpp
index 7948219..16b9f01 100644
--- a/WebCore/bindings/js/ScriptObject.cpp
+++ b/WebCore/bindings/js/ScriptObject.cpp
@@ -64,7 +64,7 @@ bool ScriptObject::set(const String& name, const String& value)
{
JSLock lock(SilenceAssertionsOnly);
PutPropertySlot slot;
- jsObject()->put(m_scriptState, Identifier(m_scriptState, name), jsString(m_scriptState, value), slot);
+ jsObject()->put(m_scriptState, Identifier(m_scriptState, stringToUString(name)), jsString(m_scriptState, stringToUString(value)), slot);
return handleException(m_scriptState);
}
diff --git a/WebCore/bindings/js/JavaScriptProfile.h b/WebCore/bindings/js/ScriptProfileNode.h
index 7b75b97..b2edcbf 100644
--- a/WebCore/bindings/js/JavaScriptProfile.h
+++ b/WebCore/bindings/js/ScriptProfileNode.h
@@ -1,5 +1,6 @@
/*
- * Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2010 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -10,10 +11,10 @@
* 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
+ * 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 INC. OR
+ * 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
@@ -23,24 +24,18 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef JavaScriptProfile_h
-#define JavaScriptProfile_h
+#ifndef ScriptProfileNode_h
+#define ScriptProfileNode_h
#if ENABLE(JAVASCRIPT_DEBUGGER)
-
-#include <runtime/JSValue.h>
-
-namespace JSC {
-class ExecState;
-class Profile;
-}
+#include <profiler/ProfileNode.h>
namespace WebCore {
-JSC::JSValue toJS(JSC::ExecState*, JSC::Profile*);
+typedef JSC::ProfileNode ScriptProfileNode;
} // namespace WebCore
#endif // ENABLE(JAVASCRIPT_DEBUGGER)
-#endif
+#endif // ScriptProfileNode_h
diff --git a/WebCore/bindings/js/ScriptProfiler.cpp b/WebCore/bindings/js/ScriptProfiler.cpp
index 789e3d3..5121232 100644
--- a/WebCore/bindings/js/ScriptProfiler.cpp
+++ b/WebCore/bindings/js/ScriptProfiler.cpp
@@ -30,18 +30,19 @@
#include "ScriptProfiler.h"
+#include "JSDOMBinding.h"
#include <profiler/Profiler.h>
namespace WebCore {
void ScriptProfiler::start(ScriptState* state, const String& title)
{
- JSC::Profiler::profiler()->startProfiling(state, title);
+ JSC::Profiler::profiler()->startProfiling(state, stringToUString(title));
}
PassRefPtr<ScriptProfile> ScriptProfiler::stop(ScriptState* state, const String& title)
{
- return JSC::Profiler::profiler()->stopProfiling(state, title);
+ return JSC::Profiler::profiler()->stopProfiling(state, stringToUString(title));
}
} // namespace WebCore
diff --git a/WebCore/bindings/js/ScriptState.cpp b/WebCore/bindings/js/ScriptState.cpp
index b9f334a..3edd1bd 100644
--- a/WebCore/bindings/js/ScriptState.cpp
+++ b/WebCore/bindings/js/ScriptState.cpp
@@ -54,7 +54,7 @@ ScriptState* scriptStateFromNode(DOMWrapperWorld* world, Node* node)
Frame* frame = document->frame();
if (!frame)
return 0;
- if (!frame->script()->canExecuteScripts())
+ if (!frame->script()->canExecuteScripts(NotAboutToExecuteScript))
return 0;
return frame->script()->globalObject(world)->globalExec();
}
diff --git a/WebCore/bindings/js/ScriptState.h b/WebCore/bindings/js/ScriptState.h
index 0c7c575..6bef4f7 100644
--- a/WebCore/bindings/js/ScriptState.h
+++ b/WebCore/bindings/js/ScriptState.h
@@ -33,23 +33,39 @@
#define ScriptState_h
#include "JSDOMBinding.h"
+#include <runtime/Protect.h>
+#include <wtf/Noncopyable.h>
namespace WebCore {
- class DOMWrapperWorld;
- class Frame;
- class Node;
- class Page;
+class DOMWrapperWorld;
+class Frame;
+class Node;
+class Page;
- // The idea is to expose "state-like" methods (hadException, and any other
- // methods where ExecState just dips into globalData) of JSC::ExecState as a
- // separate abstraction.
- // For now, the separation is purely by convention.
- typedef JSC::ExecState ScriptState;
+// The idea is to expose "state-like" methods (hadException, and any other
+// methods where ExecState just dips into globalData) of JSC::ExecState as a
+// separate abstraction.
+// For now, the separation is purely by convention.
+typedef JSC::ExecState ScriptState;
- ScriptState* mainWorldScriptState(Frame*);
+class ScriptStateProtectedPtr : public Noncopyable {
+public:
+ ScriptStateProtectedPtr() { }
+ ScriptStateProtectedPtr(ScriptState* scriptState) : m_globalObject(scriptState->lexicalGlobalObject()) { }
+ ScriptState* get()
+ {
+ if (m_globalObject)
+ return m_globalObject->globalExec();
+ return 0;
+ }
+private:
+ JSC::ProtectedPtr<JSC::JSGlobalObject> m_globalObject;
+};
- ScriptState* scriptStateFromNode(DOMWrapperWorld*, Node*);
- ScriptState* scriptStateFromPage(DOMWrapperWorld*, Page*);
+ScriptState* mainWorldScriptState(Frame*);
+
+ScriptState* scriptStateFromNode(DOMWrapperWorld*, Node*);
+ScriptState* scriptStateFromPage(DOMWrapperWorld*, Page*);
} // namespace WebCore
diff --git a/WebCore/bindings/js/ScriptString.h b/WebCore/bindings/js/ScriptString.h
index 18964b8..ad0ae95 100644
--- a/WebCore/bindings/js/ScriptString.h
+++ b/WebCore/bindings/js/ScriptString.h
@@ -31,6 +31,7 @@
#ifndef ScriptString_h
#define ScriptString_h
+#include "JSDOMBinding.h"
#include "PlatformString.h"
#include <runtime/UString.h>
#include <runtime/StringBuilder.h>
@@ -43,9 +44,12 @@ class ScriptString {
public:
ScriptString() {}
ScriptString(const char* s) : m_str(s) {}
+ ScriptString(const String& s) : m_str(stringToUString(s)) {}
ScriptString(const JSC::UString& s) : m_str(s) {}
operator JSC::UString() const { return m_str; }
+ operator String() const { return ustringToString(m_str); }
+ const JSC::UString& ustring() const { return m_str; }
bool isNull() const { return m_str.isNull(); }
size_t size() const { return m_str.size(); }
@@ -60,7 +64,7 @@ public:
{
JSC::StringBuilder buffer;
buffer.append(m_str);
- buffer.append(s);
+ buffer.append(stringToUString(s));
m_str = buffer.build();
return *this;
}
diff --git a/WebCore/bindings/js/ScriptValue.cpp b/WebCore/bindings/js/ScriptValue.cpp
index 005c329..a52024d 100644
--- a/WebCore/bindings/js/ScriptValue.cpp
+++ b/WebCore/bindings/js/ScriptValue.cpp
@@ -50,7 +50,7 @@ bool ScriptValue::getString(ScriptState* scriptState, String& result) const
UString ustring;
if (!m_value.get().getString(scriptState, ustring))
return false;
- result = ustring;
+ result = ustringToString(ustring);
return true;
}
diff --git a/WebCore/bindings/js/ScriptValue.h b/WebCore/bindings/js/ScriptValue.h
index 9ccb7ac..f4f9c68 100644
--- a/WebCore/bindings/js/ScriptValue.h
+++ b/WebCore/bindings/js/ScriptValue.h
@@ -31,14 +31,15 @@
#ifndef ScriptValue_h
#define ScriptValue_h
+#include "JSDOMBinding.h"
#include "PlatformString.h"
#include "ScriptState.h"
+#include <runtime/JSValue.h>
#include <runtime/Protect.h>
#include <wtf/PassRefPtr.h>
namespace WebCore {
-class String;
class SerializedScriptValue;
class ScriptValue {
@@ -48,7 +49,7 @@ public:
JSC::JSValue jsValue() const { return m_value.get(); }
bool getString(ScriptState*, String& result) const;
- String toString(ScriptState* scriptState) const { return m_value.get().toString(scriptState); }
+ String toString(ScriptState* scriptState) const { return ustringToString(m_value.get().toString(scriptState)); }
bool isEqual(ScriptState*, const ScriptValue&) const;
bool isNull() const;
bool isUndefined() const;
@@ -58,6 +59,8 @@ public:
PassRefPtr<SerializedScriptValue> serialize(ScriptState*);
static ScriptValue deserialize(ScriptState*, SerializedScriptValue*);
+ static ScriptValue undefined() { return ScriptValue(JSC::jsUndefined()); }
+
private:
JSC::ProtectedJSValue m_value;
};
diff --git a/WebCore/bindings/js/ScriptWrappable.h b/WebCore/bindings/js/ScriptWrappable.h
index d70cab7..5e99c1c 100644
--- a/WebCore/bindings/js/ScriptWrappable.h
+++ b/WebCore/bindings/js/ScriptWrappable.h
@@ -31,11 +31,33 @@
#ifndef ScriptWrappable_h
#define ScriptWrappable_h
+#include "JSDOMWrapper.h"
+#include <runtime/WeakGCPtr.h>
+
namespace WebCore {
class ScriptWrappable {
public:
- ScriptWrappable() { }
+ ScriptWrappable() : m_wrapper(0) { }
+
+ DOMObject* wrapper() const
+ {
+ return m_wrapper.get();
+ }
+
+ void setWrapper(DOMObject* wrapper)
+ {
+ ASSERT(wrapper);
+ m_wrapper = wrapper;
+ }
+
+ void clearWrapper(DOMObject* wrapper)
+ {
+ m_wrapper.clear(wrapper);
+ }
+
+private:
+ JSC::WeakGCPtr<DOMObject> m_wrapper;
};
} // namespace WebCore
diff --git a/WebCore/bindings/js/SerializedScriptValue.cpp b/WebCore/bindings/js/SerializedScriptValue.cpp
index fbf8899..e761480 100644
--- a/WebCore/bindings/js/SerializedScriptValue.cpp
+++ b/WebCore/bindings/js/SerializedScriptValue.cpp
@@ -56,7 +56,7 @@ public:
void set(const Identifier& propertyName, const SerializedScriptValueData& value)
{
ASSERT(m_names.size() == m_values.size());
- m_names.append(String(propertyName.ustring()).crossThreadString().impl());
+ m_names.append(identifierToString(propertyName).crossThreadString().impl());
m_values.append(value);
}
@@ -554,7 +554,7 @@ struct SerializingTreeWalker : public BaseWalker {
return SerializedScriptValueData(value);
if (value.isString())
- return SerializedScriptValueData(asString(value)->value(m_exec));
+ return SerializedScriptValueData(ustringToString(asString(value)->value(m_exec)));
if (value.isNumber())
return SerializedScriptValueData(SerializedScriptValueData::NumberType, value.uncheckedGetNumber());
@@ -777,7 +777,7 @@ struct DeserializingTreeWalker : public BaseWalker {
void putProperty(JSObject* object, const RefPtr<StringImpl> propertyName, JSValue value)
{
- object->putDirect(Identifier(m_exec, String(propertyName)), value);
+ object->putDirect(Identifier(m_exec, stringToUString(String(propertyName))), value);
}
bool startArray(RefPtr<SerializedArray>, JSArray* outArray)
diff --git a/WebCore/bindings/js/StringSourceProvider.h b/WebCore/bindings/js/StringSourceProvider.h
index 770c4fc..478c1d1 100644
--- a/WebCore/bindings/js/StringSourceProvider.h
+++ b/WebCore/bindings/js/StringSourceProvider.h
@@ -29,6 +29,7 @@
#ifndef StringSourceProvider_h
#define StringSourceProvider_h
+#include "JSDOMBinding.h"
#include "ScriptSourceProvider.h"
#include <parser/SourceCode.h>
@@ -45,7 +46,7 @@ namespace WebCore {
private:
StringSourceProvider(const String& source, const String& url)
- : ScriptSourceProvider(url)
+ : ScriptSourceProvider(stringToUString(url))
, m_source(source)
{
}
diff --git a/WebCore/bindings/js/WebCoreJSClientData.h b/WebCore/bindings/js/WebCoreJSClientData.h
new file mode 100644
index 0000000..5d03328
--- /dev/null
+++ b/WebCore/bindings/js/WebCoreJSClientData.h
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
+ * Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2007 Samuel Weinig <sam@webkit.org>
+ * Copyright (C) 2009 Google, Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef WebCoreJSClientData_h
+#define WebCoreJSClientData_h
+
+#include "DOMWrapperWorld.h"
+#include "DOMObjectHashTableMap.h"
+#include <wtf/Noncopyable.h>
+#include <wtf/HashSet.h>
+#include <wtf/RefPtr.h>
+
+namespace WebCore {
+
+class WebCoreJSClientData : public JSC::JSGlobalData::ClientData, public Noncopyable {
+ friend class JSGlobalDataWorldIterator;
+ friend void initNormalWorldClientData(JSC::JSGlobalData*);
+
+public:
+ virtual ~WebCoreJSClientData()
+ {
+ ASSERT(m_worldSet.contains(m_normalWorld.get()));
+ ASSERT(m_worldSet.size() == 1);
+ ASSERT(m_normalWorld->hasOneRef());
+ m_normalWorld.clear();
+ ASSERT(m_worldSet.isEmpty());
+ }
+
+ DOMWrapperWorld* normalWorld() { return m_normalWorld.get(); }
+
+ void getAllWorlds(Vector<DOMWrapperWorld*>& worlds)
+ {
+ copyToVector(m_worldSet, worlds);
+ }
+
+ void rememberWorld(DOMWrapperWorld* world)
+ {
+ ASSERT(!m_worldSet.contains(world));
+ m_worldSet.add(world);
+ }
+ void forgetWorld(DOMWrapperWorld* world)
+ {
+ ASSERT(m_worldSet.contains(world));
+ m_worldSet.remove(world);
+ }
+
+ DOMObjectHashTableMap hashTableMap;
+
+private:
+ HashSet<DOMWrapperWorld*> m_worldSet;
+ RefPtr<DOMWrapperWorld> m_normalWorld;
+};
+
+inline void initNormalWorldClientData(JSC::JSGlobalData* globalData)
+{
+ WebCoreJSClientData* webCoreJSClientData = new WebCoreJSClientData;
+ globalData->clientData = webCoreJSClientData; // ~JSGlobalData deletes this pointer.
+ webCoreJSClientData->m_normalWorld = DOMWrapperWorld::create(globalData, true);
+}
+
+} // namespace WebCore
+
+#endif // WebCoreJSClientData_h
diff --git a/WebCore/bindings/js/WorkerScriptController.cpp b/WebCore/bindings/js/WorkerScriptController.cpp
index adcc089..85d6861 100644
--- a/WebCore/bindings/js/WorkerScriptController.cpp
+++ b/WebCore/bindings/js/WorkerScriptController.cpp
@@ -30,11 +30,11 @@
#include "WorkerScriptController.h"
-#include "JSDOMBinding.h"
#include "JSDedicatedWorkerContext.h"
#include "JSSharedWorkerContext.h"
#include "ScriptSourceCode.h"
#include "ScriptValue.h"
+#include "WebCoreJSClientData.h"
#include "WorkerContext.h"
#include "WorkerObjectProxy.h"
#include "WorkerThread.h"
@@ -48,11 +48,11 @@ using namespace JSC;
namespace WebCore {
WorkerScriptController::WorkerScriptController(WorkerContext* workerContext)
- : m_globalData(JSGlobalData::create())
+ : m_globalData(JSGlobalData::create(ThreadStackTypeSmall))
, m_workerContext(workerContext)
, m_executionForbidden(false)
{
- m_globalData->clientData = new WebCoreJSClientData(m_globalData.get());
+ initNormalWorldClientData(m_globalData.get());
}
WorkerScriptController::~WorkerScriptController()
@@ -136,15 +136,16 @@ void WorkerScriptController::setException(ScriptValue exception)
m_workerContextWrapper->globalExec()->setException(exception.jsValue());
}
-void WorkerScriptController::forbidExecution()
+void WorkerScriptController::forbidExecution(ForbidExecutionOption option)
{
- // This function is called from another thread.
+ // This function may be called from another thread.
// Mutex protection for m_executionForbidden is needed to guarantee that the value is synchronized between processors, because
// if it were not, the worker could re-enter JSC::evaluate(), but with timeout already reset.
- // It is not critical for Interpreter::m_timeoutTime to be synchronized, we just rely on it reaching the worker thread's processor sooner or later.
+ // It is not critical for Terminator::m_shouldTerminate to be synchronized, we just rely on it reaching the worker thread's processor sooner or later.
MutexLocker lock(m_sharedDataMutex);
m_executionForbidden = true;
- m_globalData->timeoutChecker.setTimeoutInterval(1); // 1ms is the smallest timeout that can be set.
+ if (option == TerminateRunningScript)
+ m_globalData->terminator.terminateSoon();
}
} // namespace WebCore
diff --git a/WebCore/bindings/js/WorkerScriptController.h b/WebCore/bindings/js/WorkerScriptController.h
index c820cd9..38c3c30 100644
--- a/WebCore/bindings/js/WorkerScriptController.h
+++ b/WebCore/bindings/js/WorkerScriptController.h
@@ -52,6 +52,9 @@ namespace WebCore {
JSWorkerContext* workerContextWrapper()
{
+ if (m_executionForbidden)
+ return 0;
+
initScriptIfNeeded();
return m_workerContextWrapper;
}
@@ -61,7 +64,8 @@ namespace WebCore {
void setException(ScriptValue);
- void forbidExecution();
+ enum ForbidExecutionOption { TerminateRunningScript, LetRunningScriptFinish };
+ void forbidExecution(ForbidExecutionOption);
JSC::JSGlobalData* globalData() { return m_globalData.get(); }
diff --git a/WebCore/bindings/objc/DOM.mm b/WebCore/bindings/objc/DOM.mm
index 907961f..378efe2 100644
--- a/WebCore/bindings/objc/DOM.mm
+++ b/WebCore/bindings/objc/DOM.mm
@@ -37,6 +37,7 @@
#import "Frame.h"
#import "HTMLElement.h"
#import "HTMLNames.h"
+#import "Image.h"
#import "NodeFilter.h"
#import "RenderImage.h"
#import "WebScriptObjectPrivate.h"
diff --git a/WebCore/bindings/objc/WebScriptObject.mm b/WebCore/bindings/objc/WebScriptObject.mm
index d7bc90c..618459a 100644
--- a/WebCore/bindings/objc/WebScriptObject.mm
+++ b/WebCore/bindings/objc/WebScriptObject.mm
@@ -33,6 +33,9 @@
#import "Frame.h"
#import "JSDOMWindow.h"
#import "JSDOMWindowCustom.h"
+#import "JSHTMLElement.h"
+#import "JSPluginElementFunctions.h"
+#import "ObjCRuntimeObject.h"
#import "PlatformString.h"
#import "StringSourceProvider.h"
#import "WebCoreObjCExtras.h"
@@ -286,7 +289,7 @@ static void getListFromNSArray(ExecState *exec, NSArray *array, RootObject* root
ExecState* exec = [self _rootObject]->globalObject()->globalExec();
ASSERT(!exec->hadException());
- JSValue function = [self _imp]->get(exec, Identifier(exec, String(name)));
+ JSValue function = [self _imp]->get(exec, Identifier(exec, stringToUString(String(name))));
CallData callData;
CallType callType = function.getCallData(callData);
if (callType == CallTypeNone)
@@ -363,7 +366,7 @@ static void getListFromNSArray(ExecState *exec, NSArray *array, RootObject* root
JSLock lock(SilenceAssertionsOnly);
PutPropertySlot slot;
- [self _imp]->put(exec, Identifier(exec, String(key)), convertObjcValueToValue(exec, &value, ObjcObjectType, [self _rootObject]), slot);
+ [self _imp]->put(exec, Identifier(exec, stringToUString(String(key))), convertObjcValueToValue(exec, &value, ObjcObjectType, [self _rootObject]), slot);
if (exec->hadException()) {
addExceptionToConsole(exec);
@@ -388,7 +391,7 @@ static void getListFromNSArray(ExecState *exec, NSArray *array, RootObject* root
// leaving the lock permanently held
JSLock lock(SilenceAssertionsOnly);
- JSValue result = [self _imp]->get(exec, Identifier(exec, String(key)));
+ JSValue result = [self _imp]->get(exec, Identifier(exec, stringToUString(String(key))));
if (exec->hadException()) {
addExceptionToConsole(exec);
@@ -417,7 +420,7 @@ static void getListFromNSArray(ExecState *exec, NSArray *array, RootObject* root
ASSERT(!exec->hadException());
JSLock lock(SilenceAssertionsOnly);
- [self _imp]->deleteProperty(exec, Identifier(exec, String(key)));
+ [self _imp]->deleteProperty(exec, Identifier(exec, stringToUString(String(key))));
if (exec->hadException()) {
addExceptionToConsole(exec);
@@ -508,18 +511,17 @@ static void getListFromNSArray(ExecState *exec, NSArray *array, RootObject* root
{
if (value.isObject()) {
JSObject* object = asObject(value);
- ExecState* exec = rootObject->globalObject()->globalExec();
JSLock lock(SilenceAssertionsOnly);
-
- if (object->classInfo() != &RuntimeObjectImp::s_info) {
- JSValue runtimeObject = object->get(exec, Identifier(exec, "__apple_runtime_object"));
- if (runtimeObject && runtimeObject.isObject())
- object = asObject(runtimeObject);
- }
- if (object->classInfo() == &RuntimeObjectImp::s_info) {
- RuntimeObjectImp* imp = static_cast<RuntimeObjectImp*>(object);
- ObjcInstance *instance = static_cast<ObjcInstance*>(imp->getInternalInstance());
+ if (object->inherits(&JSHTMLElement::s_info)) {
+ // Plugin elements cache the instance internally.
+ HTMLElement* el = static_cast<JSHTMLElement*>(object)->impl();
+ ObjcInstance* instance = static_cast<ObjcInstance*>(pluginInstance(el));
+ if (instance)
+ return instance->getObject();
+ } else if (object->inherits(&ObjCRuntimeObject::s_info)) {
+ ObjCRuntimeObject* runtimeObject = static_cast<ObjCRuntimeObject*>(object);
+ ObjcInstance* instance = runtimeObject->getInternalObjCInstance();
if (instance)
return instance->getObject();
return nil;
diff --git a/WebCore/bindings/scripts/CodeGenerator.pm b/WebCore/bindings/scripts/CodeGenerator.pm
index 506e8ea..487a4b3 100644
--- a/WebCore/bindings/scripts/CodeGenerator.pm
+++ b/WebCore/bindings/scripts/CodeGenerator.pm
@@ -17,7 +17,7 @@
# Library General Public License for more details.
#
# You should have received a copy of the GNU Library General Public License
-# aint with this library; see the file COPYING.LIB. If not, write to
+# along with this library; see the file COPYING.LIB. If not, write to
# the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301, USA.
#
diff --git a/WebCore/bindings/scripts/CodeGeneratorGObject.pm b/WebCore/bindings/scripts/CodeGeneratorGObject.pm
new file mode 100644
index 0000000..2a38eff
--- /dev/null
+++ b/WebCore/bindings/scripts/CodeGeneratorGObject.pm
@@ -0,0 +1,1086 @@
+# Copyright (C) 2008 Luke Kenneth Casson Leighton <lkcl@lkcl.net>
+# Copyright (C) 2008 Martin Soto <soto@freedesktop.org>
+# Copyright (C) 2008 Alp Toker <alp@atoker.com>
+# Copyright (C) 2009 Adam Dingle <adam@yorba.org>
+# Copyright (C) 2009 Jim Nelson <jim@yorba.org>
+# Copyright (C) 2009, 2010 Igalia S.L.
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Library General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Library General Public License for more details.
+#
+# You should have received a copy of the GNU Library General Public License
+# along with this library; see the file COPYING.LIB. If not, write to
+# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+package CodeGeneratorGObject;
+
+# Global Variables
+my %implIncludes = ();
+my %hdrIncludes = ();
+
+my $className = "";
+
+# Default constructor
+sub new {
+ my $object = shift;
+ my $reference = { };
+
+ $codeGenerator = shift;
+ $outputDir = shift;
+ mkdir $outputDir;
+
+ bless($reference, $object);
+}
+
+sub finish {
+}
+
+my $licenceTemplate = << "EOF";
+/*
+ This file is part of the WebKit open source project.
+ This file has been generated by generate-bindings.pl. DO NOT MODIFY!
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+EOF
+
+sub GenerateModule {
+}
+
+sub GetParentClassName {
+ my $dataNode = shift;
+
+ return "WebKitDOMObject" if @{$dataNode->parents} eq 0;
+ return "WebKitDOM" . $codeGenerator->StripModule($dataNode->parents(0));
+}
+
+# From String::CamelCase 0.01
+sub camelize
+{
+ my $s = shift;
+ join('', map{ ucfirst $_ } split(/(?<=[A-Za-z])_(?=[A-Za-z])|\b/, $s));
+}
+
+sub decamelize
+{
+ my $s = shift;
+ $s =~ s{([^a-zA-Z]?)([A-Z]*)([A-Z])([a-z]?)}{
+ my $fc = pos($s)==0;
+ my ($p0,$p1,$p2,$p3) = ($1,lc$2,lc$3,$4);
+ my $t = $p0 || $fc ? $p0 : '_';
+ $t .= $p3 ? $p1 ? "${p1}_$p2$p3" : "$p2$p3" : "$p1$p2";
+ $t;
+ }ge;
+ $s;
+}
+
+sub ClassNameToGObjectType {
+ my $className = shift;
+ my $CLASS_NAME = uc(decamelize($className));
+ # Fixup: with our prefix being 'WebKitDOM' decamelize can't get
+ # WebKitDOMCSS right, so we have to fix it manually (and there
+ # might be more like this in the future)
+ $CLASS_NAME =~ s/DOMCSS/DOM_CSS/;
+ return $CLASS_NAME;
+}
+
+sub GetParentGObjType {
+ my $dataNode = shift;
+
+ return "WEBKIT_TYPE_DOM_OBJECT" if @{$dataNode->parents} eq 0;
+ return "WEBKIT_TYPE_DOM_" . ClassNameToGObjectType($codeGenerator->StripModule($dataNode->parents(0)));
+}
+
+sub GetClassName {
+ my $name = $codeGenerator->StripModule(shift);
+
+ return "WebKitDOM$name";
+}
+
+sub GetCoreObject {
+ my ($interfaceName, $name, $parameter) = @_;
+
+ return "WebCore::${interfaceName}* $name = WebKit::core($parameter);";
+}
+
+sub SkipAttribute {
+ my $attribute = shift;
+
+ if ($attribute->signature->extendedAttributes->{"CustomGetter"} ||
+ $attribute->signature->extendedAttributes->{"CustomSetter"}) {
+ return 1;
+ }
+
+ my $propType = $attribute->signature->type;
+ if ($propType eq "EventListener") {
+ return 1;
+ }
+
+ if ($propType =~ /Constructor$/) {
+ return 1;
+ }
+
+ return 0;
+}
+
+# Name type used in the g_value_{set,get}_* functions
+sub GetGValueTypeName {
+ my $type = shift;
+
+ my %types = ("DOMString", "string",
+ "float", "float",
+ "double", "double",
+ "boolean", "boolean",
+ "char", "char",
+ "long", "long",
+ "short", "int",
+ "uchar", "uchar",
+ "unsigned", "uint",
+ "int", "int",
+ "unsigned int", "uint",
+ "unsigned long long", "uint64",
+ "unsigned long", "ulong",
+ "unsigned short", "ushort");
+
+ return $types{$type} ? $types{$type} : "object";
+}
+
+# Name type used in C declarations
+sub GetGlibTypeName {
+ my $type = shift;
+ my $name = GetClassName($type);
+
+ my %types = ("DOMString", "gchar* ",
+ "float", "gfloat",
+ "double", "gdouble",
+ "boolean", "gboolean",
+ "char", "gchar",
+ "long", "glong",
+ "short", "gshort",
+ "uchar", "guchar",
+ "unsigned", "guint",
+ "int", "gint",
+ "unsigned int", "guint",
+ "unsigned long", "gulong",
+ "unsigned long long", "guint64",
+ "unsigned short", "gushort",
+ "void", "void");
+
+ return $types{$type} ? $types{$type} : "$name* ";
+}
+
+sub IsGDOMClassType {
+ my $type = shift;
+
+ return 0 if $type eq "DOMString";
+ return 0 if $type eq "float";
+ return 0 if $type eq "double";
+ return 0 if $type eq "boolean";
+ return 0 if $type eq "char";
+ return 0 if $type eq "long";
+ return 0 if $type eq "short";
+ return 0 if $type eq "uchar";
+ return 0 if $type eq "unsigned";
+ return 0 if $type eq "int";
+ return 0 if $type eq "unsigned int";
+ return 0 if $type eq "unsigned long";
+ return 0 if $type eq "unsigned long long";
+ return 0 if $type eq "unsigned short";
+ return 0 if $type eq "void";
+
+ return 1;
+}
+
+sub GenerateProperties {
+ my ($object, $interfaceName, $dataNode) = @_;
+
+ my $clsCaps = substr(ClassNameToGObjectType($className), 12);
+ my $lowerCaseIfaceName = "webkit_dom_" . (decamelize($interfaceName));
+
+ # Properties
+ my $implContent = "";
+
+ # Properties
+ $implContent = << "EOF";
+enum {
+ PROP_0,
+EOF
+ push(@cBodyPriv, $implContent);
+
+ my @txtInstallProps = ();
+ my @txtSetProps = ();
+ my @txtGetProps = ();
+
+ my $privFunction = GetCoreObject($interfaceName, "coreSelf", "self");
+
+ my $txtGetProp = << "EOF";
+static void ${lowerCaseIfaceName}_get_property(GObject* object, guint prop_id, GValue* value, GParamSpec* pspec)
+{
+ ${className}* self = WEBKIT_DOM_${clsCaps}(object);
+ $privFunction
+
+ switch (prop_id) {
+EOF
+ push(@txtGetProps, $txtGetProp);
+
+ my $txtSetProps = << "EOF";
+static void ${lowerCaseIfaceName}_set_property(GObject* object, guint prop_id, const GValue* value, GParamSpec* pspec)
+{
+ ${className} *self = WEBKIT_DOM_${clsCaps}(object);
+ $privFunction
+
+ switch (prop_id) {
+EOF
+ push(@txtSetProps, $txtSetProps);
+
+ # Iterate over the interface attributes and generate a property for
+ # each one of them.
+ SKIPENUM:
+ foreach my $attribute (@{$dataNode->attributes}) {
+ if (SkipAttribute($attribute)) {
+ next SKIPENUM;
+ }
+
+ my $camelPropName = $attribute->signature->name;
+ my $setPropNameFunction = $codeGenerator->WK_ucfirst($camelPropName);
+ my $getPropNameFunction = $codeGenerator->WK_lcfirst($camelPropName);
+
+ my $propName = decamelize($camelPropName);
+ my $propNameCaps = uc($propName);
+ $propName =~ s/_/-/g;
+ my ${propEnum} = "PROP_${propNameCaps}";
+ push(@cBodyPriv, " ${propEnum},\n");
+
+ my $propType = $attribute->signature->type;
+ my ${propGType} = decamelize($propType);
+ if ($propGType eq "event_target") {
+ $propGType = "event_target_node";
+ }
+ my ${ucPropGType} = uc($propGType);
+
+ my $gtype = GetGValueTypeName($propType);
+ my $gparamflag = "WEBKIT_PARAM_READABLE";
+ my $writeable = $attribute->type !~ /^readonly/;
+ my $const = "read-only ";
+ if ($writeable && $custom) {
+ $const = "read-only (due to custom functions needed in webkitdom)";
+ next SKIPENUM;
+ }
+ if ($writeable && !$custom) {
+ $gparamflag = "WEBKIT_PARAM_READWRITE";
+ $const = "read-write ";
+ }
+
+ my $type = GetGlibTypeName($propType);
+ $nick = decamelize("${interfaceName}_${propName}");
+ $long = "${const} ${type} ${interfaceName}.${propName}";
+
+ my $convertFunction = "";
+
+ if ($writeable && ($gtype eq "boolean" || $gtype eq "float" || $gtype eq "double" ||
+ $gtype eq "uint64" || $gtype eq "ulong" || $gtype eq "long" ||
+ $gtype eq "uint" || $gtype eq "ushort" || $gtype eq "uchar" ||
+ $gtype eq "char" || $gtype eq "string")) {
+
+ push(@txtSetProps, " case ${propEnum}:\n {\n");
+ push(@txtSetProps, " WebCore::ExceptionCode ec = 0;\n") if @{$attribute->setterExceptions};
+
+ if ($gtype eq "string") {
+ $convertFunction = "WebCore::String::fromUTF8";
+ } elsif ($attribute->signature->extendedAttributes->{"ConvertFromString"}) {
+ $convertFunction = "WebCore::String::number";
+ }
+
+ push(@txtSetProps, " coreSelf->set${setPropNameFunction}(${convertFunction}(g_value_get_$gtype(value))");
+ push(@txtSetProps, ", ec") if @{$attribute->setterExceptions};
+ push(@txtSetProps, ");\n");
+
+ push(@txtSetProps, " break;\n }\n");
+ }
+
+ push(@txtGetProps, " case ${propEnum}:\n {\n");
+
+ my $exception = "";
+ if (@{$attribute->getterExceptions}) {
+ $exception = "ec";
+ push(@txtGetProps, " WebCore::ExceptionCode ec = 0;\n");
+ }
+
+ my $postConvertFunction = "";
+ my $done = 0;
+ if ($gtype eq "string") {
+ push(@txtGetProps, " g_value_take_string(value, convertToUTF8String(coreSelf->${getPropNameFunction}(${exception})));\n");
+ $done = 1;
+ } elsif ($gtype eq "object") {
+
+ $txtGetProp = << "EOF";
+ RefPtr<WebCore::${propType}> ptr = coreSelf->${getPropNameFunction}(${exception});
+ g_value_set_object(value, WebKit::kit(ptr.get()));
+EOF
+ push(@txtGetProps, $txtGetProp);
+
+ $done = 1;
+ }
+
+ if($attribute->signature->extendedAttributes->{"ConvertFromString"}) {
+ # TODO: Add other conversion functions for different types. Current
+ # IDLs only list longs.
+ if($gtype eq "long") {
+ $convertFunction = "";
+ $postConvertFunction = ".toInt()";
+ } else {
+ die "Can't convert to type ${gtype}.";
+ }
+ }
+
+ # FIXME: get rid of this glitch?
+ my $_gtype = $gtype;
+ if ($gtype eq "ushort") {
+ $_gtype = "uint";
+ }
+
+ if (!$done) {
+ push(@txtGetProps, " g_value_set_$_gtype(value, ${convertFunction}coreSelf->${getPropNameFunction}(${exception})${postConvertFunction});\n");
+ }
+
+ push(@txtGetProps, " break;\n }\n");
+
+my %param_spec_options = ("int", "G_MININT, /* min */\nG_MAXINT, /* max */\n0, /* default */",
+ "boolean", "FALSE, /* default */",
+ "float", "G_MINFLOAT, /* min */\nG_MAXFLOAT, /* max */\n0.0, /* default */",
+ "double", "G_MINDOUBLE, /* min */\nG_MAXDOUBLE, /* max */\n0.0, /* default */",
+ "uint64", "0, /* min */\nG_MAXUINT64, /* min */\n0, /* default */",
+ "long", "G_MINLONG, /* min */\nG_MAXLONG, /* max */\n0, /* default */",
+ "ulong", "0, /* min */\nG_MAXULONG, /* max */\n0, /* default */",
+ "uint", "0, /* min */\nG_MAXUINT, /* max */\n0, /* default */",
+ "ushort", "0, /* min */\nG_MAXUINT16, /* max */\n0, /* default */",
+ "uchar", "G_MININT8, /* min */\nG_MAXINT8, /* max */\n0, /* default */",
+ "char", "0, /* min */\nG_MAXUINT8, /* max */\n0, /* default */",
+ "string", "\"\", /* default */",
+ "object", "WEBKIT_TYPE_DOM_${ucPropGType}, /* gobject type */");
+
+ my $txtInstallProp = << "EOF";
+ g_object_class_install_property(gobjectClass,
+ ${propEnum},
+ g_param_spec_${_gtype}("${propName}", /* name */
+ "$nick", /* short description */
+ "$long", /* longer - could do with some extra doc stuff here */
+ $param_spec_options{$gtype}
+ ${gparamflag}));
+EOF
+ push(@txtInstallProps, $txtInstallProp);
+ $txtInstallProp = "/* TODO! $gtype */\n";
+ }
+
+ push(@cBodyPriv, "};\n\n");
+
+ $txtGetProp = << "EOF";
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+ break;
+ }
+}
+EOF
+ push(@txtGetProps, $txtGetProp);
+
+ $txtSetProps = << "EOF";
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+ break;
+ }
+}
+EOF
+ push(@txtSetProps, $txtSetProps);
+
+ # TODO: work out if it's appropriate to split this into many different
+ # signals e.g. "click" etc.
+ my $txtInstallSignals = "";
+
+ $implContent = << "EOF";
+
+static void ${lowerCaseIfaceName}_finalize(GObject* object)
+{
+ WebKitDOMObject* dom_object = WEBKIT_DOM_OBJECT(object);
+
+ if (dom_object->coreObject != NULL) {
+ WebCore::${interfaceName}* coreObject = static_cast<WebCore::${interfaceName} *>(dom_object->coreObject);
+
+ WebKit::DOMObjectCache::forget(coreObject);
+ coreObject->deref();
+
+ dom_object->coreObject = NULL;
+ }
+
+ G_OBJECT_CLASS(${lowerCaseIfaceName}_parent_class)->finalize(object);
+}
+
+@txtSetProps
+
+@txtGetProps
+
+static void ${lowerCaseIfaceName}_class_init(${className}Class* requestClass)
+{
+ GObjectClass *gobjectClass = G_OBJECT_CLASS(requestClass);
+ gobjectClass->finalize = ${lowerCaseIfaceName}_finalize;
+ gobjectClass->set_property = ${lowerCaseIfaceName}_set_property;
+ gobjectClass->get_property = ${lowerCaseIfaceName}_get_property;
+
+@txtInstallProps
+
+$txtInstallSignals
+}
+
+static void ${lowerCaseIfaceName}_init(${className}* request)
+{
+}
+
+EOF
+ push(@cBodyPriv, $implContent);
+}
+
+sub GenerateHeader {
+ my ($object, $interfaceName, $parentClassName) = @_;
+
+ my $implContent = "";
+
+ # Add the default header template
+ @hPrefix = split("\r", $licenceTemplate);
+ push(@hPrefix, "\n");
+
+ #Header guard
+ my $guard = $className . "_h";
+
+ @hPrefixGuard = << "EOF";
+#ifndef $guard
+#define $guard
+
+EOF
+
+ $implContent = << "EOF";
+G_BEGIN_DECLS
+EOF
+
+ push(@hBodyPre, $implContent);
+
+ my $clsCaps = uc(decamelize($interfaceName));
+ my $lowerCaseIfaceName = "webkit_dom_" . (decamelize($interfaceName));
+
+ $implContent = << "EOF";
+
+#define WEBKIT_TYPE_DOM_${clsCaps} (${lowerCaseIfaceName}_get_type())
+#define WEBKIT_DOM_${clsCaps}(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), WEBKIT_TYPE_DOM_${clsCaps}, ${className}))
+#define WEBKIT_DOM_${clsCaps}_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), WEBKIT_TYPE_DOM_${clsCaps}, ${className}Class)
+#define WEBKIT_DOM_IS_${clsCaps}(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), WEBKIT_TYPE_DOM_${clsCaps}))
+#define WEBKIT_DOM_IS_${clsCaps}_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), WEBKIT_TYPE_DOM_${clsCaps}))
+#define WEBKIT_DOM_${clsCaps}_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), WEBKIT_TYPE_DOM_${clsCaps}, ${className}Class))
+
+struct _${className} {
+ ${parentClassName} parent_instance;
+};
+
+struct _${className}Class {
+ ${parentClassName}Class parent_class;
+};
+
+WEBKIT_API GType
+${lowerCaseIfaceName}_get_type (void);
+
+EOF
+
+ push(@hBody, $implContent);
+}
+
+sub getIncludeHeader {
+ my $type = shift;
+ my $name = GetClassName($type);
+
+ return "" if $type eq "int";
+ return "" if $type eq "long";
+ return "" if $type eq "short";
+ return "" if $type eq "char";
+ return "" if $type eq "float";
+ return "" if $type eq "double";
+ return "" if $type eq "unsigned";
+ return "" if $type eq "unsigned int";
+ return "" if $type eq "unsigned long";
+ return "" if $type eq "unsigned long long";
+ return "" if $type eq "unsigned short";
+ return "" if $type eq "DOMTimeStamp";
+ return "" if $type eq "EventListener";
+ return "" if $type eq "unsigned char";
+ return "" if $type eq "DOMString";
+ return "" if $type eq "float";
+ return "" if $type eq "boolean";
+ return "" if $type eq "void";
+
+ return "$name.h";
+}
+
+sub addIncludeInBody {
+ my $type = shift;
+
+ my $header = getIncludeHeader($type);
+ if ($header eq "") {
+ return;
+ }
+
+ if (IsGDOMClassType($type)) {
+ $implIncludes{"webkit/$header"} = 1;
+ } else {
+ $implIncludes{$header} = 1
+ }
+}
+
+sub GenerateFunction {
+ my ($object, $interfaceName, $function, $prefix) = @_;
+
+ my $functionSigName = $function->signature->name;
+ my $functionSigType = $function->signature->type;
+ my $functionName = "webkit_dom_" . decamelize($interfaceName) . "_" . $prefix . decamelize($functionSigName);
+ my $returnType = GetGlibTypeName($functionSigType);
+ my $returnValueIsGDOMType = IsGDOMClassType($functionSigType);
+
+ my $functionSig = "$className *self";
+
+ my $callImplParams = "";
+
+ # skip some custom functions for now
+ my $isCustomFunction = $function->signature->extendedAttributes->{"Custom"} ||
+ $function->signature->extendedAttributes->{"CustomArgumentHandling"};
+
+ foreach my $param (@{$function->parameters}) {
+ my $paramIDLType = $param->type;
+ if ($paramIDLType eq "Event") {
+ push(@hBody, "\n/* TODO: event function ${functionName} */\n\n");
+ push(@cBody, "\n/* TODO: event function ${functionName} */\n\n");
+ return;
+ }
+ addIncludeInBody($paramIDLType);
+ my $paramType = GetGlibTypeName($paramIDLType);
+ my $paramName = decamelize($param->name);
+
+ $functionSig .= ", $paramType $paramName";
+
+ my $paramIsGDOMType = IsGDOMClassType($paramIDLType);
+ if ($paramIsGDOMType) {
+ if ($paramIDLType ne "DOMObject") {
+ $implIncludes{"webkit/WebKitDOM${paramIDLType}Private.h"} = 1;
+ }
+ }
+ if ($paramIsGDOMType || ($paramIDLType eq "DOMString")) {
+ $paramName = "_g_" . $paramName;
+ }
+ if ($callImplParams) {
+ $callImplParams .= ", $paramName";
+ } else {
+ $callImplParams = "$paramName";
+ }
+ }
+
+ if ($functionSigType eq "Event") {
+ push(@hBody, "\n/* TODO: event function ${functionName} */\n\n");
+ push(@cBody, "\n/* TODO: event function ${functionName} */\n\n");
+ return;
+ }
+
+ if ($returnType ne "void" && $returnValueIsGDOMType) {
+ if ($functionSigType ne "EventTarget") {
+ $implIncludes{"webkit/WebKitDOM${functionSigType}Private.h"} = 1;
+ $implIncludes{"webkit/WebKitDOM${functionSigType}.h"} = 1;
+ }
+
+ $implIncludes{"${functionSigType}.h"} = 1;
+ }
+
+ # skip custom functions for now
+ # but skip from here to allow some headers to be created
+ # for a successful compile.
+ if ($isCustomFunction &&
+ $functionName ne "webkit_dom_node_remove_child" &&
+ $functionName ne "webkit_dom_node_insert_before" &&
+ $functionName ne "webkit_dom_node_replace_child" &&
+ $functionName ne "webkit_dom_node_append_child") {
+ push(@hBody, "\n/* TODO: custom function ${functionName} */\n\n");
+ push(@cBody, "\n/* TODO: custom function ${functionName} */\n\n");
+ return;
+ }
+
+ if(@{$function->raisesExceptions}) {
+ $functionSig .= ", GError **error";
+ }
+
+ push(@hBody, "WEBKIT_API $returnType\n$functionName ($functionSig);\n\n");
+ push(@cBody, "$returnType\n$functionName ($functionSig)\n{\n");
+
+ if ($returnType ne "void") {
+ # TODO: return proper default result
+ push(@cBody, " g_return_val_if_fail (self, 0);\n");
+ } else {
+ push(@cBody, " g_return_if_fail (self);\n");
+ }
+
+ # The WebKit::core implementations check for NULL already; no need to
+ # duplicate effort.
+ push(@cBody, " WebCore::${interfaceName} * item = WebKit::core(self);\n");
+
+ foreach my $param (@{$function->parameters}) {
+ my $paramName = decamelize($param->name);
+ my $paramIDLType = $param->type;
+ my $paramTypeIsPrimitive = $codeGenerator->IsPrimitiveType($paramIDLType);
+ my $paramIsGDOMType = IsGDOMClassType($paramIDLType);
+ if (!$paramTypeIsPrimitive) {
+ if ($returnType ne "void") {
+ # TODO: return proper default result
+ push(@cBody, " g_return_val_if_fail ($paramName, 0);\n");
+ } else {
+ push(@cBody, " g_return_if_fail ($paramName);\n");
+ }
+ }
+ }
+
+ $returnParamName = "";
+ foreach my $param (@{$function->parameters}) {
+ my $paramIDLType = $param->type;
+ my $paramName = decamelize($param->name);
+
+ my $paramIsGDOMType = IsGDOMClassType($paramIDLType);
+ if ($paramIDLType eq "DOMString") {
+ push(@cBody, " WebCore::String _g_${paramName} = WebCore::String::fromUTF8($paramName);\n");
+ }
+ if ($paramIsGDOMType) {
+ push(@cBody, " WebCore::${paramIDLType} * _g_${paramName} = WebKit::core($paramName);\n");
+ if ($returnType ne "void") {
+ # TODO: return proper default result
+ push(@cBody, " g_return_val_if_fail (_g_${paramName}, 0);\n");
+ } else {
+ push(@cBody, " g_return_if_fail (_g_${paramName});\n");
+ }
+ }
+ $returnParamName = "_g_".$paramName if $param->extendedAttributes->{"Return"};
+ }
+
+ my $assign = "";
+ my $assignPre = "";
+ my $assignPost = "";
+
+ if ($returnType ne "void" && !$isCustomFunction) {
+ if ($returnValueIsGDOMType) {
+ $assign = "PassRefPtr<WebCore::${functionSigType}> g_res = ";
+ $assignPre = "WTF::getPtr(";
+ $assignPost = ")";
+ } else {
+ $assign = "${returnType} res = ";
+ }
+ }
+ my $exceptions = "";
+ if (@{$function->raisesExceptions}) {
+ push(@cBody, " WebCore::ExceptionCode ec = 0;\n");
+ if (${callImplParams} ne "") {
+ $exceptions = ", ec";
+ } else {
+ $exceptions = "ec";
+ }
+ }
+
+ # We need to special-case these Node methods because their C++ signature is different
+ # from what we'd expect given their IDL description; see Node.h.
+ if ($functionName eq "webkit_dom_node_append_child" ||
+ $functionName eq "webkit_dom_node_insert_before" ||
+ $functionName eq "webkit_dom_node_replace_child" ||
+ $functionName eq "webkit_dom_node_remove_child") {
+ my $customNodeAppendChild = << "EOF";
+ bool ok = item->${functionSigName}(${callImplParams}${exceptions});
+ if (ok)
+ {
+ ${returnType} res = static_cast<${returnType}>(WebKit::kit($returnParamName));
+ return res;
+ }
+EOF
+ push(@cBody, $customNodeAppendChild);
+
+ if(@{$function->raisesExceptions}) {
+ my $exceptionHandling = << "EOF";
+
+ WebCore::ExceptionCodeDescription ecdesc;
+ WebCore::getExceptionCodeDescription(ec, ecdesc);
+ g_set_error_literal(error, g_quark_from_string("WEBKIT_DOM"), ecdesc.code, ecdesc.name);
+EOF
+ push(@cBody, $exceptionHandling);
+ }
+ push(@cBody, "return NULL;");
+ push(@cBody, "}\n\n");
+ return;
+ } elsif ($functionSigType eq "DOMString") {
+ push(@cBody, " ${assign}convertToUTF8String(item->${functionSigName}(${callImplParams}${exceptions}));\n" );
+ } else {
+ push(@cBody, " ${assign}${assignPre}item->${functionSigName}(${callImplParams}${exceptions}${assignPost});\n" );
+
+ if(@{$function->raisesExceptions}) {
+ my $exceptionHandling = << "EOF";
+ if(ec) {
+ WebCore::ExceptionCodeDescription ecdesc;
+ WebCore::getExceptionCodeDescription(ec, ecdesc);
+ g_set_error_literal(error, g_quark_from_string("WEBKIT_DOM"), ecdesc.code, ecdesc.name);
+ }
+EOF
+ push(@cBody, $exceptionHandling);
+ }
+ }
+
+ if ($returnType ne "void" && !$isCustomFunction) {
+ if ($functionSigType ne "DOMObject") {
+ if ($returnValueIsGDOMType) {
+ push(@cBody, " ${returnType} res = static_cast<${returnType}>(WebKit::kit(g_res.get()));\n");
+ }
+ }
+ if ($functionSigType eq "DOMObject") {
+ push(@cBody, " return NULL; /* TODO: return canvas object */\n");
+ } else {
+ push(@cBody, " return res;\n");
+ }
+ }
+ push(@cBody, "\n}\n\n");
+}
+
+sub ClassHasFunction {
+ my ($class, $name) = @_;
+
+ foreach my $function (@{$class->functions}) {
+ if ($function->signature->name eq $name) {
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+sub GenerateFunctions {
+ my ($object, $interfaceName, $dataNode) = @_;
+
+ foreach my $function (@{$dataNode->functions}) {
+ $object->GenerateFunction($interfaceName, $function, "");
+ }
+
+ TOP:
+ foreach my $attribute (@{$dataNode->attributes}) {
+ if (SkipAttribute($attribute)) {
+ next TOP;
+ }
+
+ if ($attribute->signature->name eq "type"
+ # This will conflict with the get_type() function we define to return a GType
+ # according to GObject conventions. Skip this for now.
+ || $attribute->signature->name eq "URL" # TODO: handle this
+ || $attribute->signature->extendedAttributes->{"ConvertFromString"} # TODO: handle this
+ ) {
+ next TOP;
+ }
+
+ my $attrNameUpper = $codeGenerator->WK_ucfirst($attribute->signature->name);
+ my $getname = "get${attrNameUpper}";
+ my $setname = "set${attrNameUpper}";
+ if (ClassHasFunction($dataNode, $getname) || ClassHasFunction($dataNode, $setname)) {
+ # Very occasionally an IDL file defines getter/setter functions for one of its
+ # attributes; in this case we don't need to autogenerate the getter/setter.
+ next TOP;
+ }
+
+ # Generate an attribute getter. For an attribute "foo", this is a function named
+ # "get_foo" which calls a DOM class method named foo().
+ my $function = new domFunction();
+ $function->signature($attribute->signature);
+ $function->raisesExceptions($attribute->getterExceptions);
+ $object->GenerateFunction($interfaceName, $function, "get_");
+
+ if ($attribute->type =~ /^readonly/ ||
+ $attribute->signature->extendedAttributes->{"Replaceable"} # can't handle this yet
+ ) {
+ next TOP;
+ }
+
+ # Generate an attribute setter. For an attribute, "foo", this is a function named
+ # "set_foo" which calls a DOM class method named setFoo().
+ $function = new domFunction();
+
+ $function->signature(new domSignature());
+ $function->signature->name($setname);
+ $function->signature->type("void");
+ $function->signature->extendedAttributes($attribute->signature->extendedAttributes);
+
+ my $param = new domSignature();
+ $param->name("value");
+ $param->type($attribute->signature->type);
+ my %attributes = ();
+ $param->extendedAttributes(attributes);
+ my $arrayRef = $function->parameters;
+ push(@$arrayRef, $param);
+
+ $function->raisesExceptions($attribute->setterExceptions);
+
+ $object->GenerateFunction($interfaceName, $function, "");
+ }
+}
+
+sub GenerateCFile {
+ my ($object, $interfaceName, $parentClassName, $parentGObjType, $dataNode) = @_;
+ my $implContent = "";
+
+ my $clsCaps = uc(decamelize($interfaceName));
+ my $lowerCaseIfaceName = "webkit_dom_" . decamelize($interfaceName);
+
+ $implContent = << "EOF";
+G_DEFINE_TYPE(${className}, ${lowerCaseIfaceName}, ${parentGObjType})
+
+namespace WebKit {
+
+${className}* wrap${interfaceName}(WebCore::${interfaceName}* coreObject)
+{
+ g_return_val_if_fail(coreObject != 0, 0);
+
+ ${className}* wrapper = WEBKIT_DOM_${clsCaps}(g_object_new(WEBKIT_TYPE_DOM_${clsCaps}, NULL));
+ g_return_val_if_fail(wrapper != 0, 0);
+
+ /* We call ref() rather than using a C++ smart pointer because we can't store a C++ object
+ * in a C-allocated GObject structure. See the finalize() code for the
+ * matching deref().
+ */
+
+ coreObject->ref();
+ WEBKIT_DOM_OBJECT(wrapper)->coreObject = coreObject;
+
+ return wrapper;
+}
+
+WebCore::${interfaceName}* core(${className}* request)
+{
+ g_return_val_if_fail(request != 0, 0);
+
+ WebCore::${interfaceName}* coreObject = static_cast<WebCore::${interfaceName}*>(WEBKIT_DOM_OBJECT(request)->coreObject);
+ g_return_val_if_fail(coreObject != 0, 0);
+
+ return coreObject;
+}
+
+} // namespace WebKit
+EOF
+
+ push(@cBodyPriv, $implContent);
+ $object->GenerateProperties($interfaceName, $dataNode);
+ $object->GenerateFunctions($interfaceName, $dataNode);
+}
+
+sub GenerateEndHeader {
+ my ($object) = @_;
+
+ #Header guard
+ my $guard = $className . "_h";
+
+ push(@hBody, "G_END_DECLS\n\n");
+ push(@hBody, "#endif /* $guard */\n");
+}
+
+sub GeneratePrivateHeader {
+ my $object = shift;
+ my $dataNode = shift;
+
+ my $interfaceName = $dataNode->name;
+ my $filename = "$outputDir/" . $className . "Private.h";
+ my $guard = uc(decamelize($className)) . "_PRIVATE_H";
+ my $parentClassName = GetParentClassName($dataNode);
+ my $hasLegacyParent = $dataNode->extendedAttributes->{"LegacyParent"};
+ my $hasRealParent = @{$dataNode->parents} > 0;
+ my $hasParent = $hasLegacyParent || $hasRealParent;
+
+ open(PRIVHEADER, ">$filename") or die "Couldn't open file $filename for writing";
+
+ print PRIVHEADER split("\r", $licenceTemplate);
+ print PRIVHEADER "\n";
+
+ my $text = << "EOF";
+#ifndef $guard
+#define $guard
+
+#include <glib-object.h>
+#include <webkit/${parentClassName}.h>
+#include "${interfaceName}.h"
+EOF
+
+ print PRIVHEADER $text;
+
+ print PRIVHEADER map { "#include \"$_\"\n" } sort keys(%hdrPropIncludes);
+ print PRIVHEADER "\n" if keys(%hdrPropIncludes);
+
+ $text = << "EOF";
+namespace WebKit {
+ ${className} *
+ wrap${interfaceName}(WebCore::${interfaceName} *coreObject);
+
+ WebCore::${interfaceName} *
+ core(${className} *request);
+
+EOF
+
+ print PRIVHEADER $text;
+
+ if ($className ne "WebKitDOMNode") {
+ $text = << "EOF";
+ gpointer
+ kit(WebCore::${interfaceName}* node);
+
+EOF
+ print PRIVHEADER $text;
+ }
+
+ $text = << "EOF";
+} // namespace WebKit
+
+#endif /* ${guard} */
+EOF
+ print PRIVHEADER $text;
+
+ close(PRIVHEADER);
+}
+
+sub UsesManualToJSImplementation {
+ my $type = shift;
+
+ return 1 if $type eq "Node" or $type eq "Document" or $type eq "HTMLCollection" or
+ $type eq "SVGPathSeg" or $type eq "StyleSheet" or $type eq "CSSRule" or $type eq "CSSValue" or
+ $type eq "Event" or $type eq "Element" or $type eq "Text";
+ return 0;
+}
+
+sub Generate {
+ my ($object, $dataNode) = @_;
+
+ my $hasLegacyParent = $dataNode->extendedAttributes->{"LegacyParent"};
+ my $hasRealParent = @{$dataNode->parents} > 0;
+ my $hasParent = $hasLegacyParent || $hasRealParent;
+ my $parentClassName = GetParentClassName($dataNode);
+ my $parentGObjType = GetParentGObjType($dataNode);
+ my $interfaceName = $dataNode->name;
+
+ # Add the default impl header template
+ @cPrefix = split("\r", $licenceTemplate);
+ push(@cPrefix, "\n");
+
+ $implIncludes{"webkitmarshal.h"} = 1;
+ $implIncludes{"webkitprivate.h"} = 1;
+ $implIncludes{"WebKitDOMBinding.h"} = 1;
+ $implIncludes{"gobject/ConvertToUTF8String.h"} = 1;
+ $implIncludes{"webkit/$className.h"} = 1;
+ $implIncludes{"webkit/${className}Private.h"} = 1;
+ $implIncludes{"${interfaceName}.h"} = 1;
+ $implIncludes{"ExceptionCode.h"} = 1;
+
+ $hdrIncludes{"webkit/${parentClassName}.h"} = 1;
+
+ if ($className ne "WebKitDOMNode") {
+ my $converter = << "EOF";
+namespace WebKit {
+
+gpointer kit(WebCore::$interfaceName* obj)
+{
+ g_return_val_if_fail(obj != 0, 0);
+
+ if (gpointer ret = DOMObjectCache::get(obj))
+ return ret;
+
+ return DOMObjectCache::put(obj, WebKit::wrap${interfaceName}(obj));
+}
+
+} // namespace WebKit //
+
+EOF
+ push(@cBody, $converter);
+ }
+
+ $object->GenerateHeader($interfaceName, $parentClassName);
+ $object->GenerateCFile($interfaceName, $parentClassName, $parentGObjType, $dataNode);
+ $object->GenerateEndHeader();
+ $object->GeneratePrivateHeader($dataNode);
+}
+
+# Internal helper
+sub WriteData {
+ my ($object, $name) = @_;
+
+ # Write public header.
+ my $hdrFName = "$outputDir/" . $name . ".h";
+ open(HEADER, ">$hdrFName") or die "Couldn't open file $hdrFName";
+
+ print HEADER @hPrefix;
+ print HEADER @hPrefixGuard;
+ print HEADER "#include \"webkit/webkitdomdefines.h\"\n";
+ print HEADER "#include <glib-object.h>\n";
+ print HEADER "#include <webkit/webkitdefines.h>\n";
+ print HEADER map { "#include \"$_\"\n" } sort keys(%hdrIncludes);
+ print HEADER "\n" if keys(%hdrIncludes);
+ print HEADER "\n";
+ print HEADER @hBodyPre;
+ print HEADER @hBody;
+
+ close(HEADER);
+
+ # Write the implementation sources
+ my $implFileName = "$outputDir/" . $name . ".cpp";
+ open(IMPL, ">$implFileName") or die "Couldn't open file $implFileName";
+
+ print IMPL @cPrefix;
+ print IMPL "#include <glib-object.h>\n";
+ print IMPL "#include \"config.h\"\n\n";
+ print IMPL "#include <wtf/GetPtr.h>\n";
+ print IMPL "#include <wtf/RefPtr.h>\n";
+ print IMPL map { "#include \"$_\"\n" } sort keys(%implIncludes);
+ print IMPL "\n" if keys(%implIncludes);
+ print IMPL @cBody;
+
+ print IMPL "\n";
+ print IMPL @cBodyPriv;
+
+ close(IMPL);
+
+ %implIncludes = ();
+ %hdrIncludes = ();
+ @hPrefix = ();
+ @hBody = ();
+
+ @cPrefix = ();
+ @cBody = ();
+ @cBodyPriv = ();
+}
+
+sub GenerateInterface {
+ my ($object, $dataNode, $defines) = @_;
+ my $name = $dataNode->name;
+
+ # Set up some global variables
+ $className = GetClassName($dataNode->name);
+ $object->Generate($dataNode);
+
+ # Write changes
+ my $fname = "WebKitDOM_" . $name;
+ $fname =~ s/_//g;
+ $object->WriteData($fname);
+}
diff --git a/WebCore/bindings/scripts/CodeGeneratorJS.pm b/WebCore/bindings/scripts/CodeGeneratorJS.pm
index 94fc2b8..919e321 100644
--- a/WebCore/bindings/scripts/CodeGeneratorJS.pm
+++ b/WebCore/bindings/scripts/CodeGeneratorJS.pm
@@ -17,7 +17,7 @@
# Library General Public License for more details.
#
# You should have received a copy of the GNU Library General Public License
-# aint with this library; see the file COPYING.LIB. If not, write to
+# along with this library; see the file COPYING.LIB. If not, write to
# the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301, USA.
@@ -32,6 +32,7 @@ my $writeDependencies = 0;
my @headerContentHeader = ();
my @headerContent = ();
my %headerIncludes = ();
+my %headerTrailingIncludes = ();
my @implContentHeader = ();
my @implContent = ();
@@ -143,6 +144,7 @@ sub GetVisibleClassName
my $className = shift;
return "DOMException" if $className eq "DOMCoreException";
+ return "FormData" if $className eq "DOMFormData";
return $className;
}
@@ -212,12 +214,32 @@ sub AddIncludesForSVGAnimatedType
}
}
+sub IsScriptProfileType
+{
+ my $type = shift;
+ return 1 if ($type eq "ScriptProfile" or $type eq "ScriptProfileNode");
+ return 0;
+}
+
+sub AddTypedefForScriptProfileType
+{
+ my $type = shift;
+ (my $jscType = $type) =~ s/Script//;
+
+ push(@headerContent, "typedef JSC::$jscType $type;\n\n");
+}
+
sub AddClassForwardIfNeeded
{
my $implClassName = shift;
# SVGAnimatedLength/Number/etc. are typedefs to SVGAnimatedTemplate, so don't use class forwards for them!
- push(@headerContent, "class $implClassName;\n\n") unless $codeGenerator->IsSVGAnimatedType($implClassName);
+ unless ($codeGenerator->IsSVGAnimatedType($implClassName) or IsScriptProfileType($implClassName)) {
+ push(@headerContent, "class $implClassName;\n\n");
+ # ScriptProfile and ScriptProfileNode are typedefs to JSC::Profile and JSC::ProfileNode.
+ } elsif (IsScriptProfileType($implClassName)) {
+ AddTypedefForScriptProfileType($implClassName);
+ }
}
sub IsSVGTypeNeedingContextParameter
@@ -517,6 +539,7 @@ sub GenerateHeader
# Get correct pass/store types respecting PODType flag
my $podType = $dataNode->extendedAttributes->{"PODType"};
my $implType = $podType ? "JSSVGPODTypeWrapper<$podType> " : $implClassName;
+
$headerIncludes{"$podType.h"} = 1 if $podType and $podType ne "float";
$headerIncludes{"JSSVGPODTypeWrapper.h"} = 1 if $podType;
@@ -551,7 +574,9 @@ sub GenerateHeader
# Prototype
push(@headerContent, " static JSC::JSObject* createPrototype(JSC::ExecState*, JSC::JSGlobalObject*);\n") unless ($dataNode->extendedAttributes->{"ExtendsDOMGlobalObject"});
- $implIncludes{"${className}Custom.h"} = 1 if $dataNode->extendedAttributes->{"CustomHeader"} || $dataNode->extendedAttributes->{"CustomPutFunction"} || $dataNode->extendedAttributes->{"DelegatingPutFunction"};
+ $headerTrailingIncludes{"${className}Custom.h"} = 1 if $dataNode->extendedAttributes->{"CustomHeader"};
+
+ $implIncludes{"${className}Custom.h"} = 1 if !$dataNode->extendedAttributes->{"CustomHeader"} && ($dataNode->extendedAttributes->{"CustomPutFunction"} || $dataNode->extendedAttributes->{"DelegatingPutFunction"});
my $hasGetter = $numAttributes > 0
|| !($dataNode->extendedAttributes->{"OmitConstructor"}
@@ -743,7 +768,7 @@ sub GenerateHeader
# Index getter
if ($dataNode->extendedAttributes->{"HasIndexGetter"}) {
- push(@headerContent, " static JSC::JSValue indexGetter(JSC::ExecState*, const JSC::Identifier&, const JSC::PropertySlot&);\n");
+ push(@headerContent, " static JSC::JSValue indexGetter(JSC::ExecState*, JSC::JSValue, unsigned);\n");
}
if ($dataNode->extendedAttributes->{"HasCustomIndexGetter"} || $dataNode->extendedAttributes->{"HasNumericIndexGetter"}) {
push(@headerContent, " JSC::JSValue getByIndex(JSC::ExecState*, unsigned index);\n");
@@ -758,7 +783,7 @@ sub GenerateHeader
if ($dataNode->extendedAttributes->{"HasNameGetter"} || $dataNode->extendedAttributes->{"HasOverridingNameGetter"}) {
push(@headerContent, "private:\n");
push(@headerContent, " static bool canGetItemsForName(JSC::ExecState*, $implClassName*, const JSC::Identifier&);\n");
- push(@headerContent, " static JSC::JSValue nameGetter(JSC::ExecState*, const JSC::Identifier&, const JSC::PropertySlot&);\n");
+ push(@headerContent, " static JSC::JSValue nameGetter(JSC::ExecState*, JSC::JSValue, const JSC::Identifier&);\n");
}
push(@headerContent, "};\n\n");
@@ -859,7 +884,7 @@ sub GenerateHeader
push(@headerContent,"// Attributes\n\n");
foreach my $attribute (@{$dataNode->attributes}) {
my $getter = "js" . $interfaceName . $codeGenerator->WK_ucfirst($attribute->signature->name) . ($attribute->signature->type =~ /Constructor$/ ? "Constructor" : "");
- push(@headerContent, "JSC::JSValue ${getter}(JSC::ExecState*, const JSC::Identifier&, const JSC::PropertySlot&);\n");
+ push(@headerContent, "JSC::JSValue ${getter}(JSC::ExecState*, JSC::JSValue, const JSC::Identifier&);\n");
unless ($attribute->type =~ /readonly/) {
my $setter = "setJS" . $interfaceName . $codeGenerator->WK_ucfirst($attribute->signature->name) . ($attribute->signature->type =~ /Constructor$/ ? "Constructor" : "");
push(@headerContent, "void ${setter}(JSC::ExecState*, JSC::JSObject*, JSC::JSValue);\n");
@@ -868,7 +893,7 @@ sub GenerateHeader
if (!($dataNode->extendedAttributes->{"OmitConstructor"} || $dataNode->extendedAttributes->{"CustomConstructor"})) {
my $getter = "js" . $interfaceName . "Constructor";
- push(@headerContent, "JSC::JSValue ${getter}(JSC::ExecState*, const JSC::Identifier&, const JSC::PropertySlot&);\n");
+ push(@headerContent, "JSC::JSValue ${getter}(JSC::ExecState*, JSC::JSValue, const JSC::Identifier&);\n");
}
}
@@ -876,7 +901,7 @@ sub GenerateHeader
push(@headerContent,"// Constants\n\n");
foreach my $constant (@{$dataNode->constants}) {
my $getter = "js" . $interfaceName . $codeGenerator->WK_ucfirst($constant->name);
- push(@headerContent, "JSC::JSValue ${getter}(JSC::ExecState*, const JSC::Identifier&, const JSC::PropertySlot&);\n");
+ push(@headerContent, "JSC::JSValue ${getter}(JSC::ExecState*, JSC::JSValue, const JSC::Identifier&);\n");
}
}
@@ -1286,9 +1311,9 @@ sub GenerateImplementation
push(@implContent, "#if ${conditionalString}\n");
}
- push(@implContent, "JSValue ${getFunctionName}(ExecState* exec, const Identifier&, const PropertySlot& slot)\n");
+ push(@implContent, "JSValue ${getFunctionName}(ExecState* exec, JSValue slotBase, const Identifier&)\n");
push(@implContent, "{\n");
- push(@implContent, " ${className}* castedThis = static_cast<$className*>(asObject(slot.slotBase()));\n");
+ push(@implContent, " ${className}* castedThis = static_cast<$className*>(asObject(slotBase));\n");
my $implClassNameForValueConversion = "";
if (!$podType and ($codeGenerator->IsSVGAnimatedType($implClassName) or $attribute->type !~ /^readonly/)) {
@@ -1402,9 +1427,9 @@ sub GenerateImplementation
if (!($dataNode->extendedAttributes->{"OmitConstructor"} || $dataNode->extendedAttributes->{"CustomConstructor"})) {
my $constructorFunctionName = "js" . $interfaceName . "Constructor";
- push(@implContent, "JSValue ${constructorFunctionName}(ExecState* exec, const Identifier&, const PropertySlot& slot)\n");
+ push(@implContent, "JSValue ${constructorFunctionName}(ExecState* exec, JSValue slotBase, const Identifier&)\n");
push(@implContent, "{\n");
- push(@implContent, " ${className}* domObject = static_cast<$className*>(asObject(slot.slotBase()));\n");
+ push(@implContent, " ${className}* domObject = static_cast<$className*>(asObject(slotBase));\n");
push(@implContent, " return ${className}::getConstructor(exec, domObject->globalObject());\n");
push(@implContent, "}\n");
}
@@ -1461,6 +1486,12 @@ sub GenerateImplementation
my $putFunctionName = "setJS" . $interfaceName . $codeGenerator->WK_ucfirst($name) . ($attribute->signature->type =~ /Constructor$/ ? "Constructor" : "");
my $implSetterFunctionName = $codeGenerator->WK_ucfirst($name);
+ my $conditional = $attribute->signature->extendedAttributes->{"Conditional"};
+ if ($conditional) {
+ $conditionalString = "ENABLE(" . join(") && ENABLE(", split(/&/, $conditional)) . ")";
+ push(@implContent, "#if ${conditionalString}\n");
+ }
+
push(@implContent, "void ${putFunctionName}(ExecState* exec, JSObject* thisObject, JSValue value)\n");
push(@implContent, "{\n");
@@ -1478,12 +1509,28 @@ sub GenerateImplementation
} elsif ($type eq "EventListener") {
$implIncludes{"JSEventListener.h"} = 1;
push(@implContent, " UNUSED_PARAM(exec);\n");
+ my $windowEventListener = $attribute->signature->extendedAttributes->{"WindowEventListener"};
+ if ($windowEventListener) {
+ push(@implContent, " ${className}* castedThis = static_cast<${className}*>(thisObject);\n");
+ push(@implContent, " JSDOMGlobalObject* globalObject = castedThis->globalObject();\n");
+ }
push(@implContent, " $implClassName* imp = static_cast<$implClassName*>(static_cast<$className*>(thisObject)->impl());\n");
- push(@implContent, " imp->set$implSetterFunctionName(createJSAttributeEventListener(exec, value, thisObject));\n");
+ if ($interfaceName eq "WorkerContext" and $name eq "onerror") {
+ $implIncludes{"JSWorkerContextErrorHandler.h"} = 1;
+ push(@implContent, " imp->set$implSetterFunctionName(createJSWorkerContextErrorHandler(exec, value, thisObject));\n");
+ } else {
+ if ($windowEventListener) {
+ push(@implContent, " imp->set$implSetterFunctionName(createJSAttributeEventListener(exec, value, globalObject));\n");
+ } else {
+ push(@implContent, " imp->set$implSetterFunctionName(createJSAttributeEventListener(exec, value, thisObject));\n");
+ }
+ }
} elsif ($attribute->signature->type =~ /Constructor$/) {
my $constructorType = $attribute->signature->type;
$constructorType =~ s/Constructor$//;
- $implIncludes{"JS" . $constructorType . ".h"} = 1;
+ if ($constructorType ne "DOMObject") {
+ $implIncludes{"JS" . $constructorType . ".h"} = 1;
+ }
push(@implContent, " // Shadowing a built-in constructor\n");
push(@implContent, " static_cast<$className*>(thisObject)->putDirect(Identifier(exec, \"$name\"), value);\n");
} elsif ($attribute->signature->extendedAttributes->{"Replaceable"}) {
@@ -1522,7 +1569,13 @@ sub GenerateImplementation
}
}
- push(@implContent, "}\n\n");
+ push(@implContent, "}\n");
+
+ if ($conditional) {
+ push(@implContent, "#endif\n");
+ }
+
+ push(@implContent, "\n");
}
}
}
@@ -1701,7 +1754,7 @@ sub GenerateImplementation
my $getter = "js" . $interfaceName . $codeGenerator->WK_ucfirst($constant->name);
# FIXME: this casts into int to match our previous behavior which turned 0xFFFFFFFF in -1 for NodeFilter.SHOW_ALL
- push(@implContent, "JSValue ${getter}(ExecState* exec, const Identifier&, const PropertySlot&)\n");
+ push(@implContent, "JSValue ${getter}(ExecState* exec, JSValue, const Identifier&)\n");
push(@implContent, "{\n");
push(@implContent, " return jsNumber(exec, static_cast<int>(" . $constant->value . "));\n");
push(@implContent, "}\n\n");
@@ -1709,14 +1762,14 @@ sub GenerateImplementation
}
if ($dataNode->extendedAttributes->{"HasIndexGetter"}) {
- push(@implContent, "\nJSValue ${className}::indexGetter(ExecState* exec, const Identifier&, const PropertySlot& slot)\n");
+ push(@implContent, "\nJSValue ${className}::indexGetter(ExecState* exec, JSValue slotBase, unsigned index)\n");
push(@implContent, "{\n");
- push(@implContent, " ${className}* thisObj = static_cast<$className*>(asObject(slot.slotBase()));\n");
+ push(@implContent, " ${className}* thisObj = static_cast<$className*>(asObject(slotBase));\n");
if (IndexGetterReturnsStrings($implClassName)) {
$implIncludes{"KURL.h"} = 1;
- push(@implContent, " return jsStringOrNull(exec, thisObj->impl()->item(slot.index()));\n");
+ push(@implContent, " return jsStringOrNull(exec, thisObj->impl()->item(index));\n");
} else {
- push(@implContent, " return toJS(exec, thisObj->globalObject(), static_cast<$implClassName*>(thisObj->impl())->item(slot.index()));\n");
+ push(@implContent, " return toJS(exec, thisObj->globalObject(), static_cast<$implClassName*>(thisObj->impl())->item(index));\n");
}
push(@implContent, "}\n");
if ($interfaceName eq "HTMLCollection" or $interfaceName eq "HTMLAllCollection") {
@@ -1832,7 +1885,8 @@ sub GetNativeTypeFromSignature
my %nativeType = (
"CompareHow" => "Range::CompareHow",
- "DOMString" => "const UString&",
+ "DOMString" => "const String&",
+ "DOMObject" => "ScriptValue",
"NodeFilter" => "RefPtr<NodeFilter>",
"SVGAngle" => "SVGAngle",
"SVGLength" => "SVGLength",
@@ -1883,7 +1937,11 @@ sub JSValueToNative
if ($type eq "DOMString") {
return "valueToStringWithNullCheck(exec, $value)" if $signature->extendedAttributes->{"ConvertNullToNullString"};
return "valueToStringWithUndefinedOrNullCheck(exec, $value)" if $signature->extendedAttributes->{"ConvertUndefinedOrNullToNullString"};
- return "$value.toString(exec)";
+ return "ustringToString($value.toString(exec))";
+ }
+
+ if ($type eq "DOMObject") {
+ return "$value";
}
if ($type eq "SerializedScriptValue" or $type eq "any") {
@@ -1985,7 +2043,11 @@ sub NativeToJSValue
}
if ($type eq "DOMObject") {
- $implIncludes{"JSCanvasRenderingContext2D.h"} = 1;
+ if ($implClassName eq "Document") {
+ $implIncludes{"JSCanvasRenderingContext2D.h"} = 1;
+ } else {
+ return "$value.jsValue();";
+ }
} elsif ($type =~ /SVGPathSeg/) {
$implIncludes{"JS$type.h"} = 1;
$joinedName = $type;
@@ -2123,6 +2185,7 @@ tableSizeLoop:
$i = 0;
foreach my $key (@{$keys}) {
my $conditional;
+ my $targetType;
if ($conditionals) {
$conditional = $conditionals->{$key};
@@ -2131,7 +2194,13 @@ tableSizeLoop:
my $conditionalString = "ENABLE(" . join(") && ENABLE(", split(/&/, $conditional)) . ")";
push(@implContent, "#if ${conditionalString}\n");
}
- push(@implContent, " { \"$key\", @$specials[$i], (intptr_t)@$value1[$i], (intptr_t)@$value2[$i] },\n");
+
+ if ("@$specials[$i]" =~ m/Function/) {
+ $targetType = "static_cast<NativeFunction>";
+ } else {
+ $targetType = "static_cast<PropertySlot::GetValueFunc>";
+ }
+ push(@implContent, " { \"$key\", @$specials[$i], (intptr_t)" . $targetType . "(@$value1[$i]), (intptr_t)@$value2[$i] },\n");
if ($conditional) {
push(@implContent, "#endif\n");
}
@@ -2246,12 +2315,23 @@ sub WriteData
}
print $HEADER @headerContent;
+
+ @includes = ();
+ foreach my $include (keys %headerTrailingIncludes) {
+ $include = "\"$include\"" unless $include =~ /^["<]/; # "
+ push @includes, $include;
+ }
+ foreach my $include (sort @includes) {
+ print $HEADER "#include $include\n";
+ }
+
close($HEADER);
undef($HEADER);
@headerContentHeader = ();
@headerContent = ();
%headerIncludes = ();
+ %headerTrailingIncludes = ();
}
if (defined($DEPS)) {
diff --git a/WebCore/bindings/scripts/CodeGeneratorObjC.pm b/WebCore/bindings/scripts/CodeGeneratorObjC.pm
index dcb22a7..3c5fe45 100644
--- a/WebCore/bindings/scripts/CodeGeneratorObjC.pm
+++ b/WebCore/bindings/scripts/CodeGeneratorObjC.pm
@@ -17,7 +17,7 @@
# Library General Public License for more details.
#
# You should have received a copy of the GNU Library General Public License
-# aint with this library; see the file COPYING.LIB. If not, write to
+# along with this library; see the file COPYING.LIB. If not, write to
# the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301, USA.
#
@@ -222,7 +222,13 @@ sub ReadPublicInterfaces
%publicInterfaces = ();
my $fileName = "WebCore/bindings/objc/PublicDOMInterfaces.h";
- open FILE, "-|", "/usr/bin/gcc", "-E", "-P", "-x", "objective-c",
+ my $gccLocation = "";
+ if (($Config::Config{'osname'}) =~ /solaris/i) {
+ $gccLocation = "/usr/sfw/bin/gcc";
+ } else {
+ $gccLocation = "/usr/bin/gcc";
+ }
+ open FILE, "-|", $gccLocation, "-E", "-P", "-x", "objective-c",
(map { "-D$_" } split(/ +/, $defines)), "-DOBJC_CODE_GENERATION", $fileName or die "Could not open $fileName";
my @documentContent = <FILE>;
close FILE;
diff --git a/WebCore/bindings/scripts/CodeGeneratorV8.pm b/WebCore/bindings/scripts/CodeGeneratorV8.pm
index ee51ec3..1c5f398 100644
--- a/WebCore/bindings/scripts/CodeGeneratorV8.pm
+++ b/WebCore/bindings/scripts/CodeGeneratorV8.pm
@@ -18,7 +18,7 @@
# Library General Public License for more details.
#
# You should have received a copy of the GNU Library General Public License
-# aint with this library; see the file COPYING.LIB. If not, write to
+# along with this library; see the file COPYING.LIB. If not, write to
# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.
#
@@ -84,11 +84,6 @@ sub finish
$object->WriteData();
}
-sub leftShift($$) {
- my ($value, $distance) = @_;
- return (($value << $distance) & 0xFFFFFFFF);
-}
-
# Workaround for V8 bindings difference where RGBColor is not a POD type.
sub IsPodType
{
@@ -126,13 +121,6 @@ sub GenerateModule
$module = $dataNode->module;
}
-sub GetLegacyHeaderIncludes
-{
- my $legacyParent = shift;
-
- die "Don't know what headers to include for module $module";
-}
-
sub AvoidInclusionOfType
{
my $type = shift;
@@ -142,14 +130,6 @@ sub AvoidInclusionOfType
return 0;
}
-sub UsesManualToJSImplementation
-{
- my $type = shift;
-
- return 1 if $type eq "SVGPathSeg";
- return 0;
-}
-
sub AddIncludesForType
{
my $type = $codeGenerator->StripModule(shift);
@@ -203,14 +183,6 @@ sub AddIncludesForSVGAnimatedType
$implIncludes{"SVGAnimatedTemplate.h"} = 1;
}
-sub AddClassForwardIfNeeded
-{
- my $implClassName = shift;
-
- # SVGAnimatedLength/Number/etc.. are typedefs to SVGAnimtatedTemplate, so don't use class forwards for them!
- push(@headerContent, "class $implClassName;\n\n") unless $codeGenerator->IsSVGAnimatedType($implClassName);
-}
-
# If the node has a [Conditional=XXX] attribute, returns an "ENABLE(XXX)" string for use in an #if.
sub GenerateConditionalString
{
@@ -223,6 +195,23 @@ sub GenerateConditionalString
}
}
+sub LinkOverloadedFunctions
+{
+ my $dataNode = shift;
+
+ # Identifies overloaded functions and for each function adds an array with
+ # links to its respective overloads (including itself).
+ my %nameToFunctionsMap = ();
+ foreach my $function (@{$dataNode->functions}) {
+ my $name = $function->signature->name;
+ $nameToFunctionsMap{$name} = [] if !exists $nameToFunctionsMap{$name};
+ push(@{$nameToFunctionsMap{$name}}, $function);
+ $function->{overloads} = $nameToFunctionsMap{$name};
+ $function->{overloadIndex} = @{$nameToFunctionsMap{$name}};
+ }
+
+}
+
sub GenerateHeader
{
my $object = shift;
@@ -243,19 +232,26 @@ sub GenerateHeader
@headerContent = split("\r", $headerTemplate);
push(@headerContent, "\n#if ${conditionalString}\n\n") if $conditionalString;
- push(@headerContent, "\n#ifndef $className" . "_H");
- push(@headerContent, "\n#define $className" . "_H\n\n");
+ push(@headerContent, "\n#ifndef $className" . "_h");
+ push(@headerContent, "\n#define $className" . "_h\n\n");
# Get correct pass/store types respecting PODType flag
my $podType = $dataNode->extendedAttributes->{"PODType"};
- push(@headerContent, "#include \"$podType.h\"\n") if $podType and ($podType ne "double" and $podType ne "float" and $podType ne "RGBA32");
+ my %headerInclues = ();
+ $headerIncludes{"$podType.h"} = 1 if $podType and ($podType ne "double" and $podType ne "float" and $podType ne "RGBA32");
+ $headerIncludes{"StringHash.h"} = 1;
+ $headerIncludes{"WrapperTypeInfo.h"} = 1;
+ my $headerClassInclude = GetHeaderClassInclude($implClassName);
+ $headerIncludes{$headerClassInclude} = 1 if $headerClassInclude ne "";
+
+ foreach my $headerInclude (sort keys(%headerIncludes)) {
+ push(@headerContent, "#include \"${headerInclude}\"\n");
+ }
push(@headerContent, "#include <v8.h>\n");
push(@headerContent, "#include <wtf/HashMap.h>\n");
- push(@headerContent, "#include \"StringHash.h\"\n");
- push(@headerContent, "#include \"V8Index.h\"\n");
- push(@headerContent, GetHeaderClassInclude($implClassName));
+
push(@headerContent, "\nnamespace WebCore {\n");
if ($podType) {
push(@headerContent, "\ntemplate<typename PODType> class V8SVGPODTypeWrapper;\n");
@@ -269,17 +265,22 @@ sub GenerateHeader
my $forceNewObjectParameter = IsDOMNodeType($interfaceName) ? ", bool forceNewObject = false" : "";
push(@headerContent, <<END);
- public:
- static bool HasInstance(v8::Handle<v8::Value> value);
- static v8::Persistent<v8::FunctionTemplate> GetRawTemplate();
- static v8::Persistent<v8::FunctionTemplate> GetTemplate();
- static ${nativeType}* toNative(v8::Handle<v8::Object>);
- static v8::Handle<v8::Object> wrap(${nativeType}*${forceNewObjectParameter});
+public:
+ static bool HasInstance(v8::Handle<v8::Value> value);
+ static v8::Persistent<v8::FunctionTemplate> GetRawTemplate();
+ static v8::Persistent<v8::FunctionTemplate> GetTemplate();
+ static ${nativeType}* toNative(v8::Handle<v8::Object>);
+ static v8::Handle<v8::Object> wrap(${nativeType}*${forceNewObjectParameter});
+ static void derefObject(void*);
+ static WrapperTypeInfo info;
END
+ if (IsActiveDomType($implClassName)) {
+ push(@headerContent, " static ActiveDOMObject* toActiveDOMObject(v8::Handle<v8::Object>);\n");
+ }
if ($implClassName eq "DOMWindow") {
- push(@headerContent, <<END);
- static v8::Persistent<v8::ObjectTemplate> GetShadowObjectTemplate();
+ push(@headerContent, <<END);
+ static v8::Persistent<v8::ObjectTemplate> GetShadowObjectTemplate();
END
}
@@ -288,11 +289,12 @@ END
my $name = $function->signature->name;
my $attrExt = $function->signature->extendedAttributes;
- # FIXME: We should only be generating callback declarations for functions labeled [Custom] or [V8Custom],
- # but we can't do that due to some mislabeled functions in the idl's (https://bugs.webkit.org/show_bug.cgi?id=33066).
- push(@headerContent, <<END);
- static v8::Handle<v8::Value> ${name}Callback(const v8::Arguments&);
+ if ($attrExt->{"Custom"} || $attrExt->{"V8Custom"}) {
+ push(@headerContent, <<END);
+ static v8::Handle<v8::Value> ${name}Callback(const v8::Arguments&);
END
+ }
+
if ($attrExt->{"EnabledAtRuntime"}) {
push(@enabledAtRuntime, $function);
}
@@ -300,7 +302,7 @@ END
if ($dataNode->extendedAttributes->{"CustomConstructor"} || $dataNode->extendedAttributes->{"CanBeConstructed"}) {
push(@headerContent, <<END);
- static v8::Handle<v8::Value> constructorCallback(const v8::Arguments& args);
+ static v8::Handle<v8::Value> constructorCallback(const v8::Arguments& args);
END
}
@@ -310,13 +312,13 @@ END
if ($attrExt->{"V8CustomGetter"} || $attrExt->{"CustomGetter"}
|| $attrExt->{"V8Custom"} || $attrExt->{"Custom"}) {
push(@headerContent, <<END);
- static v8::Handle<v8::Value> ${name}AccessorGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info);
+ static v8::Handle<v8::Value> ${name}AccessorGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info);
END
}
if ($attrExt->{"V8CustomSetter"} || $attrExt->{"CustomSetter"}
|| $attrExt->{"V8Custom"} || $attrExt->{"Custom"}) {
push(@headerContent, <<END);
- static void ${name}AccessorSetter(v8::Local<v8::String> name, v8::Local<v8::Value> value, const v8::AccessorInfo& info);
+ static void ${name}AccessorSetter(v8::Local<v8::String> name, v8::Local<v8::Value> value, const v8::AccessorInfo& info);
END
}
if ($attrExt->{"EnabledAtRuntime"}) {
@@ -330,24 +332,24 @@ END
if ($dataNode->extendedAttributes->{"CheckDomainSecurity"}) {
push(@headerContent, <<END);
- static bool namedSecurityCheck(v8::Local<v8::Object> host, v8::Local<v8::Value> key, v8::AccessType, v8::Local<v8::Value> data);
- static bool indexedSecurityCheck(v8::Local<v8::Object> host, uint32_t index, v8::AccessType, v8::Local<v8::Value> data);
+ static bool namedSecurityCheck(v8::Local<v8::Object> host, v8::Local<v8::Value> key, v8::AccessType, v8::Local<v8::Value> data);
+ static bool indexedSecurityCheck(v8::Local<v8::Object> host, uint32_t index, v8::AccessType, v8::Local<v8::Value> data);
END
}
push(@headerContent, <<END);
};
- v8::Handle<v8::Value> toV8(${nativeType}*${forceNewObjectParameter});
+v8::Handle<v8::Value> toV8(${nativeType}*${forceNewObjectParameter});
END
if (IsRefPtrType($implClassName)) {
push(@headerContent, <<END);
- v8::Handle<v8::Value> toV8(PassRefPtr<${nativeType} >${forceNewObjectParameter});
+v8::Handle<v8::Value> toV8(PassRefPtr<${nativeType} >${forceNewObjectParameter});
END
}
push(@headerContent, "}\n\n");
- push(@headerContent, "#endif // $className" . "_H\n");
+ push(@headerContent, "#endif // $className" . "_h\n");
push(@headerContent, "#endif // ${conditionalString}\n\n") if $conditionalString;
}
@@ -356,33 +358,25 @@ sub GetInternalFields
{
my $dataNode = shift;
my $name = $dataNode->name;
-
- # FIXME: I am hideous and hard-coded. Make me beautiful.
- return ("cacheIndex", "implementationIndex") if ($name eq "Document") || ($name eq "SVGDocument");
- return ("cacheIndex", "implementationIndex", "markerIndex", "shadowIndex") if $name eq "HTMLDocument";
- return ("cacheIndex") if IsNodeSubType($dataNode);
- return ("cacheIndex") if $name eq "EventSource";
- return ("cacheIndex") if $name eq "XMLHttpRequest";
- return ("cacheIndex") if $name eq "XMLHttpRequestUpload";
- return ("cacheIndex") if $name eq "MessagePort";
- return ("port1Index", "port2Index") if ($name eq "MessageChannel");
- return ("cacheIndex") if $name eq "AbstractWorker";
- return ("abstractWorkerCacheIndex", "cacheIndex") if $name eq "Worker";
- return ("abstractWorkerCacheIndex", "cacheIndex") if $name eq "WorkerContext";
- return ("abstractWorkerCacheIndex", "workerContextCacheIndex", "cacheIndex") if $name eq "DedicatedWorkerContext";
- return ("abstractWorkerCacheIndex", "cacheIndex") if $name eq "SharedWorker";
- return ("abstractWorkerCacheIndex", "workerContextCacheIndex", "cacheIndex") if $name eq "SharedWorkerContext";
- return ("cacheIndex") if $name eq "Notification";
- return ("cacheIndex") if $name eq "IDBRequest";
- return ("cacheIndex") if $name eq "SVGElementInstance";
- return ("consoleIndex", "historyIndex", "locationbarIndex", "menubarIndex", "navigatorIndex", "personalbarIndex",
- "screenIndex", "scrollbarsIndex", "selectionIndex", "statusbarIndex", "toolbarIndex", "locationIndex",
- "domSelectionIndex", "cacheIndex", "enteredIsolatedWorldIndex") if $name eq "DOMWindow";
- return ("cacheIndex") if $name eq "DOMApplicationCache";
- return ("cacheIndex") if $name eq "WebSocket";
- return ("ownerNodeIndex") if ($name eq "StyleSheet") || ($name eq "CSSStyleSheet");
- return ("ownerNodeIndex") if ($name eq "NamedNodeMap");
- return ();
+
+ my @customInternalFields = ();
+
+ # We can't ask whether a parent type has a given extendedAttribute, so special-case Node, AbstractWorker and WorkerContext to include all sub-types.
+ # FIXME: SVGElementInstance should probably have the EventTarget extended attribute, but doesn't.
+ if ($dataNode->extendedAttributes->{"EventTarget"} || IsNodeSubType($dataNode) || IsSubType($dataNode, "AbstractWorker") || IsSubType($dataNode, "WorkerContext")
+ || $name eq "SVGElementInstance") {
+ push(@customInternalFields, "eventListenerCacheIndex");
+ }
+
+ if (IsSubType($dataNode, "Document")) {
+ push(@customInternalFields, "implementationIndex");
+ if ($name eq "HTMLDocument") {
+ push(@customInternalFields, ("markerIndex", "shadowIndex"));
+ }
+ } elsif ($name eq "DOMWindow") {
+ push(@customInternalFields, "enteredIsolatedWorldIndex");
+ }
+ return @customInternalFields;
}
sub GetHeaderClassInclude
@@ -392,8 +386,8 @@ sub GetHeaderClassInclude
$className =~ s/Abs|Rel//;
}
return "" if (AvoidInclusionOfType($className));
- return "#include \"SVGAnimatedTemplate.h\"\n" if ($codeGenerator->IsSVGAnimatedType($className));
- return "#include \"${className}.h\"\n";
+ return "SVGAnimatedTemplate.h" if ($codeGenerator->IsSVGAnimatedType($className));
+ return "${className}.h";
}
sub GenerateHeaderCustomInternalFieldIndices
@@ -403,12 +397,12 @@ sub GenerateHeaderCustomInternalFieldIndices
my $customFieldCounter = 0;
foreach my $customInternalField (@customInternalFields) {
push(@headerContent, <<END);
- static const int ${customInternalField} = v8DefaultWrapperInternalFieldCount + ${customFieldCounter};
+ static const int ${customInternalField} = v8DefaultWrapperInternalFieldCount + ${customFieldCounter};
END
$customFieldCounter++;
}
push(@headerContent, <<END);
- static const int internalFieldCount = v8DefaultWrapperInternalFieldCount + ${customFieldCounter};
+ static const int internalFieldCount = v8DefaultWrapperInternalFieldCount + ${customFieldCounter};
END
}
@@ -439,45 +433,45 @@ sub GenerateHeaderNamedAndIndexedPropertyAccessors
$hasCustomDeleterr = 0;
$hasEnumerator = 0;
}
- if ($interfaceName eq "HTMLSelectElement") {
+ if ($interfaceName eq "HTMLSelectElement" || $interfaceName eq "HTMLAppletElement" || $interfaceName eq "HTMLEmbedElement" || $interfaceName eq "HTMLObjectElement") {
$hasCustomNamedGetter = 1;
}
my $isIndexerSpecialCase = exists $indexerSpecialCases{$interfaceName};
if ($hasCustomIndexedGetter || $isIndexerSpecialCase) {
push(@headerContent, <<END);
- static v8::Handle<v8::Value> indexedPropertyGetter(uint32_t index, const v8::AccessorInfo& info);
+ static v8::Handle<v8::Value> indexedPropertyGetter(uint32_t index, const v8::AccessorInfo& info);
END
}
if ($isIndexerSpecialCase || $hasCustomIndexedSetter) {
push(@headerContent, <<END);
- static v8::Handle<v8::Value> indexedPropertySetter(uint32_t index, v8::Local<v8::Value> value, const v8::AccessorInfo& info);
+ static v8::Handle<v8::Value> indexedPropertySetter(uint32_t index, v8::Local<v8::Value> value, const v8::AccessorInfo& info);
END
}
if ($hasCustomDeleters) {
push(@headerContent, <<END);
- static v8::Handle<v8::Boolean> indexedPropertyDeleter(uint32_t index, const v8::AccessorInfo& info);
+ static v8::Handle<v8::Boolean> indexedPropertyDeleter(uint32_t index, const v8::AccessorInfo& info);
END
}
if ($hasCustomNamedGetter) {
push(@headerContent, <<END);
- static v8::Handle<v8::Value> namedPropertyGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info);
+ static v8::Handle<v8::Value> namedPropertyGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info);
END
}
if ($hasCustomNamedSetter) {
push(@headerContent, <<END);
- static v8::Handle<v8::Value> namedPropertySetter(v8::Local<v8::String> name, v8::Local<v8::Value> value, const v8::AccessorInfo& info);
+ static v8::Handle<v8::Value> namedPropertySetter(v8::Local<v8::String> name, v8::Local<v8::Value> value, const v8::AccessorInfo& info);
END
}
if ($hasCustomDeleters || $interfaceName eq "HTMLDocument") {
push(@headerContent, <<END);
- static v8::Handle<v8::Boolean> namedPropertyDeleter(v8::Local<v8::String> name, const v8::AccessorInfo& info);
+ static v8::Handle<v8::Boolean> namedPropertyDeleter(v8::Local<v8::String> name, const v8::AccessorInfo& info);
END
}
if ($hasCustomEnumerator) {
push(@headerContent, <<END);
- static v8::Handle<v8::Array> namedPropertyEnumerator(const v8::AccessorInfo& info);
+ static v8::Handle<v8::Array> namedPropertyEnumerator(const v8::AccessorInfo& info);
END
}
}
@@ -487,16 +481,16 @@ sub GenerateHeaderCustomCall
my $dataNode = shift;
if ($dataNode->extendedAttributes->{"CustomCall"}) {
- push(@headerContent, " static v8::Handle<v8::Value> callAsFunctionCallback(const v8::Arguments&);\n");
+ push(@headerContent, " static v8::Handle<v8::Value> callAsFunctionCallback(const v8::Arguments&);\n");
}
if ($dataNode->name eq "Event") {
- push(@headerContent, " static v8::Handle<v8::Value> dataTransferAccessorGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info);\n");
- push(@headerContent, " static void valueAccessorSetter(v8::Local<v8::String> name, v8::Local<v8::Value> value, const v8::AccessorInfo& info);\n");
+ push(@headerContent, " static v8::Handle<v8::Value> dataTransferAccessorGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info);\n");
+ push(@headerContent, " static void valueAccessorSetter(v8::Local<v8::String> name, v8::Local<v8::Value> value, const v8::AccessorInfo& info);\n");
}
if ($dataNode->name eq "Location") {
- push(@headerContent, " static v8::Handle<v8::Value> assignAccessorGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info);\n");
- push(@headerContent, " static v8::Handle<v8::Value> reloadAccessorGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info);\n");
- push(@headerContent, " static v8::Handle<v8::Value> replaceAccessorGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info);\n");
+ push(@headerContent, " static v8::Handle<v8::Value> assignAccessorGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info);\n");
+ push(@headerContent, " static v8::Handle<v8::Value> reloadAccessorGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info);\n");
+ push(@headerContent, " static v8::Handle<v8::Value> replaceAccessorGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info);\n");
}
}
@@ -531,19 +525,12 @@ sub IsNodeSubType
return IsSubType($dataNode, "Node");
}
-sub IsEventSubType
-{
- my $dataNode = shift;
- return IsSubType($dataNode, "Event");
-}
-
sub GenerateDomainSafeFunctionGetter
{
my $function = shift;
- my $dataNode = shift;
my $implClassName = shift;
- my $className = "V8" . $dataNode->name;
+ my $className = "V8" . $implClassName;
my $funcName = $function->signature->name;
my $signature = "v8::Signature::New(" . $className . "::GetRawTemplate())";
@@ -551,29 +538,26 @@ sub GenerateDomainSafeFunctionGetter
$signature = "v8::Local<v8::Signature>()";
}
- my $newTemplateString = GenerateNewFunctionTemplate($function, $dataNode, $signature);
+ my $newTemplateString = GenerateNewFunctionTemplate($function, $implClassName, $signature);
push(@implContentDecls, <<END);
- static v8::Handle<v8::Value> ${funcName}AttrGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info) {
+static v8::Handle<v8::Value> ${funcName}AttrGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info)
+{
INC_STATS(\"DOM.$implClassName.$funcName._get\");
- static v8::Persistent<v8::FunctionTemplate> private_template =
- v8::Persistent<v8::FunctionTemplate>::New($newTemplateString);
+ static v8::Persistent<v8::FunctionTemplate> privateTemplate = v8::Persistent<v8::FunctionTemplate>::New($newTemplateString);
v8::Handle<v8::Object> holder = V8DOMWrapper::lookupDOMWrapper(${className}::GetTemplate(), info.This());
if (holder.IsEmpty()) {
- // can only reach here by 'object.__proto__.func', and it should passed
- // domain security check already
- return private_template->GetFunction();
+ // can only reach here by 'object.__proto__.func', and it should passed
+ // domain security check already
+ return privateTemplate->GetFunction();
}
${implClassName}* imp = ${className}::toNative(holder);
if (!V8BindingSecurity::canAccessFrame(V8BindingState::Only(), imp->frame(), false)) {
- static v8::Persistent<v8::FunctionTemplate> shared_template =
- v8::Persistent<v8::FunctionTemplate>::New($newTemplateString);
- return shared_template->GetFunction();
-
- } else {
- return private_template->GetFunction();
+ static v8::Persistent<v8::FunctionTemplate> sharedTemplate = v8::Persistent<v8::FunctionTemplate>::New($newTemplateString);
+ return sharedTemplate->GetFunction();
}
- }
+ return privateTemplate->GetFunction();
+}
END
}
@@ -581,24 +565,24 @@ END
sub GenerateConstructorGetter
{
my $implClassName = shift;
- my $classIndex = shift;
push(@implContentDecls, <<END);
- static v8::Handle<v8::Value> ${implClassName}ConstructorGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info) {
+static v8::Handle<v8::Value> ${implClassName}ConstructorGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info)
+{
INC_STATS(\"DOM.$implClassName.constructors._get\");
v8::Handle<v8::Value> data = info.Data();
- ASSERT(data->IsNumber());
- V8ClassIndex::V8WrapperType type = V8ClassIndex::FromInt(data->Int32Value());
+ ASSERT(data->IsExternal() || data->IsNumber());
+ WrapperTypeInfo* type = WrapperTypeInfo::unwrap(data);
END
- if ($classIndex eq "DOMWINDOW") {
+ if ($implClassName eq "DOMWindow") {
push(@implContentDecls, <<END);
// Get the proxy corresponding to the DOMWindow if possible to
// make sure that the constructor function is constructed in the
// context of the DOMWindow and not in the context of the caller.
return V8DOMWrapper::getConstructor(type, V8DOMWindow::toNative(info.Holder()));
END
- } elsif ($classIndex eq "DEDICATEDWORKERCONTEXT" or $classIndex eq "WORKERCONTEXT" or $classIndex eq "SHAREDWORKERCONTEXT") {
+ } elsif ($implClassName eq "DedicatedWorkerContext" or $implClassName eq "WorkerContext" or $implClassName eq "SharedWorkerContext") {
push(@implContentDecls, <<END);
return V8DOMWrapper::getConstructor(type, V8WorkerContext::toNative(info.Holder()));
END
@@ -607,8 +591,7 @@ END
}
push(@implContentDecls, <<END);
-
- }
+}
END
}
@@ -631,7 +614,6 @@ sub GenerateNormalAttrGetter
my $isPodType = IsPodType($implClassName);
my $skipContext = 0;
-
if ($isPodType) {
$implClassName = GetNativeType($implClassName);
$implIncludes{"V8SVGPODTypeWrapper.h"} = 1;
@@ -658,34 +640,36 @@ sub GenerateNormalAttrGetter
# Getter
push(@implContentDecls, <<END);
- static v8::Handle<v8::Value> ${attrName}AttrGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info) {
+static v8::Handle<v8::Value> ${attrName}AttrGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info)
+{
INC_STATS(\"DOM.$implClassName.$attrName._get\");
END
if ($isPodType) {
push(@implContentDecls, <<END);
- V8SVGPODTypeWrapper<$implClassName>* imp_wrapper = V8SVGPODTypeWrapper<$implClassName>::toNative(info.Holder());
- $implClassName imp_instance = *imp_wrapper;
+ V8SVGPODTypeWrapper<$implClassName>* impWrapper = V8SVGPODTypeWrapper<$implClassName>::toNative(info.Holder());
+ $implClassName impInstance = *impWrapper;
END
if ($getterStringUsesImp) {
push(@implContentDecls, <<END);
- $implClassName* imp = &imp_instance;
+ $implClassName* imp = &impInstance;
END
}
} elsif ($attrExt->{"v8OnProto"} || $attrExt->{"V8DisallowShadowing"}) {
- if ($interfaceName eq "DOMWindow") {
- push(@implContentDecls, <<END);
+ if ($interfaceName eq "DOMWindow") {
+ push(@implContentDecls, <<END);
v8::Handle<v8::Object> holder = info.Holder();
END
- } else {
- # perform lookup first
- push(@implContentDecls, <<END);
+ } else {
+ # perform lookup first
+ push(@implContentDecls, <<END);
v8::Handle<v8::Object> holder = V8DOMWrapper::lookupDOMWrapper(V8${interfaceName}::GetTemplate(), info.This());
- if (holder.IsEmpty()) return v8::Handle<v8::Value>();
+ if (holder.IsEmpty())
+ return v8::Handle<v8::Value>();
END
- }
- push(@implContentDecls, <<END);
+ }
+ push(@implContentDecls, <<END);
${implClassName}* imp = V8${implClassName}::toNative(holder);
END
} else {
@@ -696,7 +680,7 @@ END
my $namespace = $codeGenerator->NamespaceForAttributeName($interfaceName, $contentAttributeName);
$implIncludes{"${namespace}.h"} = 1;
push(@implContentDecls, " return getElementStringAttr(info, ${namespace}::${contentAttributeName}Attr);\n");
- push(@implContentDecls, " }\n\n");
+ push(@implContentDecls, "}\n\n");
return;
# Skip the rest of the function!
}
@@ -707,9 +691,9 @@ END
# Generate security checks if necessary
if ($attribute->signature->extendedAttributes->{"CheckNodeSecurity"}) {
- push(@implContentDecls, " if (!V8BindingSecurity::checkNodeSecurity(V8BindingState::Only(), imp->$attrName())) return v8::Handle<v8::Value>();\n\n");
+ push(@implContentDecls, " if (!V8BindingSecurity::checkNodeSecurity(V8BindingState::Only(), imp->$attrName()))\n return v8::Handle<v8::Value>();\n\n");
} elsif ($attribute->signature->extendedAttributes->{"CheckFrameSecurity"}) {
- push(@implContentDecls, " if (!V8BindingSecurity::checkNodeSecurity(V8BindingState::Only(), imp->contentDocument())) return v8::Handle<v8::Value>();\n\n");
+ push(@implContentDecls, " if (!V8BindingSecurity::checkNodeSecurity(V8BindingState::Only(), imp->contentDocument()))\n return v8::Handle<v8::Value>();\n\n");
}
my $useExceptions = 1 if @{$attribute->getterExceptions} and !($isPodType);
@@ -751,7 +735,7 @@ END
$getterString .= ".toInt()";
}
} else {
- $getterString = "imp_instance";
+ $getterString = "impInstance";
}
my $result;
@@ -768,7 +752,7 @@ END
my $implClassIsAnimatedType = $codeGenerator->IsSVGAnimatedType($implClassName);
if (not $implClassIsAnimatedType and $codeGenerator->IsPodTypeWithWriteableProperties($attrType) and not defined $attribute->signature->extendedAttributes->{"Immutable"}) {
if (IsPodType($implClassName)) {
- my $wrapper = "V8SVGStaticPODTypeWrapperWithPODTypeParent<$nativeType, $implClassName>::create($getterString, imp_wrapper)";
+ my $wrapper = "V8SVGStaticPODTypeWrapperWithPODTypeParent<$nativeType, $implClassName>::create($getterString, impWrapper)";
push(@implContentDecls, " RefPtr<V8SVGStaticPODTypeWrapperWithPODTypeParent<$nativeType, $implClassName> > wrapper = $wrapper;\n");
} else {
my $wrapper = "V8SVGStaticPODTypeWrapperWithParent<$nativeType, $implClassName>::create(imp, &${implClassName}::$getter, &${implClassName}::$setter)";
@@ -790,7 +774,7 @@ END
} else {
if ($attribute->signature->type eq "EventListener" && $dataNode->name eq "DOMWindow") {
push(@implContentDecls, " if (!imp->document())\n");
- push(@implContentDecls, " return v8::Handle<v8::Value>();\n");
+ push(@implContentDecls, " return v8::Handle<v8::Value>();\n");
}
if ($useExceptions) {
@@ -803,6 +787,32 @@ END
# Can inline the function call into the return statement to avoid overhead of using a Ref<> temporary
$result = $getterString;
}
+
+ # Special case for readonly or Replaceable attributes (with a few exceptions). This attempts to ensure that JS wrappers don't get
+ # garbage-collected prematurely when their lifetime is strongly tied to their owner. We accomplish this by inserting a reference to
+ # the newly created wrapper into an internal field of the holder object.
+ if (!IsNodeSubType($dataNode) && $attrName ne "self" && (IsWrapperType($returnType) && ($attribute->type =~ /^readonly/ || $attribute->signature->extendedAttributes->{"Replaceable"})
+ && $returnType ne "EventTarget" && $returnType ne "SerializedScriptValue" && $returnType ne "DOMWindow"
+ && $returnType !~ /SVG/ && $returnType !~ /HTML/ && !IsDOMNodeType($returnType))) {
+ AddIncludesForType($returnType);
+ my $domMapFunction = GetDomMapFunction(0, $returnType);
+ # Check for a wrapper in the wrapper cache. If there is one, we know that a hidden reference has already
+ # been created. If we don't find a wrapper, we create both a wrapper and a hidden reference.
+ push(@implContentDecls, " RefPtr<$returnType> result = ${getterString};\n");
+ push(@implContentDecls, " v8::Handle<v8::Value> wrapper = result.get() ? ${domMapFunction}.get(result.get()) : v8::Handle<v8::Value>();\n");
+ push(@implContentDecls, " if (wrapper.IsEmpty()) {\n");
+ push(@implContentDecls, " wrapper = toV8(result.get());\n");
+ push(@implContentDecls, " if (!wrapper.IsEmpty())\n");
+ if ($dataNode->name eq "DOMWindow") {
+ push(@implContentDecls, " V8DOMWrapper::setHiddenWindowReference(imp->frame(), wrapper);\n");
+ } else {
+ push(@implContentDecls, " V8DOMWrapper::setHiddenReference(info.Holder(), wrapper);\n");
+ }
+ push(@implContentDecls, " }\n");
+ push(@implContentDecls, " return wrapper;\n");
+ push(@implContentDecls, "}\n\n");
+ return;
+ }
}
if (IsSVGTypeNeedingContextParameter($attrType) && !$skipContext) {
@@ -824,27 +834,9 @@ END
push(@implContentDecls, " " . ReturnNativeToJSValue($attribute->signature, $result, " ").";\n");
}
- push(@implContentDecls, " }\n\n"); # end of getter
-}
-
-
-sub GenerateReplaceableAttrSetter
-{
- my $implClassName = shift;
-
- push(@implContentDecls,
- " static void ${attrName}AttrSetter(v8::Local<v8::String> name," .
- " v8::Local<v8::Value> value, const v8::AccessorInfo& info) {\n");
-
- push(@implContentDecls, " INC_STATS(\"DOM.$implClassName.$attrName._set\");\n");
-
- push(@implContentDecls, " v8::Local<v8::String> ${attrName}_string = v8::String::New(\"${attrName}\");\n");
- push(@implContentDecls, " info.Holder()->Delete(${attrName}_string);\n");
- push(@implContentDecls, " info.This()->Set(${attrName}_string, value);\n");
- push(@implContentDecls, " }\n\n");
+ push(@implContentDecls, "}\n\n"); # end of getter
}
-
sub GenerateNormalAttrSetter
{
my $attribute = shift;
@@ -854,10 +846,7 @@ sub GenerateNormalAttrSetter
my $attrExt = $attribute->signature->extendedAttributes;
- push(@implContentDecls,
- " static void ${attrName}AttrSetter(v8::Local<v8::String> name," .
- " v8::Local<v8::Value> value, const v8::AccessorInfo& info) {\n");
-
+ push(@implContentDecls, "static void ${attrName}AttrSetter(v8::Local<v8::String> name, v8::Local<v8::Value> value, const v8::AccessorInfo& info)\n{\n");
push(@implContentDecls, " INC_STATS(\"DOM.$implClassName.$attrName._set\");\n");
my $isPodType = IsPodType($implClassName);
@@ -866,8 +855,8 @@ sub GenerateNormalAttrSetter
$implClassName = GetNativeType($implClassName);
$implIncludes{"V8SVGPODTypeWrapper.h"} = 1;
push(@implContentDecls, " V8SVGPODTypeWrapper<$implClassName>* wrapper = V8SVGPODTypeWrapper<$implClassName>::toNative(info.Holder());\n");
- push(@implContentDecls, " $implClassName imp_instance = *wrapper;\n");
- push(@implContentDecls, " $implClassName* imp = &imp_instance;\n");
+ push(@implContentDecls, " $implClassName impInstance = *wrapper;\n");
+ push(@implContentDecls, " $implClassName* imp = &impInstance;\n");
} elsif ($attrExt->{"v8OnProto"}) {
if ($interfaceName eq "DOMWindow") {
@@ -878,7 +867,8 @@ END
# perform lookup first
push(@implContentDecls, <<END);
v8::Handle<v8::Object> holder = V8DOMWrapper::lookupDOMWrapper(V8${interfaceName}::GetTemplate(), info.This());
- if (holder.IsEmpty()) return;
+ if (holder.IsEmpty())
+ return;
END
}
push(@implContentDecls, <<END);
@@ -894,7 +884,7 @@ END
my $namespace = $codeGenerator->NamespaceForAttributeName($interfaceName, $contentAttributeName);
$implIncludes{"${namespace}.h"} = 1;
push(@implContentDecls, " setElementStringAttr(info, ${namespace}::${contentAttributeName}Attr, value);\n");
- push(@implContentDecls, " }\n\n");
+ push(@implContentDecls, "}\n\n");
return;
# Skip the rest of the function!
}
@@ -908,7 +898,7 @@ END
if ($attribute->signature->type eq "EventListener") {
if ($dataNode->name eq "DOMWindow") {
push(@implContentDecls, " if (!imp->document())\n");
- push(@implContentDecls, " return;\n");
+ push(@implContentDecls, " return;\n");
}
} else {
push(@implContentDecls, " $nativeType v = " . JSValueToNative($attribute->signature, "value") . ";\n");
@@ -947,8 +937,14 @@ END
push(@implContentDecls, " imp->setAttribute(${namespace}::${contentAttributeName}Attr, $result");
} elsif ($attribute->signature->type eq "EventListener") {
$implIncludes{"V8AbstractEventListener.h"} = 1;
- push(@implContentDecls, " transferHiddenDependency(info.Holder(), imp->$attrName(), value, V8${interfaceName}::cacheIndex);\n");
- push(@implContentDecls, " imp->set$implSetterFunctionName(V8DOMWrapper::getEventListener(imp, value, true, ListenerFindOrCreate)");
+ push(@implContentDecls, " transferHiddenDependency(info.Holder(), imp->$attrName(), value, V8${interfaceName}::eventListenerCacheIndex);\n");
+ if ($interfaceName eq "WorkerContext" and $attribute->signature->name eq "onerror") {
+ $implIncludes{"V8EventListenerList.h"} = 1;
+ $implIncludes{"V8WorkerContextErrorHandler.h"} = 1;
+ push(@implContentDecls, " imp->set$implSetterFunctionName(V8EventListenerList::findOrCreateWrapper<V8WorkerContextErrorHandler>(value, true)");
+ } else {
+ push(@implContentDecls, " imp->set$implSetterFunctionName(V8DOMWrapper::getEventListener(value, true, ListenerFindOrCreate)");
+ }
} else {
push(@implContentDecls, " imp->set$implSetterFunctionName($result");
}
@@ -971,21 +967,19 @@ END
$currentObject = "wrapper";
}
- push(@implContentDecls, " if (SVGElement* context = V8Proxy::svgContext($currentObject)) {\n");
+ push(@implContentDecls, " if (SVGElement* context = V8Proxy::svgContext($currentObject))\n");
push(@implContentDecls, " context->svgAttributeChanged(imp->associatedAttributeName());\n");
- push(@implContentDecls, " }\n");
}
push(@implContentDecls, " return;\n");
- push(@implContentDecls, " }\n\n"); # end of setter
+ push(@implContentDecls, "}\n\n"); # end of setter
}
sub GetFunctionTemplateCallbackName
{
$function = shift;
- $dataNode = shift;
+ $interfaceName = shift;
- my $interfaceName = $dataNode->name;
my $name = $function->signature->name;
if ($function->signature->extendedAttributes->{"Custom"} ||
@@ -1003,54 +997,167 @@ sub GetFunctionTemplateCallbackName
sub GenerateNewFunctionTemplate
{
$function = shift;
- $dataNode = shift;
+ $interfaceName = shift;
$signature = shift;
- my $callback = GetFunctionTemplateCallbackName($function, $dataNode);
+ my $callback = GetFunctionTemplateCallbackName($function, $interfaceName);
return "v8::FunctionTemplate::New($callback, v8::Handle<v8::Value>(), $signature)";
}
+sub GenerateEventListenerCallback
+{
+ my $implClassName = shift;
+ my $functionName = shift;
+ my $lookupType = ($functionName eq "add") ? "OrCreate" : "Only";
+ my $passRefPtrHandling = ($functionName eq "add") ? "" : ".get()";
+ my $hiddenDependencyAction = ($functionName eq "add") ? "create" : "remove";
+
+ push(@implContentDecls, <<END);
+static v8::Handle<v8::Value> ${functionName}EventListenerCallback(const v8::Arguments& args)
+{
+ INC_STATS("DOM.${implClassName}.${functionName}EventListener()");
+ RefPtr<EventListener> listener = V8DOMWrapper::getEventListener(args[1], false, ListenerFind${lookupType});
+ if (listener) {
+ V8${implClassName}::toNative(args.Holder())->${functionName}EventListener(v8ValueToAtomicWebCoreString(args[0]), listener${passRefPtrHandling}, args[2]->BooleanValue());
+ ${hiddenDependencyAction}HiddenDependency(args.Holder(), args[1], V8${implClassName}::eventListenerCacheIndex);
+ }
+ return v8::Undefined();
+}
+
+END
+}
+
+sub GenerateParametersCheckExpression
+{
+ my $numParameters = shift;
+ my $function = shift;
+
+ my @andExpression = ();
+ push(@andExpression, "args.Length() == $numParameters");
+ my $parameterIndex = 0;
+ foreach $parameter (@{$function->parameters}) {
+ last if $parameterIndex >= $numParameters;
+ my $value = "args[$parameterIndex]";
+ my $type = GetTypeFromSignature($parameter);
+
+ # Only DOMString or wrapper types are checked.
+ # For DOMString, Null, Undefined and any Object are accepted too, as
+ # these are acceptable values for a DOMString argument (any Object can
+ # be converted to a string via .toString).
+ push(@andExpression, "(${value}->IsNull() || ${value}->IsUndefined() || ${value}->IsString() || ${value}->IsObject())") if $codeGenerator->IsStringType($type);
+ push(@andExpression, "(${value}->IsNull() || V8${type}::HasInstance($value))") if IsWrapperType($type);
+
+ $parameterIndex++;
+ }
+ my $res = join(" && ", @andExpression);
+ $res = "($res)" if @andExpression > 1;
+ return $res;
+}
+
+sub GenerateFunctionParametersCheck
+{
+ my $function = shift;
+
+ my @orExpression = ();
+ my $numParameters = 0;
+ foreach $parameter (@{$function->parameters}) {
+ if ($parameter->extendedAttributes->{"Optional"}) {
+ push(@orExpression, GenerateParametersCheckExpression($numParameters, $function));
+ }
+ $numParameters++;
+ }
+ push(@orExpression, GenerateParametersCheckExpression($numParameters, $function));
+ return join(" || ", @orExpression);
+}
+
+sub GenerateOverloadedFunctionCallback
+{
+ my $function = shift;
+ my $dataNode = shift;
+ my $implClassName = shift;
+
+ # Generate code for choosing the correct overload to call. Overloads are
+ # chosen based on the total number of arguments passed and the type of
+ # values passed in non-primitive argument slots. When more than a single
+ # overload is applicable, precedence is given according to the order of
+ # declaration in the IDL.
+
+ my $name = $function->signature->name;
+ push(@implContentDecls, <<END);
+static v8::Handle<v8::Value> ${name}Callback(const v8::Arguments& args)
+{
+ INC_STATS(\"DOM.$implClassName.$name\");
+END
+
+ foreach my $overload (@{$function->{overloads}}) {
+ my $parametersCheck = GenerateFunctionParametersCheck($overload);
+ push(@implContentDecls, " if ($parametersCheck)\n");
+ push(@implContentDecls, " return ${name}$overload->{overloadIndex}Callback(args);\n");
+ }
+ push(@implContentDecls, <<END);
+ V8Proxy::setDOMException(SYNTAX_ERR);
+ return notHandledByInterceptor();
+END
+ push(@implContentDecls, "}\n\n");
+}
+
sub GenerateFunctionCallback
{
my $function = shift;
my $dataNode = shift;
- my $classIndex = shift;
my $implClassName = shift;
my $interfaceName = $dataNode->name;
my $name = $function->signature->name;
- push(@implContentDecls,
-" static v8::Handle<v8::Value> ${name}Callback(const v8::Arguments& args) {\n" .
-" INC_STATS(\"DOM.$implClassName.$name\");\n");
+ if (@{$function->{overloads}} > 1) {
+ # Append a number to an overloaded method's name to make it unique:
+ $name = $name . $function->{overloadIndex};
+ }
+
+ # Adding and removing event listeners are not standard callback behavior,
+ # but they are extremely consistent across the various classes that take event listeners,
+ # so we can generate them as a "special case".
+ if ($name eq "addEventListener") {
+ GenerateEventListenerCallback($implClassName, "add");
+ return;
+ } elsif ($name eq "removeEventListener") {
+ GenerateEventListenerCallback($implClassName, "remove");
+ return;
+ }
+
+ push(@implContentDecls, <<END);
+static v8::Handle<v8::Value> ${name}Callback(const v8::Arguments& args)
+{
+ INC_STATS(\"DOM.$implClassName.$name\");
+END
my $numParameters = @{$function->parameters};
if ($function->signature->extendedAttributes->{"RequiresAllArguments"}) {
- push(@implContentDecls,
- " if (args.Length() < $numParameters) return v8::Handle<v8::Value>();\n");
+ push(@implContentDecls, " if (args.Length() < $numParameters)\n return v8::Handle<v8::Value>();\n");
}
if (IsPodType($implClassName)) {
my $nativeClassName = GetNativeType($implClassName);
- push(@implContentDecls, " V8SVGPODTypeWrapper<$nativeClassName>* imp_wrapper = V8SVGPODTypeWrapper<$nativeClassName>::toNative(args.Holder());\n");
- push(@implContentDecls, " $nativeClassName imp_instance = *imp_wrapper;\n");
- push(@implContentDecls, " $nativeClassName* imp = &imp_instance;\n");
+ push(@implContentDecls, " V8SVGPODTypeWrapper<$nativeClassName>* impWrapper = V8SVGPODTypeWrapper<$nativeClassName>::toNative(args.Holder());\n");
+ push(@implContentDecls, " $nativeClassName impInstance = *impWrapper;\n");
+ push(@implContentDecls, " $nativeClassName* imp = &impInstance;\n");
} else {
push(@implContentDecls, <<END);
${implClassName}* imp = V8${implClassName}::toNative(args.Holder());
END
}
- # Check domain security if needed
+ # Check domain security if needed
if (($dataNode->extendedAttributes->{"CheckDomainSecurity"}
|| $interfaceName eq "DOMWindow")
&& !$function->signature->extendedAttributes->{"DoNotCheckDomainSecurity"}) {
# We have not find real use cases yet.
- push(@implContentDecls,
-" if (!V8BindingSecurity::canAccessFrame(V8BindingState::Only(), imp->frame(), true)) {\n".
-" return v8::Handle<v8::Value>();\n" .
-" }\n");
+ push(@implContentDecls, <<END);
+ if (!V8BindingSecurity::canAccessFrame(V8BindingState::Only(), imp->frame(), true))
+ return v8::Handle<v8::Value>();
+END
}
my $raisesExceptions = @{$function->raisesExceptions};
@@ -1072,16 +1179,18 @@ END
}
if ($function->signature->extendedAttributes->{"CustomArgumentHandling"}) {
- push(@implContentDecls,
-" OwnPtr<ScriptCallStack> callStack(ScriptCallStack::create(args, $numParameters));\n".
-" if (!callStack)\n".
-" return v8::Undefined();\n");
+ push(@implContentDecls, <<END);
+ OwnPtr<ScriptCallStack> callStack(ScriptCallStack::create(args, $numParameters));
+ if (!callStack)
+ return v8::Undefined();
+END
$implIncludes{"ScriptCallStack.h"} = 1;
}
if ($function->signature->extendedAttributes->{"SVGCheckSecurityDocument"}) {
- push(@implContentDecls,
-" if (!V8BindingSecurity::checkNodeSecurity(V8BindingState::Only(), imp->getSVGDocument(ec)))\n" .
-" return v8::Handle<v8::Value>();\n");
+ push(@implContentDecls, <<END);
+ if (!V8BindingSecurity::checkNodeSecurity(V8BindingState::Only(), imp->getSVGDocument(ec)))
+ return v8::Handle<v8::Value>();
+END
}
my $paramIndex = 0;
@@ -1098,20 +1207,29 @@ END
push(@implContentDecls, " }\n");
}
- if (BasicTypeCanFailConversion($parameter)) {
+ if ($parameter->type eq "SerializedScriptValue") {
+ $implIncludes{"SerializedScriptValue.h"} = 1;
+ push(@implContentDecls, " bool ${parameterName}DidThrow = false;\n");
+ } elsif (BasicTypeCanFailConversion($parameter)) {
push(@implContentDecls, " bool ${parameterName}Ok;\n");
}
push(@implContentDecls, " " . GetNativeTypeFromSignature($parameter, $paramIndex) . " $parameterName = ");
- push(@implContentDecls, JSValueToNative($parameter, "args[$paramIndex]",
- BasicTypeCanFailConversion($parameter) ? "${parameterName}Ok" : undef) . ";\n");
+
+ if ($parameter->type eq "SerializedScriptValue") {
+ push(@implContentDecls, "SerializedScriptValue::create(args[$paramIndex], ${parameterName}DidThrow);\n");
+ push(@implContentDecls, " if (${parameterName}DidThrow)\n return v8::Undefined();\n");
+ } else {
+ push(@implContentDecls, JSValueToNative($parameter, "args[$paramIndex]",
+ BasicTypeCanFailConversion($parameter) ? "${parameterName}Ok" : undef) . ";\n");
+ }
if (TypeCanFailConversion($parameter)) {
$implIncludes{"ExceptionCode.h"} = 1;
push(@implContentDecls,
" if (UNLIKELY(!$parameterName" . (BasicTypeCanFailConversion($parameter) ? "Ok" : "") . ")) {\n" .
-" ec = TYPE_MISMATCH_ERR;\n" .
-" goto fail;\n" .
+" ec = TYPE_MISMATCH_ERR;\n" .
+" goto fail;\n" .
" }\n");
}
@@ -1119,8 +1237,8 @@ END
$implIncludes{"ExceptionCode.h"} = 1;
push(@implContentDecls,
" if (UNLIKELY($parameterName < 0)) {\n" .
-" ec = INDEX_SIZE_ERR;\n" .
-" goto fail;\n" .
+" ec = INDEX_SIZE_ERR;\n" .
+" goto fail;\n" .
" }\n");
}
@@ -1133,12 +1251,12 @@ END
if ($raisesExceptions) {
push(@implContentDecls, " }\n");
- push(@implContentDecls, " fail:\n");
+ push(@implContentDecls, " fail:\n");
push(@implContentDecls, " V8Proxy::setDOMException(ec);\n");
push(@implContentDecls, " return v8::Handle<v8::Value>();\n");
}
- push(@implContentDecls, " }\n\n");
+ push(@implContentDecls, "}\n\n");
}
sub GenerateBatchedAttributeData
@@ -1164,6 +1282,10 @@ sub GenerateSingleBatchedAttribute
my $attrName = $attribute->signature->name;
my $attrExt = $attribute->signature->extendedAttributes;
+ # Attributes of type SerializedScriptValue are set in the
+ # constructor and don't require callbacks.
+ return if ($attribute->signature->type eq "SerializedScriptValue");
+
my $accessControl = "v8::DEFAULT";
if ($attrExt->{"DoNotCheckDomainSecurityOnGet"}) {
$accessControl = "v8::ALL_CAN_READ";
@@ -1172,11 +1294,11 @@ sub GenerateSingleBatchedAttribute
} elsif ($attrExt->{"DoNotCheckDomainSecurity"}) {
$accessControl = "v8::ALL_CAN_READ";
if (!($attribute->type =~ /^readonly/) && !($attrExt->{"V8ReadOnly"})) {
- $accessControl .= "|v8::ALL_CAN_WRITE";
+ $accessControl .= " | v8::ALL_CAN_WRITE";
}
}
if ($attrExt->{"V8DisallowShadowing"}) {
- $accessControl .= "|v8::PROHIBITS_OVERWRITING";
+ $accessControl .= " | v8::PROHIBITS_OVERWRITING";
}
$accessControl = "static_cast<v8::AccessControl>(" . $accessControl . ")";
@@ -1200,24 +1322,24 @@ sub GenerateSingleBatchedAttribute
# Check attributes.
if ($attrExt->{"DontEnum"}) {
- $propAttr .= "|v8::DontEnum";
+ $propAttr .= " | v8::DontEnum";
}
if ($attrExt->{"V8DisallowShadowing"}) {
- $propAttr .= "|v8::DontDelete";
+ $propAttr .= " | v8::DontDelete";
}
my $on_proto = "0 /* on instance */";
- my $data = "V8ClassIndex::INVALID_CLASS_INDEX /* no data */";
+ my $data = "0 /* no data */";
# Constructor
if ($attribute->signature->type =~ /Constructor$/) {
my $constructorType = $codeGenerator->StripModule($attribute->signature->type);
$constructorType =~ s/Constructor$//;
- my $constructorIndex = uc($constructorType);
+ $implIncludes{"V8${constructorType}.h"} = 1;
if ($customAccessor) {
$getter = "V8${customAccessor}AccessorGetter";
} else {
- $data = "V8ClassIndex::${constructorIndex}";
+ $data = "&V8${constructorType}::info";
$getter = "${interfaceName}Internal::${interfaceName}ConstructorGetter";
}
$setter = "0";
@@ -1247,7 +1369,7 @@ sub GenerateSingleBatchedAttribute
# FIXME: Investigate whether we could treat window.top as replaceable
# and allow shadowing without it being a security hole.
if (!($interfaceName eq "DOMWindow" and $attrName eq "top")) {
- $propAttr .= "|v8::ReadOnly";
+ $propAttr .= " | v8::ReadOnly";
}
}
@@ -1264,17 +1386,8 @@ sub GenerateSingleBatchedAttribute
my $commentInfo = "Attribute '$attrName' (Type: '" . $attribute->type .
"' ExtAttr: '" . join(' ', keys(%{$attrExt})) . "')";
- push(@implContent, $indent . " {\n");
- push(@implContent, $indent . " \/\/ $commentInfo\n");
- push(@implContent, $indent . " \"$attrName\",\n");
- push(@implContent, $indent . " $getter,\n");
- push(@implContent, $indent . " $setter,\n");
- push(@implContent, $indent . " $data,\n");
- push(@implContent, $indent . " $accessControl,\n");
- push(@implContent, $indent . " static_cast<v8::PropertyAttribute>($propAttr),\n");
- push(@implContent, $indent . " $on_proto\n");
- push(@implContent, $indent . " }" . $delimiter . "\n");
-END
+ push(@implContent, $indent . " \/\/ $commentInfo\n");
+ push(@implContent, $indent . " {\"$attrName\", $getter, $setter, $data, $accessControl, static_cast<v8::PropertyAttribute>($propAttr), $on_proto}" . $delimiter . "\n");
}
sub GenerateImplementationIndexer
@@ -1326,17 +1439,16 @@ sub GenerateImplementationIndexer
my $conversion = $indexer->extendedAttributes->{"ConvertNullStringTo"};
if ($conversion && $conversion eq "Null") {
push(@implContent, <<END);
- setCollectionStringOrNullIndexedGetter<${interfaceName}>(desc);
+ setCollectionStringOrNullIndexedGetter<${interfaceName}>(desc);
END
} else {
push(@implContent, <<END);
- setCollectionStringIndexedGetter<${interfaceName}>(desc);
+ setCollectionStringIndexedGetter<${interfaceName}>(desc);
END
}
} else {
- my $indexerClassIndex = uc($indexerType);
push(@implContent, <<END);
- setCollectionIndexedGetter<${interfaceName}, ${indexerType}>(desc, V8ClassIndex::${indexerClassIndex});
+ setCollectionIndexedGetter<${interfaceName}, ${indexerType}>(desc);
END
# Include the header for this indexer type, because setCollectionIndexedGetter() requires toV8() for this type.
$implIncludes{"V8${indexerType}.h"} = 1;
@@ -1358,11 +1470,11 @@ END
$hasDeleter = 0;
}
- push(@implContent, " desc->${setOn}Template()->SetIndexedPropertyHandler(V8${interfaceName}::indexedPropertyGetter");
+ push(@implContent, " desc->${setOn}Template()->SetIndexedPropertyHandler(V8${interfaceName}::indexedPropertyGetter");
push(@implContent, $hasCustomSetter ? ", V8${interfaceName}::indexedPropertySetter" : ", 0");
push(@implContent, ", 0"); # IndexedPropertyQuery -- not being used at the moment.
push(@implContent, $hasDeleter ? ", V8${interfaceName}::indexedPropertyDeleter" : ", 0");
- push(@implContent, ", nodeCollectionIndexedPropertyEnumerator<${interfaceName}>, v8::Integer::New(V8ClassIndex::NODE)") if $hasEnumerator;
+ push(@implContent, ", nodeCollectionIndexedPropertyEnumerator<${interfaceName}>") if $hasEnumerator;
push(@implContent, ");\n");
}
@@ -1380,6 +1492,10 @@ sub GenerateImplementationNamedPropertyGetter
$hasCustomGetter = 1;
}
+ if ($interfaceName eq "HTMLAppletElement" || $interfaceName eq "HTMLEmbedElement" || $interfaceName eq "HTMLObjectElement") {
+ $hasCustomGetter = 1;
+ }
+
my $hasGetter = $dataNode->extendedAttributes->{"HasNameGetter"} || $hasCustomGetter || $namedPropertyGetter;
if (!$hasGetter) {
return;
@@ -1388,9 +1504,8 @@ sub GenerateImplementationNamedPropertyGetter
if ($namedPropertyGetter && $namedPropertyGetter->type ne "Node" && !$namedPropertyGetter->extendedAttributes->{"Custom"} && !$hasCustomGetter) {
$implIncludes{"V8Collection.h"} = 1;
my $type = $namedPropertyGetter->type;
- my $classIndex = uc($type);
push(@implContent, <<END);
- setCollectionNamedGetter<${interfaceName}, ${type}>(desc, V8ClassIndex::${classIndex});
+ setCollectionNamedGetter<${interfaceName}, ${type}>(desc);
END
return;
}
@@ -1411,7 +1526,7 @@ END
$hasEnumerator = 0;
}
- push(@implContent, " desc->${setOn}Template()->SetNamedPropertyHandler(V8${interfaceName}::namedPropertyGetter, ");
+ push(@implContent, " desc->${setOn}Template()->SetNamedPropertyHandler(V8${interfaceName}::namedPropertyGetter, ");
push(@implContent, $hasSetter ? "V8${interfaceName}::namedPropertySetter, " : "0, ");
push(@implContent, "0, "); # NamedPropertyQuery -- not being used at the moment.
push(@implContent, $hasDeleter ? "V8${interfaceName}::namedPropertyDeleter, " : "0, ");
@@ -1432,7 +1547,7 @@ sub GenerateImplementationCustomCall
}
if ($hasCustomCall) {
- push(@implContent, " desc->InstanceTemplate()->SetCallAsFunctionHandler(V8${interfaceName}::callAsFunctionCallback);\n");
+ push(@implContent, " desc->InstanceTemplate()->SetCallAsFunctionHandler(V8${interfaceName}::callAsFunctionCallback);\n");
}
}
@@ -1441,7 +1556,7 @@ sub GenerateImplementationMasqueradesAsUndefined
my $dataNode = shift;
if ($dataNode->extendedAttributes->{"MasqueradesAsUndefined"})
{
- push(@implContent, " desc->InstanceTemplate()->MarkAsUndetectable();\n");
+ push(@implContent, " desc->InstanceTemplate()->MarkAsUndetectable();\n");
}
}
@@ -1450,9 +1565,9 @@ sub GenerateImplementation
my $object = shift;
my $dataNode = shift;
my $interfaceName = $dataNode->name;
+ my $visibleInterfaceName = GetVisibleInterfaceName($interfaceName);
my $className = "V8$interfaceName";
my $implClassName = $interfaceName;
- my $classIndex = uc($codeGenerator->StripModule($interfaceName));
my $hasLegacyParent = $dataNode->extendedAttributes->{"LegacyParent"};
my $conditionalString = GenerateConditionalString($dataNode);
@@ -1461,30 +1576,33 @@ sub GenerateImplementation
@implContentHeader = split("\r", $headerTemplate);
push(@implFixedHeader,
- "#include \"config.h\"\n" .
- "#include \"RuntimeEnabledFeatures.h\"\n" .
- "#include \"V8Proxy.h\"\n" .
- "#include \"V8Binding.h\"\n" .
- "#include \"V8BindingState.h\"\n" .
- "#include \"V8DOMWrapper.h\"\n" .
- "#include \"V8IsolatedContext.h\"\n\n" .
- "#undef LOG\n\n");
+ "\n#include \"config.h\"\n" .
+ "#include \"${className}.h\"\n\n");
push(@implFixedHeader, "\n#if ${conditionalString}\n\n") if $conditionalString;
+
+ $implIncludes{"RuntimeEnabledFeatures.h"} = 1;
+ $implIncludes{"V8Proxy.h"} = 1;
+ $implIncludes{"V8Binding.h"} = 1;
+ $implIncludes{"V8BindingState.h"} = 1;
+ $implIncludes{"V8DOMWrapper.h"} = 1;
+ $implIncludes{"V8IsolatedContext.h"} = 1;
if ($className =~ /^V8SVGAnimated/) {
AddIncludesForSVGAnimatedType($interfaceName);
}
- $implIncludes{"${className}.h"} = 1;
-
AddIncludesForType($interfaceName);
- push(@implContentDecls, "namespace WebCore {\n");
+ my $toActive = IsActiveDomType($interfaceName) ? "${className}::toActiveDOMObject" : "0";
+
+ push(@implContentDecls, "namespace WebCore {\n\n");
+ push(@implContentDecls, "WrapperTypeInfo ${className}::info = { ${className}::GetTemplate, ${className}::derefObject, ${toActive} };\n\n");
push(@implContentDecls, "namespace ${interfaceName}Internal {\n\n");
push(@implContentDecls, "template <typename T> void V8_USE(T) { }\n\n");
my $hasConstructors = 0;
+ my $serializedAttribute;
# Generate property accessors for attributes.
for ($index = 0; $index < @{$dataNode->attributes}; $index++) {
$attribute = @{$dataNode->attributes}[$index];
@@ -1504,6 +1622,15 @@ sub GenerateImplementation
$attribute->signature->extendedAttributes->{"v8OnProto"} = 1;
}
+ # Attributes of type SerializedScriptValue are set in the
+ # constructor and don't require callbacks.
+ if ($attrType eq "SerializedScriptValue") {
+ die "Only one attribute of type SerializedScriptValue supported" if $serializedAttribute;
+ $implIncludes{"SerializedScriptValue.h"} = 1;
+ $serializedAttribute = $attribute;
+ next;
+ }
+
# Do not generate accessor if this is a custom attribute. The
# call will be forwarded to a hand-written accessor
# implementation.
@@ -1517,29 +1644,30 @@ sub GenerateImplementation
$attribute->signature->extendedAttributes->{"V8CustomGetter"})) {
GenerateNormalAttrGetter($attribute, $dataNode, $implClassName, $interfaceName);
}
- if (!($attribute->signature->extendedAttributes->{"CustomSetter"} ||
- $attribute->signature->extendedAttributes->{"V8CustomSetter"})) {
- if ($attribute->signature->extendedAttributes->{"Replaceable"}) {
- $dataNode->extendedAttributes->{"ExtendsDOMGlobalObject"} || die "Replaceable attribute can only be used in interface that defines ExtendsDOMGlobalObject attribute!";
- # GenerateReplaceableAttrSetter($implClassName);
- } elsif ($attribute->type !~ /^readonly/ && !$attribute->signature->extendedAttributes->{"V8ReadOnly"}) {
- GenerateNormalAttrSetter($attribute, $dataNode, $implClassName, $interfaceName);
- }
+ if (!$attribute->signature->extendedAttributes->{"CustomSetter"} &&
+ !$attribute->signature->extendedAttributes->{"V8CustomSetter"} &&
+ !$attribute->signature->extendedAttributes->{"Replaceable"} &&
+ $attribute->type !~ /^readonly/ &&
+ !$attribute->signature->extendedAttributes->{"V8ReadOnly"}) {
+ GenerateNormalAttrSetter($attribute, $dataNode, $implClassName, $interfaceName);
}
}
if ($hasConstructors) {
- GenerateConstructorGetter($implClassName, $classIndex);
+ GenerateConstructorGetter($implClassName);
}
+ LinkOverloadedFunctions($dataNode);
+
my $indexer;
my $namedPropertyGetter;
# Generate methods for functions.
foreach my $function (@{$dataNode->functions}) {
- # hack for addEventListener/RemoveEventListener
- # FIXME: avoid naming conflict
if (!($function->signature->extendedAttributes->{"Custom"} || $function->signature->extendedAttributes->{"V8Custom"})) {
- GenerateFunctionCallback($function, $dataNode, $classIndex, $implClassName);
+ GenerateFunctionCallback($function, $dataNode, $implClassName);
+ if ($function->{overloadIndex} > 1 && $function->{overloadIndex} == @{$function->{overloads}}) {
+ GenerateOverloadedFunctionCallback($function, $dataNode, $implClassName);
+ }
}
if ($function->signature->name eq "item") {
@@ -1554,7 +1682,7 @@ sub GenerateImplementation
# generate an access getter that returns different function objects
# for different calling context.
if (($dataNode->extendedAttributes->{"CheckDomainSecurity"} || ($interfaceName eq "DOMWindow")) && $function->signature->extendedAttributes->{"DoNotCheckDomainSecurity"}) {
- GenerateDomainSafeFunctionGetter($function, $dataNode, $implClassName);
+ GenerateDomainSafeFunctionGetter($function, $implClassName);
}
}
@@ -1580,7 +1708,7 @@ sub GenerateImplementation
$attributes = \@normal;
# Put the attributes that disallow shadowing on the shadow object.
if (@disallowsShadowing) {
- push(@implContent, "static const BatchedAttribute shadow_attrs[] = {\n");
+ push(@implContent, "static const BatchedAttribute shadowAttrs[] = {\n");
GenerateBatchedAttributeData($dataNode, \@disallowsShadowing);
push(@implContent, "};\n");
}
@@ -1588,7 +1716,7 @@ sub GenerateImplementation
my $has_attributes = 0;
if (@$attributes) {
$has_attributes = 1;
- push(@implContent, "static const BatchedAttribute ${interfaceName}_attrs[] = {\n");
+ push(@implContent, "static const BatchedAttribute ${interfaceName}Attrs[] = {\n");
GenerateBatchedAttributeData($dataNode, $attributes);
push(@implContent, "};\n");
}
@@ -1597,6 +1725,9 @@ sub GenerateImplementation
$num_callbacks = 0;
$has_callbacks = 0;
foreach my $function (@{$dataNode->functions}) {
+ # Only one table entry is needed for overloaded methods:
+ next if $function->{overloadIndex} > 1;
+
my $attrExt = $function->signature->extendedAttributes;
# Don't put any nonstandard functions into this table:
if ($attrExt->{"V8OnInstance"}) {
@@ -1614,12 +1745,12 @@ sub GenerateImplementation
}
if (!$has_callbacks) {
$has_callbacks = 1;
- push(@implContent, "static const BatchedCallback ${interfaceName}_callbacks[] = {\n");
+ push(@implContent, "static const BatchedCallback ${interfaceName}Callbacks[] = {\n");
}
my $name = $function->signature->name;
- my $callback = GetFunctionTemplateCallbackName($function, $dataNode);
+ my $callback = GetFunctionTemplateCallbackName($function, $interfaceName);
push(@implContent, <<END);
- {"$name", $callback},
+ {"$name", $callback},
END
$num_callbacks++;
}
@@ -1629,7 +1760,7 @@ END
my $has_constants = 0;
if (@{$dataNode->constants}) {
$has_constants = 1;
- push(@implContent, "static const BatchedConstant ${interfaceName}_consts[] = {\n");
+ push(@implContent, "static const BatchedConstant ${interfaceName}Consts[] = {\n");
}
foreach my $constant (@{$dataNode->constants}) {
my $name = $constant->name;
@@ -1638,7 +1769,7 @@ END
# defines "const unsigned long SHOW_ALL = 0xFFFFFFFF". It would be better if we
# handled this here, and converted it to a -1 constant in the c++ output.
push(@implContent, <<END);
- { "${name}", static_cast<signed int>($value) },
+ {"${name}", static_cast<signed int>($value)},
END
}
if ($has_constants) {
@@ -1650,33 +1781,31 @@ END
# In namespace WebCore, add generated implementation for 'CanBeConstructed'.
if ($dataNode->extendedAttributes->{"CanBeConstructed"} && !$dataNode->extendedAttributes->{"CustomConstructor"}) {
push(@implContent, <<END);
- v8::Handle<v8::Value> ${className}::constructorCallback(const v8::Arguments& args)
- {
+v8::Handle<v8::Value> ${className}::constructorCallback(const v8::Arguments& args)
+{
INC_STATS("DOM.${interfaceName}.Contructor");
- return V8Proxy::constructDOMObject<V8ClassIndex::${classIndex}, $interfaceName>(args);
- }
+ return V8Proxy::constructDOMObject<$interfaceName>(args, &info);
+}
END
}
my $access_check = "";
if ($dataNode->extendedAttributes->{"CheckDomainSecurity"} && !($interfaceName eq "DOMWindow")) {
- $access_check = "instance->SetAccessCheckCallbacks(V8${interfaceName}::namedSecurityCheck, V8${interfaceName}::indexedSecurityCheck, v8::Integer::New(V8ClassIndex::ToInt(V8ClassIndex::${classIndex})));";
+ $access_check = "instance->SetAccessCheckCallbacks(V8${interfaceName}::namedSecurityCheck, V8${interfaceName}::indexedSecurityCheck, v8::External::Wrap(&V8${interfaceName}::info));";
}
# For the DOMWindow interface, generate the shadow object template
# configuration method.
if ($implClassName eq "DOMWindow") {
push(@implContent, <<END);
-static v8::Persistent<v8::ObjectTemplate> ConfigureShadowObjectTemplate(v8::Persistent<v8::ObjectTemplate> templ) {
- batchConfigureAttributes(templ,
- v8::Handle<v8::ObjectTemplate>(),
- shadow_attrs,
- sizeof(shadow_attrs)/sizeof(*shadow_attrs));
+static v8::Persistent<v8::ObjectTemplate> ConfigureShadowObjectTemplate(v8::Persistent<v8::ObjectTemplate> templ)
+{
+ batchConfigureAttributes(templ, v8::Handle<v8::ObjectTemplate>(), shadowAttrs, sizeof(shadowAttrs) / sizeof(*shadowAttrs));
- // Install a security handler with V8.
- templ->SetAccessCheckCallbacks(V8DOMWindow::namedSecurityCheck, V8DOMWindow::indexedSecurityCheck, v8::Integer::New(V8ClassIndex::DOMWINDOW));
- templ->SetInternalFieldCount(V8DOMWindow::internalFieldCount);
- return templ;
+ // Install a security handler with V8.
+ templ->SetAccessCheckCallbacks(V8DOMWindow::namedSecurityCheck, V8DOMWindow::indexedSecurityCheck, v8::External::Wrap(&V8DOMWindow::info));
+ templ->SetInternalFieldCount(V8DOMWindow::internalFieldCount);
+ return templ;
}
END
}
@@ -1696,45 +1825,45 @@ END
# Generate the template configuration method
push(@implContent, <<END);
-static v8::Persistent<v8::FunctionTemplate> Configure${className}Template(v8::Persistent<v8::FunctionTemplate> desc) {
- v8::Local<v8::Signature> default_signature = configureTemplate(desc, \"${interfaceName}\",
- $parentClassTemplate, V8${interfaceName}::internalFieldCount,
+static v8::Persistent<v8::FunctionTemplate> Configure${className}Template(v8::Persistent<v8::FunctionTemplate> desc)
+{
+ v8::Local<v8::Signature> defaultSignature = configureTemplate(desc, \"${visibleInterfaceName}\", $parentClassTemplate, V8${interfaceName}::internalFieldCount,
END
# Set up our attributes if we have them
if ($has_attributes) {
push(@implContent, <<END);
- ${interfaceName}_attrs, sizeof(${interfaceName}_attrs)/sizeof(*${interfaceName}_attrs),
+ ${interfaceName}Attrs, sizeof(${interfaceName}Attrs) / sizeof(*${interfaceName}Attrs),
END
} else {
push(@implContent, <<END);
- NULL, 0,
+ 0, 0,
END
}
if ($has_callbacks) {
push(@implContent, <<END);
- ${interfaceName}_callbacks, sizeof(${interfaceName}_callbacks)/sizeof(*${interfaceName}_callbacks));
+ ${interfaceName}Callbacks, sizeof(${interfaceName}Callbacks) / sizeof(*${interfaceName}Callbacks));
END
} else {
push(@implContent, <<END);
- NULL, 0);
+ 0, 0);
END
}
if ($dataNode->extendedAttributes->{"CustomConstructor"} || $dataNode->extendedAttributes->{"CanBeConstructed"}) {
push(@implContent, <<END);
- desc->SetCallHandler(V8${interfaceName}::constructorCallback);
+ desc->SetCallHandler(V8${interfaceName}::constructorCallback);
END
}
if ($access_check or @enabledAtRuntime or @{$dataNode->functions} or $has_constants) {
push(@implContent, <<END);
- v8::Local<v8::ObjectTemplate> instance = desc->InstanceTemplate();
- v8::Local<v8::ObjectTemplate> proto = desc->PrototypeTemplate();
+ v8::Local<v8::ObjectTemplate> instance = desc->InstanceTemplate();
+ v8::Local<v8::ObjectTemplate> proto = desc->PrototypeTemplate();
END
}
- push(@implContent, " $access_check\n");
+ push(@implContent, " $access_check\n");
# Setup the enable-at-runtime attrs if we have them
foreach my $runtime_attr (@enabledAtRuntime) {
@@ -1760,16 +1889,19 @@ END
# Define our functions with Set() or SetAccessor()
$total_functions = 0;
foreach my $function (@{$dataNode->functions}) {
+ # Only one accessor is needed for overloaded methods:
+ next if $function->{overloadIndex} > 1;
+
$total_functions++;
my $attrExt = $function->signature->extendedAttributes;
my $name = $function->signature->name;
my $property_attributes = "v8::DontDelete";
if ($attrExt->{"DontEnum"}) {
- $property_attributes .= "|v8::DontEnum";
+ $property_attributes .= " | v8::DontEnum";
}
if ($attrExt->{"V8ReadOnly"}) {
- $property_attributes .= "|v8::ReadOnly";
+ $property_attributes .= " | v8::ReadOnly";
}
my $commentInfo = "Function '$name' (ExtAttr: '" . join(' ', keys(%{$attrExt})) . "')";
@@ -1783,7 +1915,7 @@ END
if ($attrExt->{"EnabledAtRuntime"}) {
# Only call Set()/SetAccessor() if this method should be enabled
$enable_function = "RuntimeEnabledFeatures::" . $codeGenerator->WK_lcfirst($function->signature->name) . "Enabled";
- $conditional = "if (${enable_function}())\n";
+ $conditional = "if (${enable_function}())\n ";
}
if ($attrExt->{"DoNotCheckDomainSecurity"} &&
@@ -1802,34 +1934,28 @@ END
#
# The solution is very hacky and fragile, it really needs to be replaced
# by a better solution.
- $property_attributes .= "|v8::ReadOnly";
+ $property_attributes .= " | v8::ReadOnly";
push(@implContent, <<END);
- // $commentInfo
- $conditional $template->SetAccessor(
- v8::String::New("$name"),
- ${interfaceName}Internal::${name}AttrGetter,
- 0,
- v8::Handle<v8::Value>(),
- v8::ALL_CAN_READ,
- static_cast<v8::PropertyAttribute>($property_attributes));
+ // $commentInfo
+ ${conditional}$template->SetAccessor(v8::String::New("$name"), ${interfaceName}Internal::${name}AttrGetter, 0, v8::Handle<v8::Value>(), v8::ALL_CAN_READ, static_cast<v8::PropertyAttribute>($property_attributes));
END
$num_callbacks++;
next;
}
- my $signature = "default_signature";
- if ($attrExt->{"V8DoNotCheckSignature"}){
+ my $signature = "defaultSignature";
+ if ($attrExt->{"V8DoNotCheckSignature"}) {
$signature = "v8::Local<v8::Signature>()";
}
if (RequiresCustomSignature($function)) {
- $signature = "${name}_signature";
- push(@implContent, "\n // Custom Signature '$name'\n", CreateCustomSignature($function));
+ $signature = "${name}Signature";
+ push(@implContent, "\n // Custom Signature '$name'\n", CreateCustomSignature($function));
}
# Normal function call is a template
- my $callback = GetFunctionTemplateCallbackName($function, $dataNode);
+ my $callback = GetFunctionTemplateCallbackName($function, $interfaceName);
if ($property_attributes eq "v8::DontDelete") {
$property_attributes = "";
@@ -1837,13 +1963,13 @@ END
$property_attributes = ", static_cast<v8::PropertyAttribute>($property_attributes)";
}
- if ($template eq "proto" && $conditional eq "" && $signature eq "default_signature" && $property_attributes eq "") {
+ if ($template eq "proto" && $conditional eq "" && $signature eq "defaultSignature" && $property_attributes eq "") {
# Standard type of callback, already created in the batch, so skip it here.
next;
}
push(@implContent, <<END);
- ${conditional}$template->Set(v8::String::New("$name"), v8::FunctionTemplate::New($callback, v8::Handle<v8::Value>(), ${signature})$property_attributes);
+ ${conditional}$template->Set(v8::String::New("$name"), v8::FunctionTemplate::New($callback, v8::Handle<v8::Value>(), ${signature})$property_attributes);
END
$num_callbacks++;
}
@@ -1852,7 +1978,7 @@ END
if ($has_constants) {
push(@implContent, <<END);
- batchConfigureConstants(desc, proto, ${interfaceName}_consts, sizeof(${interfaceName}_consts)/sizeof(*${interfaceName}_consts));
+ batchConfigureConstants(desc, proto, ${interfaceName}Consts, sizeof(${interfaceName}Consts) / sizeof(*${interfaceName}Consts));
END
}
@@ -1860,23 +1986,23 @@ END
if ($interfaceName eq "DOMWindow") {
push(@implContent, <<END);
- proto->SetInternalFieldCount(V8DOMWindow::internalFieldCount);
- desc->SetHiddenPrototype(true);
- instance->SetInternalFieldCount(V8DOMWindow::internalFieldCount);
- // Set access check callbacks, but turned off initially.
- // When a context is detached from a frame, turn on the access check.
- // Turning on checks also invalidates inline caches of the object.
- instance->SetAccessCheckCallbacks(V8DOMWindow::namedSecurityCheck, V8DOMWindow::indexedSecurityCheck, v8::Integer::New(V8ClassIndex::DOMWINDOW), false);
+ proto->SetInternalFieldCount(V8DOMWindow::internalFieldCount);
+ desc->SetHiddenPrototype(true);
+ instance->SetInternalFieldCount(V8DOMWindow::internalFieldCount);
+ // Set access check callbacks, but turned off initially.
+ // When a context is detached from a frame, turn on the access check.
+ // Turning on checks also invalidates inline caches of the object.
+ instance->SetAccessCheckCallbacks(V8DOMWindow::namedSecurityCheck, V8DOMWindow::indexedSecurityCheck, v8::External::Wrap(&V8DOMWindow::info), false);
END
}
if ($interfaceName eq "Location") {
push(@implContent, <<END);
- // For security reasons, these functions are on the instance instead
- // of on the prototype object to insure that they cannot be overwritten.
- instance->SetAccessor(v8::String::New("reload"), V8Location::reloadAccessorGetter, 0, v8::Handle<v8::Value>(), v8::ALL_CAN_READ, static_cast<v8::PropertyAttribute>(v8::DontDelete | v8::ReadOnly));
- instance->SetAccessor(v8::String::New("replace"), V8Location::replaceAccessorGetter, 0, v8::Handle<v8::Value>(), v8::ALL_CAN_READ, static_cast<v8::PropertyAttribute>(v8::DontDelete | v8::ReadOnly));
- instance->SetAccessor(v8::String::New("assign"), V8Location::assignAccessorGetter, 0, v8::Handle<v8::Value>(), v8::ALL_CAN_READ, static_cast<v8::PropertyAttribute>(v8::DontDelete | v8::ReadOnly));
+ // For security reasons, these functions are on the instance instead
+ // of on the prototype object to ensure that they cannot be overwritten.
+ instance->SetAccessor(v8::String::New("reload"), V8Location::reloadAccessorGetter, 0, v8::Handle<v8::Value>(), v8::ALL_CAN_READ, static_cast<v8::PropertyAttribute>(v8::DontDelete | v8::ReadOnly));
+ instance->SetAccessor(v8::String::New("replace"), V8Location::replaceAccessorGetter, 0, v8::Handle<v8::Value>(), v8::ALL_CAN_READ, static_cast<v8::PropertyAttribute>(v8::DontDelete | v8::ReadOnly));
+ instance->SetAccessor(v8::String::New("assign"), V8Location::assignAccessorGetter, 0, v8::Handle<v8::Value>(), v8::ALL_CAN_READ, static_cast<v8::PropertyAttribute>(v8::DontDelete | v8::ReadOnly));
END
}
@@ -1886,51 +2012,86 @@ END
}
push(@implContent, <<END);
- // Custom toString template
- desc->Set(getToStringName(), getToStringTemplate());
- return desc;
+ // Custom toString template
+ desc->Set(getToStringName(), getToStringTemplate());
+ return desc;
}
-v8::Persistent<v8::FunctionTemplate> ${className}::GetRawTemplate() {
- static v8::Persistent<v8::FunctionTemplate> ${className}_raw_cache_ = createRawTemplate();
- return ${className}_raw_cache_;
+v8::Persistent<v8::FunctionTemplate> ${className}::GetRawTemplate()
+{
+ static v8::Persistent<v8::FunctionTemplate> ${className}RawCache = createRawTemplate();
+ return ${className}RawCache;
}
-v8::Persistent<v8::FunctionTemplate> ${className}::GetTemplate() {
- static v8::Persistent<v8::FunctionTemplate> ${className}_cache_ = Configure${className}Template(GetRawTemplate());
- return ${className}_cache_;
+v8::Persistent<v8::FunctionTemplate> ${className}::GetTemplate()\
+{
+ static v8::Persistent<v8::FunctionTemplate> ${className}Cache = Configure${className}Template(GetRawTemplate());
+ return ${className}Cache;
}
-${nativeType}* ${className}::toNative(v8::Handle<v8::Object> object) {
- return reinterpret_cast<${nativeType}*>(object->GetPointerFromInternalField(v8DOMWrapperObjectIndex));
+${nativeType}* ${className}::toNative(v8::Handle<v8::Object> object)
+{
+ return reinterpret_cast<${nativeType}*>(object->GetPointerFromInternalField(v8DOMWrapperObjectIndex));
}
-bool ${className}::HasInstance(v8::Handle<v8::Value> value) {
- return GetRawTemplate()->HasInstance(value);
+bool ${className}::HasInstance(v8::Handle<v8::Value> value)
+{
+ return GetRawTemplate()->HasInstance(value);
}
END
+ if (IsActiveDomType($interfaceName)) {
+ # MessagePort is handled like an active dom object even though it doesn't inherit
+ # from ActiveDOMObject, so don't try to cast it to ActiveDOMObject.
+ my $returnValue = $interfaceName eq "MessagePort" ? "0" : "toNative(object)";
+ push(@implContent, <<END);
+ActiveDOMObject* ${className}::toActiveDOMObject(v8::Handle<v8::Object> object)
+{
+ return ${returnValue};
+}
+END
+ }
+
if ($implClassName eq "DOMWindow") {
push(@implContent, <<END);
-v8::Persistent<v8::ObjectTemplate> V8DOMWindow::GetShadowObjectTemplate() {
- static v8::Persistent<v8::ObjectTemplate> V8DOMWindowShadowObject_cache_;
- if (V8DOMWindowShadowObject_cache_.IsEmpty()) {
- V8DOMWindowShadowObject_cache_ = v8::Persistent<v8::ObjectTemplate>::New(v8::ObjectTemplate::New());
- ConfigureShadowObjectTemplate(V8DOMWindowShadowObject_cache_);
- }
- return V8DOMWindowShadowObject_cache_;
+v8::Persistent<v8::ObjectTemplate> V8DOMWindow::GetShadowObjectTemplate()
+{
+ static v8::Persistent<v8::ObjectTemplate> V8DOMWindowShadowObjectCache;
+ if (V8DOMWindowShadowObjectCache.IsEmpty()) {
+ V8DOMWindowShadowObjectCache = v8::Persistent<v8::ObjectTemplate>::New(v8::ObjectTemplate::New());
+ ConfigureShadowObjectTemplate(V8DOMWindowShadowObjectCache);
+ }
+ return V8DOMWindowShadowObjectCache;
}
END
}
- GenerateToV8Converters($dataNode, $interfaceName, $className, $nativeType);
+ GenerateToV8Converters($dataNode, $interfaceName, $className, $nativeType, $serializedAttribute);
+
+ push(@implContent, <<END);
+
+void ${className}::derefObject(void* object)
+{
+END
+
+ if (IsRefPtrType($interfaceName)) {
+ push(@implContent, <<END);
+ static_cast<${nativeType}*>(object)->deref();
+END
+ }
push(@implContent, <<END);
+}
+
} // namespace WebCore
END
push(@implContent, "\n#endif // ${conditionalString}\n") if $conditionalString;
+
+ # We've already added the header for this file in implFixedHeader, so remove
+ # it from implIncludes to ensure we don't #include it twice.
+ delete $implIncludes{"${className}.h"};
}
sub GenerateToV8Converters
@@ -1939,90 +2100,107 @@ sub GenerateToV8Converters
my $interfaceName = shift;
my $className = shift;
my $nativeType = shift;
+ my $serializedAttribute = shift;
- my $wrapperType = "V8ClassIndex::" . uc($interfaceName);
my $domMapFunction = GetDomMapFunction($dataNode, $interfaceName);
my $forceNewObjectInput = IsDOMNodeType($interfaceName) ? ", bool forceNewObject" : "";
my $forceNewObjectCall = IsDOMNodeType($interfaceName) ? ", forceNewObject" : "";
push(@implContent, <<END);
-v8::Handle<v8::Object> ${className}::wrap(${nativeType}* impl${forceNewObjectInput}) {
- v8::Handle<v8::Object> wrapper;
- V8Proxy* proxy = 0;
+v8::Handle<v8::Object> ${className}::wrap(${nativeType}* impl${forceNewObjectInput})
+{
+ v8::Handle<v8::Object> wrapper;
+ V8Proxy* proxy = 0;
END
if (IsNodeSubType($dataNode)) {
push(@implContent, <<END);
- if (impl->document()) {
- proxy = V8Proxy::retrieve(impl->document()->frame());
- if (proxy && static_cast<Node*>(impl->document()) == static_cast<Node*>(impl))
- proxy->windowShell()->initContextIfNeeded();
- }
+ if (impl->document()) {
+ proxy = V8Proxy::retrieve(impl->document()->frame());
+ if (proxy && static_cast<Node*>(impl->document()) == static_cast<Node*>(impl))
+ proxy->windowShell()->initContextIfNeeded();
+ }
END
}
if ($domMapFunction) {
- push(@implContent, " if (!forceNewObject) {\n") if IsDOMNodeType($interfaceName);
+ push(@implContent, " if (!forceNewObject) {\n") if IsDOMNodeType($interfaceName);
if (IsNodeSubType($dataNode)) {
- push(@implContent, " wrapper = V8DOMWrapper::getWrapper(impl);\n");
+ push(@implContent, " wrapper = V8DOMWrapper::getWrapper(impl);\n");
} else {
- push(@implContent, " wrapper = ${domMapFunction}.get(impl);\n");
+ push(@implContent, " wrapper = ${domMapFunction}.get(impl);\n");
}
push(@implContent, <<END);
- if (!wrapper.IsEmpty())
- return wrapper;
+ if (!wrapper.IsEmpty())
+ return wrapper;
END
- push(@implContent, " }\n") if IsDOMNodeType($interfaceName);
+ push(@implContent, " }\n") if IsDOMNodeType($interfaceName);
}
if (IsNodeSubType($dataNode)) {
push(@implContent, <<END);
- v8::Handle<v8::Context> context;
- if (proxy)
- context = proxy->context();
+ v8::Handle<v8::Context> context;
+ if (proxy)
+ context = proxy->context();
- // Enter the node's context and create the wrapper in that context.
- if (!context.IsEmpty())
- context->Enter();
+ // Enter the node's context and create the wrapper in that context.
+ if (!context.IsEmpty())
+ context->Enter();
END
}
push(@implContent, <<END);
- wrapper = V8DOMWrapper::instantiateV8Object(proxy, ${wrapperType}, impl);
+ wrapper = V8DOMWrapper::instantiateV8Object(proxy, &info, impl);
END
-
if (IsNodeSubType($dataNode)) {
push(@implContent, <<END);
- // Exit the node's context if it was entered.
- if (!context.IsEmpty())
- context->Exit();
+ // Exit the node's context if it was entered.
+ if (!context.IsEmpty())
+ context->Exit();
END
}
push(@implContent, <<END);
- if (wrapper.IsEmpty())
- return wrapper;
+ if (wrapper.IsEmpty())
+ return wrapper;
+END
+ push(@implContent, "\n impl->ref();\n") if IsRefPtrType($interfaceName);
+
+ # Eagerly deserialize attributes of type SerializedScriptValue
+ # while we're in the right context.
+ if ($serializedAttribute) {
+ die "Attribute of type SerializedScriptValue expected" if $serializedAttribute->signature->type ne "SerializedScriptValue";
+ my $attrName = $serializedAttribute->signature->name;
+ my $attrAttr = "v8::DontDelete";
+ if ($serializedAttribute->type =~ /^readonly/) {
+ $attrAttr .= " | v8::ReadOnly";
+ }
+ $attrAttr = "static_cast<v8::PropertyAttribute>($attrAttr)";
+ my $getterFunc = $codeGenerator->WK_lcfirst($attrName);
+ push(@implContent, <<END);
+ SerializedScriptValue::deserializeAndSetProperty(wrapper, "${attrName}", ${attrAttr}, impl->${getterFunc}());
END
- push(@implContent, "\n impl->ref();\n") if IsRefPtrType($interfaceName);
+ }
if ($domMapFunction) {
push(@implContent, <<END);
- ${domMapFunction}.set(impl, v8::Persistent<v8::Object>::New(wrapper));
+ ${domMapFunction}.set(impl, v8::Persistent<v8::Object>::New(wrapper));
END
}
push(@implContent, <<END);
- return wrapper;
+ return wrapper;
}
END
if (IsRefPtrType($interfaceName)) {
push(@implContent, <<END);
-v8::Handle<v8::Value> toV8(PassRefPtr<${nativeType} > impl${forceNewObjectInput}) {
- return toV8(impl.get()${forceNewObjectCall});
+v8::Handle<v8::Value> toV8(PassRefPtr<${nativeType} > impl${forceNewObjectInput})
+{
+ return toV8(impl.get()${forceNewObjectCall});
}
END
}
@@ -2030,10 +2208,11 @@ END
if (!HasCustomToV8Implementation($dataNode, $interfaceName)) {
push(@implContent, <<END);
-v8::Handle<v8::Value> toV8(${nativeType}* impl${forceNewObjectInput}) {
- if (!impl)
- return v8::Null();
- return ${className}::wrap(impl${forceNewObjectCall});
+v8::Handle<v8::Value> toV8(${nativeType}* impl${forceNewObjectInput})
+{
+ if (!impl)
+ return v8::Null();
+ return ${className}::wrap(impl${forceNewObjectCall});
}
END
}
@@ -2045,21 +2224,18 @@ sub HasCustomToV8Implementation {
$interfaceName = shift;
# We generate a custom converter (but JSC doesn't) for the following:
- return 1 if $interfaceName eq "BarInfo";
return 1 if $interfaceName eq "CSSStyleSheet";
return 1 if $interfaceName eq "CanvasPixelArray";
- return 1 if $interfaceName eq "DOMSelection";
return 1 if $interfaceName eq "DOMWindow";
return 1 if $interfaceName eq "Element";
- return 1 if $interfaceName eq "Location";
return 1 if $interfaceName eq "HTMLDocument";
return 1 if $interfaceName eq "HTMLElement";
- return 1 if $interfaceName eq "History";
+ return 1 if $interfaceName eq "Location";
return 1 if $interfaceName eq "NamedNodeMap";
- return 1 if $interfaceName eq "Navigator";
return 1 if $interfaceName eq "SVGDocument";
return 1 if $interfaceName eq "SVGElement";
- return 1 if $interfaceName eq "Screen";
+ return 1 if $interfaceName eq "ScriptProfile";
+ return 1 if $interfaceName eq "ScriptProfileNode";
return 1 if $interfaceName eq "WorkerContext";
# We don't generate a custom converter (but JSC does) for the following:
return 0 if $interfaceName eq "AbstractWorker";
@@ -2076,7 +2252,7 @@ sub GetDomMapFunction
my $dataNode = shift;
my $type = shift;
return "getDOMSVGElementInstanceMap()" if $type eq "SVGElementInstance";
- return "getDOMNodeMap()" if IsNodeSubType($dataNode);
+ return "getDOMNodeMap()" if ($dataNode && IsNodeSubType($dataNode));
# Only use getDOMSVGObjectWithContextMap() for non-node svg objects
return "getDOMSVGObjectWithContextMap()" if $type =~ /SVG/;
return "" if $type eq "DOMImplementation";
@@ -2088,6 +2264,7 @@ sub IsActiveDomType
{
# FIXME: Consider making this an .idl attribute.
my $type = shift;
+ return 1 if $type eq "EventSource";
return 1 if $type eq "MessagePort";
return 1 if $type eq "XMLHttpRequest";
return 1 if $type eq "WebSocket";
@@ -2201,9 +2378,7 @@ sub GenerateFunctionCallString()
if ($returnType eq "void") {
$result .= $indent . "$functionString;\n";
} elsif ($copyFirst) {
- $result .=
- $indent . GetNativeType($returnType, 0) . " result = *imp;\n" .
- $indent . "$functionString;\n";
+ $result .= $indent . GetNativeType($returnType, 0) . " result = *imp;\n" . $indent . "$functionString;\n";
} elsif ($returnsListItemPodType) {
$result .= $indent . "RefPtr<SVGPODListItem<$nativeReturnType> > result = $functionString;\n";
} elsif (@{$function->raisesExceptions} or $returnsPodType or $isPodType or IsSVGTypeNeedingContextParameter($returnType)) {
@@ -2215,7 +2390,7 @@ sub GenerateFunctionCallString()
}
if (@{$function->raisesExceptions}) {
- $result .= $indent . "if (UNLIKELY(ec)) goto fail;\n";
+ $result .= $indent . "if (UNLIKELY(ec))\n" . $indent . " goto fail;\n";
}
# If the return type is a POD type, separate out the wrapper generation
@@ -2253,7 +2428,7 @@ sub GenerateFunctionCallString()
$generatedSVGContextRetrieval = 1;
}
- $result .= $indent . "imp_wrapper->commitChange(imp_instance, context);\n";
+ $result .= $indent . "impWrapper->commitChange(impInstance, context);\n";
}
if ($returnsPodType) {
@@ -2355,6 +2530,7 @@ sub GetNativeType
return "unsigned" if $type eq "unsigned int";
return "Node*" if $type eq "EventTarget" and $isParameter;
return "double" if $type eq "Date";
+ return "ScriptValue" if $type eq "DOMObject";
return "String" if $type eq "DOMUserData"; # FIXME: Temporary hack?
@@ -2370,75 +2546,6 @@ sub GetNativeType
return "${type}*";
}
-
-my %typeCanFailConversion = (
- "Attr" => 1,
- "WebGLArray" => 0,
- "WebGLBuffer" => 0,
- "WebGLByteArray" => 0,
- "WebGLUnsignedByteArray" => 0,
- "WebGLContextAttributes" => 0,
- "WebGLFloatArray" => 0,
- "WebGLFramebuffer" => 0,
- "CanvasGradient" => 0,
- "WebGLIntArray" => 0,
- "CanvasPixelArray" => 0,
- "WebGLProgram" => 0,
- "WebGLRenderbuffer" => 0,
- "WebGLShader" => 0,
- "WebGLShortArray" => 0,
- "WebGLTexture" => 0,
- "WebGLUniformLocation" => 0,
- "CompareHow" => 0,
- "DataGridColumn" => 0,
- "DOMString" => 0,
- "DOMWindow" => 0,
- "DocumentType" => 0,
- "Element" => 0,
- "Event" => 0,
- "EventListener" => 0,
- "EventTarget" => 0,
- "HTMLCanvasElement" => 0,
- "HTMLElement" => 0,
- "HTMLImageElement" => 0,
- "HTMLOptionElement" => 0,
- "HTMLVideoElement" => 0,
- "Node" => 0,
- "NodeFilter" => 0,
- "MessagePort" => 0,
- "NSResolver" => 0,
- "Range" => 0,
- "SQLResultSet" => 0,
- "Storage" => 0,
- "SVGAngle" => 1,
- "SVGElement" => 0,
- "SVGLength" => 1,
- "SVGMatrix" => 1,
- "SVGNumber" => 0,
- "SVGPaintType" => 0,
- "SVGPathSeg" => 0,
- "SVGPoint" => 1,
- "SVGPreserveAspectRatio" => 1,
- "SVGRect" => 1,
- "SVGTransform" => 1,
- "TouchList" => 0,
- "VoidCallback" => 1,
- "WebKitCSSMatrix" => 0,
- "WebKitPoint" => 0,
- "XPathEvaluator" => 0,
- "XPathNSResolver" => 0,
- "XPathResult" => 0,
- "boolean" => 0,
- "double" => 0,
- "float" => 0,
- "long" => 0,
- "unsigned long" => 0,
- "unsigned short" => 0,
- "long long" => 0,
- "unsigned long long" => 0
-);
-
-
sub TranslateParameter
{
my $signature = shift;
@@ -2471,10 +2578,9 @@ sub TypeCanFailConversion
my $type = GetTypeFromSignature($signature);
$implIncludes{"ExceptionCode.h"} = 1 if $type eq "Attr";
-
- return $typeCanFailConversion{$type} if exists $typeCanFailConversion{$type};
-
- die "Don't know whether a JS value can fail conversion to type $type.";
+ return 1 if $type eq "Attr";
+ return 1 if $type eq "VoidCallback";
+ return BasicTypeCanFailConversion($signature);
}
sub JSValueToNative
@@ -2501,9 +2607,11 @@ sub JSValueToNative
return $value;
}
- if ($type eq "SerializedScriptValue") {
- $implIncludes{"SerializedScriptValue.h"} = 1;
- return "SerializedScriptValue::create($value)";
+ die "Unexpected SerializedScriptValue" if $type eq "SerializedScriptValue";
+
+ if ($type eq "DOMObject") {
+ $implIncludes{"ScriptValue.h"} = 1;
+ return "ScriptValue($value)";
}
if ($type eq "NodeFilter") {
@@ -2539,17 +2647,13 @@ sub JSValueToNative
# return NULL.
return "V8${type}::HasInstance($value) ? V8${type}::toNative(v8::Handle<v8::Object>::Cast($value)) : 0";
} else {
- # TODO: Temporary to avoid Window name conflict.
- my $classIndex = uc($type);
- my $implClassName = ${type};
-
$implIncludes{"V8$type.h"} = 1;
if (IsPodType($type)) {
my $nativeType = GetNativeType($type);
$implIncludes{"V8SVGPODTypeWrapper.h"} = 1;
- return "V8SVGPODTypeUtil::toSVGPODType<${nativeType}>(V8ClassIndex::${classIndex}, $value${maybeOkParam})"
+ return "V8SVGPODTypeUtil::toSVGPODType<${nativeType}>(&V8${type}::info, $value${maybeOkParam})"
}
$implIncludes{"V8${type}.h"} = 1;
@@ -2560,7 +2664,6 @@ sub JSValueToNative
}
}
-
sub GetV8HeaderName
{
my $type = shift;
@@ -2568,17 +2671,17 @@ sub GetV8HeaderName
return "EventListener.h" if $type eq "EventListener";
return "EventTarget.h" if $type eq "EventTarget";
return "SerializedScriptValue.h" if $type eq "SerializedScriptValue";
+ return "ScriptValue.h" if $type eq "DOMObject";
return "V8${type}.h";
}
-
sub CreateCustomSignature
{
my $function = shift;
my $count = @{$function->parameters};
my $name = $function->signature->name;
- my $result = " const int ${name}_argc = ${count};\n" .
- " v8::Handle<v8::FunctionTemplate> ${name}_argv[${name}_argc] = { ";
+ my $result = " const int ${name}Argc = ${count};\n" .
+ " v8::Handle<v8::FunctionTemplate> ${name}Argv[${name}Argc] = { ";
my $first = 1;
foreach my $parameter (@{$function->parameters}) {
if ($first) { $first = 0; }
@@ -2599,7 +2702,7 @@ sub CreateCustomSignature
}
}
$result .= " };\n";
- $result .= " v8::Handle<v8::Signature> ${name}_signature = v8::Signature::New(desc, ${name}_argc, ${name}_argv);\n";
+ $result .= " v8::Handle<v8::Signature> ${name}Signature = v8::Signature::New(desc, ${name}Argc, ${name}Argv);\n";
return $result;
}
@@ -2612,11 +2715,21 @@ sub RequiresCustomSignature
$function->signature->extendedAttributes->{"V8Custom"}) {
return 0;
}
+ # No signature needed for overloaded function
+ if (@{$function->{overloads}} > 1) {
+ return 0;
+ }
foreach my $parameter (@{$function->parameters}) {
- if (IsWrapperType($parameter->type)) {
- return 1;
- }
+ if ($parameter->extendedAttributes->{"Optional"}) {
+ return 0;
+ }
+ }
+
+ foreach my $parameter (@{$function->parameters}) {
+ if (IsWrapperType($parameter->type)) {
+ return 1;
+ }
}
return 0;
}
@@ -2625,6 +2738,8 @@ sub RequiresCustomSignature
my %non_wrapper_types = (
'float' => 1,
'double' => 1,
+ 'int' => 1,
+ 'unsigned int' => 1,
'short' => 1,
'unsigned short' => 1,
'long' => 1,
@@ -2645,6 +2760,7 @@ my %non_wrapper_types = (
'SVGPaintType' => 1,
'DOMTimeStamp' => 1,
'JSObject' => 1,
+ 'DOMObject' => 1,
'EventTarget' => 1,
'NodeFilter' => 1,
'EventListener' => 1
@@ -2704,8 +2820,9 @@ sub ReturnNativeToJSValue
return "return v8::Integer::New($value)" if $nativeType eq "int";
return "return v8::Integer::NewFromUnsigned($value)" if $nativeType eq "unsigned";
- return "return v8DateOrNull($value);" if $type eq "Date";
+ return "return v8DateOrNull($value)" if $type eq "Date";
return "return v8::Number::New($value)" if $codeGenerator->IsPrimitiveType($type) or $type eq "SVGPaintType";
+ return "return $value.v8Value()" if $nativeType eq "ScriptValue";
if ($codeGenerator->IsStringType($type)) {
my $conv = $signature->extendedAttributes->{"ConvertNullStringTo"};
@@ -2775,7 +2892,11 @@ sub WriteData
my $checkType = $implInclude;
$checkType =~ s/\.h//;
- print $IMPL "#include \"$implInclude\"\n" unless $codeGenerator->IsSVGAnimatedType($checkType);
+ if ($implInclude =~ /wtf/) {
+ print $IMPL "#include \<$implInclude\>\n";
+ } else {
+ print $IMPL "#include \"$implInclude\"\n" unless $codeGenerator->IsSVGAnimatedType($checkType);
+ }
}
print $IMPL "\n";
@@ -2833,7 +2954,7 @@ sub GenerateSVGContextRetrieval
my $srcObject = "imp";
if ($srcIsPodType) {
- $srcObject = "imp_wrapper";
+ $srcObject = "impWrapper";
}
my $contextDecl;
@@ -2882,6 +3003,15 @@ sub IsSVGListTypeNeedingSpecialHandling
return 0;
}
+sub GetVisibleInterfaceName
+{
+ my $interfaceName = shift;
+
+ return "DOMException" if $interfaceName eq "DOMCoreException";
+ return "FormData" if $interfaceName eq "DOMFormData";
+ return $interfaceName;
+}
+
sub DebugPrint
{
my $output = shift;
diff --git a/WebCore/bindings/scripts/IDLParser.pm b/WebCore/bindings/scripts/IDLParser.pm
index b2577d2..7db7747 100644
--- a/WebCore/bindings/scripts/IDLParser.pm
+++ b/WebCore/bindings/scripts/IDLParser.pm
@@ -14,7 +14,7 @@
# Library General Public License for more details.
#
# You should have received a copy of the GNU Library General Public License
-# aint with this library; see the file COPYING.LIB. If not, write to
+# along with this library; see the file COPYING.LIB. If not, write to
# the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301, USA.
#
@@ -64,7 +64,14 @@ sub Parse
$parentsOnly = shift;
if (!$preprocessor) {
- $preprocessor = "/usr/bin/gcc -E -P -x c++";
+ require Config;
+ my $gccLocation = "";
+ if (($Config::Config{'osname'}) =~ /solaris/i) {
+ $gccLocation = "/usr/sfw/bin/gcc";
+ } else {
+ $gccLocation = "/usr/bin/gcc";
+ }
+ $preprocessor = $gccLocation . " -E -P -x c++";
}
if (!$defines) {
diff --git a/WebCore/bindings/scripts/IDLStructure.pm b/WebCore/bindings/scripts/IDLStructure.pm
index f5970b4..6224e54 100644
--- a/WebCore/bindings/scripts/IDLStructure.pm
+++ b/WebCore/bindings/scripts/IDLStructure.pm
@@ -14,7 +14,7 @@
# Library General Public License for more details.
#
# You should have received a copy of the GNU Library General Public License
-# aint with this library; see the file COPYING.LIB. If not, write to
+# along with this library; see the file COPYING.LIB. If not, write to
# the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301, USA.
#
diff --git a/WebCore/bindings/scripts/generate-bindings.pl b/WebCore/bindings/scripts/generate-bindings.pl
index ad29dc5..44ed4d3 100755
--- a/WebCore/bindings/scripts/generate-bindings.pl
+++ b/WebCore/bindings/scripts/generate-bindings.pl
@@ -16,7 +16,7 @@
# Library General Public License for more details.
#
# You should have received a copy of the GNU Library General Public License
-# aint with this library; see the file COPYING.LIB. If not, write to
+# along with this library; see the file COPYING.LIB. If not, write to
# the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301, USA.
#
diff --git a/WebCore/bindings/scripts/gobject-generate-headers.pl b/WebCore/bindings/scripts/gobject-generate-headers.pl
new file mode 100644
index 0000000..1017406
--- /dev/null
+++ b/WebCore/bindings/scripts/gobject-generate-headers.pl
@@ -0,0 +1,77 @@
+#!/usr/bin/perl -w
+#
+# Copyright (C) 2009 Adam Dingle <adam@yorba.org>
+#
+# This file is part of WebKit
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Library General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Library General Public License for more details.
+#
+# You should have received a copy of the GNU Library General Public License
+# aint with this library; see the file COPYING.LIB. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+# Boston, MA 02110-1301, USA.
+#
+
+my $classlist = <STDIN>;
+chomp($classlist);
+my @classes = split / /, $classlist;
+@classes = sort @classes;
+
+print <<EOF;
+/* This file is part of the WebKit open source project.
+ This file has been generated by gobject-generate-headers.pl. DO NOT MODIFY!
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+EOF
+
+my $outType = $ARGV[0];
+my $header;
+if ($outType eq "defines") {
+ $header = "webkitdomdefines_h";
+} elsif ($outType eq "gdom") {
+ $header = "webkitdom_h";
+} else {
+ die "unknown output type";
+}
+
+print "#ifndef ${header}\n";
+print "#define ${header}\n";
+print "\n";
+
+if ($outType eq "defines") {
+ foreach my $class (@classes) {
+ print "typedef struct _WebKitDOM${class} WebKitDOM${class};\n";
+ print "typedef struct _WebKitDOM${class}Class WebKitDOM${class}Class;\n";
+ print "\n";
+ }
+} elsif ($outType eq "gdom") {
+ foreach my $class (@classes) {
+ print "#include <webkit/WebKitDOM${class}.h>\n";
+ }
+}
+
+print "\n";
+print "#endif\n";
diff --git a/WebCore/bindings/v8/DOMData.cpp b/WebCore/bindings/v8/DOMData.cpp
index 417426f..568fc2c 100644
--- a/WebCore/bindings/v8/DOMData.cpp
+++ b/WebCore/bindings/v8/DOMData.cpp
@@ -39,9 +39,7 @@
namespace WebCore {
DOMData::DOMData()
- : m_delayedProcessingScheduled(false)
- , m_isMainThread(WTF::isMainThread())
- , m_owningThread(WTF::currentThread())
+ : m_owningThread(WTF::currentThread())
{
}
@@ -58,72 +56,9 @@ DOMData* DOMData::getCurrent()
return childThreadDOMData;
}
-void DOMData::ensureDeref(V8ClassIndex::V8WrapperType type, void* domObject)
+void DOMData::derefObject(WrapperTypeInfo* type, void* domObject)
{
- if (m_owningThread == WTF::currentThread()) {
- // No need to delay the work. We can deref right now.
- derefObject(type, domObject);
- return;
- }
-
- // We need to do the deref on the correct thread.
- m_delayedObjectMap.set(domObject, type);
-
- // Post a task to the owning thread in order to process the delayed queue.
- // FIXME: For now, we can only post to main thread due to WTF task posting limitation. We will fix this when we work on nested worker.
- if (!m_delayedProcessingScheduled) {
- m_delayedProcessingScheduled = true;
- if (isMainThread())
- WTF::callOnMainThread(&derefDelayedObjectsInCurrentThread, 0);
- }
-}
-
-void DOMData::derefObject(V8ClassIndex::V8WrapperType type, void* domObject)
-{
- switch (type) {
- case V8ClassIndex::NODE:
- static_cast<Node*>(domObject)->deref();
- break;
-
-#define MakeCase(type, name) \
- case V8ClassIndex::type: static_cast<name*>(domObject)->deref(); break;
- DOM_OBJECT_TYPES(MakeCase) // This includes both active and non-active.
-#undef MakeCase
-
-#if ENABLE(SVG)
-#define MakeCase(type, name) \
- case V8ClassIndex::type: static_cast<name*>(domObject)->deref(); break;
- SVG_OBJECT_TYPES(MakeCase) // This also includes SVGElementInstance.
-#undef MakeCase
-
-#define MakeCase(type, name) \
- case V8ClassIndex::type: \
- static_cast<V8SVGPODTypeWrapper<name>*>(domObject)->deref(); break;
- SVG_POD_NATIVE_TYPES(MakeCase)
-#undef MakeCase
-#endif
-
- default:
- ASSERT_NOT_REACHED();
- break;
- }
-}
-
-void DOMData::derefDelayedObjects()
-{
- WTF::MutexLocker locker(DOMDataStore::allStoresMutex());
-
- m_delayedProcessingScheduled = false;
-
- for (DelayedObjectMap::iterator iter(m_delayedObjectMap.begin()); iter != m_delayedObjectMap.end(); ++iter)
- derefObject(iter->second, iter->first);
-
- m_delayedObjectMap.clear();
-}
-
-void DOMData::derefDelayedObjectsInCurrentThread(void*)
-{
- getCurrent()->derefDelayedObjects();
+ type->derefObject(domObject);
}
} // namespace WebCore
diff --git a/WebCore/bindings/v8/DOMData.h b/WebCore/bindings/v8/DOMData.h
index 7fa9e7d..4d7331b 100644
--- a/WebCore/bindings/v8/DOMData.h
+++ b/WebCore/bindings/v8/DOMData.h
@@ -32,6 +32,7 @@
#define DOMData_h
#include "DOMDataStore.h"
+#include "V8DOMWrapper.h"
namespace WebCore {
@@ -53,62 +54,39 @@ namespace WebCore {
template<typename T>
static void handleWeakObject(DOMDataStore::DOMWrapperMapType, v8::Persistent<v8::Object>, T* domObject);
- void forgetDelayedObject(void* object) { m_delayedObjectMap.take(object); }
-
- // This is to ensure that we will deref DOM objects from the owning thread,
- // not the GC thread. The helper function will be scheduled by the GC
- // thread to get called from the owning thread.
- static void derefDelayedObjectsInCurrentThread(void*);
- void derefDelayedObjects();
-
template<typename T>
static void removeObjectsFromWrapperMap(AbstractWeakReferenceMap<T, v8::Object>& domMap);
ThreadIdentifier owningThread() const { return m_owningThread; }
private:
- typedef WTF::HashMap<void*, V8ClassIndex::V8WrapperType> DelayedObjectMap;
-
- void ensureDeref(V8ClassIndex::V8WrapperType type, void* domObject);
- static void derefObject(V8ClassIndex::V8WrapperType type, void* domObject);
+ static void derefObject(WrapperTypeInfo* type, void* domObject);
template<typename T>
class WrapperMapObjectRemover : public WeakReferenceMap<T, v8::Object>::Visitor {
public:
virtual void visitDOMWrapper(T* domObject, v8::Persistent<v8::Object> v8Object)
{
- V8ClassIndex::V8WrapperType type = V8DOMWrapper::domWrapperType(v8Object);
+ WrapperTypeInfo* type = V8DOMWrapper::domWrapperType(v8Object);
derefObject(type, domObject);
v8Object.Dispose();
}
};
- // Stores all the DOM objects that are delayed to be processed when the
- // owning thread gains control.
- DelayedObjectMap m_delayedObjectMap;
-
- // The flag to indicate if the task to do the delayed process has
- // already been posted.
- bool m_delayedProcessingScheduled;
-
- bool m_isMainThread;
ThreadIdentifier m_owningThread;
};
template<typename T>
void DOMData::handleWeakObject(DOMDataStore::DOMWrapperMapType mapType, v8::Persistent<v8::Object> v8Object, T* domObject)
{
- ASSERT(WTF::isMainThread());
DOMDataList& list = DOMDataStore::allStores();
for (size_t i = 0; i < list.size(); ++i) {
DOMDataStore* store = list[i];
+ ASSERT(store->domData()->owningThread() == WTF::currentThread());
- DOMDataStore::InternalDOMWrapperMap<T>* domMap = static_cast<DOMDataStore::InternalDOMWrapperMap<T>*>(store->getDOMWrapperMap(mapType));
-
- if (domMap->removeIfPresent(domObject, v8Object)) {
- ASSERT(store->domData()->owningThread() == WTF::currentThread());
+ DOMWrapperMap<T>* domMap = static_cast<DOMWrapperMap<T>*>(store->getDOMWrapperMap(mapType));
+ if (domMap->removeIfPresent(domObject, v8Object))
store->domData()->derefObject(V8DOMWrapper::domWrapperType(v8Object), domObject);
- }
}
}
diff --git a/WebCore/bindings/v8/DOMDataStore.cpp b/WebCore/bindings/v8/DOMDataStore.cpp
index e181ebc..5d609d8 100644
--- a/WebCore/bindings/v8/DOMDataStore.cpp
+++ b/WebCore/bindings/v8/DOMDataStore.cpp
@@ -114,11 +114,6 @@ WTF::Mutex& DOMDataStore::allStoresMutex()
return staticDOMDataListMutex;
}
-void DOMDataStore::forgetDelayedObject(DOMData* domData, void* object)
-{
- domData->forgetDelayedObject(object);
-}
-
void* DOMDataStore::getDOMWrapperMap(DOMWrapperMapType type)
{
switch (type) {
diff --git a/WebCore/bindings/v8/DOMDataStore.h b/WebCore/bindings/v8/DOMDataStore.h
index 54a49e7..c39a0ed 100644
--- a/WebCore/bindings/v8/DOMDataStore.h
+++ b/WebCore/bindings/v8/DOMDataStore.h
@@ -31,7 +31,7 @@
#ifndef DOMDataStore_h
#define DOMDataStore_h
-#include "DOMObjectsInclude.h"
+#include "V8DOMMap.h"
#include "V8Node.h"
#include <v8.h>
@@ -47,6 +47,7 @@
namespace WebCore {
class DOMData;
+ class DOMDataStore;
typedef WTF::Vector<DOMDataStore*> DOMDataList;
@@ -160,22 +161,6 @@ namespace WebCore {
#endif
};
- template <class KeyType>
- class InternalDOMWrapperMap : public DOMWrapperMap<KeyType> {
- public:
- InternalDOMWrapperMap(DOMData* domData, v8::WeakReferenceCallback callback)
- : DOMWrapperMap<KeyType>(callback), m_domData(domData) { }
-
- virtual void forget(KeyType* object)
- {
- DOMWrapperMap<KeyType>::forget(object);
- forgetDelayedObject(m_domData, object);
- }
-
- private:
- DOMData* m_domData;
- };
-
class IntrusiveDOMWrapperMap : public AbstractWeakReferenceMap<Node, v8::Object> {
public:
IntrusiveDOMWrapperMap(v8::WeakReferenceCallback callback)
@@ -252,25 +237,21 @@ namespace WebCore {
DOMDataStore(DOMData*);
virtual ~DOMDataStore();
- // A list of all DOMDataStore objects. Traversed during GC to find a thread-specific map that
- // contains the object - so we can schedule the object to be deleted on the thread which created it.
+ // A list of all DOMDataStore objects in the current V8 instance (thread). Normally, each World has a DOMDataStore.
static DOMDataList& allStores();
// Mutex to protect against concurrent access of DOMDataList.
static WTF::Mutex& allStoresMutex();
- // Helper function to avoid circular includes.
- static void forgetDelayedObject(DOMData*, void* object);
-
DOMData* domData() const { return m_domData; }
void* getDOMWrapperMap(DOMWrapperMapType);
DOMNodeMapping& domNodeMap() { return *m_domNodeMap; }
- InternalDOMWrapperMap<void>& domObjectMap() { return *m_domObjectMap; }
- InternalDOMWrapperMap<void>& activeDomObjectMap() { return *m_activeDomObjectMap; }
+ DOMWrapperMap<void>& domObjectMap() { return *m_domObjectMap; }
+ DOMWrapperMap<void>& activeDomObjectMap() { return *m_activeDomObjectMap; }
#if ENABLE(SVG)
- InternalDOMWrapperMap<SVGElementInstance>& domSvgElementInstanceMap() { return *m_domSvgElementInstanceMap; }
- InternalDOMWrapperMap<void>& domSvgObjectWithContextMap() { return *m_domSvgObjectWithContextMap; }
+ DOMWrapperMap<SVGElementInstance>& domSvgElementInstanceMap() { return *m_domSvgElementInstanceMap; }
+ DOMWrapperMap<void>& domSvgObjectWithContextMap() { return *m_domSvgObjectWithContextMap; }
#endif
// Need by V8GCController.
@@ -286,11 +267,11 @@ namespace WebCore {
#endif
DOMNodeMapping* m_domNodeMap;
- InternalDOMWrapperMap<void>* m_domObjectMap;
- InternalDOMWrapperMap<void>* m_activeDomObjectMap;
+ DOMWrapperMap<void>* m_domObjectMap;
+ DOMWrapperMap<void>* m_activeDomObjectMap;
#if ENABLE(SVG)
- InternalDOMWrapperMap<SVGElementInstance>* m_domSvgElementInstanceMap;
- InternalDOMWrapperMap<void>* m_domSvgObjectWithContextMap;
+ DOMWrapperMap<SVGElementInstance>* m_domSvgElementInstanceMap;
+ DOMWrapperMap<void>* m_domSvgObjectWithContextMap;
#endif
private:
diff --git a/WebCore/bindings/v8/DOMWrapperWorld.h b/WebCore/bindings/v8/DOMWrapperWorld.h
index f54cd4e..2a9df30 100644
--- a/WebCore/bindings/v8/DOMWrapperWorld.h
+++ b/WebCore/bindings/v8/DOMWrapperWorld.h
@@ -43,6 +43,7 @@ namespace WebCore {
class DOMWrapperWorld : public RefCounted<DOMWrapperWorld> {
public:
static PassRefPtr<DOMWrapperWorld> create() { return adoptRef(new DOMWrapperWorld()); }
+ virtual ~DOMWrapperWorld() {}
protected:
DOMWrapperWorld();
diff --git a/WebCore/bindings/v8/DateExtension.cpp b/WebCore/bindings/v8/DateExtension.cpp
index abf8967..f2b6242 100644
--- a/WebCore/bindings/v8/DateExtension.cpp
+++ b/WebCore/bindings/v8/DateExtension.cpp
@@ -88,7 +88,7 @@ void DateExtension::setAllowSleep(bool allow)
return;
v8::Handle<v8::Value> argv[1];
- argv[0] = v8::String::New(allow ? "false" : "true");
+ argv[0] = v8::Boolean::New(!allow);
v8::Handle<v8::Function>::Cast(sleepFunctionHandle)->Call(v8::Object::New(), 1, argv);
}
diff --git a/WebCore/bindings/v8/JavaScriptCallFrame.cpp b/WebCore/bindings/v8/JavaScriptCallFrame.cpp
new file mode 100644
index 0000000..049321b
--- /dev/null
+++ b/WebCore/bindings/v8/JavaScriptCallFrame.cpp
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 2010, Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "JavaScriptCallFrame.h"
+
+#if ENABLE(JAVASCRIPT_DEBUGGER)
+
+#include "V8Binding.h"
+
+namespace WebCore {
+
+JavaScriptCallFrame::JavaScriptCallFrame(v8::Handle<v8::Context> debuggerContext, v8::Handle<v8::Object> callFrame)
+ : m_debuggerContext(debuggerContext)
+ , m_callFrame(callFrame)
+{
+}
+
+JavaScriptCallFrame::~JavaScriptCallFrame()
+{
+}
+
+JavaScriptCallFrame* JavaScriptCallFrame::caller()
+{
+ if (!m_caller) {
+ v8::HandleScope handleScope;
+ v8::Context::Scope contextScope(m_debuggerContext.get());
+ v8::Handle<v8::Value> callerFrame = m_callFrame.get()->Get(v8String("caller"));
+ if (!callerFrame->IsObject())
+ return 0;
+ m_caller = JavaScriptCallFrame::create(m_debuggerContext.get(), v8::Handle<v8::Object>::Cast(callerFrame));
+ }
+ return m_caller.get();
+}
+
+int JavaScriptCallFrame::sourceID() const
+{
+ v8::HandleScope handleScope;
+ v8::Context::Scope contextScope(m_debuggerContext.get());
+ v8::Handle<v8::Value> result = m_callFrame.get()->Get(v8String("sourceID"));
+ if (result->IsInt32())
+ return result->Int32Value();
+ return 0;
+}
+
+int JavaScriptCallFrame::line() const
+{
+ v8::HandleScope handleScope;
+ v8::Context::Scope contextScope(m_debuggerContext.get());
+ v8::Handle<v8::Value> result = m_callFrame.get()->Get(v8String("line"));
+ if (result->IsInt32())
+ return result->Int32Value();
+ return 0;
+}
+
+String JavaScriptCallFrame::functionName() const
+{
+ v8::HandleScope handleScope;
+ v8::Context::Scope contextScope(m_debuggerContext.get());
+ v8::Handle<v8::Value> result = m_callFrame.get()->Get(v8String("functionName"));
+ return toWebCoreString(result);
+}
+
+v8::Handle<v8::Value> JavaScriptCallFrame::scopeChain() const
+{
+ v8::Handle<v8::Array> scopeChain = v8::Handle<v8::Array>::Cast(m_callFrame.get()->Get(v8String("scopeChain")));
+ v8::Handle<v8::Array> result = v8::Array::New(scopeChain->Length());
+ for (uint32_t i = 0; i < scopeChain->Length(); i++)
+ result->Set(i, scopeChain->Get(i));
+ return result;
+}
+
+int JavaScriptCallFrame::scopeType(int scopeIndex) const
+{
+ v8::Handle<v8::Array> scopeType = v8::Handle<v8::Array>::Cast(m_callFrame.get()->Get(v8String("scopeType")));
+ return scopeType->Get(scopeIndex)->Int32Value();
+}
+
+v8::Handle<v8::Value> JavaScriptCallFrame::thisObject() const
+{
+ return m_callFrame.get()->Get(v8String("thisObject"));
+}
+
+v8::Handle<v8::Value> JavaScriptCallFrame::evaluate(const String& expression)
+{
+ v8::Handle<v8::Function> evalFunction = v8::Handle<v8::Function>::Cast(m_callFrame.get()->Get(v8String("evaluate")));
+ v8::Handle<v8::Value> argv[] = { v8String(expression) };
+ return evalFunction->Call(m_callFrame.get(), 1, argv);
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(JAVASCRIPT_DEBUGGER)
diff --git a/WebCore/bindings/v8/JavaScriptCallFrame.h b/WebCore/bindings/v8/JavaScriptCallFrame.h
new file mode 100644
index 0000000..95a0510
--- /dev/null
+++ b/WebCore/bindings/v8/JavaScriptCallFrame.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2010, Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef JavaScriptCallFrame_h
+#define JavaScriptCallFrame_h
+
+#if ENABLE(JAVASCRIPT_DEBUGGER)
+
+#include "OwnHandle.h"
+#include "PlatformString.h"
+#include <v8-debug.h>
+
+namespace WebCore {
+
+class JavaScriptCallFrame : public RefCounted<JavaScriptCallFrame> {
+public:
+ static PassRefPtr<JavaScriptCallFrame> create(v8::Handle<v8::Context> debuggerContext, v8::Handle<v8::Object> callFrame)
+ {
+ return adoptRef(new JavaScriptCallFrame(debuggerContext, callFrame));
+ }
+ ~JavaScriptCallFrame();
+
+ JavaScriptCallFrame* caller();
+
+ int sourceID() const;
+ int line() const;
+ String functionName() const;
+
+ v8::Handle<v8::Value> scopeChain() const;
+ int scopeType(int scopeIndex) const;
+ v8::Handle<v8::Value> thisObject() const;
+
+ v8::Handle<v8::Value> evaluate(const String& expression);
+
+private:
+ JavaScriptCallFrame(v8::Handle<v8::Context> debuggerContext, v8::Handle<v8::Object> callFrame);
+
+ RefPtr<JavaScriptCallFrame> m_caller;
+ OwnHandle<v8::Context> m_debuggerContext;
+ OwnHandle<v8::Object> m_callFrame;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(JAVASCRIPT_DEBUGGER)
+
+#endif // JavaScriptCallFrame_h
diff --git a/WebCore/bindings/v8/NPV8Object.cpp b/WebCore/bindings/v8/NPV8Object.cpp
index 06243d4..56f9810 100644
--- a/WebCore/bindings/v8/NPV8Object.cpp
+++ b/WebCore/bindings/v8/NPV8Object.cpp
@@ -36,9 +36,9 @@
#include "ScriptController.h"
#include "V8GCController.h"
#include "V8Helpers.h"
-#include "V8Index.h"
#include "V8NPUtils.h"
#include "V8Proxy.h"
+#include "WrapperTypeInfo.h"
#include "npruntime_impl.h"
#include "npruntime_priv.h"
@@ -55,10 +55,20 @@
using WebCore::npObjectInternalFieldCount;
using WebCore::toV8Context;
using WebCore::toV8Proxy;
-using WebCore::V8ClassIndex;
using WebCore::V8DOMWrapper;
using WebCore::V8GCController;
using WebCore::V8Proxy;
+using WebCore::WrapperTypeInfo;
+
+namespace WebCore {
+
+WrapperTypeInfo* npObjectTypeInfo()
+{
+ static WrapperTypeInfo typeInfo = { 0, 0, false };
+ return &typeInfo;
+}
+
+}
// FIXME: Comments on why use malloc and free.
static NPObject* allocV8NPObject(NPP, NPClass*)
@@ -115,8 +125,8 @@ NPObject* npCreateV8ScriptObject(NPP npp, v8::Handle<v8::Object> object, WebCore
{
// Check to see if this object is already wrapped.
if (object->InternalFieldCount() == npObjectInternalFieldCount) {
- v8::Local<v8::Value> typeIndex = object->GetInternalField(WebCore::v8DOMWrapperTypeIndex);
- if (typeIndex->IsNumber() && typeIndex->Uint32Value() == V8ClassIndex::NPOBJECT) {
+ WrapperTypeInfo* typeInfo = static_cast<WrapperTypeInfo*>(object->GetPointerFromInternalField(WebCore::v8DOMWrapperTypeIndex));
+ if (typeInfo == WebCore::npObjectTypeInfo()) {
NPObject* returnValue = v8ObjectToNPObject(object);
_NPN_RetainObject(returnValue);
@@ -299,6 +309,9 @@ bool _NPN_GetProperty(NPP npp, NPObject* npObject, NPIdentifier propertyName, NP
v8::Handle<v8::Object> obj(object->v8Object);
v8::Local<v8::Value> v8result = obj->Get(npIdentifierToV8Identifier(propertyName));
+
+ if (v8result.IsEmpty())
+ return false;
convertV8ObjectToNPVariant(v8result, npObject, result);
return true;
diff --git a/WebCore/bindings/v8/NPV8Object.h b/WebCore/bindings/v8/NPV8Object.h
index e5550ee..b6fecce 100644
--- a/WebCore/bindings/v8/NPV8Object.h
+++ b/WebCore/bindings/v8/NPV8Object.h
@@ -30,7 +30,7 @@
#ifndef NPV8Object_h
#define NPV8Object_h
-#include "V8Index.h"
+#include "V8DOMWrapper.h"
#if PLATFORM(CHROMIUM)
// FIXME: Chromium uses a different npruntime.h, which is in
@@ -48,6 +48,8 @@ namespace WebCore {
class DOMWindow;
static const int npObjectInternalFieldCount = v8DefaultWrapperInternalFieldCount + 0;
+
+ WrapperTypeInfo* npObjectTypeInfo();
}
extern NPClass* npScriptObjectClass;
diff --git a/WebCore/bindings/v8/ScopedDOMDataStore.cpp b/WebCore/bindings/v8/ScopedDOMDataStore.cpp
index 19cd545..df4a63a 100644
--- a/WebCore/bindings/v8/ScopedDOMDataStore.cpp
+++ b/WebCore/bindings/v8/ScopedDOMDataStore.cpp
@@ -36,12 +36,12 @@ namespace WebCore {
ScopedDOMDataStore::ScopedDOMDataStore(DOMData* domData)
: DOMDataStore(domData)
{
- m_domNodeMap = new InternalDOMWrapperMap<Node>(domData, &DOMDataStore::weakNodeCallback);
- m_domObjectMap = new InternalDOMWrapperMap<void>(domData, &DOMDataStore::weakDOMObjectCallback);
- m_activeDomObjectMap = new InternalDOMWrapperMap<void>(domData, &DOMDataStore::weakActiveDOMObjectCallback);
+ m_domNodeMap = new DOMWrapperMap<Node>(&DOMDataStore::weakNodeCallback);
+ m_domObjectMap = new DOMWrapperMap<void>(&DOMDataStore::weakDOMObjectCallback);
+ m_activeDomObjectMap = new DOMWrapperMap<void>(&DOMDataStore::weakActiveDOMObjectCallback);
#if ENABLE(SVG)
- m_domSvgElementInstanceMap = new InternalDOMWrapperMap<SVGElementInstance>(domData, &DOMDataStore::weakSVGElementInstanceCallback);
- m_domSvgObjectWithContextMap = new InternalDOMWrapperMap<void>(domData, &DOMDataStore::weakSVGObjectWithContextCallback);
+ m_domSvgElementInstanceMap = new DOMWrapperMap<SVGElementInstance>(&DOMDataStore::weakSVGElementInstanceCallback);
+ m_domSvgObjectWithContextMap = new DOMWrapperMap<void>(&DOMDataStore::weakSVGObjectWithContextCallback);
#endif
}
diff --git a/WebCore/bindings/v8/ScriptCallStack.cpp b/WebCore/bindings/v8/ScriptCallStack.cpp
index 21063ed..45e7205 100644
--- a/WebCore/bindings/v8/ScriptCallStack.cpp
+++ b/WebCore/bindings/v8/ScriptCallStack.cpp
@@ -32,29 +32,33 @@
#include "ScriptCallStack.h"
#include "ScriptController.h"
+#include "ScriptDebugServer.h"
#include <v8.h>
#include "V8Binding.h"
-#include "V8Proxy.h"
namespace WebCore {
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);
+ String funcName;
+ if (!callLocation(&sourceName, &sourceLineNumber, &funcName))
+ return 0;
+ return new ScriptCallStack(arguments, skipArgumentCount, sourceName, sourceLineNumber, funcName);
}
-ScriptCallStack::ScriptCallStack(const v8::Arguments& arguments, unsigned skipArgumentCount, String sourceName, int sourceLineNumber)
- : m_lastCaller(String(), sourceName, sourceLineNumber, arguments, skipArgumentCount)
+bool ScriptCallStack::callLocation(String* sourceName, int* sourceLineNumber, String* functionName)
+{
+ if (!ScriptDebugServer::topStackFrame(*sourceName, *sourceLineNumber, *functionName))
+ return false;
+ *sourceLineNumber += 1;
+ return true;
+}
+
+ScriptCallStack::ScriptCallStack(const v8::Arguments& arguments, unsigned skipArgumentCount, String sourceName, int sourceLineNumber, String functionName)
+ : m_lastCaller(functionName, sourceName, sourceLineNumber, arguments, skipArgumentCount)
, m_scriptState(ScriptState::current())
{
}
diff --git a/WebCore/bindings/v8/ScriptCallStack.h b/WebCore/bindings/v8/ScriptCallStack.h
index 8ac394c..2433bde 100644
--- a/WebCore/bindings/v8/ScriptCallStack.h
+++ b/WebCore/bindings/v8/ScriptCallStack.h
@@ -47,6 +47,8 @@ namespace WebCore {
static ScriptCallStack* create(const v8::Arguments&, unsigned skipArgumentCount = 0);
~ScriptCallStack();
+ static bool callLocation(String* sourceName, int* sourceLineNumber, String* functionName);
+
const ScriptCallFrame& at(unsigned) const;
// FIXME: implement retrieving and storing call stack trace
unsigned size() const { return 1; }
@@ -55,7 +57,7 @@ namespace WebCore {
ScriptState* globalState() const { return m_scriptState; }
private:
- ScriptCallStack(const v8::Arguments& arguments, unsigned skipArgumentCount, String sourceName, int sourceLineNumber);
+ ScriptCallStack(const v8::Arguments& arguments, unsigned skipArgumentCount, String sourceName, int sourceLineNumber, String funcName);
ScriptCallFrame m_lastCaller;
ScriptState* m_scriptState;
diff --git a/WebCore/bindings/v8/ScriptController.cpp b/WebCore/bindings/v8/ScriptController.cpp
index 40a71be..ee15eaa 100644
--- a/WebCore/bindings/v8/ScriptController.cpp
+++ b/WebCore/bindings/v8/ScriptController.cpp
@@ -33,7 +33,6 @@
#include "ScriptController.h"
#include "PlatformBridge.h"
-#include "CString.h"
#include "Document.h"
#include "DOMWindow.h"
#include "Event.h"
@@ -48,6 +47,7 @@
#include "NPV8Object.h"
#include "ScriptSourceCode.h"
#include "Settings.h"
+#include "UserGestureIndicator.h"
#include "V8Binding.h"
#include "V8BindingState.h"
#include "V8DOMWindow.h"
@@ -59,6 +59,7 @@
#include "Widget.h"
#include "XSSAuditor.h"
#include <wtf/StdLibExtras.h>
+#include <wtf/text/CString.h>
namespace WebCore {
@@ -153,9 +154,10 @@ void ScriptController::updatePlatformScriptObjects()
bool ScriptController::processingUserGesture(DOMWrapperWorld*) const
{
Frame* activeFrame = V8Proxy::retrieveFrameForEnteredContext();
- // No script is running, so it must be run by users.
+ // No script is running, so it is user-initiated unless the gesture stack
+ // explicitly says it is not.
if (!activeFrame)
- return true;
+ return UserGestureIndicator::processingUserGesture();
V8Proxy* activeProxy = activeFrame->script()->proxy();
@@ -176,7 +178,7 @@ bool ScriptController::processingUserGesture(DOMWrapperWorld*) const
// Based on code from kjs_bindings.cpp.
// Note: This is more liberal than Firefox's implementation.
if (event) {
- if (event->createdByDOM())
+ if (!UserGestureIndicator::processingUserGesture())
return false;
const AtomicString& type = event->type();
@@ -190,7 +192,7 @@ bool ScriptController::processingUserGesture(DOMWrapperWorld*) const
if (eventOk)
return true;
- } else if (activeProxy->inlineCode() && !activeProxy->timerCallback()) {
+ } else if (m_sourceURL && m_sourceURL->isNull() && !activeProxy->timerCallback()) {
// This is the <a href="javascript:window.open('...')> case -> we let it through.
return true;
}
@@ -219,7 +221,9 @@ void ScriptController::evaluateInIsolatedWorld(unsigned worldID, const Vector<Sc
ScriptValue ScriptController::evaluate(const ScriptSourceCode& sourceCode)
{
String sourceURL = sourceCode.url();
-
+ const String* savedSourceURL = m_sourceURL;
+ m_sourceURL = &sourceURL;
+
if (!m_XSSAuditor->canEvaluate(sourceCode.source())) {
// This script is not safe to be evaluated.
return ScriptValue();
@@ -237,9 +241,11 @@ ScriptValue ScriptController::evaluate(const ScriptSourceCode& sourceCode)
v8::Local<v8::Value> object = m_proxy->evaluate(sourceCode, 0);
// Evaluating the JavaScript could cause the frame to be deallocated
- // so we starot the keep alive timer here.
+ // so we start the keep alive timer here.
m_frame->keepAlive();
+ m_sourceURL = savedSourceURL;
+
if (object.IsEmpty() || object->IsUndefined())
return ScriptValue();
@@ -402,7 +408,7 @@ NPObject* ScriptController::windowScriptNPObject()
if (m_windowScriptNPObject)
return m_windowScriptNPObject;
- if (canExecuteScripts()) {
+ if (canExecuteScripts(NotAboutToExecuteScript)) {
// JavaScript is enabled, so there is a JavaScript window object.
// Return an NPObject bound to the window object.
m_windowScriptNPObject = createScriptObject(m_frame);
@@ -419,7 +425,7 @@ NPObject* ScriptController::windowScriptNPObject()
NPObject* ScriptController::createScriptObjectForPluginElement(HTMLPlugInElement* plugin)
{
// Can't create NPObjects when JavaScript is disabled.
- if (!canExecuteScripts())
+ if (!canExecuteScripts(NotAboutToExecuteScript))
return createNoScriptObject();
v8::HandleScope handleScope;
diff --git a/WebCore/bindings/v8/ScriptController.h b/WebCore/bindings/v8/ScriptController.h
index b3995b2..7e13740 100644
--- a/WebCore/bindings/v8/ScriptController.h
+++ b/WebCore/bindings/v8/ScriptController.h
@@ -55,6 +55,11 @@ class String;
class Widget;
class XSSAuditor;
+enum ReasonForCallingCanExecuteScripts {
+ AboutToExecuteScript,
+ NotAboutToExecuteScript
+};
+
class ScriptController {
public:
ScriptController(Frame*);
@@ -113,7 +118,7 @@ public:
// Check if the javascript engine has been initialized.
bool haveInterpreter() const;
- bool canExecuteScripts();
+ bool canExecuteScripts(ReasonForCallingCanExecuteScripts);
// FIXME: void* is a compile hack.
void attachDebugger(void*);
diff --git a/WebCore/bindings/v8/ScriptDebugServer.cpp b/WebCore/bindings/v8/ScriptDebugServer.cpp
index 3fe8c34..54d7694 100644
--- a/WebCore/bindings/v8/ScriptDebugServer.cpp
+++ b/WebCore/bindings/v8/ScriptDebugServer.cpp
@@ -29,17 +29,379 @@
*/
#include "config.h"
-
#include "ScriptDebugServer.h"
+#if ENABLE(JAVASCRIPT_DEBUGGER)
+
+#include "Frame.h"
+#include "JavaScriptCallFrame.h"
+#include "Page.h"
+#include "ScriptDebugListener.h"
+#include "V8Binding.h"
+#include "V8DOMWindow.h"
+#include "V8Proxy.h"
+#include <wtf/StdLibExtras.h>
+
namespace WebCore {
-void ScriptDebugServer::recompileAllJSFunctions()
+v8::Persistent<v8::Context> ScriptDebugServer::s_utilityContext;
+
+ScriptDebugServer::MessageLoopDispatchHandler ScriptDebugServer::s_messageLoopDispatchHandler = 0;
+
+ScriptDebugServer& ScriptDebugServer::shared()
+{
+ DEFINE_STATIC_LOCAL(ScriptDebugServer, server, ());
+ return server;
+}
+
+ScriptDebugServer::ScriptDebugServer()
+ : m_pauseOnExceptionsState(DontPauseOnExceptions)
+ , m_currentCallFrameState(0)
+{
+}
+
+void ScriptDebugServer::setDebuggerScriptSource(const String& scriptSource)
+{
+ m_debuggerScriptSource = scriptSource;
+}
+
+void ScriptDebugServer::addListener(ScriptDebugListener* listener, Page* page)
+{
+#if ENABLE(V8_SCRIPT_DEBUG_SERVER)
+ v8::HandleScope scope;
+ v8::Local<v8::Context> debuggerContext = v8::Debug::GetDebugContext();
+ v8::Context::Scope contextScope(debuggerContext);
+
+ if (!m_listenersMap.size()) {
+ ensureDebuggerScriptCompiled();
+ ASSERT(!m_debuggerScript.get()->IsUndefined());
+ v8::Debug::SetMessageHandler2(&ScriptDebugServer::onV8DebugMessage);
+ v8::Debug::SetHostDispatchHandler(&ScriptDebugServer::onV8DebugHostDispatch, 100 /* ms */);
+ }
+ m_listenersMap.set(page, listener);
+ V8Proxy* proxy = V8Proxy::retrieve(page->mainFrame());
+ v8::Local<v8::Context> context = proxy->mainWorldContext();
+ String contextData = toWebCoreStringWithNullCheck(context->GetData());
+ m_contextDataMap.set(listener, contextData);
+
+ v8::Handle<v8::Function> getScriptsFunction = v8::Local<v8::Function>::Cast(m_debuggerScript.get()->Get(v8::String::New("getScripts")));
+ v8::Handle<v8::Value> value = v8::Debug::Call(getScriptsFunction);
+ if (value.IsEmpty())
+ return;
+ ASSERT(!value->IsUndefined() && value->IsArray());
+ v8::Handle<v8::Array> scriptsArray = v8::Handle<v8::Array>::Cast(value);
+ for (unsigned i = 0; i < scriptsArray->Length(); ++i)
+ dispatchDidParseSource(listener, v8::Handle<v8::Object>::Cast(scriptsArray->Get(v8::Integer::New(i))));
+#endif
+}
+
+void ScriptDebugServer::removeListener(ScriptDebugListener* listener, Page* page)
+{
+ if (!m_listenersMap.contains(page))
+ return;
+
+ m_listenersMap.remove(page);
+
+ if (m_listenersMap.isEmpty()) {
+ v8::Debug::SetMessageHandler2(0);
+ v8::Debug::SetHostDispatchHandler(0);
+ }
+ // FIXME: Remove all breakpoints set by the agent.
+ // FIXME: Force continue if detach happened in nessted message loop while
+ // debugger was paused on a breakpoint(as long as there are other
+ // attached agents v8 will wait for explicit'continue' message).
+ // FIXME: send continue command to v8 if necessary;
+}
+
+void ScriptDebugServer::setBreakpoint(const String& sourceID, unsigned lineNumber, ScriptBreakpoint breakpoint)
+{
+#if ENABLE(V8_SCRIPT_DEBUG_SERVER)
+ v8::HandleScope scope;
+ v8::Local<v8::Context> debuggerContext = v8::Debug::GetDebugContext();
+ v8::Context::Scope contextScope(debuggerContext);
+
+ v8::Local<v8::Object> args = v8::Object::New();
+ args->Set(v8::String::New("scriptId"), v8String(sourceID));
+ args->Set(v8::String::New("lineNumber"), v8::Integer::New(lineNumber));
+ args->Set(v8::String::New("condition"), v8String(breakpoint.condition));
+ args->Set(v8::String::New("enabled"), v8::Boolean::New(breakpoint.enabled));
+
+ v8::Handle<v8::Function> setBreakpointFunction = v8::Local<v8::Function>::Cast(m_debuggerScript.get()->Get(v8::String::New("setBreakpoint")));
+ v8::Debug::Call(setBreakpointFunction, args);
+#endif
+}
+
+void ScriptDebugServer::removeBreakpoint(const String& sourceID, unsigned lineNumber)
+{
+#if ENABLE(V8_SCRIPT_DEBUG_SERVER)
+ v8::HandleScope scope;
+ v8::Local<v8::Context> debuggerContext = v8::Debug::GetDebugContext();
+ v8::Context::Scope contextScope(debuggerContext);
+
+ v8::Local<v8::Object> args = v8::Object::New();
+ args->Set(v8::String::New("scriptId"), v8String(sourceID));
+ args->Set(v8::String::New("lineNumber"), v8::Integer::New(lineNumber));
+
+ v8::Handle<v8::Function> removeBreakpointFunction = v8::Local<v8::Function>::Cast(m_debuggerScript.get()->Get(v8::String::New("removeBreakpoint")));
+ v8::Debug::Call(removeBreakpointFunction, args);
+#endif
+}
+
+void ScriptDebugServer::clearBreakpoints()
+{
+#if ENABLE(V8_SCRIPT_DEBUG_SERVER)
+ ensureDebuggerScriptCompiled();
+ v8::HandleScope scope;
+ v8::Local<v8::Context> debuggerContext = v8::Debug::GetDebugContext();
+ v8::Context::Scope contextScope(debuggerContext);
+
+ v8::Handle<v8::Function> setBreakpointsActivated = v8::Local<v8::Function>::Cast(m_debuggerScript.get()->Get(v8::String::New("clearBreakpoints")));
+ v8::Debug::Call(setBreakpointsActivated);
+#endif
+}
+
+void ScriptDebugServer::setBreakpointsActivated(bool enabled)
+{
+#if ENABLE(V8_SCRIPT_DEBUG_SERVER)
+ ensureDebuggerScriptCompiled();
+ v8::HandleScope scope;
+ v8::Local<v8::Context> debuggerContext = v8::Debug::GetDebugContext();
+ v8::Context::Scope contextScope(debuggerContext);
+
+ v8::Local<v8::Object> args = v8::Object::New();
+ args->Set(v8::String::New("enabled"), v8::Boolean::New(enabled));
+ v8::Handle<v8::Function> setBreakpointsActivated = v8::Local<v8::Function>::Cast(m_debuggerScript.get()->Get(v8::String::New("setBreakpointsActivated")));
+ v8::Debug::Call(setBreakpointsActivated, args);
+#endif
+}
+
+void ScriptDebugServer::continueProgram()
+{
+#if ENABLE(V8_SCRIPT_DEBUG_SERVER)
+ String cmd("{\"seq\":1,\"type\":\"request\",\"command\":\"continue\"}");
+ v8::Debug::SendCommand(reinterpret_cast<const uint16_t*>(cmd.characters()), cmd.length(), new v8::Debug::ClientData());
+ didResume();
+#endif
+}
+
+void ScriptDebugServer::stepIntoStatement()
+{
+#if ENABLE(V8_SCRIPT_DEBUG_SERVER)
+ String cmd("{\"seq\":1,\"type\":\"request\",\"command\":\"continue\",\"arguments\":{\"stepaction\":\"in\"}}");
+ v8::Debug::SendCommand(reinterpret_cast<const uint16_t*>(cmd.characters()), cmd.length(), new v8::Debug::ClientData());
+ didResume();
+#endif
+}
+
+void ScriptDebugServer::stepOverStatement()
{
+#if ENABLE(V8_SCRIPT_DEBUG_SERVER)
+ String cmd("{\"seq\":1,\"type\":\"request\",\"command\":\"continue\",\"arguments\":{\"stepaction\":\"next\"}}");
+ v8::Debug::SendCommand(reinterpret_cast<const uint16_t*>(cmd.characters()), cmd.length(), new v8::Debug::ClientData());
+ didResume();
+#endif
}
-void ScriptDebugServer::recompileAllJSFunctionsSoon()
+void ScriptDebugServer::stepOutOfFunction()
{
+#if ENABLE(V8_SCRIPT_DEBUG_SERVER)
+ String cmd("{\"seq\":1,\"type\":\"request\",\"command\":\"continue\",\"arguments\":{\"stepaction\":\"out\"}}");
+ v8::Debug::SendCommand(reinterpret_cast<const uint16_t*>(cmd.characters()), cmd.length(), new v8::Debug::ClientData());
+ didResume();
+#endif
+}
+
+ScriptState* ScriptDebugServer::currentCallFrameState()
+{
+ return m_currentCallFrameState;
+}
+
+v8::Handle<v8::Value> ScriptDebugServer::currentCallFrameV8()
+{
+#if ENABLE(V8_SCRIPT_DEBUG_SERVER)
+ if (!m_currentCallFrame.get().IsEmpty())
+ return m_currentCallFrame.get();
+
+ // Check on a bp.
+ v8::Handle<v8::Function> currentCallFrameFunction = v8::Local<v8::Function>::Cast(m_debuggerScript.get()->Get(v8::String::New("currentCallFrame")));
+ v8::Handle<v8::Value> argv[] = { m_executionState.get() };
+ v8::Handle<v8::Value> result = currentCallFrameFunction->Call(m_debuggerScript.get(), 1, argv);
+ m_currentCallFrame.set(result);
+ return result;
+#else
+ return v8::Handle<v8::Value>();
+#endif
+}
+
+PassRefPtr<JavaScriptCallFrame> ScriptDebugServer::currentCallFrame()
+{
+ return JavaScriptCallFrame::create(v8::Debug::GetDebugContext(), v8::Handle<v8::Object>::Cast(currentCallFrameV8()));
+}
+
+void ScriptDebugServer::onV8DebugMessage(const v8::Debug::Message& message)
+{
+ ScriptDebugServer::shared().handleV8DebugMessage(message);
+}
+
+void ScriptDebugServer::onV8DebugHostDispatch()
+{
+ ScriptDebugServer::shared().handleV8DebugHostDispatch();
+}
+
+void ScriptDebugServer::handleV8DebugHostDispatch()
+{
+ if (!s_messageLoopDispatchHandler)
+ return;
+
+ Vector<WebCore::Page*> pages;
+ for (ListenersMap::iterator it = m_listenersMap.begin(); it != m_listenersMap.end(); ++it)
+ pages.append(it->first);
+
+ s_messageLoopDispatchHandler(pages);
+}
+
+void ScriptDebugServer::handleV8DebugMessage(const v8::Debug::Message& message)
+{
+ v8::HandleScope scope;
+
+ if (!message.IsEvent())
+ return;
+
+ // Ignore unsupported event types.
+ if (message.GetEvent() != v8::AfterCompile && message.GetEvent() != v8::Break)
+ return;
+
+ v8::Handle<v8::Context> context = message.GetEventContext();
+ // If the context is from one of the inpected tabs it should have its context
+ // data. Skip events from unknown contexts.
+ if (context.IsEmpty())
+ return;
+
+ // Test that context has associated global dom window object.
+ v8::Handle<v8::Object> global = context->Global();
+ if (global.IsEmpty())
+ return;
+
+ global = V8DOMWrapper::lookupDOMWrapper(V8DOMWindow::GetTemplate(), global);
+ if (global.IsEmpty())
+ return;
+
+ Frame* frame = V8Proxy::retrieveFrame(context);
+ if (frame) {
+ ScriptDebugListener* listener = m_listenersMap.get(frame->page());
+ if (listener) {
+ if (message.GetEvent() == v8::AfterCompile) {
+ v8::Context::Scope contextScope(v8::Debug::GetDebugContext());
+ v8::Local<v8::Object> args = v8::Object::New();
+ args->Set(v8::String::New("eventData"), message.GetEventData());
+ v8::Handle<v8::Function> onAfterCompileFunction = v8::Local<v8::Function>::Cast(m_debuggerScript.get()->Get(v8::String::New("getAfterCompileScript")));
+ v8::Handle<v8::Value> argv[] = { message.GetExecutionState(), args };
+ v8::Handle<v8::Value> value = onAfterCompileFunction->Call(m_debuggerScript.get(), 2, argv);
+ ASSERT(value->IsObject());
+ v8::Handle<v8::Object> object = v8::Handle<v8::Object>::Cast(value);
+ dispatchDidParseSource(listener, object);
+ } else if (message.GetEvent() == v8::Break) {
+ m_executionState.set(message.GetExecutionState());
+ m_currentCallFrameState = mainWorldScriptState(frame);
+ listener->didPause();
+ m_currentCallFrameState = 0;
+ }
+ }
+ }
+}
+
+void ScriptDebugServer::dispatchDidParseSource(ScriptDebugListener* listener, v8::Handle<v8::Object> object)
+{
+ String contextData = toWebCoreStringWithNullCheck(object->Get(v8::String::New("contextData")));
+ if (contextData != m_contextDataMap.get(listener))
+ return;
+
+ listener->didParseSource(
+ toWebCoreStringWithNullCheck(object->Get(v8::String::New("id"))),
+ toWebCoreStringWithNullCheck(object->Get(v8::String::New("name"))),
+ toWebCoreStringWithNullCheck(object->Get(v8::String::New("source"))),
+ object->Get(v8::String::New("lineOffset"))->ToInteger()->Value());
+}
+
+void ScriptDebugServer::ensureDebuggerScriptCompiled()
+{
+ if (m_debuggerScript.get().IsEmpty()) {
+ v8::HandleScope scope;
+ v8::Local<v8::Context> debuggerContext = v8::Debug::GetDebugContext();
+ v8::Context::Scope contextScope(debuggerContext);
+ m_debuggerScript.set(v8::Handle<v8::Object>::Cast(v8::Script::Compile(v8String(m_debuggerScriptSource))->Run()));
+ }
+}
+
+void ScriptDebugServer::didResume()
+{
+ m_currentCallFrame.clear();
+ m_executionState.clear();
+}
+
+// Create the utility context for holding JavaScript functions used internally
+// which are not visible to JavaScript executing on the page.
+void ScriptDebugServer::createUtilityContext()
+{
+ ASSERT(s_utilityContext.IsEmpty());
+
+ v8::HandleScope scope;
+ v8::Handle<v8::ObjectTemplate> globalTemplate = v8::ObjectTemplate::New();
+ s_utilityContext = v8::Context::New(0, globalTemplate);
+ v8::Context::Scope contextScope(s_utilityContext);
+
+ // Compile JavaScript function for retrieving the source line, the source
+ // name and the symbol name for the top JavaScript stack frame.
+ DEFINE_STATIC_LOCAL(const char*, topStackFrame,
+ ("function topStackFrame(exec_state) {"
+ " if (!exec_state.frameCount())"
+ " return undefined;"
+ " var frame = exec_state.frame(0);"
+ " var func = frame.func();"
+ " var scriptName;"
+ " if (func.resolved() && func.script())"
+ " scriptName = func.script().name();"
+ " return [scriptName, frame.sourceLine(), (func.name() || func.inferredName())];"
+ "}"));
+ v8::Script::Compile(v8::String::New(topStackFrame))->Run();
+}
+
+bool ScriptDebugServer::topStackFrame(String& sourceName, int& lineNumber, String& functionName)
+{
+ v8::HandleScope scope;
+ v8::Handle<v8::Context> v8UtilityContext = utilityContext();
+ if (v8UtilityContext.IsEmpty())
+ return false;
+ v8::Context::Scope contextScope(v8UtilityContext);
+ v8::Handle<v8::Function> topStackFrame;
+ topStackFrame = v8::Local<v8::Function>::Cast(v8UtilityContext->Global()->Get(v8::String::New("topStackFrame")));
+ if (topStackFrame.IsEmpty())
+ return false;
+ v8::Handle<v8::Value> value = v8::Debug::Call(topStackFrame);
+ if (value.IsEmpty())
+ return false;
+ // If there is no top stack frame, we still return success, but fill the input params with defaults.
+ if (value->IsUndefined()) {
+ // Fallback to setting lineNumber to 0, and source and function name to "undefined".
+ sourceName = toWebCoreString(value);
+ lineNumber = 0;
+ functionName = toWebCoreString(value);
+ return true;
+ }
+ if (!value->IsArray())
+ return false;
+ v8::Local<v8::Object> jsArray = value->ToObject();
+ v8::Local<v8::Value> sourceNameValue = jsArray->Get(0);
+ v8::Local<v8::Value> lineNumberValue = jsArray->Get(1);
+ v8::Local<v8::Value> functionNameValue = jsArray->Get(2);
+ if (sourceNameValue.IsEmpty() || lineNumberValue.IsEmpty() || functionNameValue.IsEmpty())
+ return false;
+ sourceName = toWebCoreString(sourceNameValue);
+ lineNumber = lineNumberValue->Int32Value();
+ functionName = toWebCoreString(functionNameValue);
+ return true;
}
} // namespace WebCore
+
+#endif // ENABLE(JAVASCRIPT_DEBUGGER)
diff --git a/WebCore/bindings/v8/ScriptDebugServer.h b/WebCore/bindings/v8/ScriptDebugServer.h
index b37af2f..04857e4 100644
--- a/WebCore/bindings/v8/ScriptDebugServer.h
+++ b/WebCore/bindings/v8/ScriptDebugServer.h
@@ -31,16 +31,119 @@
#ifndef ScriptDebugServer_h
#define ScriptDebugServer_h
+#if ENABLE(JAVASCRIPT_DEBUGGER)
+
+#include "OwnHandle.h"
+#include "PlatformString.h"
+#include "ScriptBreakpoint.h"
+#include "ScriptState.h"
+#include "StringHash.h"
+#include "Timer.h"
+#include <v8-debug.h>
+#include <wtf/HashMap.h>
#include <wtf/Noncopyable.h>
namespace WebCore {
+class JavaScriptCallFrame;
+class Page;
+class ScriptDebugListener;
+
class ScriptDebugServer : public Noncopyable {
public:
- static void recompileAllJSFunctions();
- static void recompileAllJSFunctionsSoon();
+ static ScriptDebugServer& shared();
+
+ // Function for retrieving the source name, line number and function name for the top
+ // JavaScript stack frame.
+ //
+ // It will return true if the caller information was successfully retrieved and written
+ // into the function parameters, otherwise the function will return false. It may
+ // fail due to a stack overflow in the underlying JavaScript implementation, handling
+ // of such exception is up to the caller.
+ static bool topStackFrame(String& sourceName, int& lineNumber, String& functionName);
+
+ void addListener(ScriptDebugListener*, Page*);
+ void removeListener(ScriptDebugListener*, Page*);
+
+ void setBreakpoint(const String& sourceID, unsigned lineNumber, ScriptBreakpoint breakpoint);
+ void removeBreakpoint(const String& sourceID, unsigned lineNumber);
+ void clearBreakpoints();
+ void setBreakpointsActivated(bool activated);
+
+ enum PauseOnExceptionsState {
+ DontPauseOnExceptions,
+ PauseOnAllExceptions,
+ PauseOnUncaughtExceptions
+ };
+ PauseOnExceptionsState pauseOnExceptionsState() const { return m_pauseOnExceptionsState; }
+ void setPauseOnExceptionsState(PauseOnExceptionsState pauseOnExceptionsState) { m_pauseOnExceptionsState = pauseOnExceptionsState; }
+
+ void pauseProgram() { }
+ void continueProgram();
+ void stepIntoStatement();
+ void stepOverStatement();
+ void stepOutOfFunction();
+
+ void recompileAllJSFunctionsSoon() { }
+ void recompileAllJSFunctions(Timer<ScriptDebugServer>* = 0) { }
+
+ ScriptState* currentCallFrameState();
+
+ void pageCreated(Page*) { }
+
+ // v8-specific methods.
+ void setDebuggerScriptSource(const String& scriptSource);
+
+ typedef void (*MessageLoopDispatchHandler)(const Vector<WebCore::Page*>&);
+ static void setMessageLoopDispatchHandler(MessageLoopDispatchHandler messageLoopDispatchHandler) { s_messageLoopDispatchHandler = messageLoopDispatchHandler; }
+
+ v8::Handle<v8::Value> currentCallFrameV8();
+ PassRefPtr<JavaScriptCallFrame> currentCallFrame();
+
+private:
+ ScriptDebugServer();
+ ~ScriptDebugServer() { }
+
+ static void onV8DebugMessage(const v8::Debug::Message& message);
+ static void onV8DebugHostDispatch();
+
+ void handleV8DebugMessage(const v8::Debug::Message& message);
+ void handleV8DebugHostDispatch();
+
+ void dispatchDidParseSource(ScriptDebugListener* listener, v8::Handle<v8::Object> sourceObject);
+
+ void ensureDebuggerScriptCompiled();
+ void didResume();
+
+ static void createUtilityContext();
+
+ // Returns a local handle of the utility context.
+ static v8::Local<v8::Context> utilityContext()
+ {
+ if (s_utilityContext.IsEmpty())
+ createUtilityContext();
+ return v8::Local<v8::Context>::New(s_utilityContext);
+ }
+
+ // Utility context holding JavaScript functions used internally.
+ static v8::Persistent<v8::Context> s_utilityContext;
+
+ typedef HashMap<Page*, ScriptDebugListener*> ListenersMap;
+ ListenersMap m_listenersMap;
+ typedef HashMap<ScriptDebugListener*, String> ContextDataMap;
+ ContextDataMap m_contextDataMap;
+ String m_debuggerScriptSource;
+ PauseOnExceptionsState m_pauseOnExceptionsState;
+ OwnHandle<v8::Object> m_debuggerScript;
+ ScriptState* m_currentCallFrameState;
+ OwnHandle<v8::Value> m_currentCallFrame;
+ OwnHandle<v8::Object> m_executionState;
+
+ static MessageLoopDispatchHandler s_messageLoopDispatchHandler;
};
} // namespace WebCore
+#endif // ENABLE(JAVASCRIPT_DEBUGGER)
+
#endif // ScriptDebugServer_h
diff --git a/WebCore/bindings/v8/ScriptEventListener.cpp b/WebCore/bindings/v8/ScriptEventListener.cpp
index b318d2e..fdb6076 100644
--- a/WebCore/bindings/v8/ScriptEventListener.cpp
+++ b/WebCore/bindings/v8/ScriptEventListener.cpp
@@ -56,7 +56,7 @@ PassRefPtr<V8LazyEventListener> createAttributeEventListener(Node* node, Attribu
if (Frame* frame = node->document()->frame()) {
ScriptController* scriptController = frame->script();
- if (!scriptController->canExecuteScripts())
+ if (!scriptController->canExecuteScripts(AboutToExecuteScript))
return 0;
if (!scriptController->xssAuditor()->canCreateInlineEventListener(attr->localName().string(), attr->value())) {
@@ -89,7 +89,7 @@ PassRefPtr<V8LazyEventListener> createAttributeEventListener(Frame* frame, Attri
String sourceURL;
ScriptController* scriptController = frame->script();
- if (!scriptController->canExecuteScripts())
+ if (!scriptController->canExecuteScripts(AboutToExecuteScript))
return 0;
if (!scriptController->xssAuditor()->canCreateInlineEventListener(attr->localName().string(), attr->value())) {
diff --git a/WebCore/bindings/v8/ScriptGCEvent.cpp b/WebCore/bindings/v8/ScriptGCEvent.cpp
new file mode 100644
index 0000000..a58a0cd
--- /dev/null
+++ b/WebCore/bindings/v8/ScriptGCEvent.cpp
@@ -0,0 +1,101 @@
+/*
+* Copyright (C) 2010 Google Inc. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are
+* met:
+*
+* * Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+* * Redistributions in binary form must reproduce the above
+* copyright notice, this list of conditions and the following disclaimer
+* in the documentation and/or other materials provided with the
+* distribution.
+* * Neither the name of Google Inc. nor the names of its
+* contributors may be used to endorse or promote products derived from
+* this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "config.h"
+
+#if ENABLE(INSPECTOR)
+
+#include "ScriptGCEvent.h"
+#include "ScriptGCEventListener.h"
+
+#include <wtf/CurrentTime.h>
+
+namespace WebCore {
+
+ScriptGCEvent::GCEventListeners ScriptGCEvent::s_eventListeners;
+double ScriptGCEvent::s_startTime = 0.0;
+size_t ScriptGCEvent::s_usedHeapSize = 0;
+
+void ScriptGCEvent::addEventListener(ScriptGCEventListener* eventListener)
+{
+ ASSERT(eventListener);
+ if (s_eventListeners.isEmpty()) {
+ v8::V8::AddGCPrologueCallback(ScriptGCEvent::gcPrologueCallback);
+ v8::V8::AddGCEpilogueCallback(ScriptGCEvent::gcEpilogueCallback);
+ }
+ s_eventListeners.append(eventListener);
+}
+
+void ScriptGCEvent::removeEventListener(ScriptGCEventListener* eventListener)
+{
+ ASSERT(eventListener);
+ ASSERT(!s_eventListeners.isEmpty());
+ size_t i = s_eventListeners.find(eventListener);
+ ASSERT(i != notFound);
+ s_eventListeners.remove(i);
+ if (s_eventListeners.isEmpty()) {
+ v8::V8::RemoveGCPrologueCallback(ScriptGCEvent::gcPrologueCallback);
+ v8::V8::RemoveGCEpilogueCallback(ScriptGCEvent::gcEpilogueCallback);
+ }
+}
+
+void ScriptGCEvent::getHeapSize(size_t& usedHeapSize, size_t& totalHeapSize)
+{
+ v8::HeapStatistics heapStatistics;
+ v8::V8::GetHeapStatistics(&heapStatistics);
+ usedHeapSize = heapStatistics.used_heap_size();
+ totalHeapSize = heapStatistics.total_heap_size();
+}
+
+size_t ScriptGCEvent::getUsedHeapSize()
+{
+ v8::HeapStatistics heapStatistics;
+ v8::V8::GetHeapStatistics(&heapStatistics);
+ return heapStatistics.used_heap_size();
+}
+
+void ScriptGCEvent::gcPrologueCallback(v8::GCType type, v8::GCCallbackFlags flags)
+{
+ s_startTime = WTF::currentTimeMS();
+ s_usedHeapSize = getUsedHeapSize();
+}
+
+void ScriptGCEvent::gcEpilogueCallback(v8::GCType type, v8::GCCallbackFlags flags)
+{
+ double endTime = WTF::currentTimeMS();
+ size_t collectedBytes = s_usedHeapSize - getUsedHeapSize();
+ GCEventListeners listeners(s_eventListeners);
+ for (GCEventListeners::iterator i = listeners.begin(); i != listeners.end(); ++i)
+ (*i)->didGC(s_startTime, endTime, collectedBytes);
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(INSPECTOR)
diff --git a/WebCore/bindings/v8/ScriptGCEvent.h b/WebCore/bindings/v8/ScriptGCEvent.h
new file mode 100644
index 0000000..80a5a38
--- /dev/null
+++ b/WebCore/bindings/v8/ScriptGCEvent.h
@@ -0,0 +1,63 @@
+/*
+* Copyright (C) 2010 Google Inc. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are
+* met:
+*
+* * Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+* * Redistributions in binary form must reproduce the above
+* copyright notice, this list of conditions and the following disclaimer
+* in the documentation and/or other materials provided with the
+* distribution.
+* * Neither the name of Google Inc. nor the names of its
+* contributors may be used to endorse or promote products derived from
+* this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef ScriptGCEvent_h
+#define ScriptGCEvent_h
+
+#if ENABLE(INSPECTOR)
+
+#include "v8.h"
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+class ScriptGCEventListener;
+
+class ScriptGCEvent
+{
+public:
+ static void addEventListener(ScriptGCEventListener*);
+ static void removeEventListener(ScriptGCEventListener*);
+ static void getHeapSize(size_t&, size_t&);
+private:
+ typedef Vector<ScriptGCEventListener*> GCEventListeners;
+ static GCEventListeners s_eventListeners;
+ static double s_startTime;
+ static size_t s_usedHeapSize;
+
+ static void gcEpilogueCallback(v8::GCType type, v8::GCCallbackFlags flags);
+ static void gcPrologueCallback(v8::GCType type, v8::GCCallbackFlags flags);
+ static size_t getUsedHeapSize();
+};
+
+} // namespace WebCore
+
+#endif // !ENABLE(INSPECTOR)
+#endif // !defined(ScriptGCEvent_h)
diff --git a/WebCore/bindings/v8/custom/V8DOMSelectionCustom.cpp b/WebCore/bindings/v8/ScriptProfile.cpp
index 0c9e745..beafea1 100644
--- a/WebCore/bindings/v8/custom/V8DOMSelectionCustom.cpp
+++ b/WebCore/bindings/v8/ScriptProfile.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 Google Inc. All rights reserved.
+ * Copyright (c) 2010, Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -29,23 +29,28 @@
*/
#include "config.h"
-#include "V8DOMSelection.h"
-#include "V8DOMWindow.h"
-#include "V8DOMWrapper.h"
+#include "ScriptProfile.h"
+
+#include "V8Binding.h"
+
+#include <v8-profiler.h>
namespace WebCore {
-v8::Handle<v8::Value> toV8(DOMSelection* impl)
+String ScriptProfile::title() const
+{
+ return toWebCoreString(m_profile->GetTitle());
+}
+
+unsigned int ScriptProfile::uid() const
+{
+ return m_profile->GetUid();
+}
+
+PassRefPtr<ScriptProfileNode> ScriptProfile::head() const
{
- if (!impl)
- return v8::Null();
- v8::Handle<v8::Object> wrapper = getDOMObjectMap().get(impl);
- if (wrapper.IsEmpty()) {
- wrapper = V8DOMSelection::wrap(impl);
- V8DOMWrapper::setHiddenWindowReference(impl->frame(), V8DOMWindow::domSelectionIndex, wrapper);
- }
- return wrapper;
+ return ScriptProfileNode::create(m_profile->GetTopDownRoot());
}
} // namespace WebCore
diff --git a/WebCore/bindings/v8/ScriptProfile.h b/WebCore/bindings/v8/ScriptProfile.h
index 1a4d677..2f42ad2 100644
--- a/WebCore/bindings/v8/ScriptProfile.h
+++ b/WebCore/bindings/v8/ScriptProfile.h
@@ -32,29 +32,33 @@
#define ScriptProfile_h
#include "PlatformString.h"
+#include "ScriptProfileNode.h"
+
+namespace v8 {
+class CpuProfile;
+}
namespace WebCore {
class ScriptProfile : public RefCounted<ScriptProfile> {
public:
- static PassRefPtr<ScriptProfile> create(const String& title, unsigned uid)
+ static PassRefPtr<ScriptProfile> create(const v8::CpuProfile* profile)
{
- return adoptRef(new ScriptProfile(title, uid));
+ return adoptRef(new ScriptProfile(profile));
}
virtual ~ScriptProfile() {}
- String title() const { return m_title; }
- unsigned int uid() const { return m_uid; }
+ String title() const;
+ unsigned int uid() const;
+ PassRefPtr<ScriptProfileNode> head() const;
protected:
- ScriptProfile(const String& title, unsigned uid)
- : m_title(title)
- , m_uid(uid)
+ ScriptProfile(const v8::CpuProfile* profile)
+ : m_profile(profile)
{}
private:
- String m_title;
- unsigned int m_uid;
+ const v8::CpuProfile* m_profile;
};
} // namespace WebCore
diff --git a/WebCore/bindings/v8/ScriptProfileNode.cpp b/WebCore/bindings/v8/ScriptProfileNode.cpp
new file mode 100644
index 0000000..3121128
--- /dev/null
+++ b/WebCore/bindings/v8/ScriptProfileNode.cpp
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2010, Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include "ScriptProfile.h"
+
+#include "V8Binding.h"
+
+#include <v8-profiler.h>
+
+namespace WebCore {
+
+String ScriptProfileNode::functionName() const
+{
+ return toWebCoreString(m_profileNode->GetFunctionName());
+}
+
+String ScriptProfileNode::url() const
+{
+ return toWebCoreString(m_profileNode->GetScriptResourceName());
+}
+
+unsigned long ScriptProfileNode::lineNumber() const
+{
+ return m_profileNode->GetLineNumber();
+}
+
+double ScriptProfileNode::totalTime() const
+{
+ // FIXME: use GetTotalMilliseconds once it is implemented in V8.
+ return m_profileNode->GetTotalSamplesCount();
+}
+
+double ScriptProfileNode::selfTime() const
+{
+ // FIXME: use GetSelfMilliseconds once it is implemented in V8.
+ return m_profileNode->GetSelfSamplesCount();
+}
+
+unsigned long ScriptProfileNode::numberOfCalls() const
+{
+ return 0;
+}
+
+ProfileNodesList ScriptProfileNode::children() const
+{
+ const int childrenCount = m_profileNode->GetChildrenCount();
+ ProfileNodesList result(childrenCount);
+ for (int i = 0; i < childrenCount; ++i)
+ result[i] = ScriptProfileNode::create(m_profileNode->GetChild(i));
+ return result;
+}
+
+bool ScriptProfileNode::visible() const
+{
+ return true;
+}
+
+unsigned long ScriptProfileNode::callUID() const
+{
+ return m_profileNode->GetCallUid();
+}
+
+} // namespace WebCore
diff --git a/WebCore/bindings/v8/ScriptProfileNode.h b/WebCore/bindings/v8/ScriptProfileNode.h
new file mode 100644
index 0000000..5acf319
--- /dev/null
+++ b/WebCore/bindings/v8/ScriptProfileNode.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2010, Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef ScriptProfileNode_h
+#define ScriptProfileNode_h
+
+#include "PlatformString.h"
+
+namespace v8 {
+class CpuProfileNode;
+}
+
+namespace WebCore {
+
+class ScriptProfileNode;
+
+typedef Vector<RefPtr<ScriptProfileNode> > ProfileNodesList;
+
+class ScriptProfileNode : public RefCounted<ScriptProfileNode> {
+public:
+ static PassRefPtr<ScriptProfileNode> create(const v8::CpuProfileNode* profileNode)
+ {
+ return adoptRef(new ScriptProfileNode(profileNode));
+ }
+ virtual ~ScriptProfileNode() {}
+
+ String functionName() const;
+ String url() const;
+ unsigned long lineNumber() const;
+ double totalTime() const;
+ double selfTime() const;
+ unsigned long numberOfCalls() const;
+ ProfileNodesList children() const;
+ bool visible() const;
+ unsigned long callUID() const;
+
+protected:
+ ScriptProfileNode(const v8::CpuProfileNode* profileNode)
+ : m_profileNode(profileNode)
+ {}
+
+private:
+ const v8::CpuProfileNode* m_profileNode;
+};
+
+} // namespace WebCore
+
+#endif // ScriptProfileNode_h
diff --git a/WebCore/bindings/v8/ScriptProfiler.cpp b/WebCore/bindings/v8/ScriptProfiler.cpp
index f238f6f..1f09420 100644
--- a/WebCore/bindings/v8/ScriptProfiler.cpp
+++ b/WebCore/bindings/v8/ScriptProfiler.cpp
@@ -31,20 +31,23 @@
#include "config.h"
#include "ScriptProfiler.h"
+#include "ScriptString.h"
+
+#include <v8-profiler.h>
namespace WebCore {
void ScriptProfiler::start(ScriptState* state, const String& title)
{
- v8::HandleScope scope;
- v8::Context::Scope contextScope(v8::Context::GetCurrent());
- v8::V8::ResumeProfiler();
+ v8::HandleScope hs;
+ v8::CpuProfiler::StartProfiling(v8String(title));
}
PassRefPtr<ScriptProfile> ScriptProfiler::stop(ScriptState* state, const String& title)
{
- v8::V8::PauseProfiler();
- return 0;
+ v8::HandleScope hs;
+ const v8::CpuProfile* profile = v8::CpuProfiler::StopProfiling(v8String(title));
+ return profile ? ScriptProfile::create(profile) : 0;
}
} // namespace WebCore
diff --git a/WebCore/bindings/v8/ScriptState.h b/WebCore/bindings/v8/ScriptState.h
index 5c5ce6c..ce350da 100644
--- a/WebCore/bindings/v8/ScriptState.h
+++ b/WebCore/bindings/v8/ScriptState.h
@@ -37,55 +37,77 @@
#include <wtf/RefCounted.h>
namespace WebCore {
- class DOMWrapperWorld;
- class Frame;
- class Node;
- class Page;
-
- class ScriptState : public Noncopyable {
- public:
- bool hadException() { return !m_exception.IsEmpty(); }
- void setException(v8::Local<v8::Value> exception)
- {
- m_exception = exception;
+class DOMWrapperWorld;
+class Frame;
+class Node;
+class Page;
+
+class ScriptState : public Noncopyable {
+public:
+ bool hadException() { return !m_exception.IsEmpty(); }
+ void setException(v8::Local<v8::Value> exception)
+ {
+ m_exception = exception;
+ }
+ v8::Local<v8::Value> exception() { return m_exception; }
+
+ v8::Local<v8::Context> context() const
+ {
+ return v8::Local<v8::Context>::New(m_context);
+ }
+
+ static ScriptState* forContext(v8::Local<v8::Context>);
+ static ScriptState* current();
+
+protected:
+ ScriptState() { }
+ ~ScriptState();
+
+private:
+ friend ScriptState* mainWorldScriptState(Frame*);
+ explicit ScriptState(v8::Handle<v8::Context>);
+
+ static void weakReferenceCallback(v8::Persistent<v8::Value> object, void* parameter);
+
+ v8::Local<v8::Value> m_exception;
+ v8::Persistent<v8::Context> m_context;
+};
+
+class EmptyScriptState : public ScriptState {
+public:
+ EmptyScriptState() : ScriptState() { }
+ ~EmptyScriptState() { }
+};
+
+class ScriptStateProtectedPtr : public Noncopyable {
+public:
+ ScriptStateProtectedPtr() : m_scriptState(0) { }
+ ScriptStateProtectedPtr(ScriptState* scriptState) : m_scriptState(scriptState)
+ {
+ v8::HandleScope handleScope;
+ // Keep the context from being GC'ed. ScriptState is guaranteed to be live while the context is live.
+ m_context = v8::Persistent<v8::Context>::New(scriptState->context());
+ }
+ ~ScriptStateProtectedPtr()
+ {
+ if (!m_context.IsEmpty()) {
+ m_context.Dispose();
+ m_context.Clear();
}
- v8::Local<v8::Value> exception() { return m_exception; }
+ }
+ ScriptState* get() { return m_scriptState; }
+private:
+ ScriptState* m_scriptState;
+ v8::Persistent<v8::Context> m_context;
+};
- v8::Local<v8::Context> context() const
- {
- return v8::Local<v8::Context>::New(m_context);
- }
-
- static ScriptState* forContext(v8::Local<v8::Context>);
- static ScriptState* current();
-
- protected:
- ScriptState() { }
- ~ScriptState();
-
- private:
- friend ScriptState* mainWorldScriptState(Frame*);
- explicit ScriptState(v8::Handle<v8::Context>);
-
- static void weakReferenceCallback(v8::Persistent<v8::Value> object, void* parameter);
-
- v8::Local<v8::Value> m_exception;
- v8::Persistent<v8::Context> m_context;
- };
-
- class EmptyScriptState : public ScriptState {
- public:
- EmptyScriptState() : ScriptState() { }
- ~EmptyScriptState() { }
- };
-
- ScriptState* mainWorldScriptState(Frame*);
+ScriptState* mainWorldScriptState(Frame*);
- ScriptState* scriptStateFromNode(DOMWrapperWorld*, Node*);
- ScriptState* scriptStateFromPage(DOMWrapperWorld*, Page*);
+ScriptState* scriptStateFromNode(DOMWrapperWorld*, Node*);
+ScriptState* scriptStateFromPage(DOMWrapperWorld*, Page*);
- inline DOMWrapperWorld* debuggerWorld() { return mainThreadNormalWorld(); }
- inline DOMWrapperWorld* pluginWorld() { return mainThreadNormalWorld(); }
+inline DOMWrapperWorld* debuggerWorld() { return mainThreadNormalWorld(); }
+inline DOMWrapperWorld* pluginWorld() { return mainThreadNormalWorld(); }
}
diff --git a/WebCore/bindings/v8/ScriptValue.h b/WebCore/bindings/v8/ScriptValue.h
index 1713f80..8241205 100644
--- a/WebCore/bindings/v8/ScriptValue.h
+++ b/WebCore/bindings/v8/ScriptValue.h
@@ -127,6 +127,8 @@ public:
PassRefPtr<SerializedScriptValue> serialize(ScriptState*);
static ScriptValue deserialize(ScriptState*, SerializedScriptValue*);
+ static ScriptValue undefined() { return ScriptValue(v8::Undefined()); }
+
void clear()
{
if (m_value.IsEmpty())
diff --git a/WebCore/bindings/v8/SerializedScriptValue.cpp b/WebCore/bindings/v8/SerializedScriptValue.cpp
index bac7f20..50ac86b 100644
--- a/WebCore/bindings/v8/SerializedScriptValue.cpp
+++ b/WebCore/bindings/v8/SerializedScriptValue.cpp
@@ -31,7 +31,18 @@
#include "config.h"
#include "SerializedScriptValue.h"
+#include "Blob.h"
+#include "ByteArray.h"
+#include "CanvasPixelArray.h"
+#include "File.h"
+#include "FileList.h"
+#include "ImageData.h"
#include "SharedBuffer.h"
+#include "V8Blob.h"
+#include "V8File.h"
+#include "V8FileList.h"
+#include "V8ImageData.h"
+#include "V8Proxy.h"
#include <v8.h>
#include <wtf/Assertions.h>
@@ -40,7 +51,6 @@
// FIXME:
// - catch V8 exceptions
-// - be ready to get empty handles
// - consider crashing in debug mode on deserialization errors
namespace WebCore {
@@ -60,19 +70,18 @@ enum SerializationTag {
FalseTag = 'F',
StringTag = 'S',
Int32Tag = 'I',
+ Uint32Tag = 'U',
+ DateTag = 'D',
NumberTag = 'N',
- ObjectTag = '{',
+ BlobTag = 'b',
+ FileTag = 'f',
+ FileListTag = 'l',
+ ImageDataTag = '#',
ArrayTag = '[',
+ ObjectTag = '{',
+ SparseArrayTag = '@',
};
-// Helpers to do verbose handle casts.
-
-template <typename T, typename U>
-static v8::Handle<T> handleCast(v8::Handle<U> handle) { return v8::Handle<T>::Cast(handle); }
-
-template <typename T, typename U>
-static v8::Local<T> handleCast(v8::Local<U> handle) { return v8::Local<T>::Cast(handle); }
-
static bool shouldCheckForCycles(int depth)
{
ASSERT(depth >= 0);
@@ -118,7 +127,8 @@ private:
// information used to reconstruct composite types.
class Writer : Noncopyable {
public:
- Writer() : m_position(0)
+ Writer()
+ : m_position(0)
{
}
@@ -134,9 +144,17 @@ public:
void writeString(const char* data, int length)
{
+ ASSERT(length >= 0);
append(StringTag);
- doWriteUint32(static_cast<uint32_t>(length));
- append(data, length);
+ doWriteString(data, length);
+ }
+
+ void writeWebCoreString(const String& string)
+ {
+ // Uses UTF8 encoding so we can read it back as either V8 or
+ // WebCore string.
+ append(StringTag);
+ doWriteWebCoreString(string);
}
void writeInt32(int32_t value)
@@ -145,19 +163,71 @@ public:
doWriteUint32(ZigZag::encode(static_cast<uint32_t>(value)));
}
+ void writeUint32(uint32_t value)
+ {
+ append(Uint32Tag);
+ doWriteUint32(value);
+ }
+
+ void writeDate(double numberValue)
+ {
+ append(DateTag);
+ doWriteNumber(numberValue);
+ }
+
void writeNumber(double number)
{
append(NumberTag);
- append(reinterpret_cast<char*>(&number), sizeof(number));
+ doWriteNumber(number);
}
- // Records that a composite object can be constructed by using
- // |length| previously stored values.
- void endComposite(SerializationTag tag, int32_t length)
+ void writeBlob(const String& path)
{
- ASSERT(tag == ObjectTag || tag == ArrayTag);
- append(tag);
- doWriteUint32(static_cast<uint32_t>(length));
+ append(BlobTag);
+ doWriteWebCoreString(path);
+ }
+
+ void writeFile(const String& path)
+ {
+ append(FileTag);
+ doWriteWebCoreString(path);
+ }
+
+ void writeFileList(const FileList& fileList)
+ {
+ append(FileListTag);
+ uint32_t length = fileList.length();
+ doWriteUint32(length);
+ for (unsigned i = 0; i < length; ++i)
+ doWriteWebCoreString(fileList.item(i)->path());
+ }
+
+ void writeImageData(uint32_t width, uint32_t height, const uint8_t* pixelData, uint32_t pixelDataLength)
+ {
+ append(ImageDataTag);
+ doWriteUint32(width);
+ doWriteUint32(height);
+ doWriteUint32(pixelDataLength);
+ append(pixelData, pixelDataLength);
+ }
+
+ void writeArray(uint32_t length)
+ {
+ append(ArrayTag);
+ doWriteUint32(length);
+ }
+
+ void writeObject(uint32_t numProperties)
+ {
+ append(ObjectTag);
+ doWriteUint32(numProperties);
+ }
+
+ void writeSparseArray(uint32_t numProperties, uint32_t length)
+ {
+ append(SparseArrayTag);
+ doWriteUint32(numProperties);
+ doWriteUint32(length);
}
Vector<BufferValueType>& data()
@@ -167,10 +237,22 @@ public:
}
private:
+ void doWriteString(const char* data, int length)
+ {
+ doWriteUint32(static_cast<uint32_t>(length));
+ append(reinterpret_cast<const uint8_t*>(data), length);
+ }
+
+ void doWriteWebCoreString(const String& string)
+ {
+ RefPtr<SharedBuffer> buffer = utf8Buffer(string);
+ doWriteString(buffer->data(), buffer->size());
+ }
+
void doWriteUint32(uint32_t value)
{
while (true) {
- char b = (value & varIntMask);
+ uint8_t b = (value & varIntMask);
value >>= varIntShift;
if (!value) {
append(b);
@@ -180,21 +262,26 @@ private:
}
}
+ void doWriteNumber(double number)
+ {
+ append(reinterpret_cast<uint8_t*>(&number), sizeof(number));
+ }
+
void append(SerializationTag tag)
{
- append(static_cast<char>(tag));
+ append(static_cast<uint8_t>(tag));
}
- void append(char b)
+ void append(uint8_t b)
{
ensureSpace(1);
- *charAt(m_position++) = b;
+ *byteAt(m_position++) = b;
}
- void append(const char* data, int length)
+ void append(const uint8_t* data, int length)
{
ensureSpace(length);
- memcpy(charAt(m_position), data, length);
+ memcpy(byteAt(m_position), data, length);
m_position += length;
}
@@ -210,41 +297,54 @@ private:
// If the writer is at odd position in the buffer, then one of
// the bytes in the last UChar is not initialized.
if (m_position % 2)
- *charAt(m_position) = static_cast<char>(PaddingTag);
+ *byteAt(m_position) = static_cast<uint8_t>(PaddingTag);
}
- char* charAt(int position) { return reinterpret_cast<char*>(m_buffer.data()) + position; }
+ uint8_t* byteAt(int position) { return reinterpret_cast<uint8_t*>(m_buffer.data()) + position; }
Vector<BufferValueType> m_buffer;
unsigned m_position;
};
class Serializer {
+ class StateBase;
public:
explicit Serializer(Writer& writer)
: m_writer(writer)
- , m_state(0)
, m_depth(0)
+ , m_hasError(false)
{
}
bool serialize(v8::Handle<v8::Value> value)
{
v8::HandleScope scope;
- StackCleaner cleaner(&m_state);
- if (!doSerialize(value))
- return false;
- while (top()) {
- int length;
- while (!top()->isDone(&length)) {
- // Note that doSerialize() can change current top().
- if (!doSerialize(top()->advance()))
- return false;
- }
- m_writer.endComposite(top()->tag(), length);
- pop();
- }
- return true;
+ StateBase* state = doSerialize(value, 0);
+ while (state)
+ state = state->advance(*this);
+ return !m_hasError;
+ }
+
+ // Functions used by serialization states.
+
+ StateBase* doSerialize(v8::Handle<v8::Value> value, StateBase* next);
+
+ StateBase* writeArray(uint32_t length, StateBase* state)
+ {
+ m_writer.writeArray(length);
+ return pop(state);
+ }
+
+ StateBase* writeObject(uint32_t numProperties, StateBase* state)
+ {
+ m_writer.writeObject(numProperties);
+ return pop(state);
+ }
+
+ StateBase* writeSparseArray(uint32_t numProperties, uint32_t length, StateBase* state)
+ {
+ m_writer.writeSparseArray(numProperties, length);
+ return pop(state);
}
private:
@@ -254,221 +354,308 @@ private:
// Link to the next state to form a stack.
StateBase* nextState() { return m_next; }
- void setNextState(StateBase* next) { m_next = next; }
// Composite object we're processing in this state.
v8::Handle<v8::Value> composite() { return m_composite; }
- // Serialization tag for the current composite.
- virtual SerializationTag tag() const = 0;
-
- // Returns whether iteration over subobjects of the current
- // composite object is done. If yes, |*length| is set to the
- // number of subobjects.
- virtual bool isDone(int* length) = 0;
-
- // Advances to the next subobject.
- // Requires: !this->isDone().
- virtual v8::Local<v8::Value> advance() = 0;
+ // Serializes (a part of) the current composite and returns
+ // the next state to process or null when this is the final
+ // state.
+ virtual StateBase* advance(Serializer&) = 0;
protected:
- StateBase(v8::Handle<v8::Value> composite)
- : m_next(0)
- , m_composite(composite)
+ StateBase(v8::Handle<v8::Value> composite, StateBase* next)
+ : m_composite(composite)
+ , m_next(next)
{
}
private:
- StateBase* m_next;
v8::Handle<v8::Value> m_composite;
+ StateBase* m_next;
};
- template <typename T, SerializationTag compositeTag>
- class State : public StateBase {
+ // Dummy state that is used to signal serialization errors.
+ class ErrorState : public StateBase {
public:
- v8::Handle<T> composite() { return handleCast<T>(StateBase::composite()); }
+ ErrorState()
+ : StateBase(v8::Handle<v8::Value>(), 0)
+ {
+ }
- virtual SerializationTag tag() const { return compositeTag; }
+ virtual StateBase* advance(Serializer&)
+ {
+ delete this;
+ return 0;
+ }
+ };
+
+ template <typename T>
+ class State : public StateBase {
+ public:
+ v8::Handle<T> composite() { return v8::Handle<T>::Cast(StateBase::composite()); }
protected:
- explicit State(v8::Handle<T> composite) : StateBase(composite)
+ State(v8::Handle<T> composite, StateBase* next)
+ : StateBase(composite, next)
{
}
};
- // Helper to clean up the state stack in case of errors.
- class StackCleaner : Noncopyable {
+#if 0
+ // Currently unused, see comment in newArrayState.
+ class ArrayState : public State<v8::Array> {
public:
- explicit StackCleaner(StateBase** stack) : m_stack(stack)
+ ArrayState(v8::Handle<v8::Array> array, StateBase* next)
+ : State<v8::Array>(array, next)
+ , m_index(-1)
{
}
- ~StackCleaner()
+ virtual StateBase* advance(Serializer& serializer)
{
- StateBase* state = *m_stack;
- while (state) {
- StateBase* tmp = state->nextState();
- delete state;
- state = tmp;
+ ++m_index;
+ for (; m_index < composite()->Length(); ++m_index) {
+ if (StateBase* newState = serializer.doSerialize(composite()->Get(m_index), this))
+ return newState;
}
- *m_stack = 0;
+ return serializer.writeArray(composite()->Length(), this);
}
private:
- StateBase** m_stack;
+ unsigned m_index;
};
+#endif
- class ArrayState : public State<v8::Array, ArrayTag> {
+ class AbstractObjectState : public State<v8::Object> {
public:
- ArrayState(v8::Handle<v8::Array> array)
- : State<v8::Array, ArrayTag>(array)
- , m_index(0)
+ AbstractObjectState(v8::Handle<v8::Object> object, StateBase* next)
+ : State<v8::Object>(object, next)
+ , m_propertyNames(object->GetPropertyNames())
+ , m_index(-1)
+ , m_numSerializedProperties(0)
+ , m_nameDone(false)
{
}
- virtual bool isDone(int* length)
+ virtual StateBase* advance(Serializer& serializer)
{
- *length = composite()->Length();
- return static_cast<int>(m_index) >= *length;
+ ++m_index;
+ for (; m_index < m_propertyNames->Length(); ++m_index) {
+ if (m_propertyName.IsEmpty()) {
+ v8::Local<v8::Value> propertyName = m_propertyNames->Get(m_index);
+ if ((propertyName->IsString() && composite()->HasRealNamedProperty(propertyName.As<v8::String>()))
+ || (propertyName->IsUint32() && composite()->HasRealIndexedProperty(propertyName->Uint32Value()))) {
+ m_propertyName = propertyName;
+ } else
+ continue;
+ }
+ ASSERT(!m_propertyName.IsEmpty());
+ if (!m_nameDone) {
+ m_nameDone = true;
+ if (StateBase* newState = serializer.doSerialize(m_propertyName, this))
+ return newState;
+ }
+ v8::Local<v8::Value> value = composite()->Get(m_propertyName);
+ m_nameDone = false;
+ m_propertyName.Clear();
+ ++m_numSerializedProperties;
+ if (StateBase* newState = serializer.doSerialize(value, this))
+ return newState;
+ }
+ return objectDone(m_numSerializedProperties, serializer);
}
- virtual v8::Local<v8::Value> advance()
- {
- ASSERT(m_index < composite()->Length());
- v8::HandleScope scope;
- return scope.Close(composite()->Get(v8::Integer::New(m_index++)));
- }
+ protected:
+ virtual StateBase* objectDone(unsigned numProperties, Serializer&) = 0;
private:
+ v8::Local<v8::Array> m_propertyNames;
+ v8::Local<v8::Value> m_propertyName;
unsigned m_index;
+ unsigned m_numSerializedProperties;
+ bool m_nameDone;
};
- class ObjectState : public State<v8::Object, ObjectTag> {
+ class ObjectState : public AbstractObjectState {
public:
- ObjectState(v8::Handle<v8::Object> object)
- : State<v8::Object, ObjectTag>(object)
- , m_propertyNames(object->GetPropertyNames())
- , m_index(-1)
- , m_length(0)
+ ObjectState(v8::Handle<v8::Object> object, StateBase* next)
+ : AbstractObjectState(object, next)
{
- nextProperty();
}
- virtual bool isDone(int* length)
+ protected:
+ virtual StateBase* objectDone(unsigned numProperties, Serializer& serializer)
{
- *length = m_length;
- return m_index >= 2 * m_propertyNames->Length();
+ return serializer.writeObject(numProperties, this);
}
+ };
- virtual v8::Local<v8::Value> advance()
+ class SparseArrayState : public AbstractObjectState {
+ public:
+ SparseArrayState(v8::Handle<v8::Array> array, StateBase* next)
+ : AbstractObjectState(array, next)
{
- ASSERT(m_index < 2 * m_propertyNames->Length());
- if (!(m_index % 2)) {
- ++m_index;
- return m_propertyName;
- }
- v8::Local<v8::Value> result = composite()->Get(m_propertyName);
- nextProperty();
- return result;
}
- private:
- void nextProperty()
+ protected:
+ virtual StateBase* objectDone(unsigned numProperties, Serializer& serializer)
{
- v8::HandleScope scope;
- ++m_index;
- ASSERT(!(m_index % 2));
- for (; m_index < 2 * m_propertyNames->Length(); m_index += 2) {
- v8::Local<v8::Value> propertyName = m_propertyNames->Get(v8::Integer::New(m_index / 2));
- if ((propertyName->IsString() && composite()->HasRealNamedProperty(handleCast<v8::String>(propertyName)))
- || (propertyName->IsInt32() && composite()->HasRealIndexedProperty(propertyName->Uint32Value()))) {
- m_propertyName = scope.Close(propertyName);
- m_length += 2;
- return;
- }
- }
+ return serializer.writeSparseArray(numProperties, composite().As<v8::Array>()->Length(), this);
}
-
- v8::Local<v8::Array> m_propertyNames;
- v8::Local<v8::Value> m_propertyName;
- unsigned m_index;
- unsigned m_length;
};
- bool doSerialize(v8::Handle<v8::Value> value)
- {
- if (value->IsUndefined())
- m_writer.writeUndefined();
- else if (value->IsNull())
- m_writer.writeNull();
- else if (value->IsTrue())
- m_writer.writeTrue();
- else if (value->IsFalse())
- m_writer.writeFalse();
- else if (value->IsInt32())
- m_writer.writeInt32(value->Int32Value());
- else if (value->IsNumber())
- m_writer.writeNumber(handleCast<v8::Number>(value)->Value());
- else if (value->IsString()) {
- v8::String::Utf8Value stringValue(value);
- m_writer.writeString(*stringValue, stringValue.length());
- } else if (value->IsArray()) {
- if (!checkComposite(value))
- return false;
- push(new ArrayState(handleCast<v8::Array>(value)));
- } else if (value->IsObject()) {
- if (!checkComposite(value))
- return false;
- push(new ObjectState(handleCast<v8::Object>(value)));
- // FIXME:
- // - check not a wrapper
- // - support File, ImageData, etc.
- }
- return true;
- }
-
- void push(StateBase* state)
+ StateBase* push(StateBase* state)
{
- state->setNextState(m_state);
- m_state = state;
+ ASSERT(state);
++m_depth;
+ return checkComposite(state) ? state : handleError(state);
}
- StateBase* top() { return m_state; }
-
- void pop()
+ StateBase* pop(StateBase* state)
{
- if (!m_state)
- return;
- StateBase* top = m_state;
- m_state = top->nextState();
- delete top;
+ ASSERT(state);
--m_depth;
+ StateBase* next = state->nextState();
+ delete state;
+ return next;
+ }
+
+ StateBase* handleError(StateBase* state)
+ {
+ m_hasError = true;
+ while (state) {
+ StateBase* tmp = state->nextState();
+ delete state;
+ state = tmp;
+ }
+ return new ErrorState;
}
- bool checkComposite(v8::Handle<v8::Value> composite)
+ bool checkComposite(StateBase* top)
{
+ ASSERT(top);
if (m_depth > maxDepth)
return false;
if (!shouldCheckForCycles(m_depth))
return true;
- for (StateBase* state = top(); state; state = state->nextState()) {
+ v8::Handle<v8::Value> composite = top->composite();
+ for (StateBase* state = top->nextState(); state; state = state->nextState()) {
if (state->composite() == composite)
return false;
}
return true;
}
+ void writeString(v8::Handle<v8::Value> value)
+ {
+ v8::String::Utf8Value stringValue(value);
+ m_writer.writeString(*stringValue, stringValue.length());
+ }
+
+ void writeBlob(v8::Handle<v8::Value> value)
+ {
+ Blob* blob = V8Blob::toNative(value.As<v8::Object>());
+ if (!blob)
+ return;
+ m_writer.writeBlob(blob->path());
+ }
+
+ void writeFile(v8::Handle<v8::Value> value)
+ {
+ File* file = V8File::toNative(value.As<v8::Object>());
+ if (!file)
+ return;
+ m_writer.writeFile(file->path());
+ }
+
+ void writeFileList(v8::Handle<v8::Value> value)
+ {
+ FileList* fileList = V8FileList::toNative(value.As<v8::Object>());
+ if (!fileList)
+ return;
+ m_writer.writeFileList(*fileList);
+ }
+
+ void writeImageData(v8::Handle<v8::Value> value)
+ {
+ ImageData* imageData = V8ImageData::toNative(value.As<v8::Object>());
+ if (!imageData)
+ return;
+ WTF::ByteArray* pixelArray = imageData->data()->data();
+ m_writer.writeImageData(imageData->width(), imageData->height(), pixelArray->data(), pixelArray->length());
+ }
+
+ static StateBase* newArrayState(v8::Handle<v8::Array> array, StateBase* next)
+ {
+ // FIXME: use plain Array state when we can quickly check that
+ // an array is not sparse and has only indexed properties.
+ return new SparseArrayState(array, next);
+ }
+
+ static StateBase* newObjectState(v8::Handle<v8::Object> object, StateBase* next)
+ {
+ // FIXME:
+ // - check not a wrapper
+ // - support File, etc.
+ return new ObjectState(object, next);
+ }
+
Writer& m_writer;
- StateBase* m_state;
int m_depth;
+ bool m_hasError;
+};
+
+Serializer::StateBase* Serializer::doSerialize(v8::Handle<v8::Value> value, StateBase* next)
+{
+ if (value->IsUndefined())
+ m_writer.writeUndefined();
+ else if (value->IsNull())
+ m_writer.writeNull();
+ else if (value->IsTrue())
+ m_writer.writeTrue();
+ else if (value->IsFalse())
+ m_writer.writeFalse();
+ else if (value->IsInt32())
+ m_writer.writeInt32(value->Int32Value());
+ else if (value->IsUint32())
+ m_writer.writeUint32(value->Uint32Value());
+ else if (value->IsDate())
+ m_writer.writeDate(value->NumberValue());
+ else if (value->IsNumber())
+ m_writer.writeNumber(value.As<v8::Number>()->Value());
+ else if (value->IsString())
+ writeString(value);
+ else if (value->IsArray())
+ return push(newArrayState(value.As<v8::Array>(), next));
+ else if (V8File::HasInstance(value))
+ writeFile(value);
+ else if (V8Blob::HasInstance(value))
+ writeBlob(value);
+ else if (V8FileList::HasInstance(value))
+ writeFileList(value);
+ else if (V8ImageData::HasInstance(value))
+ writeImageData(value);
+ else if (value->IsObject())
+ return push(newObjectState(value.As<v8::Object>(), next));
+ return 0;
+}
+
+// Interface used by Reader to create objects of composite types.
+class CompositeCreator {
+public:
+ virtual ~CompositeCreator() { }
+
+ virtual bool createArray(uint32_t length, v8::Handle<v8::Value>* value) = 0;
+ virtual bool createObject(uint32_t numProperties, v8::Handle<v8::Value>* value) = 0;
+ virtual bool createSparseArray(uint32_t numProperties, uint32_t length, v8::Handle<v8::Value>* value) = 0;
};
// Reader is responsible for deserializing primitive types and
// restoring information about saved objects of composite types.
class Reader {
public:
- Reader(const char* buffer, int length)
+ Reader(const uint8_t* buffer, int length)
: m_buffer(buffer)
, m_length(length)
, m_position(0)
@@ -478,16 +665,16 @@ public:
bool isEof() const { return m_position >= m_length; }
- bool read(SerializationTag* tag, v8::Handle<v8::Value>* value, int* length)
+ bool read(v8::Handle<v8::Value>* value, CompositeCreator& creator)
{
- uint32_t rawLength;
- if (!readTag(tag))
+ SerializationTag tag;
+ if (!readTag(&tag))
return false;
- switch (*tag) {
+ switch (tag) {
case InvalidTag:
return false;
case PaddingTag:
- break;
+ return true;
case UndefinedTag:
*value = v8::Undefined();
break;
@@ -508,18 +695,65 @@ public:
if (!readInt32(value))
return false;
break;
+ case Uint32Tag:
+ if (!readUint32(value))
+ return false;
+ break;
+ case DateTag:
+ if (!readDate(value))
+ return false;
+ break;
case NumberTag:
if (!readNumber(value))
return false;
break;
- case ObjectTag:
- case ArrayTag:
- if (!doReadUint32(&rawLength))
+ case BlobTag:
+ if (!readBlob(value))
+ return false;
+ break;
+ case FileTag:
+ if (!readFile(value))
+ return false;
+ break;
+ case FileListTag:
+ if (!readFileList(value))
+ return false;
+ break;
+ case ImageDataTag:
+ if (!readImageData(value))
+ return false;
+ break;
+ case ArrayTag: {
+ uint32_t length;
+ if (!doReadUint32(&length))
+ return false;
+ if (!creator.createArray(length, value))
return false;
- *length = rawLength;
break;
}
- return true;
+ case ObjectTag: {
+ uint32_t numProperties;
+ if (!doReadUint32(&numProperties))
+ return false;
+ if (!creator.createObject(numProperties, value))
+ return false;
+ break;
+ }
+ case SparseArrayTag: {
+ uint32_t numProperties;
+ uint32_t length;
+ if (!doReadUint32(&numProperties))
+ return false;
+ if (!doReadUint32(&length))
+ return false;
+ if (!creator.createSparseArray(numProperties, length, value))
+ return false;
+ break;
+ }
+ default:
+ return false;
+ }
+ return !value->IsEmpty();
}
private:
@@ -538,7 +772,19 @@ private:
return false;
if (m_position + length > m_length)
return false;
- *value = v8::String::New(m_buffer + m_position, length);
+ *value = v8::String::New(reinterpret_cast<const char*>(m_buffer + m_position), length);
+ m_position += length;
+ return true;
+ }
+
+ bool readWebCoreString(String* string)
+ {
+ uint32_t length;
+ if (!doReadUint32(&length))
+ return false;
+ if (m_position + length > m_length)
+ return false;
+ *string = String::fromUTF8(reinterpret_cast<const char*>(m_buffer + m_position), length);
m_position += length;
return true;
}
@@ -552,22 +798,96 @@ private:
return true;
}
- bool readNumber(v8::Handle<v8::Value>* value)
+ bool readUint32(v8::Handle<v8::Value>* value)
{
- if (m_position + sizeof(double) > m_length)
+ uint32_t rawValue;
+ if (!doReadUint32(&rawValue))
+ return false;
+ *value = v8::Integer::New(rawValue);
+ return true;
+ }
+
+ bool readDate(v8::Handle<v8::Value>* value)
+ {
+ double numberValue;
+ if (!doReadNumber(&numberValue))
return false;
+ *value = v8::Date::New(numberValue);
+ return true;
+ }
+
+ bool readNumber(v8::Handle<v8::Value>* value)
+ {
double number;
- char* numberAsByteArray = reinterpret_cast<char*>(&number);
- for (unsigned i = 0; i < sizeof(double); ++i)
- numberAsByteArray[i] = m_buffer[m_position++];
+ if (!doReadNumber(&number))
+ return false;
*value = v8::Number::New(number);
return true;
}
+ bool readImageData(v8::Handle<v8::Value>* value)
+ {
+ uint32_t width;
+ uint32_t height;
+ uint32_t pixelDataLength;
+ if (!doReadUint32(&width))
+ return false;
+ if (!doReadUint32(&height))
+ return false;
+ if (!doReadUint32(&pixelDataLength))
+ return false;
+ if (m_position + pixelDataLength > m_length)
+ return false;
+ PassRefPtr<ImageData> imageData = ImageData::create(width, height);
+ WTF::ByteArray* pixelArray = imageData->data()->data();
+ ASSERT(pixelArray);
+ ASSERT(pixelArray->length() >= pixelDataLength);
+ memcpy(pixelArray->data(), m_buffer + m_position, pixelDataLength);
+ m_position += pixelDataLength;
+ *value = toV8(imageData);
+ return true;
+ }
+
+ bool readBlob(v8::Handle<v8::Value>* value)
+ {
+ String path;
+ if (!readWebCoreString(&path))
+ return false;
+ PassRefPtr<Blob> blob = Blob::create(path);
+ *value = toV8(blob);
+ return true;
+ }
+
+ bool readFile(v8::Handle<v8::Value>* value)
+ {
+ String path;
+ if (!readWebCoreString(&path))
+ return false;
+ PassRefPtr<File> file = File::create(path);
+ *value = toV8(file);
+ return true;
+ }
+
+ bool readFileList(v8::Handle<v8::Value>* value)
+ {
+ uint32_t length;
+ if (!doReadUint32(&length))
+ return false;
+ PassRefPtr<FileList> fileList = FileList::create();
+ for (unsigned i = 0; i < length; ++i) {
+ String path;
+ if (!readWebCoreString(&path))
+ return false;
+ fileList->append(File::create(path));
+ }
+ *value = toV8(fileList);
+ return true;
+ }
+
bool doReadUint32(uint32_t* value)
{
*value = 0;
- char currentByte;
+ uint8_t currentByte;
int shift = 0;
do {
if (m_position >= m_length)
@@ -579,64 +899,94 @@ private:
return true;
}
- const char* m_buffer;
+ bool doReadNumber(double* number)
+ {
+ if (m_position + sizeof(double) > m_length)
+ return false;
+ uint8_t* numberAsByteArray = reinterpret_cast<uint8_t*>(number);
+ for (unsigned i = 0; i < sizeof(double); ++i)
+ numberAsByteArray[i] = m_buffer[m_position++];
+ return true;
+ }
+
+ const uint8_t* m_buffer;
const unsigned m_length;
unsigned m_position;
};
-class Deserializer {
+class Deserializer : public CompositeCreator {
public:
- explicit Deserializer(Reader& reader) : m_reader(reader)
+ explicit Deserializer(Reader& reader)
+ : m_reader(reader)
{
}
- v8::Local<v8::Value> deserialize()
+ v8::Handle<v8::Value> deserialize()
{
v8::HandleScope scope;
while (!m_reader.isEof()) {
if (!doDeserialize())
- return v8::Local<v8::Value>();
+ return v8::Null();
}
if (stackDepth() != 1)
- return v8::Local<v8::Value>();
+ return v8::Null();
return scope.Close(element(0));
}
+ virtual bool createArray(uint32_t length, v8::Handle<v8::Value>* value)
+ {
+ if (length > stackDepth())
+ return false;
+ v8::Local<v8::Array> array = v8::Array::New(length);
+ if (array.IsEmpty())
+ return false;
+ const int depth = stackDepth() - length;
+ for (unsigned i = 0; i < length; ++i)
+ array->Set(i, element(depth + i));
+ pop(length);
+ *value = array;
+ return true;
+ }
+
+ virtual bool createObject(uint32_t numProperties, v8::Handle<v8::Value>* value)
+ {
+ v8::Local<v8::Object> object = v8::Object::New();
+ if (object.IsEmpty())
+ return false;
+ return initializeObject(object, numProperties, value);
+ }
+
+ virtual bool createSparseArray(uint32_t numProperties, uint32_t length, v8::Handle<v8::Value>* value)
+ {
+ v8::Local<v8::Array> array = v8::Array::New(length);
+ if (array.IsEmpty())
+ return false;
+ return initializeObject(array, numProperties, value);
+ }
+
private:
+ bool initializeObject(v8::Handle<v8::Object> object, uint32_t numProperties, v8::Handle<v8::Value>* value)
+ {
+ unsigned length = 2 * numProperties;
+ if (length > stackDepth())
+ return false;
+ for (unsigned i = stackDepth() - length; i < stackDepth(); i += 2) {
+ v8::Local<v8::Value> propertyName = element(i);
+ v8::Local<v8::Value> propertyValue = element(i + 1);
+ object->Set(propertyName, propertyValue);
+ }
+ pop(length);
+ *value = object;
+ return true;
+ }
+
bool doDeserialize()
{
- SerializationTag tag;
v8::Local<v8::Value> value;
- int length = 0;
- if (!m_reader.read(&tag, &value, &length))
+ if (!m_reader.read(&value, *this))
return false;
- if (!value.IsEmpty()) {
+ if (!value.IsEmpty())
push(value);
- } else if (tag == ObjectTag) {
- if (length > stackDepth())
- return false;
- v8::Local<v8::Object> object = v8::Object::New();
- for (int i = stackDepth() - length; i < stackDepth(); i += 2) {
- v8::Local<v8::Value> propertyName = element(i);
- v8::Local<v8::Value> propertyValue = element(i + 1);
- object->Set(propertyName, propertyValue);
- }
- pop(length);
- push(object);
- } else if (tag == ArrayTag) {
- if (length > stackDepth())
- return false;
- v8::Local<v8::Array> array = v8::Array::New(length);
- const int depth = stackDepth() - length;
- {
- v8::HandleScope scope;
- for (int i = 0; i < length; ++i)
- array->Set(v8::Integer::New(i), element(depth + i));
- }
- pop(length);
- push(array);
- } else if (tag != PaddingTag)
- return false;
return true;
}
@@ -648,7 +998,7 @@ private:
m_stack.shrink(m_stack.size() - length);
}
- int stackDepth() const { return m_stack.size(); }
+ unsigned stackDepth() const { return m_stack.size(); }
v8::Local<v8::Value> element(unsigned index)
{
@@ -662,12 +1012,14 @@ private:
} // namespace
-SerializedScriptValue::SerializedScriptValue(v8::Handle<v8::Value> value)
+SerializedScriptValue::SerializedScriptValue(v8::Handle<v8::Value> value, bool& didThrow)
{
+ didThrow = false;
Writer writer;
Serializer serializer(writer);
if (!serializer.serialize(value)) {
- // FIXME: throw exception
+ throwError(NOT_SUPPORTED_ERR);
+ didThrow = true;
return;
}
m_data = StringImpl::adopt(writer.data());
@@ -679,19 +1031,18 @@ SerializedScriptValue::SerializedScriptValue(String data, StringDataMode mode)
m_data = data;
else {
ASSERT(mode == StringValue);
- RefPtr<SharedBuffer> buffer = utf8Buffer(data);
Writer writer;
- writer.writeString(buffer->data(), buffer->size());
+ writer.writeWebCoreString(data);
m_data = StringImpl::adopt(writer.data());
}
}
-v8::Local<v8::Value> SerializedScriptValue::deserialize()
+v8::Handle<v8::Value> SerializedScriptValue::deserialize()
{
if (!m_data.impl())
- return v8::Local<v8::Value>();
+ return v8::Null();
COMPILE_ASSERT(sizeof(BufferValueType) == 2, BufferValueTypeIsTwoBytes);
- Reader reader(reinterpret_cast<const char*>(m_data.impl()->characters()), 2 * m_data.length());
+ Reader reader(reinterpret_cast<const uint8_t*>(m_data.impl()->characters()), 2 * m_data.length());
Deserializer deserializer(reader);
return deserializer.deserialize();
}
diff --git a/WebCore/bindings/v8/SerializedScriptValue.h b/WebCore/bindings/v8/SerializedScriptValue.h
index 7eb8935..8205a42 100644
--- a/WebCore/bindings/v8/SerializedScriptValue.h
+++ b/WebCore/bindings/v8/SerializedScriptValue.h
@@ -40,10 +40,36 @@ namespace WebCore {
class SerializedScriptValue : public RefCounted<SerializedScriptValue> {
public:
+ // Deserializes the given value and sets it as a property on the
+ // object.
+ static void deserializeAndSetProperty(v8::Handle<v8::Object> object,
+ const char* propertyName,
+ v8::PropertyAttribute attribute,
+ SerializedScriptValue* value)
+ {
+ if (!value)
+ return;
+ v8::Handle<v8::Value> deserialized = value->deserialize();
+ object->ForceSet(v8::String::NewSymbol(propertyName), deserialized, attribute);
+ }
+
// Creates a serialized representation of the given V8 value.
static PassRefPtr<SerializedScriptValue> create(v8::Handle<v8::Value> value)
{
- return adoptRef(new SerializedScriptValue(value));
+ bool didThrow;
+ return adoptRef(new SerializedScriptValue(value, didThrow));
+ }
+
+ // Creates a serialized representation of the given V8 value.
+ //
+ // If a serialization error occurs (e.g., cyclic input value) this
+ // function returns an empty representation, schedules a V8 exception to
+ // be thrown using v8::ThrowException(), and sets |didThrow|. In this case
+ // the caller must not invoke any V8 operations until control returns to
+ // V8. When serialization is successful, |didThrow| is false.
+ static PassRefPtr<SerializedScriptValue> create(v8::Handle<v8::Value> value, bool& didThrow)
+ {
+ return adoptRef(new SerializedScriptValue(value, didThrow));
}
// Creates a serialized value with the given data obtained from a
@@ -74,9 +100,9 @@ public:
String toWireString() const { return m_data; }
- // Deserializes the value (in the current context). Returns an
- // empty handle in case of failure.
- v8::Local<v8::Value> deserialize();
+ // Deserializes the value (in the current context). Returns a null value in
+ // case of failure.
+ v8::Handle<v8::Value> deserialize();
private:
enum StringDataMode {
@@ -86,7 +112,7 @@ private:
SerializedScriptValue() { }
- explicit SerializedScriptValue(v8::Handle<v8::Value>);
+ SerializedScriptValue(v8::Handle<v8::Value>, bool& didThrow);
SerializedScriptValue(String data, StringDataMode mode);
diff --git a/WebCore/bindings/v8/StaticDOMDataStore.cpp b/WebCore/bindings/v8/StaticDOMDataStore.cpp
index 722051b..0b0d531 100644
--- a/WebCore/bindings/v8/StaticDOMDataStore.cpp
+++ b/WebCore/bindings/v8/StaticDOMDataStore.cpp
@@ -36,11 +36,11 @@ namespace WebCore {
StaticDOMDataStore::StaticDOMDataStore(DOMData* domData)
: DOMDataStore(domData)
, m_staticDomNodeMap(&DOMDataStore::weakNodeCallback)
- , m_staticDomObjectMap(domData, &DOMDataStore::weakDOMObjectCallback)
- , m_staticActiveDomObjectMap(domData, &DOMDataStore::weakActiveDOMObjectCallback)
+ , m_staticDomObjectMap(&DOMDataStore::weakDOMObjectCallback)
+ , m_staticActiveDomObjectMap(&DOMDataStore::weakActiveDOMObjectCallback)
#if ENABLE(SVG)
- , m_staticDomSvgElementInstanceMap(domData, &DOMDataStore::weakSVGElementInstanceCallback)
- , m_staticDomSvgObjectWithContextMap(domData, &DOMDataStore::weakSVGObjectWithContextCallback)
+ , m_staticDomSvgElementInstanceMap(&DOMDataStore::weakSVGElementInstanceCallback)
+ , m_staticDomSvgObjectWithContextMap(&DOMDataStore::weakSVGObjectWithContextCallback)
#endif
{
m_domNodeMap = &m_staticDomNodeMap;
diff --git a/WebCore/bindings/v8/StaticDOMDataStore.h b/WebCore/bindings/v8/StaticDOMDataStore.h
index 64a90e0..d1e5a30 100644
--- a/WebCore/bindings/v8/StaticDOMDataStore.h
+++ b/WebCore/bindings/v8/StaticDOMDataStore.h
@@ -49,11 +49,11 @@ public:
private:
IntrusiveDOMWrapperMap m_staticDomNodeMap;
- InternalDOMWrapperMap<void> m_staticDomObjectMap;
- InternalDOMWrapperMap<void> m_staticActiveDomObjectMap;
+ DOMWrapperMap<void> m_staticDomObjectMap;
+ DOMWrapperMap<void> m_staticActiveDomObjectMap;
#if ENABLE(SVG)
- InternalDOMWrapperMap<SVGElementInstance> m_staticDomSvgElementInstanceMap;
- InternalDOMWrapperMap<void> m_staticDomSvgObjectWithContextMap;
+ DOMWrapperMap<SVGElementInstance> m_staticDomSvgElementInstanceMap;
+ DOMWrapperMap<void> m_staticDomSvgObjectWithContextMap;
#endif
};
diff --git a/WebCore/bindings/v8/V8AbstractEventListener.cpp b/WebCore/bindings/v8/V8AbstractEventListener.cpp
index 944fd57..6dc2b29 100644
--- a/WebCore/bindings/v8/V8AbstractEventListener.cpp
+++ b/WebCore/bindings/v8/V8AbstractEventListener.cpp
@@ -88,8 +88,6 @@ void V8AbstractEventListener::handleEvent(ScriptExecutionContext* context, Event
v8::Handle<v8::Value> jsEvent = toV8(event);
invokeEventHandler(context, event, jsEvent);
-
- Document::updateStyleForAllDocuments();
}
void V8AbstractEventListener::disposeListenerObject()
@@ -147,11 +145,8 @@ void V8AbstractEventListener::invokeEventHandler(ScriptExecutionContext* context
if (!tryCatch.CanContinue())
return;
- // If an error occurs while handling the event, it should be reported.
- if (tryCatch.HasCaught()) {
- reportException(0, tryCatch);
- tryCatch.Reset();
- }
+ // If an error occurs while handling the event, it should be reported in a regular way.
+ tryCatch.Reset();
// Restore the old event. This must be done for all exit paths through this method.
if (savedEvent.IsEmpty())
diff --git a/WebCore/bindings/v8/V8Binding.cpp b/WebCore/bindings/v8/V8Binding.cpp
index 34020be..e0904d7 100644
--- a/WebCore/bindings/v8/V8Binding.cpp
+++ b/WebCore/bindings/v8/V8Binding.cpp
@@ -32,7 +32,6 @@
#include "V8Binding.h"
#include "AtomicString.h"
-#include "CString.h"
#include "Element.h"
#include "MathExtras.h"
#include "PlatformString.h"
@@ -43,6 +42,7 @@
#include "Threading.h"
#include "V8Element.h"
#include "V8Proxy.h"
+#include <wtf/text/CString.h>
#include <v8.h>
@@ -174,6 +174,53 @@ int toInt32(v8::Handle<v8::Value> value, bool& ok)
return intValue->Value();
}
+uint32_t toUInt32(v8::Handle<v8::Value> value, bool& ok)
+{
+ ok = true;
+
+ // FIXME: there is currently no Value::IsUint32(). This code does
+ // some contortions to avoid silently converting out-of-range
+ // values to uint32_t.
+
+ // Fast case. The value is already a 32-bit positive integer.
+ if (value->IsInt32()) {
+ int32_t result = value->Int32Value();
+ if (result >= 0)
+ return result;
+ }
+
+ // 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 unsigned integer?
+ v8::Local<v8::Uint32> uintValue = value->ToUint32();
+ if (uintValue.IsEmpty()) {
+ ok = false;
+ return 0;
+ }
+
+ // FIXME: v8::Uint32::Value is not defined!
+ // http://code.google.com/p/v8/issues/detail?id=624
+ v8::Local<v8::Int32> intValue = value->ToInt32();
+ if (intValue.IsEmpty()) {
+ ok = false;
+ return 0;
+ }
+
+ return static_cast<uint32_t>(intValue->Value());
+}
+
String toWebCoreString(const v8::Arguments& args, int index) {
return v8ValueToWebCoreString(args[index]);
}
diff --git a/WebCore/bindings/v8/V8Binding.h b/WebCore/bindings/v8/V8Binding.h
index 0be0ebd..696cd1a 100644
--- a/WebCore/bindings/v8/V8Binding.h
+++ b/WebCore/bindings/v8/V8Binding.h
@@ -108,6 +108,17 @@ namespace WebCore {
return toInt32(value, ok);
}
+ // Convert a value to a 32-bit unsigned integer. The conversion fails if the
+ // value cannot be converted to an unsigned integer or converts to nan or to an infinity.
+ uint32_t toUInt32(v8::Handle<v8::Value> value, bool& ok);
+
+ // Convert a value to a 32-bit unsigned integer assuming the conversion cannot fail.
+ inline uint32_t toUInt32(v8::Handle<v8::Value> value)
+ {
+ bool ok;
+ return toUInt32(value, ok);
+ }
+
inline float toFloat(v8::Local<v8::Value> value)
{
return static_cast<float>(value->NumberValue());
diff --git a/WebCore/bindings/v8/V8Collection.h b/WebCore/bindings/v8/V8Collection.h
index 9611571..1757c85 100644
--- a/WebCore/bindings/v8/V8Collection.h
+++ b/WebCore/bindings/v8/V8Collection.h
@@ -34,6 +34,7 @@
#include "HTMLFormElement.h"
#include "HTMLSelectElement.h"
#include "V8Binding.h"
+#include "V8Node.h"
#include "V8Proxy.h"
#include <v8.h>
@@ -63,7 +64,7 @@ template<class Collection, class ItemType> static v8::Handle<v8::Value> getNamed
{
// FIXME: assert object is a collection type
ASSERT(V8DOMWrapper::maybeDOMWrapper(object));
- ASSERT(V8DOMWrapper::domWrapperType(object) != V8ClassIndex::NODE);
+ ASSERT(V8DOMWrapper::domWrapperType(object) != &V8Node::info);
Collection* collection = toNativeCollection<Collection>(object);
AtomicString propertyName = toAtomicWebCoreStringWithNullCheck(name);
return getV8Object<ItemType>(collection->namedItem(propertyName));
@@ -89,7 +90,7 @@ template<class Collection, class ItemType> static v8::Handle<v8::Value> getIndex
{
// FIXME: Assert that object must be a collection type.
ASSERT(V8DOMWrapper::maybeDOMWrapper(object));
- ASSERT(V8DOMWrapper::domWrapperType(object) != V8ClassIndex::NODE);
+ ASSERT(V8DOMWrapper::domWrapperType(object) != &V8Node::info);
Collection* collection = toNativeCollection<Collection>(object);
return getV8Object<ItemType>(collection->item(index));
}
@@ -154,17 +155,16 @@ template<class Collection> static v8::Handle<v8::Value> collectionStringIndexedP
// 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)
+template<class Collection, class ItemType> static void setCollectionIndexedGetter(v8::Handle<v8::FunctionTemplate> desc)
{
- desc->InstanceTemplate()->SetIndexedPropertyHandler(collectionIndexedPropertyGetter<Collection, ItemType>, 0, 0, 0, collectionIndexedPropertyEnumerator<Collection>,
- v8::Integer::New(V8ClassIndex::ToInt(type)));
+ desc->InstanceTemplate()->SetIndexedPropertyHandler(collectionIndexedPropertyGetter<Collection, ItemType>, 0, 0, 0, collectionIndexedPropertyEnumerator<Collection>);
}
// Add named getter to the function template for a collection.
-template<class Collection, class ItemType> static void setCollectionNamedGetter(v8::Handle<v8::FunctionTemplate> desc, V8ClassIndex::V8WrapperType type)
+template<class Collection, class ItemType> static void setCollectionNamedGetter(v8::Handle<v8::FunctionTemplate> desc)
{
- desc->InstanceTemplate()->SetNamedPropertyHandler(collectionNamedPropertyGetter<Collection, ItemType>, 0, 0, 0, 0, v8::Integer::New(V8ClassIndex::ToInt(type)));
+ desc->InstanceTemplate()->SetNamedPropertyHandler(collectionNamedPropertyGetter<Collection, ItemType>, 0, 0, 0, 0);
}
// Add indexed getter returning a string or null to a function template for a collection.
diff --git a/WebCore/bindings/v8/V8DOMMap.cpp b/WebCore/bindings/v8/V8DOMMap.cpp
index fa2fba3..b478d06 100644
--- a/WebCore/bindings/v8/V8DOMMap.cpp
+++ b/WebCore/bindings/v8/V8DOMMap.cpp
@@ -33,7 +33,6 @@
#include "DOMData.h"
#include "DOMDataStore.h"
-#include "DOMObjectsInclude.h"
#include "MainThreadDOMData.h"
#include "ScopedDOMDataStore.h"
@@ -95,13 +94,10 @@ DOMWrapperMap<void>& getDOMSVGObjectWithContextMap()
#endif // ENABLE(SVG)
-static void removeAllDOMObjectsInCurrentThreadHelper()
+void removeAllDOMObjectsInCurrentThread()
{
v8::HandleScope scope;
- // Deref all objects in the delayed queue.
- DOMData::getCurrent()->derefDelayedObjects();
-
// The DOM objects with the following types only exist on the main thread.
if (WTF::isMainThread()) {
// Remove all DOM nodes.
@@ -123,17 +119,6 @@ static void removeAllDOMObjectsInCurrentThreadHelper()
DOMData::removeObjectsFromWrapperMap<void>(getActiveDOMObjectMap());
}
-void removeAllDOMObjectsInCurrentThread()
-{
- // Use the locker only if it has already been invoked before, as by worker thread.
- if (v8::Locker::IsActive()) {
- v8::Locker locker;
- removeAllDOMObjectsInCurrentThreadHelper();
- } else
- removeAllDOMObjectsInCurrentThreadHelper();
-}
-
-
void visitDOMNodesInCurrentThread(DOMWrapperMap<Node>::Visitor* visitor)
{
v8::HandleScope scope;
diff --git a/WebCore/bindings/v8/V8DOMWindowShell.cpp b/WebCore/bindings/v8/V8DOMWindowShell.cpp
index cdf4393..6087479 100644
--- a/WebCore/bindings/v8/V8DOMWindowShell.cpp
+++ b/WebCore/bindings/v8/V8DOMWindowShell.cpp
@@ -31,12 +31,10 @@
#include "config.h"
#include "V8DOMWindowShell.h"
-#include "CString.h"
#include "PlatformBridge.h"
#include "CSSMutableStyleDeclaration.h"
#include "DateExtension.h"
#include "DocumentLoader.h"
-#include "DOMObjectsInclude.h"
#include "Frame.h"
#include "FrameLoaderClient.h"
#include "InspectorTimelineAgent.h"
@@ -51,9 +49,9 @@
#include "V8DOMMap.h"
#include "V8DOMWindow.h"
#include "V8Document.h"
+#include "V8GCForContextDispose.h"
#include "V8HiddenPropertyName.h"
#include "V8History.h"
-#include "V8Index.h"
#include "V8Location.h"
#include "V8Proxy.h"
#include "WorkerContextExecutionProxy.h"
@@ -68,6 +66,7 @@
#include <wtf/StdLibExtras.h>
#include <wtf/StringExtras.h>
#include <wtf/UnusedParam.h>
+#include <wtf/text/CString.h>
#ifdef ANDROID_INSTRUMENT
#include "TimeCounter.h"
@@ -96,28 +95,20 @@ static void reportFatalErrorInV8(const char* location, const char* message)
static Frame* getTargetFrame(v8::Local<v8::Object> host, v8::Local<v8::Value> data)
{
Frame* target = 0;
- switch (V8ClassIndex::FromInt(data->Int32Value())) {
- case V8ClassIndex::DOMWINDOW: {
+ WrapperTypeInfo* type = WrapperTypeInfo::unwrap(data);
+ if (V8DOMWindow::info.equals(type)) {
v8::Handle<v8::Object> window = V8DOMWrapper::lookupDOMWrapper(V8DOMWindow::GetTemplate(), host);
if (window.IsEmpty())
return target;
DOMWindow* targetWindow = V8DOMWindow::toNative(window);
target = targetWindow->frame();
- break;
- }
- case V8ClassIndex::LOCATION: {
+ } else if (V8History::info.equals(type)) {
History* history = V8History::toNative(host);
target = history->frame();
- break;
- }
- case V8ClassIndex::HISTORY: {
+ } else if (V8Location::info.equals(type)) {
Location* location = V8Location::toNative(host);
target = location->frame();
- break;
- }
- default:
- break;
}
return target;
}
@@ -144,7 +135,6 @@ bool V8DOMWindowShell::isContextInitialized()
// m_context, m_global, and m_wrapperBoilerplates should
// all be non-empty if if m_context is non-empty.
ASSERT(m_context.IsEmpty() || !m_global.IsEmpty());
- ASSERT(m_context.IsEmpty() || !m_wrapperBoilerplates.IsEmpty());
return !m_context.IsEmpty();
}
@@ -154,15 +144,20 @@ void V8DOMWindowShell::disposeContextHandles()
m_frame->loader()->client()->didDestroyScriptContextForFrame();
m_context.Dispose();
m_context.Clear();
+
+ // It's likely that disposing the context has created a lot of
+ // garbage. Notify V8 about this so it'll have a chance of cleaning
+ // it up when idle.
+ V8GCForContextDispose::instance().notifyContextDisposed();
}
- if (!m_wrapperBoilerplates.IsEmpty()) {
-#ifndef NDEBUG
- V8GCController::unregisterGlobalHandle(this, m_wrapperBoilerplates);
-#endif
- m_wrapperBoilerplates.Dispose();
- m_wrapperBoilerplates.Clear();
+ WrapperBoilerplateMap::iterator it = m_wrapperBoilerplates.begin();
+ for (; it != m_wrapperBoilerplates.end(); ++it) {
+ v8::Persistent<v8::Object> wrapper = it->second;
+ wrapper.Dispose();
+ wrapper.Clear();
}
+ m_wrapperBoilerplates.clear();
}
void V8DOMWindowShell::destroyGlobal()
@@ -299,19 +294,15 @@ void V8DOMWindowShell::initContextIfNeeded()
#endif
}
- installHiddenObjectPrototype(v8Context);
- m_wrapperBoilerplates = v8::Persistent<v8::Array>::New(v8::Array::New(V8ClassIndex::WRAPPER_TYPE_COUNT));
- // Bail out if allocation failed.
- if (m_wrapperBoilerplates.IsEmpty()) {
+ if (!installHiddenObjectPrototype(v8Context)) {
disposeContextHandles();
return;
}
-#ifndef NDEBUG
- V8GCController::registerGlobalHandle(PROXY, this, m_wrapperBoilerplates);
-#endif
- if (!installDOMWindow(v8Context, m_frame->domWindow()))
+ if (!installDOMWindow(v8Context, m_frame->domWindow())) {
disposeContextHandles();
+ return;
+ }
updateDocument();
@@ -357,7 +348,7 @@ v8::Persistent<v8::Context> V8DOMWindowShell::createNewContext(v8::Handle<v8::Ob
// Note: we check the loader URL here instead of the document URL
// because we might be currently loading an URL into a blank page.
// See http://code.google.com/p/chromium/issues/detail?id=10924
- if (extensions[i].scheme.length() > 0 && (extensions[i].scheme != m_frame->loader()->activeDocumentLoader()->url().protocol() || extensions[i].scheme != m_frame->page()->mainFrame()->loader()->activeDocumentLoader()->url().protocol()))
+ if (extensions[i].scheme.length() > 0 && (extensions[i].scheme != m_frame->loader()->activeDocumentLoader()->url().protocol()))
continue;
extensionNames[index++] = extensions[i].extension->name();
@@ -369,6 +360,7 @@ v8::Persistent<v8::Context> V8DOMWindowShell::createNewContext(v8::Handle<v8::Ob
}
void V8DOMWindowShell::setContext(v8::Handle<v8::Context> context)
+<<<<<<< HEAD
{
// if we already have a context, clear it before setting the new one.
if (!m_context.IsEmpty()) {
@@ -379,29 +371,37 @@ void V8DOMWindowShell::setContext(v8::Handle<v8::Context> context)
}
bool V8DOMWindowShell::installDOMWindow(v8::Handle<v8::Context> context, DOMWindow* window)
+=======
+>>>>>>> webkit.org at r58033
{
- v8::Handle<v8::String> implicitProtoString = v8::String::New("__proto__");
- if (implicitProtoString.IsEmpty())
- return false;
+ // if we already have a context, clear it before setting the new one.
+ if (!m_context.IsEmpty()) {
+ m_context.Dispose();
+ m_context.Clear();
+ }
+ m_context = v8::Persistent<v8::Context>::New(context);
+}
+bool V8DOMWindowShell::installDOMWindow(v8::Handle<v8::Context> context, DOMWindow* window)
+{
// Create a new JS window object and use it as the prototype for the shadow global object.
- v8::Handle<v8::Function> windowConstructor = V8DOMWrapper::getConstructor(V8ClassIndex::DOMWINDOW, getHiddenObjectPrototype(context));
+ v8::Handle<v8::Function> windowConstructor = V8DOMWrapper::getConstructor(&V8DOMWindow::info, getHiddenObjectPrototype(context));
v8::Local<v8::Object> jsWindow = SafeAllocation::newInstance(windowConstructor);
// Bail out if allocation failed.
if (jsWindow.IsEmpty())
return false;
// Wrap the window.
- V8DOMWrapper::setDOMWrapper(jsWindow, V8ClassIndex::ToInt(V8ClassIndex::DOMWINDOW), window);
- V8DOMWrapper::setDOMWrapper(v8::Handle<v8::Object>::Cast(jsWindow->GetPrototype()), V8ClassIndex::ToInt(V8ClassIndex::DOMWINDOW), window);
+ V8DOMWrapper::setDOMWrapper(jsWindow, &V8DOMWindow::info, window);
+ V8DOMWrapper::setDOMWrapper(v8::Handle<v8::Object>::Cast(jsWindow->GetPrototype()), &V8DOMWindow::info, window);
window->ref();
V8DOMWrapper::setJSWrapperForDOMObject(window, v8::Persistent<v8::Object>::New(jsWindow));
// Insert the window instance as the prototype of the shadow object.
- v8::Handle<v8::Object> v8Global = context->Global();
- V8DOMWrapper::setDOMWrapper(v8::Handle<v8::Object>::Cast(v8Global->GetPrototype()), V8ClassIndex::ToInt(V8ClassIndex::DOMWINDOW), window);
- v8Global->Set(implicitProtoString, jsWindow);
+ v8::Handle<v8::Object> v8RealGlobal = v8::Handle<v8::Object>::Cast(context->Global()->GetPrototype());
+ V8DOMWrapper::setDOMWrapper(v8RealGlobal, &V8DOMWindow::info, window);
+ v8RealGlobal->SetPrototype(jsWindow);
return true;
}
@@ -533,31 +533,38 @@ v8::Handle<v8::Value> V8DOMWindowShell::getHiddenObjectPrototype(v8::Handle<v8::
return context->Global()->GetHiddenValue(V8HiddenPropertyName::objectPrototype());
}
-void V8DOMWindowShell::installHiddenObjectPrototype(v8::Handle<v8::Context> context)
+bool V8DOMWindowShell::installHiddenObjectPrototype(v8::Handle<v8::Context> context)
{
v8::Handle<v8::String> objectString = v8::String::New("Object");
v8::Handle<v8::String> prototypeString = v8::String::New("prototype");
v8::Handle<v8::String> hiddenObjectPrototypeString = V8HiddenPropertyName::objectPrototype();
// Bail out if allocation failed.
if (objectString.IsEmpty() || prototypeString.IsEmpty() || hiddenObjectPrototypeString.IsEmpty())
- return;
+ return false;
v8::Handle<v8::Object> object = v8::Handle<v8::Object>::Cast(context->Global()->Get(objectString));
+ // Bail out if fetching failed.
+ if (object.IsEmpty())
+ return false;
v8::Handle<v8::Value> objectPrototype = object->Get(prototypeString);
+ // Bail out if fetching failed.
+ if (objectPrototype.IsEmpty())
+ return false;
context->Global()->SetHiddenValue(hiddenObjectPrototypeString, objectPrototype);
+
+ return true;
}
-v8::Local<v8::Object> V8DOMWindowShell::createWrapperFromCacheSlowCase(V8ClassIndex::V8WrapperType type)
+v8::Local<v8::Object> V8DOMWindowShell::createWrapperFromCacheSlowCase(WrapperTypeInfo* type)
{
// Not in cache.
- int classIndex = V8ClassIndex::ToInt(type);
initContextIfNeeded();
v8::Context::Scope scope(m_context);
v8::Local<v8::Function> function = V8DOMWrapper::getConstructor(type, getHiddenObjectPrototype(m_context));
v8::Local<v8::Object> instance = SafeAllocation::newInstance(function);
if (!instance.IsEmpty()) {
- m_wrapperBoilerplates->Set(v8::Integer::New(classIndex), instance);
+ m_wrapperBoilerplates.set(type, v8::Persistent<v8::Object>::New(instance));
return instance->Clone();
}
return notHandledByInterceptor();
diff --git a/WebCore/bindings/v8/V8DOMWindowShell.h b/WebCore/bindings/v8/V8DOMWindowShell.h
index 6b8952d..f4eaff2 100644
--- a/WebCore/bindings/v8/V8DOMWindowShell.h
+++ b/WebCore/bindings/v8/V8DOMWindowShell.h
@@ -31,7 +31,8 @@
#ifndef V8DOMWindowShell_h
#define V8DOMWindowShell_h
-#include "V8Index.h"
+#include "WrapperTypeInfo.h"
+#include <wtf/HashMap.h>
#include <wtf/PassRefPtr.h>
#include <wtf/RefCounted.h>
#include <wtf/RefPtr.h>
@@ -73,16 +74,15 @@ public:
static v8::Handle<v8::Value> getHiddenObjectPrototype(v8::Handle<v8::Context>);
// WARNING: Call |installHiddenObjectPrototype| only on fresh contexts!
- static void installHiddenObjectPrototype(v8::Handle<v8::Context>);
+ static bool installHiddenObjectPrototype(v8::Handle<v8::Context>);
// To create JS Wrapper objects, we create a cache of a 'boiler plate'
// object, and then simply Clone that object each time we need a new one.
// This is faster than going through the full object creation process.
- v8::Local<v8::Object> createWrapperFromCache(V8ClassIndex::V8WrapperType type)
+ v8::Local<v8::Object> createWrapperFromCache(WrapperTypeInfo* type)
{
- int classIndex = V8ClassIndex::ToInt(type);
- v8::Local<v8::Object> clone(m_wrapperBoilerplates->CloneElementAt(classIndex));
- return clone.IsEmpty() ? createWrapperFromCacheSlowCase(type) : clone;
+ v8::Persistent<v8::Object> boilerplate = m_wrapperBoilerplates.get(type);
+ return boilerplate.IsEmpty() ? createWrapperFromCacheSlowCase(type) : boilerplate->Clone();
}
static void setLocation(DOMWindow*, const String& relativeURL);
@@ -102,15 +102,14 @@ private:
void updateDocumentWrapperCache();
void clearDocumentWrapperCache();
- v8::Local<v8::Object> createWrapperFromCacheSlowCase(V8ClassIndex::V8WrapperType);
+ v8::Local<v8::Object> createWrapperFromCacheSlowCase(WrapperTypeInfo*);
Frame* m_frame;
// 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
- // activated boilerplates.
- v8::Persistent<v8::Array> m_wrapperBoilerplates;
+ // The boilerplate is used to create additional wrappers of the same type.
+ typedef WTF::HashMap<WrapperTypeInfo*, v8::Persistent<v8::Object> > WrapperBoilerplateMap;
+ WrapperBoilerplateMap m_wrapperBoilerplates;
v8::Persistent<v8::Context> m_context;
v8::Persistent<v8::Object> m_global;
diff --git a/WebCore/bindings/v8/V8DOMWrapper.cpp b/WebCore/bindings/v8/V8DOMWrapper.cpp
index cf11e6c..ac29170 100644
--- a/WebCore/bindings/v8/V8DOMWrapper.cpp
+++ b/WebCore/bindings/v8/V8DOMWrapper.cpp
@@ -1,10 +1,10 @@
/*
* Copyright (C) 2009 Google Inc. All rights reserved.
- *
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
- *
+ *
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
@@ -14,7 +14,7 @@
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
- *
+ *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -33,44 +33,50 @@
#include "CSSMutableStyleDeclaration.h"
#include "DOMDataStore.h"
-#include "DOMObjectsInclude.h"
#include "DocumentLoader.h"
#include "FrameLoaderClient.h"
#include "Notification.h"
-#include "SVGElementInstance.h"
-#include "SVGPathSeg.h"
#include "ScriptController.h"
#include "V8AbstractEventListener.h"
#include "V8Binding.h"
#include "V8Collection.h"
#include "V8CustomEventListener.h"
+#include "V8DedicatedWorkerContext.h"
#include "V8DOMApplicationCache.h"
#include "V8DOMMap.h"
#include "V8DOMWindow.h"
#include "V8EventListenerList.h"
+#include "V8EventSource.h"
#include "V8HTMLCollection.h"
#include "V8HTMLDocument.h"
-#include "V8Index.h"
#include "V8IsolatedContext.h"
#include "V8Location.h"
#include "V8MessageChannel.h"
#include "V8NamedNodeMap.h"
#include "V8Node.h"
+#include "V8NodeFilterCondition.h"
#include "V8NodeList.h"
#include "V8Notification.h"
#include "V8Proxy.h"
-#include "V8SVGElementInstance.h"
#include "V8SharedWorker.h"
#include "V8SharedWorkerContext.h"
#include "V8StyleSheet.h"
#include "V8WebSocket.h"
#include "V8Worker.h"
#include "V8WorkerContext.h"
+#include "V8WorkerContextEventListener.h"
#include "V8XMLHttpRequest.h"
#include "WebGLArray.h"
#include "WebGLContextAttributes.h"
#include "WebGLUniformLocation.h"
#include "WorkerContextExecutionProxy.h"
+#include "WrapperTypeInfo.h"
+
+#if ENABLE(SVG)
+#include "SVGElementInstance.h"
+#include "SVGPathSeg.h"
+#include "V8SVGElementInstance.h"
+#endif
#include <algorithm>
#include <utility>
@@ -86,60 +92,11 @@ namespace WebCore {
typedef HashMap<Node*, v8::Object*> DOMNodeMap;
typedef HashMap<void*, v8::Object*> DOMObjectMap;
-#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
-
// The caller must have increased obj's ref count.
void V8DOMWrapper::setJSWrapperForDOMObject(void* object, v8::Persistent<v8::Object> wrapper)
{
ASSERT(V8DOMWrapper::maybeDOMWrapper(wrapper));
-#ifndef NDEBUG
- V8ClassIndex::V8WrapperType type = V8DOMWrapper::domWrapperType(wrapper);
- switch (type) {
-#define MAKE_CASE(TYPE, NAME) case V8ClassIndex::TYPE:
- ACTIVE_DOM_OBJECT_TYPES(MAKE_CASE)
- ASSERT_NOT_REACHED();
-#undef MAKE_CASE
- default:
- break;
- }
-#endif
+ ASSERT(!domWrapperType(wrapper)->toActiveDOMObjectFunction);
getDOMObjectMap().set(object, wrapper);
}
@@ -147,16 +104,7 @@ void V8DOMWrapper::setJSWrapperForDOMObject(void* object, v8::Persistent<v8::Obj
void V8DOMWrapper::setJSWrapperForActiveDOMObject(void* object, v8::Persistent<v8::Object> wrapper)
{
ASSERT(V8DOMWrapper::maybeDOMWrapper(wrapper));
-#ifndef NDEBUG
- V8ClassIndex::V8WrapperType type = V8DOMWrapper::domWrapperType(wrapper);
- switch (type) {
-#define MAKE_CASE(TYPE, NAME) case V8ClassIndex::TYPE: break;
- ACTIVE_DOM_OBJECT_TYPES(MAKE_CASE)
- default:
- ASSERT_NOT_REACHED();
-#undef MAKE_CASE
- }
-#endif
+ ASSERT(domWrapperType(wrapper)->toActiveDOMObjectFunction);
getActiveDOMObjectMap().set(object, wrapper);
}
@@ -167,7 +115,7 @@ void V8DOMWrapper::setJSWrapperForDOMNode(Node* node, v8::Persistent<v8::Object>
getDOMNodeMap().set(node, wrapper);
}
-v8::Local<v8::Function> V8DOMWrapper::getConstructor(V8ClassIndex::V8WrapperType type, v8::Handle<v8::Value> objectPrototype)
+v8::Local<v8::Function> V8DOMWrapper::getConstructor(WrapperTypeInfo* type, v8::Handle<v8::Value> objectPrototype)
{
// A DOM constructor is a function instance created from a DOM constructor
// template. There is one instance per context. A DOM constructor is
@@ -178,7 +126,7 @@ v8::Local<v8::Function> V8DOMWrapper::getConstructor(V8ClassIndex::V8WrapperType
// The reason for 2) is that, in Safari, a DOM constructor is a normal JS
// object, but not a function. Hotmail relies on the fact that, in Safari,
// HTMLElement.__proto__ == Object.prototype.
- v8::Handle<v8::FunctionTemplate> functionTemplate = V8ClassIndex::getTemplate(type);
+ v8::Handle<v8::FunctionTemplate> functionTemplate = type->getTemplate();
// Getting the function might fail if we're running out of
// stack or memory.
v8::TryCatch tryCatch;
@@ -187,11 +135,11 @@ v8::Local<v8::Function> V8DOMWrapper::getConstructor(V8ClassIndex::V8WrapperType
return v8::Local<v8::Function>();
// Hotmail fix, see comments above.
if (!objectPrototype.IsEmpty())
- value->Set(v8::String::New("__proto__"), objectPrototype);
+ value->SetPrototype(objectPrototype);
return value;
}
-v8::Local<v8::Function> V8DOMWrapper::getConstructorForContext(V8ClassIndex::V8WrapperType type, v8::Handle<v8::Context> context)
+v8::Local<v8::Function> V8DOMWrapper::getConstructorForContext(WrapperTypeInfo* type, v8::Handle<v8::Context> context)
{
// Enter the scope for this context to get the correct constructor.
v8::Context::Scope scope(context);
@@ -199,7 +147,7 @@ v8::Local<v8::Function> V8DOMWrapper::getConstructorForContext(V8ClassIndex::V8W
return getConstructor(type, V8DOMWindowShell::getHiddenObjectPrototype(context));
}
-v8::Local<v8::Function> V8DOMWrapper::getConstructor(V8ClassIndex::V8WrapperType type, DOMWindow* window)
+v8::Local<v8::Function> V8DOMWrapper::getConstructor(WrapperTypeInfo* type, DOMWindow* window)
{
Frame* frame = window->frame();
if (!frame)
@@ -213,9 +161,14 @@ v8::Local<v8::Function> V8DOMWrapper::getConstructor(V8ClassIndex::V8WrapperType
}
#if ENABLE(WORKERS)
+<<<<<<< HEAD
v8::Local<v8::Function> V8DOMWrapper::getConstructor(V8ClassIndex::V8WrapperType type, WorkerContext*)
+=======
+v8::Local<v8::Function> V8DOMWrapper::getConstructor(WrapperTypeInfo* type, WorkerContext*)
+>>>>>>> webkit.org at r58033
{
- WorkerContextExecutionProxy* proxy = WorkerContextExecutionProxy::retrieve();
+ WorkerScriptController* controller = WorkerScriptController::controllerForContext();
+ WorkerContextExecutionProxy* proxy = controller ? controller->proxy() : 0;
if (!proxy)
return v8::Local<v8::Function>();
@@ -226,8 +179,22 @@ v8::Local<v8::Function> V8DOMWrapper::getConstructor(V8ClassIndex::V8WrapperType
return getConstructorForContext(type, context);
}
#endif
+<<<<<<< HEAD
+=======
-void V8DOMWrapper::setHiddenWindowReference(Frame* frame, const int internalIndex, v8::Handle<v8::Object> jsObject)
+void V8DOMWrapper::setHiddenReference(v8::Handle<v8::Object> parent, v8::Handle<v8::Value> child)
+{
+ v8::Local<v8::Value> hiddenReferenceObject = parent->GetInternalField(v8DOMHiddenReferenceArrayIndex);
+ if (hiddenReferenceObject->IsNull() || hiddenReferenceObject->IsUndefined()) {
+ hiddenReferenceObject = v8::Array::New();
+ parent->SetInternalField(v8DOMHiddenReferenceArrayIndex, hiddenReferenceObject);
+ }
+ v8::Local<v8::Array> hiddenReferenceArray = v8::Local<v8::Array>::Cast(hiddenReferenceObject);
+ hiddenReferenceArray->Set(v8::Integer::New(hiddenReferenceArray->Length()), child);
+}
+>>>>>>> webkit.org at r58033
+
+void V8DOMWrapper::setHiddenWindowReference(Frame* frame, v8::Handle<v8::Value> jsObject)
{
// Get DOMWindow
if (!frame)
@@ -236,21 +203,18 @@ void V8DOMWrapper::setHiddenWindowReference(Frame* frame, const int internalInde
if (context.IsEmpty())
return;
- ASSERT(internalIndex < V8DOMWindow::internalFieldCount);
-
v8::Handle<v8::Object> global = context->Global();
// Look for real DOM wrapper.
global = V8DOMWrapper::lookupDOMWrapper(V8DOMWindow::GetTemplate(), global);
ASSERT(!global.IsEmpty());
- ASSERT(global->GetInternalField(internalIndex)->IsUndefined());
- global->SetInternalField(internalIndex, jsObject);
+
+ setHiddenReference(global, jsObject);
}
-V8ClassIndex::V8WrapperType V8DOMWrapper::domWrapperType(v8::Handle<v8::Object> object)
+WrapperTypeInfo* V8DOMWrapper::domWrapperType(v8::Handle<v8::Object> object)
{
ASSERT(V8DOMWrapper::maybeDOMWrapper(object));
- v8::Handle<v8::Value> type = object->GetInternalField(v8DOMWrapperTypeIndex);
- return V8ClassIndex::FromInt(type->Int32Value());
+ return static_cast<WrapperTypeInfo*>(object->GetPointerFromInternalField(v8DOMWrapperTypeIndex));
}
PassRefPtr<NodeFilter> V8DOMWrapper::wrapNativeNodeFilter(v8::Handle<v8::Value> filter)
@@ -275,15 +239,24 @@ static bool globalObjectPrototypeIsDOMWindow(v8::Handle<v8::Object> objectProtot
#if ENABLE(SHARED_WORKERS)
// We can identify what type of context the global object is wrapping by looking at the
// internal field count of its prototype. This assumes WorkerContexts and DOMWindows have different numbers
- // of internal fields, so a COMPILE_ASSERT is included to warn if this ever changes. DOMWindow has
- // traditionally had far more internal fields than any other class.
- COMPILE_ASSERT(V8DOMWindow::internalFieldCount != V8WorkerContext::internalFieldCount && V8DOMWindow::internalFieldCount != V8SharedWorkerContext::internalFieldCount,
+ // of internal fields, so a COMPILE_ASSERT is included to warn if this ever changes.
+#if ENABLE(WORKERS)
+ COMPILE_ASSERT(V8DOMWindow::internalFieldCount != V8WorkerContext::internalFieldCount,
DOMWindowAndWorkerContextHaveUnequalFieldCounts);
+<<<<<<< HEAD
+=======
+ COMPILE_ASSERT(V8DOMWindow::internalFieldCount != V8DedicatedWorkerContext::internalFieldCount,
+ DOMWindowAndDedicatedWorkerContextHaveUnequalFieldCounts);
+#endif
+#if ENABLE(SHARED_WORKERS)
+ COMPILE_ASSERT(V8DOMWindow::internalFieldCount != V8SharedWorkerContext::internalFieldCount,
+ DOMWindowAndSharedWorkerContextHaveUnequalFieldCounts);
+>>>>>>> webkit.org at r58033
#endif
return objectPrototype->InternalFieldCount() == V8DOMWindow::internalFieldCount;
}
-v8::Local<v8::Object> V8DOMWrapper::instantiateV8Object(V8Proxy* proxy, V8ClassIndex::V8WrapperType type, void* impl)
+v8::Local<v8::Object> V8DOMWrapper::instantiateV8Object(V8Proxy* proxy, WrapperTypeInfo* type, void* impl)
{
WorkerContext* workerContext = 0;
if (V8IsolatedContext::getEntered()) {
@@ -316,12 +289,16 @@ v8::Local<v8::Object> V8DOMWrapper::instantiateV8Object(V8Proxy* proxy, V8ClassI
function = getConstructor(type, workerContext);
else
#endif
+<<<<<<< HEAD
function = V8ClassIndex::getTemplate(type)->GetFunction();
+=======
+ function = type->getTemplate()->GetFunction();
+>>>>>>> webkit.org at r58033
instance = SafeAllocation::newInstance(function);
}
if (!instance.IsEmpty()) {
// Avoid setting the DOM wrapper for failed allocations.
- setDOMWrapper(instance, V8ClassIndex::ToInt(type), impl);
+ setDOMWrapper(instance, type, impl);
}
return instance;
}
@@ -338,10 +315,6 @@ bool V8DOMWrapper::maybeDOMWrapper(v8::Handle<v8::Value> value)
ASSERT(object->InternalFieldCount() >= v8DefaultWrapperInternalFieldCount);
- v8::Handle<v8::Value> type = object->GetInternalField(v8DOMWrapperTypeIndex);
- ASSERT(type->IsInt32());
- ASSERT(V8ClassIndex::INVALID_CLASS_INDEX < type->Int32Value() && type->Int32Value() < V8ClassIndex::CLASSINDEX_END);
-
v8::Handle<v8::Value> wrapper = object->GetInternalField(v8DOMWrapperObjectIndex);
ASSERT(wrapper->IsNumber() || wrapper->IsExternal());
@@ -356,7 +329,7 @@ bool V8DOMWrapper::isValidDOMObject(v8::Handle<v8::Value> value)
return v8::Handle<v8::Object>::Cast(value)->InternalFieldCount();
}
-bool V8DOMWrapper::isWrapperOfType(v8::Handle<v8::Value> value, V8ClassIndex::V8WrapperType classType)
+bool V8DOMWrapper::isWrapperOfType(v8::Handle<v8::Value> value, WrapperTypeInfo* type)
{
if (!isValidDOMObject(value))
return false;
@@ -367,11 +340,8 @@ bool V8DOMWrapper::isWrapperOfType(v8::Handle<v8::Value> value, V8ClassIndex::V8
v8::Handle<v8::Value> wrapper = object->GetInternalField(v8DOMWrapperObjectIndex);
ASSERT(wrapper->IsNumber() || wrapper->IsExternal());
- v8::Handle<v8::Value> type = object->GetInternalField(v8DOMWrapperTypeIndex);
- ASSERT(type->IsInt32());
- ASSERT(V8ClassIndex::INVALID_CLASS_INDEX < type->Int32Value() && type->Int32Value() < V8ClassIndex::CLASSINDEX_END);
-
- return V8ClassIndex::FromInt(type->Int32Value()) == classType;
+ WrapperTypeInfo* typeInfo = static_cast<WrapperTypeInfo*>(object->GetPointerFromInternalField(v8DOMWrapperTypeIndex));
+ return typeInfo == type;
}
v8::Handle<v8::Object> V8DOMWrapper::getWrapper(Node* node)
@@ -440,9 +410,6 @@ v8::Handle<v8::Value> V8DOMWrapper::convertEventTargetToV8Object(EventTarget* ta
return wrapper;
}
- if (XMLHttpRequest* xhr = target->toXMLHttpRequest())
- return toV8(xhr);
-
// MessagePort is created within its JS counterpart
if (MessagePort* port = target->toMessagePort()) {
v8::Handle<v8::Object> wrapper = getActiveDOMObjectMap().get(port);
@@ -470,6 +437,7 @@ v8::Handle<v8::Value> V8DOMWrapper::convertEventTargetToV8Object(EventTarget* ta
return notHandledByInterceptor();
}
+<<<<<<< HEAD
PassRefPtr<EventListener> V8DOMWrapper::getEventListener(Node* node, v8::Local<v8::Value> value, bool isAttribute, ListenerLookupType lookup)
{
return (lookup == ListenerFindOnly) ? V8EventListenerList::findWrapper(value, isAttribute) : V8EventListenerList::findOrCreateWrapper<V8EventListener>(value, isAttribute);
@@ -530,37 +498,23 @@ PassRefPtr<EventListener> V8DOMWrapper::getEventListener(XMLHttpRequestUpload* u
#if ENABLE(EVENTSOURCE)
PassRefPtr<EventListener> V8DOMWrapper::getEventListener(EventSource* eventSource, v8::Local<v8::Value> value, bool isAttribute, ListenerLookupType lookup)
+=======
+PassRefPtr<EventListener> V8DOMWrapper::getEventListener(v8::Local<v8::Value> value, bool isAttribute, ListenerLookupType lookup)
+>>>>>>> webkit.org at r58033
{
- if (V8Proxy::retrieve(eventSource->scriptExecutionContext()))
- return (lookup == ListenerFindOnly) ? V8EventListenerList::findWrapper(value, isAttribute) : V8EventListenerList::findOrCreateWrapper<V8EventListener>(value, isAttribute);
-
+ v8::Handle<v8::Context> context = v8::Context::GetCurrent();
+ if (context.IsEmpty())
+ return 0;
+ if (lookup == ListenerFindOnly)
+ return V8EventListenerList::findWrapper(value, isAttribute);
+ v8::Handle<v8::Object> globalPrototype = v8::Handle<v8::Object>::Cast(context->Global()->GetPrototype());
+ if (globalObjectPrototypeIsDOMWindow(globalPrototype))
+ return V8EventListenerList::findOrCreateWrapper<V8EventListener>(value, isAttribute);
#if ENABLE(WORKERS)
- WorkerContextExecutionProxy* workerContextProxy = WorkerContextExecutionProxy::retrieve();
- if (workerContextProxy)
- return workerContextProxy->findOrCreateEventListener(value, isAttribute, lookup == ListenerFindOnly);
-#endif
-
+ return V8EventListenerList::findOrCreateWrapper<V8WorkerContextEventListener>(value, isAttribute);
+#else
return 0;
-}
#endif
-
-PassRefPtr<EventListener> V8DOMWrapper::getEventListener(EventTarget* eventTarget, v8::Local<v8::Value> value, bool isAttribute, ListenerLookupType lookup)
-{
- if (V8Proxy::retrieve(eventTarget->scriptExecutionContext()))
- return (lookup == ListenerFindOnly) ? V8EventListenerList::findWrapper(value, isAttribute) : V8EventListenerList::findOrCreateWrapper<V8EventListener>(value, isAttribute);
-
-#if ENABLE(WORKERS)
- WorkerContextExecutionProxy* workerContextProxy = WorkerContextExecutionProxy::retrieve();
- if (workerContextProxy)
- return workerContextProxy->findOrCreateEventListener(value, isAttribute, lookup == ListenerFindOnly);
-#endif
-
- return 0;
-}
-
-PassRefPtr<EventListener> V8DOMWrapper::getEventListener(V8Proxy* proxy, v8::Local<v8::Value> value, bool isAttribute, ListenerLookupType lookup)
-{
- return (lookup == ListenerFindOnly) ? V8EventListenerList::findWrapper(value, isAttribute) : V8EventListenerList::findOrCreateWrapper<V8EventListener>(value, isAttribute);
}
} // namespace WebCore
diff --git a/WebCore/bindings/v8/V8DOMWrapper.h b/WebCore/bindings/v8/V8DOMWrapper.h
index 8a3fa3f..97e269a 100644
--- a/WebCore/bindings/v8/V8DOMWrapper.h
+++ b/WebCore/bindings/v8/V8DOMWrapper.h
@@ -39,62 +39,19 @@
#include "V8CustomXPathNSResolver.h"
#include "V8DOMMap.h"
#include "V8Event.h"
-#include "V8Index.h"
#include "V8Utilities.h"
#include "V8XPathNSResolver.h"
+#include "WrapperTypeInfo.h"
#include "XPathNSResolver.h"
#include <v8.h>
namespace WebCore {
- // FIXME: This probably aren't all needed.
- class CSSRule;
- class CSSRuleList;
- class CSSStyleDeclaration;
- class CSSValue;
- class CSSValueList;
- class ClientRectList;
- class DOMImplementation;
class DOMWindow;
- class Document;
- class Element;
- class Event;
- class EventListener;
class EventTarget;
class Frame;
- class HTMLCollection;
- class HTMLDocument;
- class HTMLElement;
- class HTMLOptionsCollection;
- class MediaList;
- class MimeType;
- class MimeTypeArray;
- class NamedNodeMap;
- class Navigator;
class Node;
- class NodeFilter;
- class NodeList;
- class Plugin;
- class PluginArray;
- class SVGElement;
-#if ENABLE(SVG)
- class SVGElementInstance;
-#endif
- class Screen;
- class ScriptExecutionContext;
-#if ENABLE(DOM_STORAGE)
- class Storage;
- class StorageEvent;
-#endif
- class String;
- class StyleSheet;
- class StyleSheetList;
- class V8EventListener;
- class V8ObjectEventListener;
class V8Proxy;
-#if ENABLE(WEB_SOCKETS)
- class WebSocket;
-#endif
class WorkerContext;
enum ListenerLookupType {
@@ -110,11 +67,11 @@ namespace WebCore {
#endif
// Sets contents of a DOM wrapper.
- static void setDOMWrapper(v8::Handle<v8::Object> object, int type, void* cptr)
+ static void setDOMWrapper(v8::Handle<v8::Object> object, WrapperTypeInfo* type, void* cptr)
{
ASSERT(object->InternalFieldCount() >= 2);
object->SetPointerInInternalField(v8DOMWrapperObjectIndex, cptr);
- object->SetInternalField(v8DOMWrapperTypeIndex, v8::Integer::New(type));
+ object->SetPointerInInternalField(v8DOMWrapperTypeIndex, type);
}
static v8::Handle<v8::Object> lookupDOMWrapper(v8::Handle<v8::FunctionTemplate> functionTemplate, v8::Handle<v8::Object> object)
@@ -122,7 +79,7 @@ namespace WebCore {
return object.IsEmpty() ? object : object->FindInstanceInPrototypeChain(functionTemplate);
}
- static V8ClassIndex::V8WrapperType domWrapperType(v8::Handle<v8::Object>);
+ static WrapperTypeInfo* domWrapperType(v8::Handle<v8::Object>);
static v8::Handle<v8::Value> convertEventTargetToV8Object(PassRefPtr<EventTarget> eventTarget)
{
@@ -131,27 +88,7 @@ namespace WebCore {
static v8::Handle<v8::Value> convertEventTargetToV8Object(EventTarget*);
- static PassRefPtr<EventListener> getEventListener(Node* node, v8::Local<v8::Value> value, bool isAttribute, ListenerLookupType lookup);
-
- static PassRefPtr<EventListener> getEventListener(SVGElementInstance* element, v8::Local<v8::Value> value, bool isAttribute, ListenerLookupType lookup);
-
- static PassRefPtr<EventListener> getEventListener(AbstractWorker* worker, v8::Local<v8::Value> value, bool isAttribute, ListenerLookupType lookup);
-
-#if ENABLE(NOTIFICATIONS)
- static PassRefPtr<EventListener> getEventListener(Notification* notification, v8::Local<v8::Value> value, bool isAttribute, ListenerLookupType lookup);
-#endif
-
- static PassRefPtr<EventListener> getEventListener(WorkerContext* workerContext, v8::Local<v8::Value> value, bool isAttribute, ListenerLookupType lookup);
-
- static PassRefPtr<EventListener> getEventListener(XMLHttpRequestUpload* upload, v8::Local<v8::Value> value, bool isAttribute, ListenerLookupType lookup);
-
-#if ENABLE(EVENTSOURCE)
- static PassRefPtr<EventListener> getEventListener(EventSource* eventTarget, v8::Local<v8::Value> value, bool isAttribute, ListenerLookupType lookup);
-#endif
-
- static PassRefPtr<EventListener> getEventListener(EventTarget* eventTarget, v8::Local<v8::Value> value, bool isAttribute, ListenerLookupType lookup);
-
- static PassRefPtr<EventListener> getEventListener(V8Proxy* proxy, v8::Local<v8::Value> value, bool isAttribute, ListenerLookupType lookup);
+ static PassRefPtr<EventListener> getEventListener(v8::Local<v8::Value> value, bool isAttribute, ListenerLookupType lookup);
#if ENABLE(XPATH)
// XPath-related utilities
@@ -161,7 +98,7 @@ namespace WebCore {
if (V8XPathNSResolver::HasInstance(value))
resolver = V8XPathNSResolver::toNative(v8::Handle<v8::Object>::Cast(value));
else if (value->IsObject())
- resolver = V8CustomXPathNSResolver::create(proxy, value->ToObject());
+ resolver = V8CustomXPathNSResolver::create(value->ToObject());
return resolver;
}
#endif
@@ -169,10 +106,12 @@ namespace WebCore {
// Wrap JS node filter in C++.
static PassRefPtr<NodeFilter> wrapNativeNodeFilter(v8::Handle<v8::Value>);
- static v8::Local<v8::Function> getConstructorForContext(V8ClassIndex::V8WrapperType, v8::Handle<v8::Context>);
- static v8::Local<v8::Function> getConstructor(V8ClassIndex::V8WrapperType, v8::Handle<v8::Value> objectPrototype);
- static v8::Local<v8::Function> getConstructor(V8ClassIndex::V8WrapperType, DOMWindow*);
- static v8::Local<v8::Function> getConstructor(V8ClassIndex::V8WrapperType, WorkerContext*);
+ static v8::Local<v8::Function> getConstructorForContext(WrapperTypeInfo*, v8::Handle<v8::Context>);
+ static v8::Local<v8::Function> getConstructor(WrapperTypeInfo*, v8::Handle<v8::Value> objectPrototype);
+ static v8::Local<v8::Function> getConstructor(WrapperTypeInfo*, DOMWindow*);
+#if ENABLE(WORKERS)
+ static v8::Local<v8::Function> getConstructor(WrapperTypeInfo*, WorkerContext*);
+#endif
// Set JS wrapper of a DOM object, the caller in charge of increase ref.
static void setJSWrapperForDOMObject(void*, v8::Persistent<v8::Object>);
@@ -182,18 +121,14 @@ namespace WebCore {
static bool isValidDOMObject(v8::Handle<v8::Value>);
// Check whether a V8 value is a wrapper of type |classType|.
- static bool isWrapperOfType(v8::Handle<v8::Value>, V8ClassIndex::V8WrapperType);
+ static bool isWrapperOfType(v8::Handle<v8::Value>, WrapperTypeInfo*);
+
+ static void setHiddenReference(v8::Handle<v8::Object> parent, v8::Handle<v8::Value> child);
-#if ENABLE(3D_CANVAS)
- static void setIndexedPropertiesToExternalArray(v8::Handle<v8::Object>,
- int,
- void*,
- int);
-#endif
// Set hidden references in a DOMWindow object of a frame.
- static void setHiddenWindowReference(Frame*, const int internalIndex, v8::Handle<v8::Object>);
+ static void setHiddenWindowReference(Frame*, v8::Handle<v8::Value>);
- static v8::Local<v8::Object> instantiateV8Object(V8Proxy* proxy, V8ClassIndex::V8WrapperType type, void* impl);
+ static v8::Local<v8::Object> instantiateV8Object(V8Proxy* proxy, WrapperTypeInfo*, void* impl);
static v8::Handle<v8::Object> getWrapper(Node*);
};
diff --git a/WebCore/bindings/v8/V8GCController.cpp b/WebCore/bindings/v8/V8GCController.cpp
index b478636..61b2a88 100644
--- a/WebCore/bindings/v8/V8GCController.cpp
+++ b/WebCore/bindings/v8/V8GCController.cpp
@@ -31,11 +31,18 @@
#include "config.h"
#include "V8GCController.h"
+#include "ActiveDOMObject.h"
+#include "Attr.h"
#include "DOMDataStore.h"
-#include "DOMObjectsInclude.h"
+#include "Frame.h"
+#include "HTMLImageElement.h"
+#include "HTMLNames.h"
+#include "MessagePort.h"
+#include "SVGElement.h"
#include "V8DOMMap.h"
-#include "V8Index.h"
+#include "V8MessagePort.h"
#include "V8Proxy.h"
+#include "WrapperTypeInfo.h"
#include <algorithm>
#include <utility>
@@ -112,7 +119,7 @@ static void enumerateDOMObjectMap(DOMObjectMap& wrapperMap)
{
for (DOMObjectMap::iterator it = wrapperMap.begin(), end = wrapperMap.end(); it != end; ++it) {
v8::Persistent<v8::Object> wrapper(it->second);
- V8ClassIndex::V8WrapperType type = V8DOMWrapper::domWrapperType(wrapper);
+ WrapperTypeInfo* type = V8DOMWrapper::domWrapperType(wrapper);
void* object = it->first;
UNUSED_PARAM(type);
UNUSED_PARAM(object);
@@ -123,7 +130,7 @@ class DOMObjectVisitor : public DOMWrapperMap<void>::Visitor {
public:
void visitDOMWrapper(void* object, v8::Persistent<v8::Object> wrapper)
{
- V8ClassIndex::V8WrapperType type = V8DOMWrapper::domWrapperType(wrapper);
+ WrapperTypeInfo* type = V8DOMWrapper::domWrapperType(wrapper);
UNUSED_PARAM(type);
UNUSED_PARAM(object);
}
@@ -181,36 +188,26 @@ class GCPrologueVisitor : public DOMWrapperMap<void>::Visitor {
public:
void visitDOMWrapper(void* object, v8::Persistent<v8::Object> wrapper)
{
- ASSERT(wrapper.IsWeak());
- V8ClassIndex::V8WrapperType type = V8DOMWrapper::domWrapperType(wrapper);
- switch (type) {
-#define MAKE_CASE(TYPE, NAME) \
- case V8ClassIndex::TYPE: { \
- NAME* impl = static_cast<NAME*>(object); \
- if (impl->hasPendingActivity()) \
- wrapper.ClearWeak(); \
- break; \
- }
- ACTIVE_DOM_OBJECT_TYPES(MAKE_CASE)
- default:
- ASSERT_NOT_REACHED();
-#undef MAKE_CASE
+ WrapperTypeInfo* typeInfo = V8DOMWrapper::domWrapperType(wrapper);
+
+ // Additional handling of message port ensuring that entangled ports also
+ // have their wrappers entangled. This should ideally be handled when the
+ // ports are actually entangled in MessagePort::entangle, but to avoid
+ // forking MessagePort.* this is postponed to GC time. Having this postponed
+ // has the drawback that the wrappers are "entangled/unentangled" for each
+ // GC even though their entaglement most likely is still the same.
+ if (V8MessagePort::info.equals(typeInfo)) {
+ // 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);
+ if (port1->isEntangled() || port1->hasPendingActivity())
+ wrapper.ClearWeak();
+ } else {
+ ActiveDOMObject* activeDOMObject = typeInfo->toActiveDOMObject(wrapper);
+ if (activeDOMObject && activeDOMObject->hasPendingActivity())
+ wrapper.ClearWeak();
}
-
- // Additional handling of message port ensuring that entangled ports also
- // have their wrappers entangled. This should ideally be handled when the
- // ports are actually entangled in MessagePort::entangle, but to avoid
- // forking MessagePort.* this is postponed to GC time. Having this postponed
- // 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) {
- // 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);
- if (port1->isEntangled())
- wrapper.ClearWeak();
}
-}
};
class GrouperItem {
@@ -369,30 +366,20 @@ class GCEpilogueVisitor : public DOMWrapperMap<void>::Visitor {
public:
void visitDOMWrapper(void* object, v8::Persistent<v8::Object> wrapper)
{
- V8ClassIndex::V8WrapperType type = V8DOMWrapper::domWrapperType(wrapper);
- switch (type) {
-#define MAKE_CASE(TYPE, NAME) \
- case V8ClassIndex::TYPE: { \
- NAME* impl = static_cast<NAME*>(object); \
- if (impl->hasPendingActivity()) { \
- ASSERT(!wrapper.IsWeak()); \
- wrapper.MakeWeak(impl, &DOMDataStore::weakActiveDOMObjectCallback); \
- } \
- break; \
- }
-ACTIVE_DOM_OBJECT_TYPES(MAKE_CASE)
- default:
- ASSERT_NOT_REACHED();
-#undef MAKE_CASE
- }
-
- if (type == V8ClassIndex::MESSAGEPORT) {
+ WrapperTypeInfo* typeInfo = V8DOMWrapper::domWrapperType(wrapper);
+ if (V8MessagePort::info.equals(typeInfo)) {
MessagePort* port1 = static_cast<MessagePort*>(object);
// 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())
+ if ((!wrapper.IsWeak() && !wrapper.IsNearDeath()) || port1->hasPendingActivity())
wrapper.MakeWeak(port1, &DOMDataStore::weakActiveDOMObjectCallback);
+ } else {
+ ActiveDOMObject* activeDOMObject = typeInfo->toActiveDOMObject(wrapper);
+ if (activeDOMObject && activeDOMObject->hasPendingActivity()) {
+ ASSERT(!wrapper.IsWeak());
+ wrapper.MakeWeak(activeDOMObject, &DOMDataStore::weakActiveDOMObjectCallback);
+ }
}
}
};
diff --git a/WebCore/bindings/v8/V8GCForContextDispose.cpp b/WebCore/bindings/v8/V8GCForContextDispose.cpp
new file mode 100644
index 0000000..06a0555
--- /dev/null
+++ b/WebCore/bindings/v8/V8GCForContextDispose.cpp
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "V8GCForContextDispose.h"
+
+#include <wtf/StdLibExtras.h>
+
+namespace WebCore {
+
+V8GCForContextDispose::V8GCForContextDispose()
+ : m_pseudoIdleTimer(this, &V8GCForContextDispose::pseudoIdleTimerFired)
+{
+}
+
+void V8GCForContextDispose::notifyContextDisposed()
+{
+ v8::V8::ContextDisposedNotification();
+ if (!m_pseudoIdleTimer.isActive())
+ m_pseudoIdleTimer.startOneShot(0.8);
+}
+
+void V8GCForContextDispose::notifyIdleSooner(double maximumFireInterval)
+{
+ if (m_pseudoIdleTimer.isActive()) {
+ double nextFireInterval = m_pseudoIdleTimer.nextFireInterval();
+ if (nextFireInterval > maximumFireInterval) {
+ m_pseudoIdleTimer.stop();
+ m_pseudoIdleTimer.startOneShot(maximumFireInterval);
+ }
+ }
+}
+
+V8GCForContextDispose& V8GCForContextDispose::instance()
+{
+ DEFINE_STATIC_LOCAL(V8GCForContextDispose, staticInstance, ());
+ return staticInstance;
+}
+
+void V8GCForContextDispose::pseudoIdleTimerFired(Timer<V8GCForContextDispose>*)
+{
+ v8::V8::IdleNotification();
+}
+
+} // namespace WebCore
diff --git a/WebCore/bindings/v8/V8GCForContextDispose.h b/WebCore/bindings/v8/V8GCForContextDispose.h
new file mode 100644
index 0000000..b15c5af
--- /dev/null
+++ b/WebCore/bindings/v8/V8GCForContextDispose.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef V8GCForContextDispose_h
+#define V8GCForContextDispose_h
+
+#include "Timer.h"
+#include <v8.h>
+
+namespace WebCore {
+
+class V8GCForContextDispose {
+public:
+ void notifyContextDisposed();
+ void notifyIdleSooner(double maximumFireInterval);
+
+ static V8GCForContextDispose& instance();
+
+private:
+ V8GCForContextDispose(); // Use instance() instead.
+ void pseudoIdleTimerFired(Timer<V8GCForContextDispose>*);
+
+ Timer<V8GCForContextDispose> m_pseudoIdleTimer;
+};
+
+}
+
+#endif // V8GCForContextDispose_h
diff --git a/WebCore/bindings/v8/V8Helpers.cpp b/WebCore/bindings/v8/V8Helpers.cpp
index a690017..486bc48 100644
--- a/WebCore/bindings/v8/V8Helpers.cpp
+++ b/WebCore/bindings/v8/V8Helpers.cpp
@@ -33,16 +33,10 @@
#include "DOMWindow.h"
#include "NPV8Object.h"
-#include "V8Index.h"
#include "V8Proxy.h"
namespace WebCore {
-void wrapNPObject(v8::Handle<v8::Object> object, NPObject* npObject)
-{
- V8DOMWrapper::setDOMWrapper(object, V8ClassIndex::NPOBJECT, npObject);
-}
-
v8::Local<v8::Context> toV8Context(NPP npp, NPObject* npObject)
{
V8NPObject* object = reinterpret_cast<V8NPObject*>(npObject);
diff --git a/WebCore/bindings/v8/V8Helpers.h b/WebCore/bindings/v8/V8Helpers.h
index 469833e..e90f5d6 100644
--- a/WebCore/bindings/v8/V8Helpers.h
+++ b/WebCore/bindings/v8/V8Helpers.h
@@ -37,9 +37,6 @@
namespace WebCore {
class V8Proxy;
- // Associates an NPObject with a V8 object.
- void wrapNPObject(v8::Handle<v8::Object>, NPObject*);
-
v8::Local<v8::Context> toV8Context(NPP, NPObject*);
V8Proxy* toV8Proxy(NPObject*);
diff --git a/WebCore/bindings/v8/V8IsolatedContext.h b/WebCore/bindings/v8/V8IsolatedContext.h
index 70ca270..5cd9c65 100644
--- a/WebCore/bindings/v8/V8IsolatedContext.h
+++ b/WebCore/bindings/v8/V8IsolatedContext.h
@@ -34,7 +34,6 @@
#include "IsolatedWorld.h"
#include "ScriptSourceCode.h" // for WebCore::ScriptSourceCode
#include "V8DOMWindow.h"
-#include "V8Index.h"
#include "V8Proxy.h"
#include "V8Utilities.h"
#include <v8.h>
diff --git a/WebCore/bindings/v8/V8LazyEventListener.h b/WebCore/bindings/v8/V8LazyEventListener.h
index 078dcf1..f174d23 100644
--- a/WebCore/bindings/v8/V8LazyEventListener.h
+++ b/WebCore/bindings/v8/V8LazyEventListener.h
@@ -60,6 +60,12 @@ namespace WebCore {
virtual v8::Local<v8::Value> callListenerFunction(ScriptExecutionContext*, v8::Handle<v8::Value> jsEvent, Event*);
+ // Needs to return true for all event handlers implemented in JavaScript so that
+ // the SVG code does not add the event handler in both
+ // SVGUseElement::buildShadowTree and again in
+ // SVGUseElement::transferEventListenersToShadowTree
+ virtual bool wasCreatedFromMarkup() const { return true; }
+
String m_functionName;
bool m_isSVGEvent;
String m_code;
diff --git a/WebCore/bindings/v8/V8NPObject.cpp b/WebCore/bindings/v8/V8NPObject.cpp
index b873d5f..1ea6487 100644
--- a/WebCore/bindings/v8/V8NPObject.cpp
+++ b/WebCore/bindings/v8/V8NPObject.cpp
@@ -375,7 +375,7 @@ v8::Local<v8::Object> createV8ObjectForNPObject(NPObject* object, NPObject* root
if (value.IsEmpty())
return value;
- wrapNPObject(value, object);
+ V8DOMWrapper::setDOMWrapper(value, npObjectTypeInfo(), object);
// KJS retains the object as part of its wrapper (see Bindings::CInstance).
_NPN_RetainObject(object);
@@ -394,7 +394,7 @@ void forgetV8ObjectForNPObject(NPObject* object)
if (staticNPObjectMap.contains(object)) {
v8::HandleScope scope;
v8::Persistent<v8::Object> handle(staticNPObjectMap.get(object));
- V8DOMWrapper::setDOMWrapper(handle, WebCore::V8ClassIndex::NPOBJECT, 0);
+ V8DOMWrapper::setDOMWrapper(handle, npObjectTypeInfo(), 0);
staticNPObjectMap.forget(object);
_NPN_ReleaseObject(object);
}
diff --git a/WebCore/bindings/v8/V8NodeFilterCondition.cpp b/WebCore/bindings/v8/V8NodeFilterCondition.cpp
index a8868b5..2170698 100644
--- a/WebCore/bindings/v8/V8NodeFilterCondition.cpp
+++ b/WebCore/bindings/v8/V8NodeFilterCondition.cpp
@@ -72,10 +72,7 @@ short V8NodeFilterCondition::acceptNode(ScriptState* state, Node* node) const
OwnArrayPtr<v8::Handle<v8::Value> > args(new v8::Handle<v8::Value>[1]);
args[0] = toV8(node);
- V8Proxy* proxy = V8Proxy::retrieve();
- ASSERT(proxy);
-
- v8::Handle<v8::Value> result = proxy->callFunction(callback, object, 1, args.get());
+ v8::Handle<v8::Value> result = V8Proxy::callFunctionWithoutFrame(callback, object, 1, args.get());
if (exceptionCatcher.HasCaught()) {
state->setException(exceptionCatcher.Exception());
diff --git a/WebCore/bindings/v8/V8Proxy.cpp b/WebCore/bindings/v8/V8Proxy.cpp
index 85db554..878b86a 100644
--- a/WebCore/bindings/v8/V8Proxy.cpp
+++ b/WebCore/bindings/v8/V8Proxy.cpp
@@ -33,14 +33,16 @@
#include "CSSMutableStyleDeclaration.h"
#include "DateExtension.h"
-#include "DOMObjectsInclude.h"
#include "DocumentLoader.h"
+#include "Frame.h"
#include "FrameLoaderClient.h"
#include "InspectorTimelineAgent.h"
#include "Page.h"
#include "PageGroup.h"
#include "PlatformBridge.h"
+#include "SVGElement.h"
#include "ScriptController.h"
+#include "Settings.h"
#include "StorageNamespace.h"
#include "V8Binding.h"
#include "V8BindingState.h"
@@ -51,19 +53,21 @@
#include "V8DOMWindow.h"
#include "V8EventException.h"
#include "V8HiddenPropertyName.h"
-#include "V8Index.h"
#include "V8IsolatedContext.h"
#include "V8RangeException.h"
-#include "V8SVGException.h"
#include "V8XMLHttpRequestException.h"
#include "V8XPathException.h"
+#include "WorkerContext.h"
#include "WorkerContextExecutionProxy.h"
+#if ENABLE(SVG)
+#include "V8SVGException.h"
+#endif
+
#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>
@@ -80,8 +84,6 @@
namespace WebCore {
-v8::Persistent<v8::Context> V8Proxy::m_utilityContext;
-
// Static list of registered extensions
V8Extensions V8Proxy::m_extensions;
@@ -501,9 +503,32 @@ v8::Local<v8::Value> V8Proxy::callFunction(v8::Handle<v8::Function> function, v8
// execution finishs before firing the timer.
m_frame->keepAlive();
+#if ENABLE(INSPECTOR)
+ Page* inspectedPage = InspectorTimelineAgent::instanceCount() ? m_frame->page(): 0;
+ if (inspectedPage)
+ if (InspectorTimelineAgent* timelineAgent = inspectedPage->inspectorTimelineAgent()) {
+ v8::ScriptOrigin origin = function->GetScriptOrigin();
+ String resourceName("undefined");
+ int lineNumber = 1;
+ if (!origin.ResourceName().IsEmpty()) {
+ resourceName = toWebCoreString(origin.ResourceName());
+ lineNumber = function->GetScriptLineNumber() + 1;
+ }
+ timelineAgent->willCallFunction(resourceName, lineNumber);
+ } else
+ inspectedPage = 0;
+#endif // !ENABLE(INSPECTOR)
+
m_recursion++;
result = function->Call(receiver, argc, args);
m_recursion--;
+
+#if ENABLE(INSPECTOR)
+ if (inspectedPage)
+ if (InspectorTimelineAgent* timelineAgent = inspectedPage->inspectorTimelineAgent())
+ timelineAgent->didCallFunction();
+#endif // !ENABLE(INSPECTOR)
+
}
// Release the storage mutex if applicable.
@@ -518,6 +543,17 @@ v8::Local<v8::Value> V8Proxy::callFunction(v8::Handle<v8::Function> function, v8
return result;
}
+v8::Local<v8::Value> V8Proxy::callFunctionWithoutFrame(v8::Handle<v8::Function> function, v8::Handle<v8::Object> receiver, int argc, v8::Handle<v8::Value> args[])
+{
+ V8GCController::checkMemoryUsage();
+ v8::Local<v8::Value> result = function->Call(receiver, argc, args);
+
+ if (v8::V8::IsDead())
+ handleFatalErrorInV8();
+
+ return result;
+}
+
v8::Local<v8::Value> V8Proxy::newInstance(v8::Handle<v8::Function> constructor, int argc, v8::Handle<v8::Value> args[])
{
// No artificial limitations on the depth of recursion, see comment in
@@ -594,7 +630,7 @@ V8Proxy* V8Proxy::retrieve(Frame* frame)
{
if (!frame)
return 0;
- return frame->script()->canExecuteScripts() ? frame->script()->proxy() : 0;
+ return frame->script()->canExecuteScripts(NotAboutToExecuteScript) ? frame->script()->proxy() : 0;
}
V8Proxy* V8Proxy::retrieve(ScriptExecutionContext* context)
@@ -675,10 +711,12 @@ void V8Proxy::setDOMException(int exceptionCode)
exception = toV8(XPathException::create(description));
break;
#endif
+ default:
+ ASSERT_NOT_REACHED();
}
- ASSERT(!exception.IsEmpty());
- v8::ThrowException(exception);
+ if (!exception.IsEmpty())
+ v8::ThrowException(exception);
}
v8::Handle<v8::Value> V8Proxy::throwError(ErrorType type, const char* message)
@@ -754,95 +792,11 @@ v8::Handle<v8::Value> V8Proxy::checkNewLegal(const v8::Arguments& args)
return args.This();
}
-void V8Proxy::bindJsObjectToWindow(Frame* frame, const char* name, int type, v8::Handle<v8::FunctionTemplate> descriptor, void* impl)
-{
- // Get environment.
- v8::Handle<v8::Context> v8Context = V8Proxy::mainWorldContext(frame);
- if (v8Context.IsEmpty())
- return; // JS not enabled.
-
- v8::Context::Scope scope(v8Context);
- v8::Handle<v8::Object> instance = descriptor->GetFunction();
- V8DOMWrapper::setDOMWrapper(instance, type, impl);
-
- v8::Handle<v8::Object> global = v8Context->Global();
- global->Set(v8::String::New(name), instance);
-}
-
void V8Proxy::processConsoleMessages()
{
V8ConsoleMessage::processDelayed();
}
-// Create the utility context for holding JavaScript functions used internally
-// which are not visible to JavaScript executing on the page.
-void V8Proxy::createUtilityContext()
-{
- ASSERT(m_utilityContext.IsEmpty());
-
- v8::HandleScope scope;
- v8::Handle<v8::ObjectTemplate> globalTemplate = v8::ObjectTemplate::New();
- m_utilityContext = v8::Context::New(0, globalTemplate);
- v8::Context::Scope contextScope(m_utilityContext);
-
- // Compile JavaScript function for retrieving the source line of the top
- // JavaScript stack frame.
- DEFINE_STATIC_LOCAL(const char*, frameSourceLineSource,
- ("function frameSourceLine(exec_state) {"
- " return exec_state.frame(0).sourceLine();"
- "}"));
- v8::Script::Compile(v8::String::New(frameSourceLineSource))->Run();
-
- // Compile JavaScript function for retrieving the source name of the top
- // JavaScript stack frame.
- DEFINE_STATIC_LOCAL(const char*, frameSourceNameSource,
- ("function frameSourceName(exec_state) {"
- " var frame = exec_state.frame(0);"
- " if (frame.func().resolved() && "
- " frame.func().script() && "
- " frame.func().script().name()) {"
- " return frame.func().script().name();"
- " }"
- "}"));
- v8::Script::Compile(v8::String::New(frameSourceNameSource))->Run();
-}
-
-bool V8Proxy::sourceLineNumber(int& result)
-{
- v8::HandleScope scope;
- v8::Handle<v8::Context> v8UtilityContext = V8Proxy::utilityContext();
- if (v8UtilityContext.IsEmpty())
- 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())
- return false;
- v8::Handle<v8::Value> value = v8::Debug::Call(frameSourceLine);
- if (value.IsEmpty())
- return false;
- result = value->Int32Value();
- return true;
-}
-
-bool V8Proxy::sourceName(String& result)
-{
- v8::HandleScope scope;
- v8::Handle<v8::Context> v8UtilityContext = utilityContext();
- if (v8UtilityContext.IsEmpty())
- 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())
- return false;
- v8::Handle<v8::Value> value = v8::Debug::Call(frameSourceName);
- if (value.IsEmpty())
- return false;
- result = toWebCoreString(value);
- return true;
-}
-
void V8Proxy::registerExtensionWithV8(v8::Extension* extension)
{
// If the extension exists in our list, it was already registered with V8.
diff --git a/WebCore/bindings/v8/V8Proxy.h b/WebCore/bindings/v8/V8Proxy.h
index 44ed506..98bc902 100644
--- a/WebCore/bindings/v8/V8Proxy.h
+++ b/WebCore/bindings/v8/V8Proxy.h
@@ -39,7 +39,7 @@
#include "V8DOMWindowShell.h"
#include "V8DOMWrapper.h"
#include "V8GCController.h"
-#include "V8Index.h"
+#include "WrapperTypeInfo.h"
#include <v8.h>
#include <wtf/PassRefPtr.h> // so generated bindings don't have to
#include <wtf/Vector.h>
@@ -76,7 +76,7 @@ namespace WebCore {
const char* const name;
v8::AccessorGetter getter;
v8::AccessorSetter setter;
- V8ClassIndex::V8WrapperType data;
+ WrapperTypeInfo* data;
v8::AccessControl settings;
v8::PropertyAttribute attribute;
bool onProto;
@@ -89,7 +89,7 @@ namespace WebCore {
(attribute.onProto ? proto : instance)->SetAccessor(v8::String::New(attribute.name),
attribute.getter,
attribute.setter,
- attribute.data == V8ClassIndex::INVALID_CLASS_INDEX ? v8::Handle<v8::Value>() : v8::Integer::New(V8ClassIndex::ToInt(attribute.data)),
+ v8::External::Wrap(attribute.data),
attribute.settings,
attribute.attribute);
}
@@ -224,6 +224,9 @@ namespace WebCore {
// Call the function with the given receiver and arguments.
v8::Local<v8::Value> callFunction(v8::Handle<v8::Function>, v8::Handle<v8::Object>, int argc, v8::Handle<v8::Value> argv[]);
+ // Call the function with the given receiver and arguments.
+ static v8::Local<v8::Value> callFunctionWithoutFrame(v8::Handle<v8::Function>, v8::Handle<v8::Object>, int argc, v8::Handle<v8::Value> argv[]);
+
// Call the function as constructor with the given arguments.
v8::Local<v8::Value> newInstance(v8::Handle<v8::Function>, int argc, v8::Handle<v8::Value> argv[]);
@@ -298,26 +301,12 @@ namespace WebCore {
// Schedule an error object to be thrown.
static v8::Handle<v8::Value> throwError(ErrorType, const char* message);
- // Create an instance of a function descriptor and set to the global object
- // as a named property. Used by v8_test_shell.
- static void bindJsObjectToWindow(Frame*, const char* name, int type, v8::Handle<v8::FunctionTemplate>, void*);
-
- template <int tag, typename T>
- static v8::Handle<v8::Value> constructDOMObject(const v8::Arguments&);
+ template <typename T>
+ static v8::Handle<v8::Value> constructDOMObject(const v8::Arguments&, WrapperTypeInfo*);
// Process any pending JavaScript console messages.
static void processConsoleMessages();
- // Function for retrieving the line number and source name for the top
- // JavaScript stack frame.
- //
- // 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();
v8::Local<v8::Context> mainWorldContext();
@@ -368,23 +357,10 @@ namespace WebCore {
static const char* svgExceptionName(int exceptionCode);
#endif
- static void createUtilityContext();
-
- // Returns a local handle of the utility context.
- static v8::Local<v8::Context> utilityContext()
- {
- if (m_utilityContext.IsEmpty())
- createUtilityContext();
- return v8::Local<v8::Context>::New(m_utilityContext);
- }
-
Frame* m_frame;
// For the moment, we have one of these. Soon we will have one per DOMWrapperWorld.
RefPtr<V8DOMWindowShell> m_windowShell;
-
- // Utility context holding JavaScript functions used internally.
- static v8::Persistent<v8::Context> m_utilityContext;
int m_handlerLineNumber;
@@ -418,8 +394,8 @@ namespace WebCore {
IsolatedWorldMap m_isolatedWorlds;
};
- template <int tag, typename T>
- v8::Handle<v8::Value> V8Proxy::constructDOMObject(const v8::Arguments& args)
+ template <typename T>
+ v8::Handle<v8::Value> V8Proxy::constructDOMObject(const v8::Arguments& args, WrapperTypeInfo* type)
{
if (!args.IsConstructCall())
return throwError(V8Proxy::TypeError, "DOM object constructor cannot be called as a function.");
@@ -427,7 +403,7 @@ namespace WebCore {
// Note: it's OK to let this RefPtr go out of scope because we also call
// SetDOMWrapper(), which effectively holds a reference to obj.
RefPtr<T> obj = T::create();
- V8DOMWrapper::setDOMWrapper(args.Holder(), tag, obj.get());
+ V8DOMWrapper::setDOMWrapper(args.Holder(), type, obj.get());
obj->ref();
V8DOMWrapper::setJSWrapperForDOMObject(obj.get(), v8::Persistent<v8::Object>::New(args.Holder()));
return args.Holder();
@@ -449,19 +425,22 @@ namespace WebCore {
}
inline v8::Handle<v8::Primitive> throwError(const char* message, V8Proxy::ErrorType type = V8Proxy::TypeError)
{
- V8Proxy::throwError(type, message);
+ if (!v8::V8::IsExecutionTerminating())
+ V8Proxy::throwError(type, message);
return v8::Undefined();
}
inline v8::Handle<v8::Primitive> throwError(ExceptionCode ec)
{
- V8Proxy::setDOMException(ec);
+ if (!v8::V8::IsExecutionTerminating())
+ V8Proxy::setDOMException(ec);
return v8::Undefined();
}
inline v8::Handle<v8::Primitive> throwError(v8::Local<v8::Value> exception)
{
- v8::ThrowException(exception);
+ if (!v8::V8::IsExecutionTerminating())
+ v8::ThrowException(exception);
return v8::Undefined();
}
diff --git a/WebCore/bindings/v8/V8SVGPODTypeWrapper.h b/WebCore/bindings/v8/V8SVGPODTypeWrapper.h
index d4cdcf8..c044a06 100644
--- a/WebCore/bindings/v8/V8SVGPODTypeWrapper.h
+++ b/WebCore/bindings/v8/V8SVGPODTypeWrapper.h
@@ -396,13 +396,13 @@ public:
class V8SVGPODTypeUtil {
public:
template <class P>
- static P toSVGPODType(V8ClassIndex::V8WrapperType type, v8::Handle<v8::Value> object, bool& ok);
+ static P toSVGPODType(WrapperTypeInfo* info, v8::Handle<v8::Value> object, bool& ok);
};
template <class P>
-P V8SVGPODTypeUtil::toSVGPODType(V8ClassIndex::V8WrapperType type, v8::Handle<v8::Value> object, bool& ok)
+P V8SVGPODTypeUtil::toSVGPODType(WrapperTypeInfo* info, v8::Handle<v8::Value> object, bool& ok)
{
- if (!V8DOMWrapper::isWrapperOfType(object, type)) {
+ if (!V8DOMWrapper::isWrapperOfType(object, info)) {
ok = false;
return P();
}
diff --git a/WebCore/bindings/v8/V8Utilities.cpp b/WebCore/bindings/v8/V8Utilities.cpp
index c7314f1..ffccb06 100644
--- a/WebCore/bindings/v8/V8Utilities.cpp
+++ b/WebCore/bindings/v8/V8Utilities.cpp
@@ -125,54 +125,17 @@ void navigateIfAllowed(Frame* frame, const KURL& url, bool lockHistory, bool loc
frame->redirectScheduler()->scheduleLocationChange(url.string(), callingFrame->loader()->outgoingReferrer(), lockHistory, lockBackForwardList, processingUserGesture());
}
-ScriptExecutionContext* getScriptExecutionContext(ScriptState* scriptState)
+ScriptExecutionContext* getScriptExecutionContext()
{
#if ENABLE(WORKERS)
- WorkerContextExecutionProxy* proxy = WorkerContextExecutionProxy::retrieve();
- if (proxy)
- return proxy->workerContext()->scriptExecutionContext();
+ if (WorkerScriptController* controller = WorkerScriptController::controllerForContext())
+ return controller->workerContext();
#endif
- Frame* frame;
- if (scriptState) {
- v8::HandleScope handleScope;
- frame = V8Proxy::retrieveFrame(scriptState->context());
- } else
- frame = V8Proxy::retrieveFrameForCurrentContext();
-
- if (frame)
+ if (Frame* frame = V8Proxy::retrieveFrameForCurrentContext())
return frame->document()->scriptExecutionContext();
return 0;
}
-void reportException(ScriptState* scriptState, v8::TryCatch& exceptionCatcher)
-{
- String errorMessage;
- int lineNumber = 0;
- String sourceURL;
-
- // There can be a situation that an exception is thrown without setting a message.
- v8::Local<v8::Message> message = exceptionCatcher.Message();
- if (message.IsEmpty()) {
- v8::Local<v8::String> exceptionString = exceptionCatcher.Exception()->ToString();
- // Conversion of the exception object to string can fail if an
- // exception is thrown during conversion.
- if (!exceptionString.IsEmpty())
- errorMessage = toWebCoreString(exceptionString);
- } else {
- errorMessage = toWebCoreString(message->Get());
- lineNumber = message->GetLineNumber();
- sourceURL = toWebCoreString(message->GetScriptResourceName());
- }
-
- // 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();
-}
-
} // namespace WebCore
diff --git a/WebCore/bindings/v8/V8Utilities.h b/WebCore/bindings/v8/V8Utilities.h
index 944823a..cbe7a7b 100644
--- a/WebCore/bindings/v8/V8Utilities.h
+++ b/WebCore/bindings/v8/V8Utilities.h
@@ -54,12 +54,7 @@ namespace WebCore {
KURL completeURL(const String& relativeURL);
void navigateIfAllowed(Frame*, const KURL&, bool lockHistory, bool lockBackForwardList);
- ScriptExecutionContext* getScriptExecutionContext(ScriptState*);
- inline ScriptExecutionContext* getScriptExecutionContext() {
- return getScriptExecutionContext(0);
- }
-
- void reportException(ScriptState*, v8::TryCatch&);
+ ScriptExecutionContext* getScriptExecutionContext();
class AllowAllocation {
public:
diff --git a/WebCore/bindings/v8/V8WorkerContextErrorHandler.cpp b/WebCore/bindings/v8/V8WorkerContextErrorHandler.cpp
new file mode 100644
index 0000000..5a75a40
--- /dev/null
+++ b/WebCore/bindings/v8/V8WorkerContextErrorHandler.cpp
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if ENABLE(WORKERS)
+
+#include "V8WorkerContextErrorHandler.h"
+
+#include "ErrorEvent.h"
+#include "V8Binding.h"
+
+namespace WebCore {
+
+V8WorkerContextErrorHandler::V8WorkerContextErrorHandler(v8::Local<v8::Object> listener, bool isInline, const WorldContextHandle& worldContext)
+ : V8WorkerContextEventListener(listener, isInline, worldContext)
+{
+}
+
+v8::Local<v8::Value> V8WorkerContextErrorHandler::callListenerFunction(ScriptExecutionContext* context, v8::Handle<v8::Value> jsEvent, Event* event)
+{
+ ASSERT(event->isErrorEvent());
+ v8::Local<v8::Object> listener = getListenerObject(context);
+ v8::Local<v8::Value> returnValue;
+ if (!listener.IsEmpty() && listener->IsFunction()) {
+ ErrorEvent* errorEvent = static_cast<ErrorEvent*>(event);
+ v8::Local<v8::Function> callFunction = v8::Local<v8::Function>::Cast(listener);
+ v8::Local<v8::Object> thisValue = v8::Context::GetCurrent()->Global();
+ v8::Handle<v8::Value> parameters[3] = { v8String(errorEvent->message()), v8String(errorEvent->filename()), v8::Integer::New(errorEvent->lineno()) };
+ returnValue = callFunction->Call(thisValue, 3, parameters);
+ if (!returnValue.IsEmpty() && returnValue->IsBoolean() && !returnValue->BooleanValue())
+ event->preventDefault();
+ }
+ return returnValue;
+}
+
+} // namespace WebCore
+
+#endif // WORKERS
diff --git a/WebCore/bindings/v8/V8WorkerContextErrorHandler.h b/WebCore/bindings/v8/V8WorkerContextErrorHandler.h
new file mode 100644
index 0000000..cd1e0e6
--- /dev/null
+++ b/WebCore/bindings/v8/V8WorkerContextErrorHandler.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef V8WorkerContextErrorHandler_h
+#define V8WorkerContextErrorHandler_h
+
+#if ENABLE(WORKERS)
+
+#include "V8WorkerContextEventListener.h"
+#include <v8.h>
+#include <wtf/PassRefPtr.h>
+
+namespace WebCore {
+
+class V8WorkerContextErrorHandler : public V8WorkerContextEventListener {
+public:
+ static PassRefPtr<V8WorkerContextErrorHandler> create(v8::Local<v8::Object> listener, bool isInline, const WorldContextHandle& worldContext)
+ {
+ return adoptRef(new V8WorkerContextErrorHandler(listener, isInline, worldContext));
+ }
+
+private:
+ V8WorkerContextErrorHandler(v8::Local<v8::Object> listener, bool isInline, const WorldContextHandle& worldContext);
+
+ virtual v8::Local<v8::Value> callListenerFunction(ScriptExecutionContext*, v8::Handle<v8::Value> jsEvent, Event*);
+};
+
+} // namespace WebCore
+
+#endif // WORKERS
+
+#endif // V8WorkerContextErrorHandler_h
diff --git a/WebCore/bindings/v8/V8WorkerContextEventListener.cpp b/WebCore/bindings/v8/V8WorkerContextEventListener.cpp
index fa89ae6..30b9865 100644
--- a/WebCore/bindings/v8/V8WorkerContextEventListener.cpp
+++ b/WebCore/bindings/v8/V8WorkerContextEventListener.cpp
@@ -82,56 +82,6 @@ void V8WorkerContextEventListener::handleEvent(ScriptExecutionContext* context,
invokeEventHandler(context, event, jsEvent);
}
-bool V8WorkerContextEventListener::reportError(ScriptExecutionContext* context, const String& message, const String& url, int lineNumber)
-{
- if (!context)
- return false;
-
- // The callback function can clear the event listener and destroy 'this' object. Keep a local reference to it.
- RefPtr<V8AbstractEventListener> protect(this);
-
- v8::HandleScope handleScope;
-
- WorkerContextExecutionProxy* proxy = workerProxy(context);
- if (!proxy)
- return false;
-
- v8::Handle<v8::Context> v8Context = proxy->context();
- if (v8Context.IsEmpty())
- return false;
-
- // Enter the V8 context in which to perform the event handling.
- v8::Context::Scope scope(v8Context);
-
- v8::Local<v8::Object> listener = getListenerObject(context);
- v8::Local<v8::Value> returnValue;
- {
- // Catch exceptions thrown in calling the function so they do not propagate to javascript code that caused the event to fire.
- v8::TryCatch tryCatch;
- tryCatch.SetVerbose(true);
-
- // Call the function.
- if (!listener.IsEmpty() && listener->IsFunction()) {
- v8::Local<v8::Function> callFunction = v8::Local<v8::Function>::Cast(listener);
- v8::Local<v8::Object> thisValue = v8::Context::GetCurrent()->Global();
-
- v8::Handle<v8::Value> parameters[3] = { v8String(message), v8String(url), v8::Integer::New(lineNumber) };
- returnValue = callFunction->Call(thisValue, 3, parameters);
- }
-
- // If an error occurs while handling the script error, it should be bubbled up.
- if (tryCatch.HasCaught()) {
- tryCatch.Reset();
- return false;
- }
- }
-
- // If the function returns false, then the error is handled. Otherwise, the error is not handled.
- bool errorHandled = returnValue->IsBoolean() && !returnValue->BooleanValue();
-
- return errorHandled;
-}
-
v8::Local<v8::Value> V8WorkerContextEventListener::callListenerFunction(ScriptExecutionContext* context, v8::Handle<v8::Value> jsEvent, Event* event)
{
v8::Local<v8::Function> handlerFunction = getListenerFunction(context);
diff --git a/WebCore/bindings/v8/V8WorkerContextEventListener.h b/WebCore/bindings/v8/V8WorkerContextEventListener.h
index 4487497..1d0bfc8 100644
--- a/WebCore/bindings/v8/V8WorkerContextEventListener.h
+++ b/WebCore/bindings/v8/V8WorkerContextEventListener.h
@@ -50,11 +50,11 @@ namespace WebCore {
}
virtual void handleEvent(ScriptExecutionContext*, Event*);
- virtual bool reportError(ScriptExecutionContext*, const String& message, const String& url, int lineNumber);
- private:
+ protected:
V8WorkerContextEventListener(v8::Local<v8::Object> listener, bool isInline, const WorldContextHandle& worldContext);
+ private:
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 e4b417e..16e0b41 100644
--- a/WebCore/bindings/v8/WorkerContextExecutionProxy.cpp
+++ b/WebCore/bindings/v8/WorkerContextExecutionProxy.cpp
@@ -35,33 +35,20 @@
#include "WorkerContextExecutionProxy.h"
-#include "DOMCoreException.h"
#include "DedicatedWorkerContext.h"
#include "Event.h"
-#include "EventSource.h"
-#include "Notification.h"
-#include "NotificationCenter.h"
-#include "EventException.h"
-#include "MessagePort.h"
-#include "RangeException.h"
#include "SharedWorker.h"
#include "SharedWorkerContext.h"
#include "V8Binding.h"
+#include "V8ConsoleMessage.h"
#include "V8DOMMap.h"
-#include "V8Index.h"
+#include "V8DedicatedWorkerContext.h"
#include "V8Proxy.h"
-#include "V8WorkerContext.h"
-#include "V8WorkerContextEventListener.h"
-#if ENABLE(WEB_SOCKETS)
-#include "WebSocket.h"
-#endif
+#include "V8SharedWorkerContext.h"
#include "Worker.h"
#include "WorkerContext.h"
-#include "WorkerLocation.h"
-#include "WorkerNavigator.h"
#include "WorkerScriptController.h"
-#include "XMLHttpRequest.h"
-#include "XMLHttpRequestException.h"
+#include "WrapperTypeInfo.h"
namespace WebCore {
@@ -71,6 +58,26 @@ static void reportFatalErrorInV8(const char* location, const char* message)
CRASH();
}
+static void v8MessageHandler(v8::Handle<v8::Message> message, v8::Handle<v8::Value> data)
+{
+ static bool isReportingException = false;
+ // Exceptions that occur in error handler should be ignored since in that case
+ // WorkerContext::reportException will send the exception to the worker object.
+ if (isReportingException)
+ return;
+ isReportingException = true;
+
+ // During the frame teardown, there may not be a valid context.
+ if (ScriptExecutionContext* context = getScriptExecutionContext()) {
+ String errorMessage = toWebCoreString(message->Get());
+ int lineNumber = message->GetLineNumber();
+ String sourceURL = toWebCoreString(message->GetScriptResourceName());
+ context->reportException(errorMessage, lineNumber, sourceURL);
+ }
+
+ isReportingException = false;
+}
+
WorkerContextExecutionProxy::WorkerContextExecutionProxy(WorkerContext* workerContext)
: m_workerContext(workerContext)
, m_recursion(0)
@@ -100,21 +107,6 @@ void WorkerContextExecutionProxy::dispose()
}
}
-WorkerContextExecutionProxy* WorkerContextExecutionProxy::retrieve()
-{
- // Happens on frame destruction, check otherwise GetCurrent() will crash.
- if (!v8::Context::InContext())
- return 0;
- v8::Handle<v8::Context> context = v8::Context::GetCurrent();
- v8::Handle<v8::Object> global = context->Global();
- global = V8DOMWrapper::lookupDOMWrapper(V8WorkerContext::GetTemplate(), global);
- // Return 0 if the current executing context is not the worker context.
- if (global.IsEmpty())
- return 0;
- WorkerContext* workerContext = V8WorkerContext::toNative(global);
- return workerContext->script()->proxy();
-}
-
void WorkerContextExecutionProxy::initV8IfNeeded()
{
static bool v8Initialized = false;
@@ -134,46 +126,53 @@ void WorkerContextExecutionProxy::initV8IfNeeded()
v8Initialized = true;
}
-void WorkerContextExecutionProxy::initContextIfNeeded()
+bool WorkerContextExecutionProxy::initContextIfNeeded()
{
// Bail out if the context has already been initialized.
if (!m_context.IsEmpty())
- return;
+ return true;
+
+ // Setup the security handlers and message listener. This only has
+ // to be done once.
+ static bool isV8Initialized = false;
+ if (!isV8Initialized)
+ v8::V8::AddMessageListener(&v8MessageHandler);
// Create a new environment
v8::Persistent<v8::ObjectTemplate> globalTemplate;
m_context = v8::Context::New(0, globalTemplate);
+ if (m_context.IsEmpty())
+ return false;
// Starting from now, use local context only.
v8::Local<v8::Context> context = v8::Local<v8::Context>::New(m_context);
- v8::Context::Scope scope(context);
- // Allocate strings used during initialization.
- v8::Handle<v8::String> implicitProtoString = v8::String::New("__proto__");
+ v8::Context::Scope scope(context);
// Create a new JS object and use it as the prototype for the shadow global object.
- V8ClassIndex::V8WrapperType contextType = V8ClassIndex::DEDICATEDWORKERCONTEXT;
+ WrapperTypeInfo* contextType = &V8DedicatedWorkerContext::info;
#if ENABLE(SHARED_WORKERS)
if (!m_workerContext->isDedicatedWorkerContext())
- contextType = V8ClassIndex::SHAREDWORKERCONTEXT;
+ contextType = &V8SharedWorkerContext::info;
#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()) {
dispose();
- return;
+ return false;
}
// Wrap the object.
- V8DOMWrapper::setDOMWrapper(jsWorkerContext, V8ClassIndex::ToInt(contextType), m_workerContext);
+ V8DOMWrapper::setDOMWrapper(jsWorkerContext, contextType, m_workerContext);
V8DOMWrapper::setJSWrapperForDOMObject(m_workerContext, v8::Persistent<v8::Object>::New(jsWorkerContext));
m_workerContext->ref();
// Insert the object instance as the prototype of the shadow object.
- v8::Handle<v8::Object> globalObject = m_context->Global();
- globalObject->Set(implicitProtoString, jsWorkerContext);
+ v8::Handle<v8::Object> globalObject = v8::Handle<v8::Object>::Cast(m_context->Global()->GetPrototype());
+ globalObject->SetPrototype(jsWorkerContext);
+ return true;
}
bool WorkerContextExecutionProxy::forgetV8EventObject(Event* event)
@@ -189,7 +188,9 @@ ScriptValue WorkerContextExecutionProxy::evaluate(const String& script, const St
{
v8::HandleScope hs;
- initContextIfNeeded();
+ if (!initContextIfNeeded())
+ return ScriptValue();
+
v8::Context::Scope scope(m_context);
v8::TryCatch exceptionCatcher;
@@ -198,6 +199,9 @@ ScriptValue WorkerContextExecutionProxy::evaluate(const String& script, const St
v8::Handle<v8::Script> compiledScript = V8Proxy::compileScript(scriptString, fileName, baseLine);
v8::Local<v8::Value> result = runScript(compiledScript);
+ if (!exceptionCatcher.CanContinue())
+ return ScriptValue();
+
if (exceptionCatcher.HasCaught()) {
v8::Local<v8::Message> message = exceptionCatcher.Message();
state->hadException = true;
@@ -247,11 +251,6 @@ v8::Local<v8::Value> WorkerContextExecutionProxy::runScript(v8::Handle<v8::Scrip
return result;
}
-PassRefPtr<V8EventListener> WorkerContextExecutionProxy::findOrCreateEventListener(v8::Local<v8::Value> object, bool isInline, bool findOnly)
-{
- return findOnly ? V8EventListenerList::findWrapper(object, isInline) : V8EventListenerList::findOrCreateWrapper<V8WorkerContextEventListener>(object, isInline);
-}
-
void WorkerContextExecutionProxy::trackEvent(Event* event)
{
m_events.append(event);
diff --git a/WebCore/bindings/v8/WorkerContextExecutionProxy.h b/WebCore/bindings/v8/WorkerContextExecutionProxy.h
index 67a472b..58824b9 100644
--- a/WebCore/bindings/v8/WorkerContextExecutionProxy.h
+++ b/WebCore/bindings/v8/WorkerContextExecutionProxy.h
@@ -35,8 +35,6 @@
#if ENABLE(WORKERS)
#include "ScriptValue.h"
-#include "V8EventListenerList.h"
-#include "V8Index.h"
#include <v8.h>
#include <wtf/OwnPtr.h>
#include <wtf/Vector.h>
@@ -45,8 +43,6 @@ namespace WebCore {
class Event;
class EventTarget;
- class V8EventListener;
- class V8WorkerContextEventListener;
class WorkerContext;
struct WorkerContextExecutionState {
@@ -64,9 +60,6 @@ namespace WebCore {
WorkerContextExecutionProxy(WorkerContext*);
~WorkerContextExecutionProxy();
- // Finds/creates event listener wrappers.
- PassRefPtr<V8EventListener> findOrCreateEventListener(v8::Local<v8::Value> listener, bool isInline, bool findOnly);
-
// Track the event so that we can detach it from the JS wrapper when a worker
// terminates. This is needed because we need to be able to dispose these
// events and releases references to their event targets: WorkerContext.
@@ -78,15 +71,9 @@ namespace WebCore {
// Returns a local handle of the context.
v8::Local<v8::Context> context() { return v8::Local<v8::Context>::New(m_context); }
- // Returns WorkerContext object.
- WorkerContext* workerContext() { return m_workerContext; }
-
- // Returns WorkerContextExecutionProxy object of the currently executing context. 0 will be returned if the current executing context is not the worker context.
- static WorkerContextExecutionProxy* retrieve();
-
private:
void initV8IfNeeded();
- void initContextIfNeeded();
+ bool initContextIfNeeded();
void dispose();
// Run an already compiled script.
diff --git a/WebCore/bindings/v8/WorkerScriptController.cpp b/WebCore/bindings/v8/WorkerScriptController.cpp
index f2311bf..7db0d8d 100644
--- a/WebCore/bindings/v8/WorkerScriptController.cpp
+++ b/WebCore/bindings/v8/WorkerScriptController.cpp
@@ -41,6 +41,7 @@
#include "DOMTimer.h"
#include "V8DOMMap.h"
#include "V8Proxy.h"
+#include "V8WorkerContext.h"
#include "WorkerContext.h"
#include "WorkerContextExecutionProxy.h"
#include "WorkerObjectProxy.h"
@@ -85,11 +86,13 @@ ScriptValue WorkerScriptController::evaluate(const ScriptSourceCode& sourceCode,
return result;
}
-void WorkerScriptController::forbidExecution()
+void WorkerScriptController::forbidExecution(ForbidExecutionOption option)
{
- // This function is called from another thread.
+ // This function may be called from another thread.
MutexLocker lock(m_sharedDataMutex);
m_executionForbidden = true;
+ if (option == TerminateRunningScript)
+ v8::V8::TerminateExecution();
}
void WorkerScriptController::setException(ScriptValue exception)
@@ -97,6 +100,21 @@ void WorkerScriptController::setException(ScriptValue exception)
throwError(*exception.v8Value());
}
+WorkerScriptController* WorkerScriptController::controllerForContext()
+{
+ // Happens on frame destruction, check otherwise GetCurrent() will crash.
+ if (!v8::Context::InContext())
+ return 0;
+ v8::Handle<v8::Context> context = v8::Context::GetCurrent();
+ v8::Handle<v8::Object> global = context->Global();
+ global = V8DOMWrapper::lookupDOMWrapper(V8WorkerContext::GetTemplate(), global);
+ // Return 0 if the current executing context is not the worker context.
+ if (global.IsEmpty())
+ return 0;
+ WorkerContext* workerContext = V8WorkerContext::toNative(global);
+ return workerContext->script();
+}
+
} // namespace WebCore
#endif // ENABLE(WORKERS)
diff --git a/WebCore/bindings/v8/WorkerScriptController.h b/WebCore/bindings/v8/WorkerScriptController.h
index 07e224c..616697a 100644
--- a/WebCore/bindings/v8/WorkerScriptController.h
+++ b/WebCore/bindings/v8/WorkerScriptController.h
@@ -48,14 +48,19 @@ namespace WebCore {
WorkerScriptController(WorkerContext*);
~WorkerScriptController();
- WorkerContextExecutionProxy* proxy() { return m_proxy.get(); }
+ WorkerContextExecutionProxy* proxy() { return m_executionForbidden ? 0 : m_proxy.get(); }
+ WorkerContext* workerContext() { return m_workerContext; }
ScriptValue evaluate(const ScriptSourceCode&);
ScriptValue evaluate(const ScriptSourceCode&, ScriptValue* exception);
void setException(ScriptValue);
- void forbidExecution();
+ enum ForbidExecutionOption { TerminateRunningScript, LetRunningScriptFinish };
+ void forbidExecution(ForbidExecutionOption);
+
+ // Returns WorkerScriptController for the currently executing context. 0 will be returned if the current executing context is not the worker context.
+ static WorkerScriptController* controllerForContext();
private:
WorkerContext* m_workerContext;
diff --git a/WebCore/bindings/v8/WrapperTypeInfo.h b/WebCore/bindings/v8/WrapperTypeInfo.h
new file mode 100644
index 0000000..1d1cbfd
--- /dev/null
+++ b/WebCore/bindings/v8/WrapperTypeInfo.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef WrapperTypeInfo_h
+#define WrapperTypeInfo_h
+
+#include <v8.h>
+
+namespace WebCore {
+
+ class ActiveDOMObject;
+
+ static const int v8DOMWrapperTypeIndex = 0;
+ static const int v8DOMWrapperObjectIndex = 1;
+ static const int v8DOMHiddenReferenceArrayIndex = 2;
+ static const int v8DefaultWrapperInternalFieldCount = 3;
+
+ typedef v8::Persistent<v8::FunctionTemplate> (*GetTemplateFunction)();
+ typedef void (*DerefObjectFunction)(void*);
+ typedef ActiveDOMObject* (*ToActiveDOMObjectFunction)(v8::Handle<v8::Object>);
+
+ // This struct provides a way to store a bunch of information that is helpful when unwrapping
+ // v8 objects. Each v8 bindings class has exactly one static WrapperTypeInfo member, so
+ // comparing pointers is a safe way to determine if types match.
+ struct WrapperTypeInfo {
+
+ static WrapperTypeInfo* unwrap(v8::Handle<v8::Value> typeInfoWrapper)
+ {
+ return reinterpret_cast<WrapperTypeInfo*>(v8::External::Unwrap(typeInfoWrapper));
+ }
+
+
+ bool equals(const WrapperTypeInfo* that) const
+ {
+ return this == that;
+ }
+
+ v8::Persistent<v8::FunctionTemplate> getTemplate() { return getTemplateFunction(); }
+
+ void derefObject(void* object)
+ {
+ if (derefObjectFunction)
+ derefObjectFunction(object);
+ }
+
+ ActiveDOMObject* toActiveDOMObject(v8::Handle<v8::Object> object)
+ {
+ if (!toActiveDOMObjectFunction)
+ return 0;
+ return toActiveDOMObjectFunction(object);
+ }
+
+ const GetTemplateFunction getTemplateFunction;
+ const DerefObjectFunction derefObjectFunction;
+ const ToActiveDOMObjectFunction toActiveDOMObjectFunction;
+ };
+}
+
+#endif // WrapperTypeInfo_h
diff --git a/WebCore/bindings/v8/custom/V8AbstractWorkerCustom.cpp b/WebCore/bindings/v8/custom/V8AbstractWorkerCustom.cpp
deleted file mode 100644
index e776438..0000000
--- a/WebCore/bindings/v8/custom/V8AbstractWorkerCustom.cpp
+++ /dev/null
@@ -1,81 +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(WORKERS)
-#include "V8AbstractWorker.h"
-
-#include "AbstractWorker.h"
-#include "ExceptionCode.h"
-#include "ScriptExecutionContext.h"
-#include "V8Binding.h"
-#include "V8Proxy.h"
-#include "V8Utilities.h"
-#include "WorkerContextExecutionProxy.h"
-
-namespace WebCore {
-
-v8::Handle<v8::Value> V8AbstractWorker::addEventListenerCallback(const v8::Arguments& args)
-{
- INC_STATS(L"DOM.AbstractWorker.addEventListener()");
- AbstractWorker* worker = V8AbstractWorker::toNative(args.Holder());
-
- RefPtr<EventListener> listener = V8DOMWrapper::getEventListener(worker, args[1], false, ListenerFindOrCreate);
- if (listener) {
- String type = toWebCoreString(args[0]);
- bool useCapture = args[2]->BooleanValue();
- worker->addEventListener(type, listener, useCapture);
-
- createHiddenDependency(args.Holder(), args[1], cacheIndex);
- }
- return v8::Undefined();
-}
-
-v8::Handle<v8::Value> V8AbstractWorker::removeEventListenerCallback(const v8::Arguments& args)
-{
- INC_STATS(L"DOM.AbstractWorker.removeEventListener()");
- AbstractWorker* worker = V8AbstractWorker::toNative(args.Holder());
-
- RefPtr<EventListener> listener = V8DOMWrapper::getEventListener(worker, args[1], false, ListenerFindOnly);
- if (listener) {
- String type = toWebCoreString(args[0]);
- bool useCapture = args[2]->BooleanValue();
- worker->removeEventListener(type, listener.get(), useCapture);
-
- removeHiddenDependency(args.Holder(), args[1], cacheIndex);
- }
-
- return v8::Undefined();
-}
-
-} // namespace WebCore
-
-#endif // ENABLE(WORKERS)
diff --git a/WebCore/bindings/v8/custom/V8CSSStyleSheetCustom.cpp b/WebCore/bindings/v8/custom/V8CSSStyleSheetCustom.cpp
index 5dcc966..9effca3 100644
--- a/WebCore/bindings/v8/custom/V8CSSStyleSheetCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8CSSStyleSheetCustom.cpp
@@ -31,6 +31,7 @@
#include "config.h"
#include "V8CSSStyleSheet.h"
+#include "V8DOMWrapper.h"
#include "V8Node.h"
namespace WebCore {
@@ -43,7 +44,7 @@ v8::Handle<v8::Value> toV8(CSSStyleSheet* impl)
// Add a hidden reference from stylesheet object to its owner node.
Node* ownerNode = impl->ownerNode();
if (ownerNode && !wrapper.IsEmpty())
- wrapper->SetInternalField(V8CSSStyleSheet::ownerNodeIndex, toV8(ownerNode));
+ V8DOMWrapper::setHiddenReference(wrapper, toV8(ownerNode));
return wrapper;
}
diff --git a/WebCore/bindings/v8/custom/V8CSSValueCustom.cpp b/WebCore/bindings/v8/custom/V8CSSValueCustom.cpp
index b06bc3c..601a62a 100644
--- a/WebCore/bindings/v8/custom/V8CSSValueCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8CSSValueCustom.cpp
@@ -33,9 +33,12 @@
#include "V8CSSPrimitiveValue.h"
#include "V8CSSValueList.h"
+#include "V8WebKitCSSTransformValue.h"
+
+#if ENABLE(SVG)
#include "V8SVGColor.h"
#include "V8SVGPaint.h"
-#include "V8WebKitCSSTransformValue.h"
+#endif
namespace WebCore {
diff --git a/WebCore/bindings/v8/custom/V8CanvasRenderingContext2DCustom.cpp b/WebCore/bindings/v8/custom/V8CanvasRenderingContext2DCustom.cpp
index 9a05d72..26fc626 100644
--- a/WebCore/bindings/v8/custom/V8CanvasRenderingContext2DCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8CanvasRenderingContext2DCustom.cpp
@@ -98,362 +98,4 @@ void V8CanvasRenderingContext2D::fillStyleAccessorSetter(v8::Local<v8::String> n
impl->setFillStyle(toCanvasStyle(value));
}
-// TODO: SetStrokeColor and SetFillColor are similar except function names,
-// consolidate them into one.
-v8::Handle<v8::Value> V8CanvasRenderingContext2D::setStrokeColorCallback(const v8::Arguments& args)
-{
- INC_STATS("DOM.CanvasRenderingContext2D.setStrokeColor()");
- CanvasRenderingContext2D* context = V8CanvasRenderingContext2D::toNative(args.Holder());
- switch (args.Length()) {
- case 1:
- if (args[0]->IsString())
- context->setStrokeColor(toWebCoreString(args[0]));
- else
- context->setStrokeColor(toFloat(args[0]));
- break;
- case 2:
- if (args[0]->IsString())
- context->setStrokeColor(toWebCoreString(args[0]), toFloat(args[1]));
- else
- context->setStrokeColor(toFloat(args[0]), toFloat(args[1]));
- break;
- case 4:
- context->setStrokeColor(toFloat(args[0]), toFloat(args[1]), toFloat(args[2]), toFloat(args[3]));
- break;
- case 5:
- context->setStrokeColor(toFloat(args[0]), toFloat(args[1]), toFloat(args[2]), toFloat(args[3]), toFloat(args[4]));
- break;
- default:
- V8Proxy::throwError(V8Proxy::SyntaxError, "setStrokeColor: Invalid number of arguments");
- break;
- }
- return v8::Undefined();
-}
-
-v8::Handle<v8::Value> V8CanvasRenderingContext2D::setFillColorCallback(const v8::Arguments& args)
-{
- INC_STATS("DOM.CanvasRenderingContext2D.setFillColor()");
- CanvasRenderingContext2D* context = V8CanvasRenderingContext2D::toNative(args.Holder());
- switch (args.Length()) {
- case 1:
- if (args[0]->IsString())
- context->setFillColor(toWebCoreString(args[0]));
- else
- context->setFillColor(toFloat(args[0]));
- break;
- case 2:
- if (args[0]->IsString())
- context->setFillColor(toWebCoreString(args[0]), toFloat(args[1]));
- else
- context->setFillColor(toFloat(args[0]), toFloat(args[1]));
- break;
- case 4:
- context->setFillColor(toFloat(args[0]), toFloat(args[1]), toFloat(args[2]), toFloat(args[3]));
- break;
- case 5:
- context->setFillColor(toFloat(args[0]), toFloat(args[1]), toFloat(args[2]), toFloat(args[3]), toFloat(args[4]));
- break;
- default:
- V8Proxy::throwError(V8Proxy::SyntaxError, "setFillColor: Invalid number of arguments");
- break;
- }
- return v8::Undefined();
-}
-
-v8::Handle<v8::Value> V8CanvasRenderingContext2D::strokeRectCallback(const v8::Arguments& args)
-{
- INC_STATS("DOM.CanvasRenderingContext2D.strokeRect()");
- CanvasRenderingContext2D* context = V8CanvasRenderingContext2D::toNative(args.Holder());
- if (args.Length() == 5)
- context->strokeRect(toFloat(args[0]), toFloat(args[1]), toFloat(args[2]), toFloat(args[3]), toFloat(args[4]));
- else if (args.Length() == 4)
- context->strokeRect(toFloat(args[0]), toFloat(args[1]), toFloat(args[2]), toFloat(args[3]));
- else {
- V8Proxy::setDOMException(INDEX_SIZE_ERR);
- return notHandledByInterceptor();
- }
- return v8::Undefined();
-}
-
-v8::Handle<v8::Value> V8CanvasRenderingContext2D::setShadowCallback(const v8::Arguments& args)
-{
- INC_STATS("DOM.CanvasRenderingContext2D.setShadow()");
- CanvasRenderingContext2D* context = V8CanvasRenderingContext2D::toNative(args.Holder());
-
- switch (args.Length()) {
- case 3:
- context->setShadow(toFloat(args[0]), toFloat(args[1]), toFloat(args[2]));
- break;
- case 4:
- if (args[3]->IsString())
- context->setShadow(toFloat(args[0]), toFloat(args[1]), toFloat(args[2]), toWebCoreString(args[3]));
- else
- context->setShadow(toFloat(args[0]), toFloat(args[1]), toFloat(args[2]), toFloat(args[3]));
- break;
- case 5:
- if (args[3]->IsString())
- context->setShadow(toFloat(args[0]), toFloat(args[1]), toFloat(args[2]), toWebCoreString(args[3]), toFloat(args[4]));
- else
- context->setShadow(toFloat(args[0]), toFloat(args[1]), toFloat(args[2]), toFloat(args[3]), toFloat(args[4]));
- break;
- case 7:
- context->setShadow(toFloat(args[0]), toFloat(args[1]), toFloat(args[2]), toFloat(args[3]), toFloat(args[4]), toFloat(args[5]), toFloat(args[6]));
- break;
- case 8:
- context->setShadow(toFloat(args[0]), toFloat(args[1]), toFloat(args[2]), toFloat(args[3]), toFloat(args[4]), toFloat(args[5]), toFloat(args[6]), toFloat(args[7]));
- break;
- default:
- V8Proxy::throwError(V8Proxy::SyntaxError, "setShadow: Invalid number of arguments");
- break;
- }
-
- return v8::Undefined();
-}
-
-v8::Handle<v8::Value> V8CanvasRenderingContext2D::drawImageCallback(const v8::Arguments& args)
-{
- INC_STATS("DOM.CanvasRenderingContext2D.drawImage()");
- CanvasRenderingContext2D* context = V8CanvasRenderingContext2D::toNative(args.Holder());
-
- v8::Handle<v8::Value> arg = args[0];
-
- if (V8HTMLImageElement::HasInstance(arg)) {
- ExceptionCode ec = 0;
- HTMLImageElement* imageElement = V8HTMLImageElement::toNative(v8::Handle<v8::Object>::Cast(arg));
- switch (args.Length()) {
- case 3:
- context->drawImage(imageElement, toFloat(args[1]), toFloat(args[2]));
- break;
- case 5:
- context->drawImage(imageElement, toFloat(args[1]), toFloat(args[2]), toFloat(args[3]), toFloat(args[4]), ec);
- if (ec != 0) {
- V8Proxy::setDOMException(ec);
- return notHandledByInterceptor();
- }
- break;
- case 9:
- context->drawImage(imageElement,
- FloatRect(toFloat(args[1]), toFloat(args[2]), toFloat(args[3]), toFloat(args[4])),
- FloatRect(toFloat(args[5]), toFloat(args[6]), toFloat(args[7]), toFloat(args[8])),
- ec);
- if (ec != 0) {
- V8Proxy::setDOMException(ec);
- return notHandledByInterceptor();
- }
- break;
- default:
- return throwError("drawImage: Invalid number of arguments", V8Proxy::SyntaxError);
- }
- return v8::Undefined();
- }
-
- // HTMLCanvasElement
- if (V8HTMLCanvasElement::HasInstance(arg)) {
- ExceptionCode ec = 0;
- HTMLCanvasElement* canvasElement = V8HTMLCanvasElement::toNative(v8::Handle<v8::Object>::Cast(arg));
- switch (args.Length()) {
- case 3:
- context->drawImage(canvasElement, toFloat(args[1]), toFloat(args[2]));
- break;
- case 5:
- context->drawImage(canvasElement, toFloat(args[1]), toFloat(args[2]), toFloat(args[3]), toFloat(args[4]), ec);
- if (ec != 0) {
- V8Proxy::setDOMException(ec);
- return notHandledByInterceptor();
- }
- break;
- case 9:
- context->drawImage(canvasElement,
- FloatRect(toFloat(args[1]), toFloat(args[2]), toFloat(args[3]), toFloat(args[4])),
- FloatRect(toFloat(args[5]), toFloat(args[6]), toFloat(args[7]), toFloat(args[8])),
- ec);
- if (ec != 0) {
- V8Proxy::setDOMException(ec);
- return notHandledByInterceptor();
- }
- break;
- default:
- return throwError("drawImage: Invalid number of arguments", V8Proxy::SyntaxError);
- }
- return v8::Undefined();
- }
-
-#if ENABLE(VIDEO)
- // HTMLVideoElement
- if (V8HTMLVideoElement::HasInstance(arg)) {
- ExceptionCode ec = 0;
- HTMLVideoElement* videoElement = V8HTMLVideoElement::toNative(v8::Handle<v8::Object>::Cast(arg));
- switch (args.Length()) {
- case 3:
- context->drawImage(videoElement, toFloat(args[1]), toFloat(args[2]));
- break;
- case 5:
- context->drawImage(videoElement, toFloat(args[1]), toFloat(args[2]), toFloat(args[3]), toFloat(args[4]), ec);
- if (ec != 0) {
- V8Proxy::setDOMException(ec);
- return notHandledByInterceptor();
- }
- break;
- case 9:
- context->drawImage(videoElement,
- FloatRect(toFloat(args[1]), toFloat(args[2]), toFloat(args[3]), toFloat(args[4])),
- FloatRect(toFloat(args[5]), toFloat(args[6]), toFloat(args[7]), toFloat(args[8])),
- ec);
- if (ec != 0) {
- V8Proxy::setDOMException(ec);
- return notHandledByInterceptor();
- }
- break;
- default:
- return throwError("drawImage: Invalid number of arguments", V8Proxy::SyntaxError);
- }
- return v8::Undefined();
- }
-#endif
-
- V8Proxy::setDOMException(TYPE_MISMATCH_ERR);
- return notHandledByInterceptor();
-}
-
-
-v8::Handle<v8::Value> V8CanvasRenderingContext2D::drawImageFromRectCallback(const v8::Arguments& args)
-{
- INC_STATS("DOM.CanvasRenderingContext2D.drawImageFromRect()");
- CanvasRenderingContext2D* context = V8CanvasRenderingContext2D::toNative(args.Holder());
-
- v8::Handle<v8::Value> arg = args[0];
-
- if (V8HTMLImageElement::HasInstance(arg)) {
- HTMLImageElement* imageElement = V8HTMLImageElement::toNative(v8::Handle<v8::Object>::Cast(arg));
- context->drawImageFromRect(imageElement, toFloat(args[1]), toFloat(args[2]), toFloat(args[3]), toFloat(args[4]), toFloat(args[5]), toFloat(args[6]), toFloat(args[7]), toFloat(args[8]), toWebCoreString(args[9]));
- } else
- V8Proxy::throwError(V8Proxy::TypeError, "drawImageFromRect: Invalid type of arguments");
-
- return v8::Undefined();
-}
-
-v8::Handle<v8::Value> V8CanvasRenderingContext2D::createPatternCallback(const v8::Arguments& args)
-{
- INC_STATS("DOM.CanvasRenderingContext2D.createPattern()");
- CanvasRenderingContext2D* context = V8CanvasRenderingContext2D::toNative(args.Holder());
-
- v8::Handle<v8::Value> arg = args[0];
-
- if (V8HTMLImageElement::HasInstance(arg)) {
- HTMLImageElement* imageElement = V8HTMLImageElement::toNative(v8::Handle<v8::Object>::Cast(arg));
- ExceptionCode ec = 0;
- RefPtr<CanvasPattern> pattern = context->createPattern(imageElement, toWebCoreStringWithNullCheck(args[1]), ec);
- if (ec != 0) {
- V8Proxy::setDOMException(ec);
- return notHandledByInterceptor();
- }
- return toV8(pattern.release());
- }
-
- if (V8HTMLCanvasElement::HasInstance(arg)) {
- HTMLCanvasElement* canvasElement = V8HTMLCanvasElement::toNative(v8::Handle<v8::Object>::Cast(arg));
- ExceptionCode ec = 0;
- RefPtr<CanvasPattern> pattern = context->createPattern(canvasElement, toWebCoreStringWithNullCheck(args[1]), ec);
- if (ec != 0) {
- V8Proxy::setDOMException(ec);
- return notHandledByInterceptor();
- }
- return toV8(pattern.release());
- }
-
- V8Proxy::setDOMException(TYPE_MISMATCH_ERR);
- return notHandledByInterceptor();
-}
-
-v8::Handle<v8::Value> V8CanvasRenderingContext2D::fillTextCallback(const v8::Arguments& args)
-{
- INC_STATS("DOM.CanvasRenderingContext2D.fillText()");
-
- CanvasRenderingContext2D* context = V8CanvasRenderingContext2D::toNative(args.Holder());
-
- // Two forms:
- // * fillText(text, x, y)
- // * fillText(text, x, y, maxWidth)
- if (args.Length() < 3 || args.Length() > 4) {
- V8Proxy::setDOMException(SYNTAX_ERR);
- return notHandledByInterceptor();
- }
-
- String text = toWebCoreString(args[0]);
- float x = toFloat(args[1]);
- float y = toFloat(args[2]);
-
- if (args.Length() == 4) {
- float maxWidth = toFloat(args[3]);
- context->fillText(text, x, y, maxWidth);
- } else
- context->fillText(text, x, y);
-
- return v8::Undefined();
-}
-
-v8::Handle<v8::Value> V8CanvasRenderingContext2D::strokeTextCallback(const v8::Arguments& args)
-{
- INC_STATS("DOM.CanvasRenderingContext2D.strokeText()");
- CanvasRenderingContext2D* context = V8CanvasRenderingContext2D::toNative(args.Holder());
-
- // Two forms:
- // * strokeText(text, x, y)
- // * strokeText(text, x, y, maxWidth)
- if (args.Length() < 3 || args.Length() > 4) {
- V8Proxy::setDOMException(SYNTAX_ERR);
- return notHandledByInterceptor();
- }
-
- String text = toWebCoreString(args[0]);
- float x = toFloat(args[1]);
- float y = toFloat(args[2]);
-
- if (args.Length() == 4) {
- float maxWidth = toFloat(args[3]);
- context->strokeText(text, x, y, maxWidth);
- } else
- context->strokeText(text, x, y);
-
- return v8::Undefined();
-}
-
-v8::Handle<v8::Value> V8CanvasRenderingContext2D::putImageDataCallback(const v8::Arguments& args)
-{
- INC_STATS("DOM.CanvasRenderingContext2D.putImageData()");
-
- // Two froms:
- // * putImageData(ImageData, x, y)
- // * putImageData(ImageData, x, y, dirtyX, dirtyY, dirtyWidth, dirtyHeight)
- if (args.Length() != 3 && args.Length() != 7) {
- V8Proxy::setDOMException(SYNTAX_ERR);
- return notHandledByInterceptor();
- }
-
- CanvasRenderingContext2D* context = V8CanvasRenderingContext2D::toNative(args.Holder());
-
- ImageData* imageData = 0;
-
- // Need to check that the argument is of the correct type, since
- // toNative() expects it to be correct. If the argument was incorrect
- // we leave it null, and putImageData() will throw the correct exception
- // (TYPE_MISMATCH_ERR).
- if (V8DOMWrapper::isWrapperOfType(args[0], V8ClassIndex::IMAGEDATA))
- imageData = V8ImageData::toNative(v8::Handle<v8::Object>::Cast(args[0]));
-
- ExceptionCode ec = 0;
-
- if (args.Length() == 7)
- context->putImageData(imageData, toFloat(args[1]), toFloat(args[2]), toFloat(args[3]), toFloat(args[4]), toFloat(args[5]), toFloat(args[6]), ec);
- else
- context->putImageData(imageData, toFloat(args[1]), toFloat(args[2]), ec);
-
- if (ec != 0) {
- V8Proxy::setDOMException(ec);
- return notHandledByInterceptor();
- }
-
- return v8::Undefined();
-}
-
} // namespace WebCore
diff --git a/WebCore/bindings/v8/custom/V8ConsoleCustom.cpp b/WebCore/bindings/v8/custom/V8ConsoleCustom.cpp
new file mode 100644
index 0000000..9026420
--- /dev/null
+++ b/WebCore/bindings/v8/custom/V8ConsoleCustom.cpp
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include "V8Console.h"
+
+#include "Console.h"
+#include "ScriptProfile.h"
+#include "V8Binding.h"
+#include "V8Proxy.h"
+#include "V8ScriptProfile.h"
+
+namespace WebCore {
+
+typedef Vector<RefPtr<ScriptProfile> > ProfilesArray;
+
+v8::Handle<v8::Value> V8Console::profilesAccessorGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info)
+{
+ INC_STATS("DOM.Console.profilesAccessorGetter");
+ Console* imp = V8Console::toNative(info.Holder());
+ const ProfilesArray& profiles = imp->profiles();
+ v8::Handle<v8::Array> result = v8::Array::New(profiles.size());
+ int index = 0;
+ ProfilesArray::const_iterator end = profiles.end();
+ for (ProfilesArray::const_iterator iter = profiles.begin(); iter != end; ++iter)
+ result->Set(v8::Integer::New(index++), toV8(iter->get()));
+ return result;
+}
+
+} // namespace WebCore
diff --git a/WebCore/bindings/v8/custom/V8CustomBinding.h b/WebCore/bindings/v8/custom/V8CustomBinding.h
deleted file mode 100644
index e69de29..0000000
--- a/WebCore/bindings/v8/custom/V8CustomBinding.h
+++ /dev/null
diff --git a/WebCore/bindings/v8/custom/V8CustomIDBCallbacks.h b/WebCore/bindings/v8/custom/V8CustomIDBCallbacks.h
new file mode 100644
index 0000000..1517f15
--- /dev/null
+++ b/WebCore/bindings/v8/custom/V8CustomIDBCallbacks.h
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef V8CustomIDBCallbacks_h
+#define V8CustomIDBCallbacks_h
+
+#include "Document.h"
+#include "Frame.h"
+#include "IDBDatabaseError.h"
+#include "V8CustomVoidCallback.h"
+#include "V8IDBDatabaseError.h"
+#include "WorldContextHandle.h"
+#include <v8.h>
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+#include <wtf/RefPtr.h>
+
+#if ENABLE(INDEXED_DATABASE)
+
+namespace WebCore {
+
+// FIXME: Maybe split common parts into a base class.
+template <typename ResultType, typename ResultWrapperType>
+class V8CustomIDBCallbacks : public IDBCallbacks<ResultType> {
+public:
+ static PassRefPtr<V8CustomIDBCallbacks> create(v8::Local<v8::Value> onSuccess, v8::Local<v8::Value> onError, ScriptExecutionContext* scriptExecutionContext)
+ {
+ return adoptRef(new V8CustomIDBCallbacks(onSuccess, onError, scriptExecutionContext));
+ }
+
+ virtual ~V8CustomIDBCallbacks()
+ {
+ m_onSuccess.Dispose();
+ m_onError.Dispose();
+ }
+
+ // FIXME: Handle suspend/resume correctly.
+
+private:
+ V8CustomIDBCallbacks(v8::Local<v8::Value> onSuccess, v8::Local<v8::Value> onError, ScriptExecutionContext* scriptExecutionContext)
+ : IDBCallbacks<ResultType>(scriptExecutionContext, this)
+ , m_onSuccess(onSuccess->IsObject() ? v8::Persistent<v8::Object>::New(onSuccess->ToObject()) : v8::Persistent<v8::Object>())
+ , m_onError(onError->IsObject() ? v8::Persistent<v8::Object>::New(onError->ToObject()) : v8::Persistent<v8::Object>())
+ , m_worldContext(UseCurrentWorld)
+ {
+ }
+
+ template <typename Type>
+ void onEvent(v8::Persistent<v8::Object> callback, PassRefPtr<Type> value)
+ {
+ if (!ActiveDOMObject::scriptExecutionContext())
+ return;
+ if (callback.IsEmpty())
+ return;
+
+ v8::HandleScope handleScope;
+ v8::Handle<v8::Context> context = toV8Context(ActiveDOMObject::scriptExecutionContext(), m_worldContext);
+ if (context.IsEmpty())
+ return;
+
+ v8::Context::Scope scope(context);
+ v8::Handle<v8::Value> argv[] = {
+ toV8(value)
+ };
+
+ // FIXME: Make this work for workers.
+ ASSERT(ActiveDOMObject::scriptExecutionContext()->isDocument());
+ RefPtr<Frame> protector(static_cast<Document*>(ActiveDOMObject::scriptExecutionContext())->frame());
+
+ bool callbackReturnValue = false;
+ // FIXME: Do we care if this thing returns true (i.e. it raised an exception)?
+ invokeCallback(callback, 1, argv, callbackReturnValue);
+ }
+
+ virtual void onSuccessAsync(PassRefPtr<ResultType> result)
+ {
+ onEvent(m_onSuccess, ResultWrapperType::create(result));
+ }
+
+ virtual void onErrorAsync(PassRefPtr<IDBDatabaseError> error)
+ {
+ onEvent(m_onError, error);
+ }
+
+ // FIXME: Use OwnHandles.
+ v8::Persistent<v8::Object> m_onSuccess;
+ v8::Persistent<v8::Object> m_onError;
+
+ WorldContextHandle m_worldContext;
+};
+
+}
+
+#endif
+
+#endif // V8CustomIDBCallbacks_h
diff --git a/WebCore/bindings/v8/custom/V8CustomSQLStatementCallback.cpp b/WebCore/bindings/v8/custom/V8CustomSQLStatementCallback.cpp
index d30b95a..df0cc53 100644
--- a/WebCore/bindings/v8/custom/V8CustomSQLStatementCallback.cpp
+++ b/WebCore/bindings/v8/custom/V8CustomSQLStatementCallback.cpp
@@ -35,6 +35,7 @@
#include "V8CustomSQLStatementCallback.h"
#include "Frame.h"
+#include "ScriptExecutionContext.h"
#include "V8CustomVoidCallback.h"
#include "V8SQLResultSet.h"
#include "V8SQLTransaction.h"
@@ -44,6 +45,7 @@ namespace WebCore {
V8CustomSQLStatementCallback::V8CustomSQLStatementCallback(v8::Local<v8::Object> callback, Frame* frame)
: m_callback(v8::Persistent<v8::Object>::New(callback))
, m_frame(frame)
+ , m_worldContext(UseCurrentWorld)
{
}
@@ -52,15 +54,15 @@ V8CustomSQLStatementCallback::~V8CustomSQLStatementCallback()
m_callback.Dispose();
}
-void V8CustomSQLStatementCallback::handleEvent(SQLTransaction* transaction, SQLResultSet* resultSet, bool& raisedException)
+void V8CustomSQLStatementCallback::handleEvent(ScriptExecutionContext* context, SQLTransaction* transaction, SQLResultSet* resultSet, bool& raisedException)
{
v8::HandleScope handleScope;
- v8::Handle<v8::Context> context = V8Proxy::context(m_frame.get());
- if (context.IsEmpty())
+ v8::Handle<v8::Context> v8Context = toV8Context(context, m_worldContext);
+ if (v8Context.IsEmpty())
return;
- v8::Context::Scope scope(context);
+ v8::Context::Scope scope(v8Context);
v8::Handle<v8::Value> argv[] = {
toV8(transaction),
@@ -77,4 +79,3 @@ void V8CustomSQLStatementCallback::handleEvent(SQLTransaction* transaction, SQLR
} // namespace WebCore
#endif
-
diff --git a/WebCore/bindings/v8/custom/V8CustomSQLStatementCallback.h b/WebCore/bindings/v8/custom/V8CustomSQLStatementCallback.h
index 58ee943..31f53e4 100644
--- a/WebCore/bindings/v8/custom/V8CustomSQLStatementCallback.h
+++ b/WebCore/bindings/v8/custom/V8CustomSQLStatementCallback.h
@@ -34,9 +34,9 @@
#if ENABLE(DATABASE)
#include "SQLStatementCallback.h"
+#include "WorldContextHandle.h"
#include <v8.h>
-#include <wtf/PassRefPtr.h>
-#include <wtf/RefPtr.h>
+#include <wtf/Forward.h>
namespace WebCore {
@@ -51,12 +51,13 @@ public:
}
virtual ~V8CustomSQLStatementCallback();
- virtual void handleEvent(SQLTransaction*, SQLResultSet*, bool& raisedException);
+ virtual void handleEvent(ScriptExecutionContext*, SQLTransaction*, SQLResultSet*, bool& raisedException);
private:
V8CustomSQLStatementCallback(v8::Local<v8::Object>, Frame*);
v8::Persistent<v8::Object> m_callback;
RefPtr<Frame> m_frame;
+ WorldContextHandle m_worldContext;
};
} // namespace WebCore
diff --git a/WebCore/bindings/v8/custom/V8CustomSQLStatementErrorCallback.cpp b/WebCore/bindings/v8/custom/V8CustomSQLStatementErrorCallback.cpp
index f733ede..2545f24 100644
--- a/WebCore/bindings/v8/custom/V8CustomSQLStatementErrorCallback.cpp
+++ b/WebCore/bindings/v8/custom/V8CustomSQLStatementErrorCallback.cpp
@@ -35,6 +35,7 @@
#include "V8CustomSQLStatementErrorCallback.h"
#include "Frame.h"
+#include "ScriptExecutionContext.h"
#include "V8CustomVoidCallback.h"
#include "V8SQLError.h"
#include "V8SQLTransaction.h"
@@ -44,6 +45,7 @@ namespace WebCore {
V8CustomSQLStatementErrorCallback::V8CustomSQLStatementErrorCallback(v8::Local<v8::Object> callback, Frame* frame)
: m_callback(v8::Persistent<v8::Object>::New(callback))
, m_frame(frame)
+ , m_worldContext(UseCurrentWorld)
{
}
@@ -52,15 +54,15 @@ V8CustomSQLStatementErrorCallback::~V8CustomSQLStatementErrorCallback()
m_callback.Dispose();
}
-bool V8CustomSQLStatementErrorCallback::handleEvent(SQLTransaction* transaction, SQLError* error)
+bool V8CustomSQLStatementErrorCallback::handleEvent(ScriptExecutionContext* context, SQLTransaction* transaction, SQLError* error)
{
v8::HandleScope handleScope;
- v8::Handle<v8::Context> context = V8Proxy::context(m_frame.get());
- if (context.IsEmpty())
+ v8::Handle<v8::Context> v8Context = toV8Context(context, m_worldContext);
+ if (v8Context.IsEmpty())
return true;
- v8::Context::Scope scope(context);
+ v8::Context::Scope scope(v8Context);
v8::Handle<v8::Value> argv[] = {
toV8(transaction),
@@ -75,7 +77,7 @@ bool V8CustomSQLStatementErrorCallback::handleEvent(SQLTransaction* transaction,
// statement, if any, or onto the next overall step otherwise. Otherwise,
// the error callback did not return false, or there was no error callback.
// Jump to the last step in the overall steps.
- return invokeCallbackTreatOnlyExplicitFalseAsFalse(m_callback, 2, argv, callbackReturnValue) || callbackReturnValue;
+ return invokeCallback(m_callback, 2, argv, callbackReturnValue) || callbackReturnValue;
}
} // namespace WebCore
diff --git a/WebCore/bindings/v8/custom/V8CustomSQLStatementErrorCallback.h b/WebCore/bindings/v8/custom/V8CustomSQLStatementErrorCallback.h
index 685efc6..c3d7f79 100644
--- a/WebCore/bindings/v8/custom/V8CustomSQLStatementErrorCallback.h
+++ b/WebCore/bindings/v8/custom/V8CustomSQLStatementErrorCallback.h
@@ -34,8 +34,7 @@
#if ENABLE(DATABASE)
#include "SQLStatementErrorCallback.h"
-
-#include "SQLStatementErrorCallback.h"
+#include "WorldContextHandle.h"
#include <v8.h>
#include <wtf/PassRefPtr.h>
#include <wtf/RefPtr.h>
@@ -53,12 +52,13 @@ public:
}
virtual ~V8CustomSQLStatementErrorCallback();
- virtual bool handleEvent(SQLTransaction*, SQLError*);
+ virtual bool handleEvent(ScriptExecutionContext*, SQLTransaction*, SQLError*);
private:
V8CustomSQLStatementErrorCallback(v8::Local<v8::Object>, Frame*);
v8::Persistent<v8::Object> m_callback;
RefPtr<Frame> m_frame;
+ WorldContextHandle m_worldContext;
};
} // namespace WebCore
diff --git a/WebCore/bindings/v8/custom/V8CustomSQLTransactionCallback.cpp b/WebCore/bindings/v8/custom/V8CustomSQLTransactionCallback.cpp
index 68002d7..efe415c 100644
--- a/WebCore/bindings/v8/custom/V8CustomSQLTransactionCallback.cpp
+++ b/WebCore/bindings/v8/custom/V8CustomSQLTransactionCallback.cpp
@@ -35,6 +35,7 @@
#include "V8CustomSQLTransactionCallback.h"
#include "Frame.h"
+#include "ScriptExecutionContext.h"
#include "V8CustomVoidCallback.h"
#include "V8SQLTransaction.h"
@@ -43,6 +44,7 @@ namespace WebCore {
V8CustomSQLTransactionCallback::V8CustomSQLTransactionCallback(v8::Local<v8::Object> callback, Frame* frame)
: m_callback(v8::Persistent<v8::Object>::New(callback))
, m_frame(frame)
+ , m_worldContext(UseCurrentWorld)
{
}
@@ -52,15 +54,15 @@ V8CustomSQLTransactionCallback::~V8CustomSQLTransactionCallback()
}
-void V8CustomSQLTransactionCallback::handleEvent(SQLTransaction* transaction, bool& raisedException)
+void V8CustomSQLTransactionCallback::handleEvent(ScriptExecutionContext* context, SQLTransaction* transaction, bool& raisedException)
{
v8::HandleScope handleScope;
- v8::Handle<v8::Context> context = V8Proxy::context(m_frame.get());
- if (context.IsEmpty())
+ v8::Handle<v8::Context> v8Context = toV8Context(context, m_worldContext);
+ if (v8Context.IsEmpty())
return;
- v8::Context::Scope scope(context);
+ v8::Context::Scope scope(v8Context);
v8::Handle<v8::Value> argv[] = {
toV8(transaction)
@@ -79,4 +81,3 @@ void V8CustomSQLTransactionCallback::handleEvent(SQLTransaction* transaction, bo
} // namespace WebCore
#endif
-
diff --git a/WebCore/bindings/v8/custom/V8CustomSQLTransactionCallback.h b/WebCore/bindings/v8/custom/V8CustomSQLTransactionCallback.h
index 665404d..60ad529 100644
--- a/WebCore/bindings/v8/custom/V8CustomSQLTransactionCallback.h
+++ b/WebCore/bindings/v8/custom/V8CustomSQLTransactionCallback.h
@@ -34,9 +34,9 @@
#if ENABLE(DATABASE)
#include "SQLTransactionCallback.h"
+#include "WorldContextHandle.h"
#include <v8.h>
-#include <wtf/PassRefPtr.h>
-#include <wtf/RefPtr.h>
+#include <wtf/Forward.h>
namespace WebCore {
@@ -51,12 +51,13 @@ public:
}
virtual ~V8CustomSQLTransactionCallback();
- virtual void handleEvent(SQLTransaction*, bool& raisedException);
+ virtual void handleEvent(ScriptExecutionContext*, SQLTransaction*, bool& raisedException);
private:
V8CustomSQLTransactionCallback(v8::Local<v8::Object>, Frame*);
v8::Persistent<v8::Object> m_callback;
RefPtr<Frame> m_frame;
+ WorldContextHandle m_worldContext;
};
} // namespace WebCore
diff --git a/WebCore/bindings/v8/custom/V8CustomSQLTransactionErrorCallback.cpp b/WebCore/bindings/v8/custom/V8CustomSQLTransactionErrorCallback.cpp
index cf5a0ef..1ef711a 100644
--- a/WebCore/bindings/v8/custom/V8CustomSQLTransactionErrorCallback.cpp
+++ b/WebCore/bindings/v8/custom/V8CustomSQLTransactionErrorCallback.cpp
@@ -35,6 +35,7 @@
#include "V8CustomSQLTransactionErrorCallback.h"
#include "Frame.h"
+#include "ScriptExecutionContext.h"
#include "V8CustomVoidCallback.h"
#include "V8SQLError.h"
@@ -43,6 +44,7 @@ namespace WebCore {
V8CustomSQLTransactionErrorCallback::V8CustomSQLTransactionErrorCallback(v8::Local<v8::Object> callback, Frame* frame)
: m_callback(v8::Persistent<v8::Object>::New(callback))
, m_frame(frame)
+ , m_worldContext(UseCurrentWorld)
{
}
@@ -51,15 +53,15 @@ V8CustomSQLTransactionErrorCallback::~V8CustomSQLTransactionErrorCallback()
m_callback.Dispose();
}
-void V8CustomSQLTransactionErrorCallback::handleEvent(SQLError* error)
+void V8CustomSQLTransactionErrorCallback::handleEvent(ScriptExecutionContext* context, SQLError* error)
{
v8::HandleScope handleScope;
- v8::Handle<v8::Context> context = V8Proxy::context(m_frame.get());
- if (context.IsEmpty())
+ v8::Handle<v8::Context> v8Context = toV8Context(context, m_worldContext);
+ if (v8Context.IsEmpty())
return;
- v8::Context::Scope scope(context);
+ v8::Context::Scope scope(v8Context);
v8::Handle<v8::Value> argv[] = {
toV8(error)
@@ -75,4 +77,3 @@ void V8CustomSQLTransactionErrorCallback::handleEvent(SQLError* error)
} // namespace WebCore
#endif
-
diff --git a/WebCore/bindings/v8/custom/V8CustomSQLTransactionErrorCallback.h b/WebCore/bindings/v8/custom/V8CustomSQLTransactionErrorCallback.h
index 0387deb..72e9e7a 100644
--- a/WebCore/bindings/v8/custom/V8CustomSQLTransactionErrorCallback.h
+++ b/WebCore/bindings/v8/custom/V8CustomSQLTransactionErrorCallback.h
@@ -34,9 +34,9 @@
#if ENABLE(DATABASE)
#include "SQLTransactionErrorCallback.h"
+#include "WorldContextHandle.h"
#include <v8.h>
-#include <wtf/PassRefPtr.h>
-#include <wtf/RefPtr.h>
+#include <wtf/Forward.h>
namespace WebCore {
@@ -51,13 +51,14 @@ public:
}
virtual ~V8CustomSQLTransactionErrorCallback();
- virtual void handleEvent(SQLError*);
+ virtual void handleEvent(ScriptExecutionContext*, SQLError*);
private:
V8CustomSQLTransactionErrorCallback(v8::Local<v8::Object>, Frame*);
v8::Persistent<v8::Object> m_callback;
RefPtr<Frame> m_frame;
+ WorldContextHandle m_worldContext;
};
} // namespace WebCore
diff --git a/WebCore/bindings/v8/custom/V8CustomVoidCallback.cpp b/WebCore/bindings/v8/custom/V8CustomVoidCallback.cpp
index 8c69e76..f4ea62a 100644
--- a/WebCore/bindings/v8/custom/V8CustomVoidCallback.cpp
+++ b/WebCore/bindings/v8/custom/V8CustomVoidCallback.cpp
@@ -29,10 +29,10 @@
*/
#include "config.h"
-#include "V8Binding.h"
#include "V8CustomVoidCallback.h"
#include "Frame.h"
+#include "V8Binding.h"
namespace WebCore {
@@ -64,7 +64,7 @@ void V8CustomVoidCallback::handleEvent()
invokeCallback(m_callback, 0, 0, callbackReturnValue);
}
-static bool invokeCallbackHelper(v8::Persistent<v8::Object> callback, int argc, v8::Handle<v8::Value> argv[], v8::Handle<v8::Value>& returnValue)
+bool invokeCallback(v8::Persistent<v8::Object> callback, int argc, v8::Handle<v8::Value> argv[], bool& callbackReturnValue)
{
v8::TryCatch exceptionCatcher;
@@ -73,9 +73,8 @@ static bool invokeCallbackHelper(v8::Persistent<v8::Object> callback, int argc,
callbackFunction = v8::Local<v8::Function>::New(v8::Persistent<v8::Function>::Cast(callback));
} else if (callback->IsObject()) {
v8::Local<v8::Value> handleEventFunction = callback->Get(v8::String::NewSymbol("handleEvent"));
- if (handleEventFunction->IsFunction()) {
+ if (handleEventFunction->IsFunction())
callbackFunction = v8::Local<v8::Function>::Cast(handleEventFunction);
- }
} else
return false;
@@ -87,7 +86,8 @@ static bool invokeCallbackHelper(v8::Persistent<v8::Object> callback, int argc,
V8Proxy* proxy = V8Proxy::retrieve();
ASSERT(proxy);
- returnValue = proxy->callFunction(callbackFunction, thisObject, argc, argv);
+ v8::Handle<v8::Value> result = proxy->callFunction(callbackFunction, thisObject, argc, argv);
+ callbackReturnValue = !result.IsEmpty() && result->BooleanValue();
if (exceptionCatcher.HasCaught()) {
v8::Local<v8::Message> message = exceptionCatcher.Message();
@@ -98,20 +98,4 @@ static bool invokeCallbackHelper(v8::Persistent<v8::Object> callback, int argc,
return false;
}
-bool invokeCallback(v8::Persistent<v8::Object> callback, int argc, v8::Handle<v8::Value> argv[], bool& callbackReturnValue)
-{
- v8::Handle<v8::Value> returnValue;
- bool result = invokeCallbackHelper(callback, argc, argv, returnValue);
- callbackReturnValue = !returnValue.IsEmpty() && returnValue->IsBoolean() && returnValue->BooleanValue();
- return result;
-}
-
-bool invokeCallbackTreatOnlyExplicitFalseAsFalse(v8::Persistent<v8::Object> callback, int argc, v8::Handle<v8::Value> argv[], bool& callbackReturnValue)
-{
- v8::Handle<v8::Value> returnValue;
- bool result = invokeCallbackHelper(callback, argc, argv, returnValue);
- callbackReturnValue = !returnValue.IsEmpty() && !returnValue->IsFalse();
- return result;
-}
-
} // namespace WebCore
diff --git a/WebCore/bindings/v8/custom/V8CustomVoidCallback.h b/WebCore/bindings/v8/custom/V8CustomVoidCallback.h
index 6b7b3e8..586296b 100644
--- a/WebCore/bindings/v8/custom/V8CustomVoidCallback.h
+++ b/WebCore/bindings/v8/custom/V8CustomVoidCallback.h
@@ -60,7 +60,6 @@ private:
// Returns false if callback failed (null, wrong type, or threw exception).
bool invokeCallback(v8::Persistent<v8::Object> callback, int argc, v8::Handle<v8::Value> argv[], bool& callbackReturnValue);
-bool invokeCallbackTreatOnlyExplicitFalseAsFalse(v8::Persistent<v8::Object> callback, int argc, v8::Handle<v8::Value> argv[], bool& callbackReturnValue);
} // namespace WebCore
diff --git a/WebCore/bindings/v8/custom/V8CustomXPathNSResolver.cpp b/WebCore/bindings/v8/custom/V8CustomXPathNSResolver.cpp
index e45cba0..01448d9 100644
--- a/WebCore/bindings/v8/custom/V8CustomXPathNSResolver.cpp
+++ b/WebCore/bindings/v8/custom/V8CustomXPathNSResolver.cpp
@@ -38,14 +38,13 @@
namespace WebCore {
-PassRefPtr<V8CustomXPathNSResolver> V8CustomXPathNSResolver::create(V8Proxy* proxy, v8::Handle<v8::Object> resolver)
+PassRefPtr<V8CustomXPathNSResolver> V8CustomXPathNSResolver::create(v8::Handle<v8::Object> resolver)
{
- return adoptRef(new V8CustomXPathNSResolver(proxy, resolver));
+ return adoptRef(new V8CustomXPathNSResolver(resolver));
}
-V8CustomXPathNSResolver::V8CustomXPathNSResolver(V8Proxy* proxy, v8::Handle<v8::Object> resolver)
- : m_proxy(proxy)
- , m_resolver(resolver)
+V8CustomXPathNSResolver::V8CustomXPathNSResolver(v8::Handle<v8::Object> resolver)
+ : m_resolver(resolver)
{
}
@@ -55,14 +54,6 @@ 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");
@@ -74,8 +65,10 @@ String V8CustomXPathNSResolver::lookupNamespaceURI(const String& prefix)
}
if (lookupNamespaceURIFunc.IsEmpty() && !m_resolver->IsFunction()) {
- Frame* frame = proxy->frame();
- logInfo(frame, "XPathNSResolver does not have a lookupNamespaceURI method.", String());
+ if (V8Proxy* proxy = V8Proxy::retrieve()) {
+ if (Frame* frame = proxy->frame())
+ logInfo(frame, "XPathNSResolver does not have a lookupNamespaceURI method.", String());
+ }
return String();
}
@@ -87,7 +80,7 @@ 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;
- v8::Handle<v8::Value> retval = proxy->callFunction(function, m_resolver, argc, argv);
+ v8::Handle<v8::Value> retval = V8Proxy::callFunctionWithoutFrame(function, m_resolver, argc, argv);
// Eat exceptions from namespace resolver and return an empty string. This will most likely cause NAMESPACE_ERR.
if (try_catch.HasCaught())
diff --git a/WebCore/bindings/v8/custom/V8CustomXPathNSResolver.h b/WebCore/bindings/v8/custom/V8CustomXPathNSResolver.h
index 15ac27d..cf84438 100644
--- a/WebCore/bindings/v8/custom/V8CustomXPathNSResolver.h
+++ b/WebCore/bindings/v8/custom/V8CustomXPathNSResolver.h
@@ -49,15 +49,14 @@ class V8Proxy;
// must not exceed the lifetime of the passed handle.
class V8CustomXPathNSResolver : public XPathNSResolver {
public:
- static PassRefPtr<V8CustomXPathNSResolver> create(V8Proxy* proxy, v8::Handle<v8::Object> resolver);
+ static PassRefPtr<V8CustomXPathNSResolver> create(v8::Handle<v8::Object> resolver);
virtual ~V8CustomXPathNSResolver();
virtual String lookupNamespaceURI(const String& prefix);
private:
- V8CustomXPathNSResolver(V8Proxy* proxy, v8::Handle<v8::Object> resolver);
+ explicit V8CustomXPathNSResolver(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/V8DOMApplicationCacheCustom.cpp b/WebCore/bindings/v8/custom/V8DOMApplicationCacheCustom.cpp
deleted file mode 100644
index 61760b3..0000000
--- a/WebCore/bindings/v8/custom/V8DOMApplicationCacheCustom.cpp
+++ /dev/null
@@ -1,80 +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 "V8DOMApplicationCache.h"
-
-#if ENABLE(OFFLINE_WEB_APPLICATIONS)
-
-#include "ApplicationCacheHost.h"
-#include "DOMApplicationCache.h"
-#include "V8Binding.h"
-#include "V8Document.h"
-#include "V8Proxy.h"
-#include "V8Utilities.h"
-#include "WorkerContextExecutionProxy.h"
-
-namespace WebCore {
-
-// Handles appcache.addEventListner(name, func, capture) method calls
-v8::Handle<v8::Value> V8DOMApplicationCache::addEventListenerCallback(const v8::Arguments& args)
-{
- INC_STATS("DOMApplicationCache.addEventListener()");
- DOMApplicationCache* appcache = V8DOMApplicationCache::toNative(args.Holder());
-
- RefPtr<EventListener> listener = V8DOMWrapper::getEventListener(appcache, args[1], false, ListenerFindOrCreate);
- if (listener) {
- createHiddenDependency(args.Holder(), args[1], cacheIndex);
- String eventType = toWebCoreString(args[0]);
- bool useCapture = args[2]->BooleanValue();
- appcache->addEventListener(eventType, listener, useCapture);
- }
- return v8::Undefined();
-}
-
-// Handles appcache.removeEventListner(name, func, capture) method calls
-v8::Handle<v8::Value> V8DOMApplicationCache::removeEventListenerCallback(const v8::Arguments& args)
-{
- INC_STATS("DOMApplicationCache.removeEventListener()");
- DOMApplicationCache* appcache = V8DOMApplicationCache::toNative(args.Holder());
-
- RefPtr<EventListener> listener = V8DOMWrapper::getEventListener(appcache, args[1], false, ListenerFindOnly);
- if (listener) {
- removeHiddenDependency(args.Holder(), args[1], cacheIndex);
- String eventType = toWebCoreString(args[0]);
- bool useCapture = args[2]->BooleanValue();
- appcache->removeEventListener(eventType, listener.get(), useCapture);
- }
- return v8::Undefined();
-}
-
-} // namespace WebCore
-
-#endif // ENABLE(OFFLINE_WEB_APPLICATIONS)
diff --git a/WebCore/bindings/v8/custom/V8DOMFormDataCustom.cpp b/WebCore/bindings/v8/custom/V8DOMFormDataCustom.cpp
new file mode 100644
index 0000000..8a39332
--- /dev/null
+++ b/WebCore/bindings/v8/custom/V8DOMFormDataCustom.cpp
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "V8DOMFormData.h"
+
+#include "DOMFormData.h"
+#include "V8Binding.h"
+#include "V8Blob.h"
+#include "V8Proxy.h"
+#include "V8Utilities.h"
+
+namespace WebCore {
+
+v8::Handle<v8::Value> V8DOMFormData::appendCallback(const v8::Arguments& args)
+{
+ INC_STATS("DOM.FormData.append()");
+
+ if (args.Length() < 2)
+ return throwError("Not enough arguments", V8Proxy::SyntaxError);
+
+ DOMFormData* domFormData = V8DOMFormData::toNative(args.Holder());
+
+ String name = toWebCoreStringWithNullCheck(args[0]);
+
+ v8::Handle<v8::Value> arg = args[1];
+ if (V8Blob::HasInstance(arg)) {
+ v8::Handle<v8::Object> object = v8::Handle<v8::Object>::Cast(arg);
+ Blob* blob = V8Blob::toNative(object);
+ ASSERT(blob);
+ domFormData->append(name, blob);
+ } else
+ domFormData->append(name, toWebCoreStringWithNullCheck(arg));
+
+ return v8::Undefined();
+}
+
+} // namespace WebCore
diff --git a/WebCore/bindings/v8/custom/V8DOMWindowCustom.cpp b/WebCore/bindings/v8/custom/V8DOMWindowCustom.cpp
index 9719837..6a53a1f 100644
--- a/WebCore/bindings/v8/custom/V8DOMWindowCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8DOMWindowCustom.cpp
@@ -31,7 +31,6 @@
#include "config.h"
#include "V8DOMWindow.h"
-#include "Base64.h"
#include "Chrome.h"
#include "Database.h"
#include "DOMTimer.h"
@@ -55,7 +54,13 @@
#include "V8BindingDOMWindow.h"
#include "V8BindingState.h"
#include "V8CustomEventListener.h"
+#include "V8Database.h"
+#include "V8DatabaseCallback.h"
+#include "V8GCForContextDispose.h"
+#include "V8HTMLAudioElementConstructor.h"
#include "V8HTMLCollection.h"
+#include "V8HTMLImageElementConstructor.h"
+#include "V8HTMLOptionElementConstructor.h"
#include "V8MessagePortCustom.h"
#include "V8Node.h"
#include "V8Proxy.h"
@@ -135,38 +140,14 @@ v8::Handle<v8::Value> WindowSetTimeoutImpl(const v8::Arguments& args, bool singl
id = DOMTimer::install(scriptContext, new ScheduledAction(V8Proxy::context(imp->frame()), functionString), timeout, singleShot);
}
- return v8::Integer::New(id);
-}
-
-static bool isAscii(const String& str)
-{
- for (size_t i = 0; i < str.length(); i++) {
- if (str[i] > 0xFF)
- return false;
+ // Try to do the idle notification before the timeout expires to get better
+ // use of any idle time. Aim for the middle of the interval for simplicity.
+ if (timeout > 0) {
+ double maximumFireInterval = static_cast<double>(timeout) / 1000 / 2;
+ V8GCForContextDispose::instance().notifyIdleSooner(maximumFireInterval);
}
- return true;
-}
-static v8::Handle<v8::Value> convertBase64(const String& str, bool encode)
-{
- if (!isAscii(str)) {
- V8Proxy::setDOMException(INVALID_CHARACTER_ERR);
- return notHandledByInterceptor();
- }
-
- Vector<char> inputCharacters(str.length());
- for (size_t i = 0; i < str.length(); i++)
- inputCharacters[i] = static_cast<char>(str[i]);
- Vector<char> outputCharacters;
-
- if (encode)
- base64Encode(inputCharacters, outputCharacters);
- else {
- if (!base64Decode(inputCharacters, outputCharacters))
- return throwError("Cannot decode base64", V8Proxy::GeneralError);
- }
-
- return v8String(String(outputCharacters.data(), outputCharacters.size()));
+ return v8::Integer::New(id);
}
v8::Handle<v8::Value> V8DOMWindow::eventAccessorGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info)
@@ -250,7 +231,7 @@ void V8DOMWindow::openerAccessorSetter(v8::Local<v8::String> name, v8::Local<v8:
v8::Handle<v8::Value> V8DOMWindow::AudioAccessorGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info)
{
DOMWindow* window = V8DOMWindow::toNative(info.Holder());
- return V8DOMWrapper::getConstructor(V8ClassIndex::AUDIO, window);
+ return V8DOMWrapper::getConstructor(&V8HTMLAudioElementConstructor::info, window);
}
#endif
@@ -258,13 +239,13 @@ v8::Handle<v8::Value> V8DOMWindow::AudioAccessorGetter(v8::Local<v8::String> nam
v8::Handle<v8::Value> V8DOMWindow::ImageAccessorGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info)
{
DOMWindow* window = V8DOMWindow::toNative(info.Holder());
- return V8DOMWrapper::getConstructor(V8ClassIndex::IMAGE, window);
+ return V8DOMWrapper::getConstructor(&V8HTMLImageElementConstructor::info, window);
}
v8::Handle<v8::Value> V8DOMWindow::OptionAccessorGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info)
{
DOMWindow* window = V8DOMWindow::toNative(info.Holder());
- return V8DOMWrapper::getConstructor(V8ClassIndex::OPTION, window);
+ return V8DOMWrapper::getConstructor(&V8HTMLOptionElementConstructor::info, window);
}
v8::Handle<v8::Value> V8DOMWindow::addEventListenerCallback(const v8::Arguments& args)
@@ -289,11 +270,11 @@ v8::Handle<v8::Value> V8DOMWindow::addEventListenerCallback(const v8::Arguments&
if (!proxy)
return v8::Undefined();
- RefPtr<EventListener> listener = V8DOMWrapper::getEventListener(proxy, args[1], false, ListenerFindOrCreate);
+ RefPtr<EventListener> listener = V8DOMWrapper::getEventListener(args[1], false, ListenerFindOrCreate);
if (listener) {
imp->addEventListener(eventType, listener, useCapture);
- createHiddenDependency(args.Holder(), args[1], cacheIndex);
+ createHiddenDependency(args.Holder(), args[1], eventListenerCacheIndex);
}
return v8::Undefined();
@@ -321,11 +302,11 @@ v8::Handle<v8::Value> V8DOMWindow::removeEventListenerCallback(const v8::Argumen
if (!proxy)
return v8::Undefined();
- RefPtr<EventListener> listener = V8DOMWrapper::getEventListener(proxy, args[1], false, ListenerFindOnly);
+ RefPtr<EventListener> listener = V8DOMWrapper::getEventListener(args[1], false, ListenerFindOnly);
if (listener) {
imp->removeEventListener(eventType, listener.get(), useCapture);
- removeHiddenDependency(args.Holder(), args[1], cacheIndex);
+ removeHiddenDependency(args.Holder(), args[1], eventListenerCacheIndex);
}
return v8::Undefined();
@@ -339,8 +320,11 @@ v8::Handle<v8::Value> V8DOMWindow::postMessageCallback(const v8::Arguments& args
DOMWindow* source = V8Proxy::retrieveFrameForCallingContext()->domWindow();
ASSERT(source->frame());
- v8::TryCatch tryCatch;
- RefPtr<SerializedScriptValue> message = SerializedScriptValue::create(args[0]);
+ bool didThrow = false;
+ RefPtr<SerializedScriptValue> message = SerializedScriptValue::create(args[0], didThrow);
+ if (didThrow)
+ return v8::Undefined();
+
MessagePortArray portArray;
String targetOrigin;
@@ -348,6 +332,7 @@ v8::Handle<v8::Value> V8DOMWindow::postMessageCallback(const v8::Arguments& args
// postMessage(message, port, targetOrigin);
// or
// postMessage(message, targetOrigin);
+ v8::TryCatch tryCatch;
if (args.Length() > 2) {
if (!getMessagePortArray(args[1], portArray))
return v8::Undefined();
@@ -364,44 +349,6 @@ v8::Handle<v8::Value> V8DOMWindow::postMessageCallback(const v8::Arguments& args
return throwError(ec);
}
-v8::Handle<v8::Value> V8DOMWindow::atobCallback(const v8::Arguments& args)
-{
- INC_STATS("DOM.DOMWindow.atob()");
-
- if (args[0]->IsNull())
- return v8String("");
- String str = toWebCoreString(args[0]);
-
- DOMWindow* imp = V8DOMWindow::toNative(args.Holder());
-
- if (!V8BindingSecurity::canAccessFrame(V8BindingState::Only(), imp->frame(), true))
- return v8::Undefined();
-
- if (args.Length() < 1)
- return throwError("Not enough arguments", V8Proxy::SyntaxError);
-
- return convertBase64(str, false);
-}
-
-v8::Handle<v8::Value> V8DOMWindow::btoaCallback(const v8::Arguments& args)
-{
- INC_STATS("DOM.DOMWindow.btoa()");
-
- if (args[0]->IsNull())
- return v8String("");
- String str = toWebCoreString(args[0]);
-
- DOMWindow* imp = V8DOMWindow::toNative(args.Holder());
-
- if (!V8BindingSecurity::canAccessFrame(V8BindingState::Only(), imp->frame(), true))
- return v8::Undefined();
-
- if (args.Length() < 1)
- return throwError("Not enough arguments", V8Proxy::SyntaxError);
-
- return convertBase64(str, true);
-}
-
// FIXME(fqian): returning string is cheating, and we should
// fix this by calling toString function on the receiver.
// However, V8 implements toString in JavaScript, which requires
@@ -768,39 +715,33 @@ v8::Handle<v8::Value> V8DOMWindow::setIntervalCallback(const v8::Arguments& args
return WindowSetTimeoutImpl(args, false);
}
-
-void ClearTimeoutImpl(const v8::Arguments& args)
+v8::Handle<v8::Value> V8DOMWindow::openDatabaseCallback(const v8::Arguments& args)
{
- int handle = toInt32(args[0]);
+ INC_STATS("DOM.DOMWindow.openDatabase");
+ if (args.Length() < 4)
+ return v8::Undefined();
- v8::Handle<v8::Object> holder = args.Holder();
- DOMWindow* imp = V8DOMWindow::toNative(holder);
+ DOMWindow* imp = V8DOMWindow::toNative(args.Holder());
if (!V8BindingSecurity::canAccessFrame(V8BindingState::Only(), imp->frame(), true))
- return;
- ScriptExecutionContext* context = static_cast<ScriptExecutionContext*>(imp->document());
- if (!context)
- return;
- DOMTimer::removeById(context, handle);
-}
+ return v8::Undefined();
+ ExceptionCode ec = 0;
+ String name = toWebCoreString(args[0]);
+ String version = toWebCoreString(args[1]);
+ String displayName = toWebCoreString(args[2]);
+ unsigned long estimatedSize = args[3]->IntegerValue();
+ RefPtr<DatabaseCallback> creationCallback;
+ if ((args.Length() >= 5) && args[4]->IsObject())
+ creationCallback = V8DatabaseCallback::create(args[4], imp->frame());
-v8::Handle<v8::Value> V8DOMWindow::clearTimeoutCallback(const v8::Arguments& args)
-{
- INC_STATS("DOM.DOMWindow.clearTimeout");
- ClearTimeoutImpl(args);
- return v8::Undefined();
-}
+ v8::Handle<v8::Value> result = toV8(imp->openDatabase(name, version, displayName, estimatedSize, creationCallback.release(), ec));
-v8::Handle<v8::Value> V8DOMWindow::clearIntervalCallback(const v8::Arguments& args)
-{
- INC_STATS("DOM.DOMWindow.clearInterval");
- ClearTimeoutImpl(args);
- return v8::Undefined();
+ V8Proxy::setDOMException(ec);
+ return result;
}
-bool V8DOMWindow::namedSecurityCheck(v8::Local<v8::Object> host, v8::Local<v8::Value> key, v8::AccessType type, v8::Local<v8::Value> data)
+bool V8DOMWindow::namedSecurityCheck(v8::Local<v8::Object> host, v8::Local<v8::Value> key, v8::AccessType type, v8::Local<v8::Value>)
{
- ASSERT(V8ClassIndex::FromInt(data->Int32Value()) == V8ClassIndex::DOMWINDOW);
v8::Handle<v8::Object> window = V8DOMWrapper::lookupDOMWrapper(V8DOMWindow::GetTemplate(), host);
if (window.IsEmpty())
return false; // the frame is gone.
@@ -824,9 +765,8 @@ bool V8DOMWindow::namedSecurityCheck(v8::Local<v8::Object> host, v8::Local<v8::V
return V8BindingSecurity::canAccessFrame(V8BindingState::Only(), target, false);
}
-bool V8DOMWindow::indexedSecurityCheck(v8::Local<v8::Object> host, uint32_t index, v8::AccessType type, v8::Local<v8::Value> data)
+bool V8DOMWindow::indexedSecurityCheck(v8::Local<v8::Object> host, uint32_t index, v8::AccessType type, v8::Local<v8::Value>)
{
- ASSERT(V8ClassIndex::FromInt(data->Int32Value()) == V8ClassIndex::DOMWINDOW);
v8::Handle<v8::Object> window = V8DOMWrapper::lookupDOMWrapper(V8DOMWindow::GetTemplate(), host);
if (window.IsEmpty())
return false;
diff --git a/WebCore/bindings/v8/custom/V8DatabaseCallback.cpp b/WebCore/bindings/v8/custom/V8DatabaseCallback.cpp
new file mode 100644
index 0000000..088d89f
--- /dev/null
+++ b/WebCore/bindings/v8/custom/V8DatabaseCallback.cpp
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2010, Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if ENABLE(DATABASE)
+
+#include "V8DatabaseCallback.h"
+
+#include "Frame.h"
+#include "ScriptExecutionContext.h"
+#include "V8CustomVoidCallback.h"
+#include "V8Database.h"
+
+namespace WebCore {
+
+V8DatabaseCallback::V8DatabaseCallback(v8::Local<v8::Object> callback, Frame* frame)
+ : m_callback(v8::Persistent<v8::Object>::New(callback))
+ , m_frame(frame)
+ , m_worldContext(UseCurrentWorld)
+{
+}
+
+V8DatabaseCallback::~V8DatabaseCallback()
+{
+ m_callback.Dispose();
+}
+
+void V8DatabaseCallback::handleEvent(ScriptExecutionContext* context, Database* database)
+{
+ v8::HandleScope handleScope;
+
+ v8::Handle<v8::Context> v8Context = toV8Context(context, m_worldContext);
+ if (v8Context.IsEmpty())
+ return;
+
+ v8::Context::Scope scope(v8Context);
+
+ v8::Handle<v8::Value> argv[] = {
+ toV8(database)
+ };
+
+ // Protect the frame until the callback returns.
+ RefPtr<Frame> protector(m_frame);
+
+ bool callbackReturnValue = false;
+ invokeCallback(m_callback, 1, argv, callbackReturnValue);
+}
+
+} // namespace WebCore
+
+#endif
diff --git a/WebCore/bindings/v8/custom/V8DatabaseCallback.h b/WebCore/bindings/v8/custom/V8DatabaseCallback.h
new file mode 100644
index 0000000..064a9a7
--- /dev/null
+++ b/WebCore/bindings/v8/custom/V8DatabaseCallback.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef V8DatabaseCallback_h
+#define V8DatabaseCallback_h
+
+#if ENABLE(DATABASE)
+
+#include "DatabaseCallback.h"
+#include "WorldContextHandle.h"
+#include <v8.h>
+#include <wtf/Forward.h>
+
+namespace WebCore {
+
+class Frame;
+
+class V8DatabaseCallback : public DatabaseCallback {
+public:
+ static PassRefPtr<V8DatabaseCallback> create(v8::Local<v8::Value> value, Frame* frame)
+ {
+ ASSERT(value->IsObject());
+ return adoptRef(new V8DatabaseCallback(value->ToObject(), frame));
+ }
+ virtual ~V8DatabaseCallback();
+
+ virtual void handleEvent(ScriptExecutionContext*, Database*);
+
+private:
+ V8DatabaseCallback(v8::Local<v8::Object>, Frame*);
+
+ v8::Persistent<v8::Object> m_callback;
+ RefPtr<Frame> m_frame;
+ WorldContextHandle m_worldContext;
+};
+
+} // namespace WebCore
+
+#endif
+
+#endif // V8DatabaseCallback_h
diff --git a/WebCore/bindings/v8/custom/V8DedicatedWorkerContextCustom.cpp b/WebCore/bindings/v8/custom/V8DedicatedWorkerContextCustom.cpp
index 4486dbe..8fcf9a8 100644
--- a/WebCore/bindings/v8/custom/V8DedicatedWorkerContextCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8DedicatedWorkerContextCustom.cpp
@@ -46,7 +46,10 @@ v8::Handle<v8::Value> V8DedicatedWorkerContext::postMessageCallback(const v8::Ar
{
INC_STATS(L"DOM.DedicatedWorkerContext.postMessage");
DedicatedWorkerContext* workerContext = V8DedicatedWorkerContext::toNative(args.Holder());
- RefPtr<SerializedScriptValue> message = SerializedScriptValue::create(args[0]);
+ bool didThrow = false;
+ RefPtr<SerializedScriptValue> message = SerializedScriptValue::create(args[0], didThrow);
+ if (didThrow)
+ return v8::Undefined();
MessagePortArray portArray;
if (args.Length() > 1) {
if (!getMessagePortArray(args[1], portArray))
diff --git a/WebCore/bindings/v8/custom/V8DocumentCustom.cpp b/WebCore/bindings/v8/custom/V8DocumentCustom.cpp
index 8968707..9fa9f80 100644
--- a/WebCore/bindings/v8/custom/V8DocumentCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8DocumentCustom.cpp
@@ -46,11 +46,16 @@
#include "V8IsolatedContext.h"
#include "V8Node.h"
#include "V8Proxy.h"
-#include "V8SVGDocument.h"
+#if ENABLE(3D_CANVAS)
#include "V8WebGLRenderingContext.h"
+#endif
#include "V8XPathNSResolver.h"
#include "V8XPathResult.h"
+#if ENABLE(SVG)
+#include "V8SVGDocument.h"
+#endif
+
#include <wtf/RefPtr.h>
namespace WebCore {
@@ -67,7 +72,7 @@ v8::Handle<v8::Value> V8Document::evaluateCallback(const v8::Arguments& args)
if (V8Node::HasInstance(args[1]))
contextNode = V8Node::toNative(v8::Handle<v8::Object>::Cast(args[1]));
- RefPtr<XPathNSResolver> resolver = V8DOMWrapper::getXPathNSResolver(args[2], V8Proxy::retrieve(V8Proxy::retrieveFrameForCallingContext()));
+ RefPtr<XPathNSResolver> resolver = V8DOMWrapper::getXPathNSResolver(args[2]);
if (!resolver && !args[2]->IsNull() && !args[2]->IsUndefined())
return throwError(TYPE_MISMATCH_ERR);
diff --git a/WebCore/bindings/v8/custom/V8ElementCustom.cpp b/WebCore/bindings/v8/custom/V8ElementCustom.cpp
index 86f134e..8256110 100644
--- a/WebCore/bindings/v8/custom/V8ElementCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8ElementCustom.cpp
@@ -45,7 +45,10 @@
#include "V8BindingState.h"
#include "V8HTMLElement.h"
#include "V8Proxy.h"
+
+#if ENABLE(SVG)
#include "V8SVGElement.h"
+#endif
#include <wtf/RefPtr.h>
diff --git a/WebCore/bindings/v8/custom/V8EventCustom.cpp b/WebCore/bindings/v8/custom/V8EventCustom.cpp
index 79bddc0..b2728ec 100644
--- a/WebCore/bindings/v8/custom/V8EventCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8EventCustom.cpp
@@ -33,11 +33,13 @@
#include "Clipboard.h"
#include "ClipboardEvent.h"
+#include "CustomEvent.h"
#include "Event.h"
#include "V8BeforeLoadEvent.h"
#include "V8Binding.h"
#include "V8Clipboard.h"
#include "V8CompositionEvent.h"
+#include "V8CustomEvent.h"
#include "V8ErrorEvent.h"
#include "V8KeyboardEvent.h"
#include "V8MessageEvent.h"
@@ -48,7 +50,6 @@
#include "V8PopStateEvent.h"
#include "V8ProgressEvent.h"
#include "V8Proxy.h"
-#include "V8SVGZoomEvent.h"
#include "V8StorageEvent.h"
#include "V8TextEvent.h"
#include "V8TouchEvent.h"
@@ -58,6 +59,10 @@
#include "V8WheelEvent.h"
#include "V8XMLHttpRequestProgressEvent.h"
+#if ENABLE(SVG)
+#include "V8SVGZoomEvent.h"
+#endif
+
namespace WebCore {
void V8Event::valueAccessorSetter(v8::Local<v8::String> name, v8::Local<v8::Value> value, const v8::AccessorInfo& info)
@@ -140,6 +145,8 @@ v8::Handle<v8::Value> toV8(Event* impl)
#endif
if (impl->isBeforeLoadEvent())
return toV8(static_cast<BeforeLoadEvent*>(impl));
+ if (impl->isCustomEvent())
+ return toV8(static_cast<CustomEvent*>(impl));
return V8Event::wrap(impl);
}
} // namespace WebCore
diff --git a/WebCore/bindings/v8/custom/V8EventSourceConstructor.cpp b/WebCore/bindings/v8/custom/V8EventSourceConstructor.cpp
index 793ffb6..01e9c44 100644
--- a/WebCore/bindings/v8/custom/V8EventSourceConstructor.cpp
+++ b/WebCore/bindings/v8/custom/V8EventSourceConstructor.cpp
@@ -56,17 +56,17 @@ v8::Handle<v8::Value> V8EventSource::constructorCallback(const v8::Arguments& ar
if (!context)
return throwError("EventSource constructor's associated context is not available", V8Proxy::ReferenceError);
if (args.Length() != 1)
- return throwError("EventSource constructor wrong number of parameters", V8Proxy::TypeError);
+ return throwError("Not enough arguments", V8Proxy::SyntaxError);
ExceptionCode ec = 0;
String url = toWebCoreString(args[0]);
RefPtr<EventSource> eventSource = EventSource::create(url, context, ec);
-
+
if (ec)
return throwError(ec);
- V8DOMWrapper::setDOMWrapper(args.Holder(), V8ClassIndex::ToInt(V8ClassIndex::EVENTSOURCE), eventSource.get());
+ V8DOMWrapper::setDOMWrapper(args.Holder(), &info, eventSource.get());
// Add object to the wrapper map.
eventSource->ref();
diff --git a/WebCore/bindings/v8/custom/V8EventSourceCustom.cpp b/WebCore/bindings/v8/custom/V8EventSourceCustom.cpp
deleted file mode 100644
index a7f79db..0000000
--- a/WebCore/bindings/v8/custom/V8EventSourceCustom.cpp
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright 2010, The Android Open Source Project
- *
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``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(EVENTSOURCE)
-#include "V8EventSource.h"
-
-#include "EventSource.h"
-
-#include "V8Binding.h"
-#include "V8Proxy.h"
-
-namespace WebCore {
-
-v8::Handle<v8::Value> V8EventSource::addEventListenerCallback(const v8::Arguments& args)
-{
- INC_STATS("DOM.EventSource.addEventListener()");
- EventSource* eventSource = V8EventSource::toNative(args.Holder());
-
- RefPtr<EventListener> listener = V8DOMWrapper::getEventListener(eventSource, args[1], false, ListenerFindOrCreate);
- if (listener) {
- String type = toWebCoreString(args[0]);
- bool useCapture = args[2]->BooleanValue();
- eventSource->addEventListener(type, listener, useCapture);
-
- createHiddenDependency(args.Holder(), args[1], cacheIndex);
- }
- return v8::Undefined();
-}
-
-v8::Handle<v8::Value> V8EventSource::removeEventListenerCallback(const v8::Arguments& args)
-{
- INC_STATS("DOM.EventSource.removeEventListener()");
- EventSource* eventSource = V8EventSource::toNative(args.Holder());
-
- RefPtr<EventListener> listener = V8DOMWrapper::getEventListener(eventSource, args[1], false, ListenerFindOnly);
- if (listener) {
- String type = toWebCoreString(args[0]);
- bool useCapture = args[2]->BooleanValue();
- eventSource->removeEventListener(type, listener.get(), useCapture);
-
- removeHiddenDependency(args.Holder(), args[1], cacheIndex);
- }
-
- return v8::Undefined();
-}
-
-} // namespace WebCore
-
-#endif // ENABLE(EVENTSOURCE)
diff --git a/WebCore/bindings/v8/custom/V8HTMLAudioElementConstructor.cpp b/WebCore/bindings/v8/custom/V8HTMLAudioElementConstructor.cpp
index 9b75db8..df16501 100644
--- a/WebCore/bindings/v8/custom/V8HTMLAudioElementConstructor.cpp
+++ b/WebCore/bindings/v8/custom/V8HTMLAudioElementConstructor.cpp
@@ -44,6 +44,8 @@
namespace WebCore {
+WrapperTypeInfo V8HTMLAudioElementConstructor::info = { V8HTMLAudioElementConstructor::GetTemplate, 0, false };
+
static v8::Handle<v8::Value> v8HTMLAudioElementConstructorCallback(const v8::Arguments& args)
{
INC_STATS("DOM.HTMLAudioElement.Contructor");
@@ -69,7 +71,7 @@ static v8::Handle<v8::Value> v8HTMLAudioElementConstructorCallback(const v8::Arg
src = toWebCoreString(args[0]);
RefPtr<HTMLAudioElement> audio = HTMLAudioElement::createForJSConstructor(document, src);
- V8DOMWrapper::setDOMWrapper(args.Holder(), V8ClassIndex::ToInt(V8ClassIndex::AUDIO), audio.get());
+ V8DOMWrapper::setDOMWrapper(args.Holder(), &V8HTMLAudioElementConstructor::info, audio.get());
audio->ref();
V8DOMWrapper::setJSWrapperForDOMNode(audio.get(), v8::Persistent<v8::Object>::New(args.Holder()));
return args.Holder();
diff --git a/WebCore/bindings/v8/custom/V8HTMLAudioElementConstructor.h b/WebCore/bindings/v8/custom/V8HTMLAudioElementConstructor.h
index 711f539..8bc5f2c 100755
--- a/WebCore/bindings/v8/custom/V8HTMLAudioElementConstructor.h
+++ b/WebCore/bindings/v8/custom/V8HTMLAudioElementConstructor.h
@@ -31,6 +31,8 @@
#ifndef V8HTMLAudioElementConstructor_h
#define V8HTMLAudioElementConstructor_h
+#include "WrapperTypeInfo.h"
+
#include <v8.h>
namespace WebCore {
@@ -38,6 +40,7 @@ namespace WebCore {
class V8HTMLAudioElementConstructor {
public:
static v8::Persistent<v8::FunctionTemplate> GetTemplate();
+ static WrapperTypeInfo info;
};
}
diff --git a/WebCore/bindings/v8/custom/V8HTMLCanvasElementCustom.cpp b/WebCore/bindings/v8/custom/V8HTMLCanvasElementCustom.cpp
index 54a003c..67ba38b 100644
--- a/WebCore/bindings/v8/custom/V8HTMLCanvasElementCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8HTMLCanvasElementCustom.cpp
@@ -39,7 +39,9 @@
#include "V8CanvasRenderingContext2D.h"
#include "V8Node.h"
#include "V8Proxy.h"
+#if ENABLE(3D_CANVAS)
#include "V8WebGLRenderingContext.h"
+#endif
namespace WebCore {
@@ -54,7 +56,7 @@ v8::Handle<v8::Value> V8HTMLCanvasElement::getContextCallback(const v8::Argument
if (contextId == "experimental-webgl" || contextId == "webkit-3d") {
attrs = WebGLContextAttributes::create();
WebGLContextAttributes* webGLAttrs = static_cast<WebGLContextAttributes*>(attrs.get());
- if (args.Length() > 1 && args[0]->IsObject()) {
+ if (args.Length() > 1 && args[1]->IsObject()) {
v8::Handle<v8::Object> jsAttrs = args[1]->ToObject();
v8::Handle<v8::String> alpha = v8::String::New("alpha");
if (jsAttrs->Has(alpha))
diff --git a/WebCore/bindings/v8/custom/V8HTMLImageElementConstructor.cpp b/WebCore/bindings/v8/custom/V8HTMLImageElementConstructor.cpp
index 29b4813..4751224 100644
--- a/WebCore/bindings/v8/custom/V8HTMLImageElementConstructor.cpp
+++ b/WebCore/bindings/v8/custom/V8HTMLImageElementConstructor.cpp
@@ -44,6 +44,8 @@
namespace WebCore {
+WrapperTypeInfo V8HTMLImageElementConstructor::info = { V8HTMLImageElementConstructor::GetTemplate, 0, false };
+
static v8::Handle<v8::Value> v8HTMLImageElementConstructorCallback(const v8::Arguments& args)
{
INC_STATS("DOM.HTMLImageElement.Contructor");
@@ -80,7 +82,7 @@ static v8::Handle<v8::Value> v8HTMLImageElementConstructorCallback(const v8::Arg
}
RefPtr<HTMLImageElement> image = HTMLImageElement::createForJSConstructor(document, optionalWidth, optionalHeight);
- V8DOMWrapper::setDOMWrapper(args.Holder(), V8ClassIndex::ToInt(V8ClassIndex::IMAGE), image.get());
+ V8DOMWrapper::setDOMWrapper(args.Holder(), &V8HTMLImageElementConstructor::info, image.get());
image->ref();
V8DOMWrapper::setJSWrapperForDOMNode(image.get(), v8::Persistent<v8::Object>::New(args.Holder()));
return args.Holder();
diff --git a/WebCore/bindings/v8/custom/V8HTMLImageElementConstructor.h b/WebCore/bindings/v8/custom/V8HTMLImageElementConstructor.h
index 19ee944..5db4946 100755
--- a/WebCore/bindings/v8/custom/V8HTMLImageElementConstructor.h
+++ b/WebCore/bindings/v8/custom/V8HTMLImageElementConstructor.h
@@ -31,6 +31,8 @@
#ifndef V8HTMLImageElementConstructor_h
#define V8HTMLImageElementConstructor_h
+#include "WrapperTypeInfo.h"
+
#include <v8.h>
namespace WebCore {
@@ -38,6 +40,7 @@ namespace WebCore {
class V8HTMLImageElementConstructor {
public:
static v8::Persistent<v8::FunctionTemplate> GetTemplate();
+ static WrapperTypeInfo info;
};
}
diff --git a/WebCore/bindings/v8/custom/V8HTMLOptionElementConstructor.cpp b/WebCore/bindings/v8/custom/V8HTMLOptionElementConstructor.cpp
index 1ff1d2e..6b84856 100644
--- a/WebCore/bindings/v8/custom/V8HTMLOptionElementConstructor.cpp
+++ b/WebCore/bindings/v8/custom/V8HTMLOptionElementConstructor.cpp
@@ -44,6 +44,8 @@
namespace WebCore {
+WrapperTypeInfo V8HTMLOptionElementConstructor::info = { V8HTMLOptionElementConstructor::GetTemplate, 0, false };
+
static v8::Handle<v8::Value> v8HTMLOptionElementConstructorCallback(const v8::Arguments& args)
{
INC_STATS("DOM.HTMLOptionElement.Contructor");
@@ -78,7 +80,7 @@ static v8::Handle<v8::Value> v8HTMLOptionElementConstructorCallback(const v8::Ar
if (ec)
throwError(ec);
- V8DOMWrapper::setDOMWrapper(args.Holder(), V8ClassIndex::ToInt(V8ClassIndex::OPTION), option.get());
+ V8DOMWrapper::setDOMWrapper(args.Holder(), &V8HTMLOptionElementConstructor::info, option.get());
option->ref();
V8DOMWrapper::setJSWrapperForDOMNode(option.get(), v8::Persistent<v8::Object>::New(args.Holder()));
return args.Holder();
diff --git a/WebCore/bindings/v8/custom/V8HTMLOptionElementConstructor.h b/WebCore/bindings/v8/custom/V8HTMLOptionElementConstructor.h
index 905a745..2adf0fe 100755
--- a/WebCore/bindings/v8/custom/V8HTMLOptionElementConstructor.h
+++ b/WebCore/bindings/v8/custom/V8HTMLOptionElementConstructor.h
@@ -31,6 +31,8 @@
#ifndef V8HTMLOptionElementConstructor_h
#define V8HTMLOptionElementConstructor_h
+#include "WrapperTypeInfo.h"
+
#include <v8.h>
namespace WebCore {
@@ -38,6 +40,7 @@ namespace WebCore {
class V8HTMLOptionElementConstructor {
public:
static v8::Persistent<v8::FunctionTemplate> GetTemplate();
+ static WrapperTypeInfo info;
};
}
diff --git a/WebCore/bindings/v8/custom/V8HistoryCustom.cpp b/WebCore/bindings/v8/custom/V8HistoryCustom.cpp
index 6075ec5..ad2b9a9 100644
--- a/WebCore/bindings/v8/custom/V8HistoryCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8HistoryCustom.cpp
@@ -43,7 +43,10 @@ namespace WebCore {
v8::Handle<v8::Value> V8History::pushStateCallback(const v8::Arguments& args)
{
- RefPtr<SerializedScriptValue> historyState = SerializedScriptValue::create(args[0]);
+ bool didThrow = false;
+ RefPtr<SerializedScriptValue> historyState = SerializedScriptValue::create(args[0], didThrow);
+ if (didThrow)
+ return v8::Undefined();
v8::TryCatch tryCatch;
String title = toWebCoreStringWithNullOrUndefinedCheck(args[1]);
@@ -64,7 +67,10 @@ v8::Handle<v8::Value> V8History::pushStateCallback(const v8::Arguments& args)
v8::Handle<v8::Value> V8History::replaceStateCallback(const v8::Arguments& args)
{
- RefPtr<SerializedScriptValue> historyState = SerializedScriptValue::create(args[0]);
+ bool didThrow = false;
+ RefPtr<SerializedScriptValue> historyState = SerializedScriptValue::create(args[0], didThrow);
+ if (didThrow)
+ return v8::Undefined();
v8::TryCatch tryCatch;
String title = toWebCoreStringWithNullOrUndefinedCheck(args[1]);
@@ -83,33 +89,18 @@ v8::Handle<v8::Value> V8History::replaceStateCallback(const v8::Arguments& args)
return throwError(ec);
}
-bool V8History::indexedSecurityCheck(v8::Local<v8::Object> host, uint32_t index, v8::AccessType type, v8::Local<v8::Value> data)
+bool V8History::indexedSecurityCheck(v8::Local<v8::Object> host, uint32_t index, v8::AccessType type, v8::Local<v8::Value>)
{
- ASSERT(V8ClassIndex::FromInt(data->Int32Value()) == V8ClassIndex::HISTORY);
// Only allow same origin access.
History* history = V8History::toNative(host);
return V8BindingSecurity::canAccessFrame(V8BindingState::Only(), history->frame(), false);
}
-bool V8History::namedSecurityCheck(v8::Local<v8::Object> host, v8::Local<v8::Value> key, v8::AccessType type, v8::Local<v8::Value> data)
+bool V8History::namedSecurityCheck(v8::Local<v8::Object> host, v8::Local<v8::Value> key, v8::AccessType type, v8::Local<v8::Value>)
{
- ASSERT(V8ClassIndex::FromInt(data->Int32Value()) == V8ClassIndex::HISTORY);
// Only allow same origin access.
History* history = V8History::toNative(host);
return V8BindingSecurity::canAccessFrame(V8BindingState::Only(), history->frame(), false);
}
-v8::Handle<v8::Value> toV8(History* impl)
-{
- if (!impl)
- return v8::Null();
- v8::Handle<v8::Object> wrapper = getDOMObjectMap().get(impl);
- if (wrapper.IsEmpty()) {
- wrapper = V8History::wrap(impl);
- if (!wrapper.IsEmpty())
- V8DOMWrapper::setHiddenWindowReference(impl->frame(), V8DOMWindow::historyIndex, wrapper);
- }
- return wrapper;
-}
-
} // namespace WebCore
diff --git a/WebCore/bindings/v8/custom/V8IndexedDatabaseRequestCustom.cpp b/WebCore/bindings/v8/custom/V8IndexedDatabaseRequestCustom.cpp
index 0fd182c..e8c2b68 100644
--- a/WebCore/bindings/v8/custom/V8IndexedDatabaseRequestCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8IndexedDatabaseRequestCustom.cpp
@@ -33,7 +33,12 @@
#if ENABLE(INDEXED_DATABASE)
#include "V8IndexedDatabaseRequest.h"
+#include "IDBDatabaseError.h"
+#include "IDBDatabaseRequest.h"
#include "V8Binding.h"
+#include "V8CustomIDBCallbacks.h"
+#include "V8IDBDatabaseError.h"
+#include "V8IDBDatabaseRequest.h"
#include "V8Proxy.h"
namespace WebCore {
@@ -45,12 +50,32 @@ v8::Handle<v8::Value> V8IndexedDatabaseRequest::openCallback(const v8::Arguments
return throwError(V8Proxy::TypeError);
V8Parameter<> name = args[0];
V8Parameter<> description = args[1];
+
bool modifyDatabase = true;
- if (args.Length() > 2)
+ if (args.Length() > 2 && !args[2]->IsUndefined() && !args[2]->IsNull())
modifyDatabase = args[2]->BooleanValue();
+ v8::Local<v8::Value> onError;
+ v8::Local<v8::Value> onSuccess;
+ if (args.Length() > 3 && !args[3]->IsUndefined() && !args[3]->IsNull()) {
+ if (!args[3]->IsObject())
+ return throwError("onerror callback was not the proper type");
+ onError = args[3];
+ }
+ if (args.Length() > 4 && !args[4]->IsUndefined() && !args[4]->IsNull()) {
+ if (!args[4]->IsObject())
+ return throwError("onsuccess callback was not the proper type");
+ onSuccess = args[4];
+ }
+ if (!onError->IsObject() && !onSuccess->IsObject())
+ return throwError("Neither the onerror nor the onsuccess callbacks were set.");
+
+ Frame* frame = V8Proxy::retrieveFrameForCurrentContext();
+ RefPtr<V8CustomIDBCallbacks<IDBDatabase, IDBDatabaseRequest> > callbacks =
+ V8CustomIDBCallbacks<IDBDatabase, IDBDatabaseRequest>::create(onSuccess, onError, frame->document());
+
ExceptionCode ec = 0;
- imp->open(name, description, modifyDatabase, ec);
+ imp->open(name, description, modifyDatabase, callbacks, ec);
if (ec)
return throwError(ec);
return v8::Handle<v8::Value>();
diff --git a/WebCore/bindings/v8/custom/V8InjectedScriptHostCustom.cpp b/WebCore/bindings/v8/custom/V8InjectedScriptHostCustom.cpp
index 054f9ba..4c091c8 100644
--- a/WebCore/bindings/v8/custom/V8InjectedScriptHostCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8InjectedScriptHostCustom.cpp
@@ -39,10 +39,14 @@
#include "InspectorController.h"
#include "Node.h"
#include "Page.h"
+#include "ScriptDebugServer.h"
#include "SerializedScriptValue.h"
#include "V8Binding.h"
+#include "V8BindingState.h"
+#include "V8DOMWindow.h"
#include "V8Database.h"
+#include "V8JavaScriptCallFrame.h"
#include "V8Node.h"
#include "V8Proxy.h"
#include "V8Storage.h"
@@ -59,7 +63,6 @@ static void WeakReferenceCallback(v8::Persistent<v8::Value> object, void* parame
static v8::Local<v8::Object> createInjectedScriptHostV8Wrapper(InjectedScriptHost* host)
{
- V8ClassIndex::V8WrapperType descriptorType = V8ClassIndex::INJECTEDSCRIPTHOST;
v8::Local<v8::Function> function = V8InjectedScriptHost::GetTemplate()->GetFunction();
if (function.IsEmpty()) {
// Return if allocation failed.
@@ -70,7 +73,7 @@ static v8::Local<v8::Object> createInjectedScriptHostV8Wrapper(InjectedScriptHos
// Avoid setting the wrapper if allocation failed.
return v8::Local<v8::Object>();
}
- V8DOMWrapper::setDOMWrapper(instance, V8ClassIndex::ToInt(descriptorType), host);
+ V8DOMWrapper::setDOMWrapper(instance, &V8InjectedScriptHost::info, host);
// Create a weak reference to the v8 wrapper of InspectorBackend to deref
// InspectorBackend when the wrapper is garbage collected.
host->ref();
@@ -79,7 +82,7 @@ static v8::Local<v8::Object> createInjectedScriptHostV8Wrapper(InjectedScriptHos
return instance;
}
-static ScriptObject createInjectedScript(const String& scriptSource, InjectedScriptHost* injectedScriptHost, ScriptState* inspectedScriptState, long id)
+ScriptObject InjectedScriptHost::createInjectedScript(const String& scriptSource, ScriptState* inspectedScriptState, long id)
{
v8::HandleScope scope;
@@ -90,7 +93,7 @@ static ScriptObject createInjectedScript(const String& scriptSource, InjectedScr
// instead of calling toV8() that would create the
// wrapper in the current context.
// FIXME: make it possible to use generic bindings factory for InjectedScriptHost.
- v8::Local<v8::Object> scriptHostWrapper = createInjectedScriptHostV8Wrapper(injectedScriptHost);
+ v8::Local<v8::Object> scriptHostWrapper = createInjectedScriptHostV8Wrapper(this);
if (scriptHostWrapper.IsEmpty())
return ScriptObject();
@@ -109,9 +112,10 @@ static ScriptObject createInjectedScript(const String& scriptSource, InjectedScr
v8::Handle<v8::Value> args[] = {
scriptHostWrapper,
windowGlobal,
- v8::Number::New(id)
+ v8::Number::New(id),
+ v8::String::New("v8")
};
- v8::Local<v8::Value> injectedScriptValue = v8::Function::Cast(*v)->Call(windowGlobal, 3, args);
+ v8::Local<v8::Value> injectedScriptValue = v8::Function::Cast(*v)->Call(windowGlobal, 4, args);
v8::Local<v8::Object> injectedScript(v8::Object::Cast(*injectedScriptValue));
return ScriptObject(inspectedScriptState, injectedScript);
}
@@ -151,6 +155,20 @@ v8::Handle<v8::Value> V8InjectedScriptHost::pushNodePathToFrontendCallback(const
return v8::Undefined();
}
+#if ENABLE(JAVASCRIPT_DEBUGGER)
+v8::Handle<v8::Value> V8InjectedScriptHost::currentCallFrameCallback(const v8::Arguments& args)
+{
+ INC_STATS("InjectedScriptHost.currentCallFrame()");
+ return toV8(ScriptDebugServer::shared().currentCallFrame());
+}
+
+v8::Handle<v8::Value> V8InjectedScriptHost::isActivationCallback(const v8::Arguments& args)
+{
+ INC_STATS("InjectedScriptHost.isActivation()");
+ return v8::Boolean::New(true);
+}
+#endif
+
#if ENABLE(DATABASE)
v8::Handle<v8::Value> V8InjectedScriptHost::databaseForIdCallback(const v8::Arguments& args)
{
@@ -226,12 +244,27 @@ InjectedScript InjectedScriptHost::injectedScriptFor(ScriptState* inspectedScrip
return InjectedScript(ScriptObject(inspectedScriptState, v8::Local<v8::Object>::Cast(val)));
ASSERT(!m_injectedScriptSource.isEmpty());
- ScriptObject injectedScriptObject = createInjectedScript(m_injectedScriptSource, this, inspectedScriptState, m_nextInjectedScriptId);
- InjectedScript result(injectedScriptObject);
- m_idToInjectedScript.set(m_nextInjectedScriptId, result);
- ++m_nextInjectedScriptId;
- global->SetHiddenValue(key, injectedScriptObject.v8Object());
+ pair<long, ScriptObject> injectedScript = injectScript(m_injectedScriptSource, inspectedScriptState);
+ InjectedScript result(injectedScript.second);
+ m_idToInjectedScript.set(injectedScript.first, result);
+ global->SetHiddenValue(key, injectedScript.second.v8Object());
return result;
}
+bool InjectedScriptHost::canAccessInspectedWindow(ScriptState* scriptState)
+{
+ v8::HandleScope handleScope;
+ v8::Local<v8::Context> context = scriptState->context();
+ v8::Local<v8::Object> global = context->Global();
+ if (global.IsEmpty())
+ return false;
+ v8::Handle<v8::Object> holder = V8DOMWrapper::lookupDOMWrapper(V8DOMWindow::GetTemplate(), global);
+ if (holder.IsEmpty())
+ return false;
+ Frame* frame = V8DOMWindow::toNative(holder)->frame();
+
+ v8::Context::Scope contextScope(context);
+ return V8BindingSecurity::canAccessFrame(V8BindingState::Only(), frame, false);
+}
+
} // namespace WebCore
diff --git a/WebCore/bindings/v8/custom/V8InspectorFrontendHostCustom.cpp b/WebCore/bindings/v8/custom/V8InspectorFrontendHostCustom.cpp
index b823034..7f4ccf7 100644
--- a/WebCore/bindings/v8/custom/V8InspectorFrontendHostCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8InspectorFrontendHostCustom.cpp
@@ -35,12 +35,65 @@
#include "InspectorFrontendHost.h"
#include "V8Binding.h"
+#include "V8MouseEvent.h"
#include "V8Proxy.h"
namespace WebCore {
+v8::Handle<v8::Value> V8InspectorFrontendHost::platformCallback(const v8::Arguments&)
+{
+#if defined(OS_MACOSX)
+ return v8String("mac");
+#elif defined(OS_LINUX)
+ return v8String("linux");
+#elif defined(OS_WIN)
+ return v8String("windows");
+#else
+ return v8String("unknown");
+#endif
+}
+
+v8::Handle<v8::Value> V8InspectorFrontendHost::portCallback(const v8::Arguments&)
+{
+ return v8::Undefined();
+}
+
v8::Handle<v8::Value> V8InspectorFrontendHost::showContextMenuCallback(const v8::Arguments& args)
{
+ if (args.Length() < 2)
+ return v8::Undefined();
+
+ v8::Local<v8::Object> eventWrapper = v8::Local<v8::Object>::Cast(args[0]);
+ if (!V8MouseEvent::info.equals(V8DOMWrapper::domWrapperType(eventWrapper)))
+ return v8::Undefined();
+
+ Event* event = V8Event::toNative(eventWrapper);
+ if (!args[1]->IsArray())
+ return v8::Undefined();
+
+ v8::Local<v8::Array> array = v8::Local<v8::Array>::Cast(args[1]);
+ Vector<ContextMenuItem*> items;
+
+ for (size_t i = 0; i < array->Length(); ++i) {
+ v8::Local<v8::Object> item = v8::Local<v8::Object>::Cast(array->Get(v8::Integer::New(i)));
+ v8::Local<v8::Value> label = item->Get(v8::String::New("label"));
+ v8::Local<v8::Value> id = item->Get(v8::String::New("id"));
+ if (label->IsUndefined() || id->IsUndefined()) {
+ items.append(new ContextMenuItem(SeparatorType,
+ ContextMenuItemTagNoAction,
+ String()));
+ } else {
+ ContextMenuAction typedId = static_cast<ContextMenuAction>(
+ ContextMenuItemBaseCustomTag + id->ToInt32()->Value());
+ items.append(new ContextMenuItem(ActionType,
+ typedId,
+ toWebCoreStringWithNullCheck(label)));
+ }
+ }
+
+ InspectorFrontendHost* frontendHost = V8InspectorFrontendHost::toNative(args.Holder());
+ frontendHost->showContextMenu(event, items);
+
return v8::Undefined();
}
diff --git a/WebCore/bindings/v8/custom/V8JavaScriptCallFrameCustom.cpp b/WebCore/bindings/v8/custom/V8JavaScriptCallFrameCustom.cpp
new file mode 100644
index 0000000..e2a691d
--- /dev/null
+++ b/WebCore/bindings/v8/custom/V8JavaScriptCallFrameCustom.cpp
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "V8JavaScriptCallFrame.h"
+
+#if ENABLE(JAVASCRIPT_DEBUGGER)
+
+#include "V8Binding.h"
+#include "V8Proxy.h"
+
+namespace WebCore {
+
+v8::Handle<v8::Value> V8JavaScriptCallFrame::evaluateCallback(const v8::Arguments& args)
+{
+ INC_STATS("V8JavaScriptCallFrame.evaluateCallback()");
+ JavaScriptCallFrame* impl = V8JavaScriptCallFrame::toNative(args.Holder());
+ String expression = toWebCoreStringWithNullOrUndefinedCheck(args[0]);
+ return impl->evaluate(expression);
+}
+
+v8::Handle<v8::Value> V8JavaScriptCallFrame::scopeChainAccessorGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info)
+{
+ INC_STATS("V8JavaScriptCallFrame.scopeChainAccessorGetter()");
+ JavaScriptCallFrame* impl = V8JavaScriptCallFrame::toNative(info.Holder());
+ return impl->scopeChain();
+}
+
+v8::Handle<v8::Value> V8JavaScriptCallFrame::scopeTypeCallback(const v8::Arguments& args)
+{
+ INC_STATS("V8JavaScriptCallFrame.scopeTypeCallback()");
+ JavaScriptCallFrame* impl = V8JavaScriptCallFrame::toNative(args.Holder());
+ int scopeIndex = args[0]->Int32Value();
+ return v8::Int32::New(impl->scopeType(scopeIndex));
+}
+
+v8::Handle<v8::Value> V8JavaScriptCallFrame::thisObjectAccessorGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info)
+{
+ INC_STATS("V8JavaScriptCallFrame.thisObjectAccessorGetter()");
+ JavaScriptCallFrame* impl = V8JavaScriptCallFrame::toNative(info.Holder());
+ return impl->thisObject();
+}
+
+v8::Handle<v8::Value> V8JavaScriptCallFrame::typeAccessorGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info)
+{
+ INC_STATS("V8JavaScriptCallFrame.typeAccessorGetter()");
+ return v8String("function");
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(JAVASCRIPT_DEBUGGER)
diff --git a/WebCore/bindings/v8/custom/V8LocationCustom.cpp b/WebCore/bindings/v8/custom/V8LocationCustom.cpp
index b5df601..ac305c9 100644
--- a/WebCore/bindings/v8/custom/V8LocationCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8LocationCustom.cpp
@@ -75,9 +75,14 @@ void V8Location::hashAccessorSetter(v8::Local<v8::String> name, v8::Local<v8::Va
if (hash.startsWith("#"))
hash = hash.substring(1);
- if (oldRef == hash || (oldRef.isNull() && hash.isEmpty()))
- return;
+
+ // Note that by parsing the URL and *then* comparing fragments, we are
+ // comparing fragments post-canonicalization, and so this handles the
+ // cases where fragment identifiers are ignored or invalid.
url.setFragmentIdentifier(hash);
+ String newRef = url.fragmentIdentifier();
+ if (oldRef == newRef || (oldRef.isNull() && newRef.isEmpty()))
+ return;
navigateIfAllowed(frame, url, false, false);
}
@@ -185,7 +190,10 @@ void V8Location::protocolAccessorSetter(v8::Local<v8::String> name, v8::Local<v8
return;
KURL url = frame->loader()->url();
- url.setProtocol(protocol);
+ if (!url.setProtocol(protocol)) {
+ throwError("Can't set protocol", V8Proxy::SyntaxError);
+ return;
+ }
navigateIfAllowed(frame, url, false, false);
}
@@ -342,17 +350,15 @@ v8::Handle<v8::Value> V8Location::toStringCallback(const v8::Arguments& args)
return v8String(result);
}
-bool V8Location::indexedSecurityCheck(v8::Local<v8::Object> host, uint32_t index, v8::AccessType type, v8::Local<v8::Value> data)
+bool V8Location::indexedSecurityCheck(v8::Local<v8::Object> host, uint32_t index, v8::AccessType type, v8::Local<v8::Value>)
{
- ASSERT(V8ClassIndex::FromInt(data->Int32Value()) == V8ClassIndex::LOCATION);
// Only allow same origin access
Location* imp = V8Location::toNative(host);
return V8BindingSecurity::canAccessFrame(V8BindingState::Only(), imp->frame(), false);
}
-bool V8Location::namedSecurityCheck(v8::Local<v8::Object> host, v8::Local<v8::Value> key, v8::AccessType type, v8::Local<v8::Value> data)
+bool V8Location::namedSecurityCheck(v8::Local<v8::Object> host, v8::Local<v8::Value> key, v8::AccessType type, v8::Local<v8::Value>)
{
- ASSERT(V8ClassIndex::FromInt(data->Int32Value()) == V8ClassIndex::LOCATION);
// Only allow same origin access
Location* imp = V8Location::toNative(host);
return V8BindingSecurity::canAccessFrame(V8BindingState::Only(), imp->frame(), false);
@@ -366,7 +372,7 @@ v8::Handle<v8::Value> toV8(Location* impl)
if (wrapper.IsEmpty()) {
wrapper = V8Location::wrap(impl);
if (!wrapper.IsEmpty())
- V8DOMWrapper::setHiddenWindowReference(impl->frame(), V8DOMWindow::locationIndex, wrapper);
+ V8DOMWrapper::setHiddenWindowReference(impl->frame(), wrapper);
}
return wrapper;
}
diff --git a/WebCore/bindings/v8/custom/V8MessageChannelConstructor.cpp b/WebCore/bindings/v8/custom/V8MessageChannelConstructor.cpp
index 4fb82ba..b966e42 100644
--- a/WebCore/bindings/v8/custom/V8MessageChannelConstructor.cpp
+++ b/WebCore/bindings/v8/custom/V8MessageChannelConstructor.cpp
@@ -67,11 +67,11 @@ v8::Handle<v8::Value> V8MessageChannel::constructorCallback(const v8::Arguments&
// Create references from the MessageChannel wrapper to the two
// MessagePort wrappers to make sure that the MessagePort wrappers
// stay alive as long as the MessageChannel wrapper is around.
- messageChannel->SetInternalField(V8MessageChannel::port1Index, toV8(obj->port1()));
- messageChannel->SetInternalField(V8MessageChannel::port2Index, toV8(obj->port2()));
+ V8DOMWrapper::setHiddenReference(messageChannel, toV8(obj->port1()));
+ V8DOMWrapper::setHiddenReference(messageChannel, toV8(obj->port2()));
// Setup the standard wrapper object internal fields.
- V8DOMWrapper::setDOMWrapper(messageChannel, V8ClassIndex::MESSAGECHANNEL, obj.get());
+ V8DOMWrapper::setDOMWrapper(messageChannel, &info, obj.get());
return toV8(obj.release(), messageChannel);
}
diff --git a/WebCore/bindings/v8/custom/V8MessageEventCustom.cpp b/WebCore/bindings/v8/custom/V8MessageEventCustom.cpp
index d41a785..cca4a24 100644
--- a/WebCore/bindings/v8/custom/V8MessageEventCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8MessageEventCustom.cpp
@@ -84,6 +84,8 @@ v8::Handle<v8::Value> V8MessageEvent::initMessageEventCallback(const v8::Argumen
return v8::Undefined();
}
event->initMessageEvent(typeArg, canBubbleArg, cancelableArg, dataArg.release(), originArg, lastEventIdArg, sourceArg, portArray.release());
+ v8::PropertyAttribute dataAttr = static_cast<v8::PropertyAttribute>(v8::DontDelete | v8::ReadOnly);
+ SerializedScriptValue::deserializeAndSetProperty(args.Holder(), "data", dataAttr, event->data());
return v8::Undefined();
}
diff --git a/WebCore/bindings/v8/custom/V8MessagePortCustom.cpp b/WebCore/bindings/v8/custom/V8MessagePortCustom.cpp
index 9890668..c41ed38 100644
--- a/WebCore/bindings/v8/custom/V8MessagePortCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8MessagePortCustom.cpp
@@ -42,42 +42,14 @@
namespace WebCore {
-v8::Handle<v8::Value> V8MessagePort::addEventListenerCallback(const v8::Arguments& args)
-{
- INC_STATS("DOM.MessagePort.addEventListener()");
- MessagePort* messagePort = V8MessagePort::toNative(args.Holder());
- RefPtr<EventListener> listener = V8DOMWrapper::getEventListener(messagePort, args[1], false, ListenerFindOrCreate);
- if (listener) {
- String type = toWebCoreString(args[0]);
- bool useCapture = args[2]->BooleanValue();
- messagePort->addEventListener(type, listener, useCapture);
-
- createHiddenDependency(args.Holder(), args[1], cacheIndex);
- }
- return v8::Undefined();
-}
-
-v8::Handle<v8::Value> V8MessagePort::removeEventListenerCallback(const v8::Arguments& args)
-{
- INC_STATS("DOM.MessagePort.removeEventListener()");
- MessagePort* messagePort = V8MessagePort::toNative(args.Holder());
- RefPtr<EventListener> listener = V8DOMWrapper::getEventListener(messagePort, args[1], false, ListenerFindOnly);
- if (listener) {
- String type = toWebCoreString(args[0]);
- bool useCapture = args[2]->BooleanValue();
- messagePort->removeEventListener(type, listener.get(), useCapture);
-
- removeHiddenDependency(args.Holder(), args[1], cacheIndex);
- }
-
- return v8::Undefined();
-}
-
v8::Handle<v8::Value> V8MessagePort::postMessageCallback(const v8::Arguments& args)
{
INC_STATS("DOM.MessagePort.postMessage");
MessagePort* messagePort = V8MessagePort::toNative(args.Holder());
- RefPtr<SerializedScriptValue> message = SerializedScriptValue::create(args[0]);
+ bool didThrow = false;
+ RefPtr<SerializedScriptValue> message = SerializedScriptValue::create(args[0], didThrow);
+ if (didThrow)
+ return v8::Undefined();
MessagePortArray portArray;
if (args.Length() > 1) {
if (!getMessagePortArray(args[1], portArray))
diff --git a/WebCore/bindings/v8/custom/V8NamedNodeMapCustom.cpp b/WebCore/bindings/v8/custom/V8NamedNodeMapCustom.cpp
index 611ab94..4e1dd21 100644
--- a/WebCore/bindings/v8/custom/V8NamedNodeMapCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8NamedNodeMapCustom.cpp
@@ -32,7 +32,9 @@
#include "V8NamedNodeMap.h"
#include "NamedNodeMap.h"
+#include "V8Attr.h"
#include "V8Binding.h"
+#include "V8BindingState.h"
#include "V8Element.h"
#include "V8Node.h"
#include "V8Proxy.h"
@@ -73,6 +75,48 @@ v8::Handle<v8::Value> V8NamedNodeMap::namedPropertyGetter(v8::Local<v8::String>
return toV8(result.release());
}
+v8::Handle<v8::Value> V8NamedNodeMap::setNamedItemNSCallback(const v8::Arguments& args)
+{
+ INC_STATS("DOM.NamedNodeMap.setNamedItemNS");
+ NamedNodeMap* imp = V8NamedNodeMap::toNative(args.Holder());
+ Node* newNode = V8Node::HasInstance(args[0]) ? V8Node::toNative(v8::Handle<v8::Object>::Cast(args[0])) : 0;
+
+ if (newNode && newNode->nodeType() == Node::ATTRIBUTE_NODE && imp->element()) {
+ if (!V8BindingSecurity::allowSettingSrcToJavascriptURL(V8BindingState::Only(), imp->element(), newNode->nodeName(), newNode->nodeValue()))
+ return v8::Handle<v8::Value>();
+ }
+
+ ExceptionCode ec = 0;
+ RefPtr<Node> result = imp->setNamedItemNS(newNode, ec);
+ if (UNLIKELY(ec)) {
+ throwError(ec);
+ return v8::Handle<v8::Value>();
+ }
+
+ return toV8(result.release());
+}
+
+v8::Handle<v8::Value> V8NamedNodeMap::setNamedItemCallback(const v8::Arguments & args)
+{
+ INC_STATS("DOM.NamedNodeMap.setNamedItem");
+ NamedNodeMap* imp = V8NamedNodeMap::toNative(args.Holder());
+ Node* newNode = V8Node::HasInstance(args[0]) ? V8Node::toNative(v8::Handle<v8::Object>::Cast(args[0])) : 0;
+
+ if (newNode && newNode->nodeType() == Node::ATTRIBUTE_NODE && imp->element()) {
+ if (!V8BindingSecurity::allowSettingSrcToJavascriptURL(V8BindingState::Only(), imp->element(), newNode->nodeName(), newNode->nodeValue()))
+ return v8::Handle<v8::Value>();
+ }
+
+ ExceptionCode ec = 0;
+ RefPtr<Node> result = imp->setNamedItem(newNode, ec);
+ if (UNLIKELY(ec)) {
+ throwError(ec);
+ return v8::Handle<v8::Value>();
+ }
+
+ return toV8(result.release());
+}
+
v8::Handle<v8::Value> toV8(NamedNodeMap* impl)
{
if (!impl)
@@ -80,10 +124,8 @@ v8::Handle<v8::Value> toV8(NamedNodeMap* impl)
v8::Handle<v8::Object> wrapper = V8NamedNodeMap::wrap(impl);
// Add a hidden reference from named node map to its owner node.
Element* element = impl->element();
- if (!wrapper.IsEmpty() && element) {
- v8::Handle<v8::Value> owner = toV8(element);
- wrapper->SetInternalField(V8NamedNodeMap::ownerNodeIndex, owner);
- }
+ if (!wrapper.IsEmpty() && element)
+ V8DOMWrapper::setHiddenReference(wrapper, toV8(element));
return wrapper;
}
diff --git a/WebCore/bindings/v8/custom/V8NodeCustom.cpp b/WebCore/bindings/v8/custom/V8NodeCustom.cpp
index 7907283..0a7198a 100644
--- a/WebCore/bindings/v8/custom/V8NodeCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8NodeCustom.cpp
@@ -37,6 +37,7 @@
#include "V8AbstractEventListener.h"
#include "V8Attr.h"
#include "V8Binding.h"
+#include "V8BindingState.h"
#include "V8CDATASection.h"
#include "V8Comment.h"
#include "V8CustomEventListener.h"
@@ -56,38 +57,43 @@
namespace WebCore {
-v8::Handle<v8::Value> V8Node::addEventListenerCallback(const v8::Arguments& args)
+static inline bool isFrameSrc(Element *element, const String& name)
{
- INC_STATS("DOM.Node.addEventListener()");
- Node* node = V8Node::toNative(args.Holder());
-
- RefPtr<EventListener> listener = V8DOMWrapper::getEventListener(node, args[1], false, ListenerFindOrCreate);
- if (listener) {
- String type = toWebCoreString(args[0]);
- bool useCapture = args[2]->BooleanValue();
- node->addEventListener(type, listener, useCapture);
- createHiddenDependency(args.Holder(), args[1], cacheIndex);
+ return element && (element->hasTagName(HTMLNames::iframeTag) || element->hasTagName(HTMLNames::frameTag)) && equalIgnoringCase(name, "src");
+}
+
+void V8Node::textContentAccessorSetter(v8::Local<v8::String> name, v8::Local<v8::Value> value, const v8::AccessorInfo& info)
+{
+ Node* imp = V8Node::toNative(info.Holder());
+ String nodeValue = toWebCoreStringWithNullCheck(value);
+
+ if (imp->nodeType() == Node::ATTRIBUTE_NODE) {
+ Element * ownerElement = V8Attr::toNative(info.Holder())->ownerElement();
+ if (ownerElement && !V8BindingSecurity::allowSettingSrcToJavascriptURL(V8BindingState::Only(), ownerElement, imp->nodeName(), nodeValue))
+ return;
}
- return v8::Undefined();
+
+ ExceptionCode ec = 0;
+ imp->setTextContent(nodeValue, ec);
+ if (ec)
+ throwError(ec);
}
-v8::Handle<v8::Value> V8Node::removeEventListenerCallback(const v8::Arguments& args)
+void V8Node::nodeValueAccessorSetter(v8::Local<v8::String> name, v8::Local<v8::Value> value, const v8::AccessorInfo& info)
{
- INC_STATS("DOM.Node.removeEventListener()");
- Node* node = V8Node::toNative(args.Holder());
-
- // It is possbile that the owner document of the node is detached
- // from the frame.
- // See issue http://b/878909
- RefPtr<EventListener> listener = V8DOMWrapper::getEventListener(node, args[1], false, ListenerFindOnly);
- if (listener) {
- AtomicString type = v8ValueToAtomicWebCoreString(args[0]);
- bool useCapture = args[2]->BooleanValue();
- node->removeEventListener(type, listener.get(), useCapture);
- removeHiddenDependency(args.Holder(), args[1], cacheIndex);
+ Node* imp = V8Node::toNative(info.Holder());
+ String nodeValue = toWebCoreStringWithNullCheck(value);
+
+ if (imp->nodeType() == Node::ATTRIBUTE_NODE) {
+ Element * ownerElement = V8Attr::toNative(info.Holder())->ownerElement();
+ if (ownerElement && !V8BindingSecurity::allowSettingSrcToJavascriptURL(V8BindingState::Only(), ownerElement, imp->nodeName(), nodeValue))
+ return;
}
- return v8::Undefined();
+ ExceptionCode ec = 0;
+ imp->setNodeValue(nodeValue, ec);
+ if (ec)
+ throwError(ec);
}
// This function is customized to take advantage of the optional 4th argument: shouldLazyAttach
@@ -96,6 +102,12 @@ v8::Handle<v8::Value> V8Node::insertBeforeCallback(const v8::Arguments& args)
INC_STATS("DOM.Node.insertBefore");
v8::Handle<v8::Object> holder = args.Holder();
Node* imp = V8Node::toNative(holder);
+
+ if (imp->nodeType() == Node::ATTRIBUTE_NODE && isFrameSrc(V8Attr::toNative(holder)->ownerElement(), imp->nodeName())) {
+ V8Proxy::setDOMException(NOT_SUPPORTED_ERR);
+ return v8::Handle<v8::Value>();
+ }
+
ExceptionCode ec = 0;
Node* newChild = V8Node::HasInstance(args[0]) ? V8Node::toNative(v8::Handle<v8::Object>::Cast(args[0])) : 0;
Node* refChild = V8Node::HasInstance(args[1]) ? V8Node::toNative(v8::Handle<v8::Object>::Cast(args[1])) : 0;
@@ -115,6 +127,12 @@ v8::Handle<v8::Value> V8Node::replaceChildCallback(const v8::Arguments& args)
INC_STATS("DOM.Node.replaceChild");
v8::Handle<v8::Object> holder = args.Holder();
Node* imp = V8Node::toNative(holder);
+
+ if (imp->nodeType() == Node::ATTRIBUTE_NODE && isFrameSrc(V8Attr::toNative(holder)->ownerElement(), imp->nodeName())) {
+ V8Proxy::setDOMException(NOT_SUPPORTED_ERR);
+ return v8::Handle<v8::Value>();
+ }
+
ExceptionCode ec = 0;
Node* newChild = V8Node::HasInstance(args[0]) ? V8Node::toNative(v8::Handle<v8::Object>::Cast(args[0])) : 0;
Node* oldChild = V8Node::HasInstance(args[1]) ? V8Node::toNative(v8::Handle<v8::Object>::Cast(args[1])) : 0;
@@ -133,6 +151,12 @@ v8::Handle<v8::Value> V8Node::removeChildCallback(const v8::Arguments& args)
INC_STATS("DOM.Node.removeChild");
v8::Handle<v8::Object> holder = args.Holder();
Node* imp = V8Node::toNative(holder);
+
+ if (imp->nodeType() == Node::ATTRIBUTE_NODE && isFrameSrc(V8Attr::toNative(holder)->ownerElement(), imp->nodeName())) {
+ V8Proxy::setDOMException(NOT_SUPPORTED_ERR);
+ return v8::Handle<v8::Value>();
+ }
+
ExceptionCode ec = 0;
Node* oldChild = V8Node::HasInstance(args[0]) ? V8Node::toNative(v8::Handle<v8::Object>::Cast(args[0])) : 0;
bool success = imp->removeChild(oldChild, ec);
@@ -151,6 +175,12 @@ v8::Handle<v8::Value> V8Node::appendChildCallback(const v8::Arguments& args)
INC_STATS("DOM.Node.appendChild");
v8::Handle<v8::Object> holder = args.Holder();
Node* imp = V8Node::toNative(holder);
+
+ if (imp->nodeType() == Node::ATTRIBUTE_NODE && isFrameSrc(V8Attr::toNative(holder)->ownerElement(), imp->nodeName())) {
+ V8Proxy::setDOMException(NOT_SUPPORTED_ERR);
+ return v8::Handle<v8::Value>();
+ }
+
ExceptionCode ec = 0;
Node* newChild = V8Node::HasInstance(args[0]) ? V8Node::toNative(v8::Handle<v8::Object>::Cast(args[0])) : 0;
bool success = imp->appendChild(newChild, ec, true );
diff --git a/WebCore/bindings/v8/custom/V8NotificationCenterCustom.cpp b/WebCore/bindings/v8/custom/V8NotificationCenterCustom.cpp
index 9c3ab45..30773e3 100644
--- a/WebCore/bindings/v8/custom/V8NotificationCenterCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8NotificationCenterCustom.cpp
@@ -46,38 +46,6 @@
namespace WebCore {
-v8::Handle<v8::Value> V8Notification::addEventListenerCallback(const v8::Arguments& args)
-{
- INC_STATS("DOM.Notification.addEventListener()");
- Notification* notification = V8Notification::toNative(args.Holder());
-
- RefPtr<EventListener> listener = V8DOMWrapper::getEventListener(notification, args[1], false, ListenerFindOrCreate);
- if (listener) {
- String type = toWebCoreString(args[0]);
- bool useCapture = args[2]->BooleanValue();
- notification->addEventListener(type, listener, useCapture);
- createHiddenDependency(args.Holder(), args[1], cacheIndex);
- }
-
- return v8::Undefined();
-}
-
-v8::Handle<v8::Value> V8Notification::removeEventListenerCallback(const v8::Arguments& args)
-{
- INC_STATS("DOM.Notification.removeEventListener()");
- Notification* notification = V8Notification::toNative(args.Holder());
-
- RefPtr<EventListener> listener = V8DOMWrapper::getEventListener(notification, args[1], false, ListenerFindOnly);
- if (listener) {
- String type = toWebCoreString(args[0]);
- bool useCapture = args[2]->BooleanValue();
- notification->removeEventListener(type, listener.get(), useCapture);
- removeHiddenDependency(args.Holder(), args[1], cacheIndex);
- }
-
- return v8::Undefined();
-}
-
v8::Handle<v8::Value> V8NotificationCenter::createHTMLNotificationCallback(const v8::Arguments& args)
{
INC_STATS(L"DOM.NotificationCenter.CreateHTMLNotification()");
diff --git a/WebCore/bindings/v8/custom/V8PopStateEventCustom.cpp b/WebCore/bindings/v8/custom/V8PopStateEventCustom.cpp
index 46e9929..cdb160d 100644
--- a/WebCore/bindings/v8/custom/V8PopStateEventCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8PopStateEventCustom.cpp
@@ -35,6 +35,8 @@
#include "SerializedScriptValue.h"
#include "V8Proxy.h"
+#include <v8.h>
+
namespace WebCore {
v8::Handle<v8::Value> V8PopStateEvent::initPopStateEventCallback(const v8::Arguments& args)
@@ -44,7 +46,11 @@ v8::Handle<v8::Value> V8PopStateEvent::initPopStateEventCallback(const v8::Argum
String typeArg = v8ValueToWebCoreString(args[0]);
bool canBubbleArg = args[1]->BooleanValue();
bool cancelableArg = args[2]->BooleanValue();
- RefPtr<SerializedScriptValue> stateArg = SerializedScriptValue::create(args[3]);
+
+ bool didThrow = false;
+ RefPtr<SerializedScriptValue> stateArg = SerializedScriptValue::create(args[3], didThrow);
+ if (didThrow)
+ return v8::Undefined();
PopStateEvent* event = V8PopStateEvent::toNative(args.Holder());
event->initPopStateEvent(typeArg, canBubbleArg, cancelableArg, stateArg.release());
diff --git a/WebCore/bindings/v8/custom/V8SVGDocumentCustom.cpp b/WebCore/bindings/v8/custom/V8SVGDocumentCustom.cpp
index 558c03b..8dce61b 100644
--- a/WebCore/bindings/v8/custom/V8SVGDocumentCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8SVGDocumentCustom.cpp
@@ -29,6 +29,8 @@
*/
#include "config.h"
+
+#if ENABLE(SVG)
#include "V8SVGDocument.h"
#include "V8IsolatedContext.h"
@@ -51,3 +53,5 @@ v8::Handle<v8::Value> toV8(SVGDocument* impl, bool forceNewObject)
}
} // namespace WebCore
+
+#endif
diff --git a/WebCore/bindings/v8/custom/V8SVGElementCustom.cpp b/WebCore/bindings/v8/custom/V8SVGElementCustom.cpp
index 0ce48ce..7ad5f41 100644
--- a/WebCore/bindings/v8/custom/V8SVGElementCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8SVGElementCustom.cpp
@@ -29,10 +29,10 @@
*/
#include "config.h"
-#include "V8SVGElement.h"
#if ENABLE(SVG)
+#include "V8SVGElement.h"
#include "V8SVGElementWrapperFactory.h"
namespace WebCore {
diff --git a/WebCore/bindings/v8/custom/V8SVGElementInstanceCustom.cpp b/WebCore/bindings/v8/custom/V8SVGElementInstanceCustom.cpp
deleted file mode 100644
index 56c37bd..0000000
--- a/WebCore/bindings/v8/custom/V8SVGElementInstanceCustom.cpp
+++ /dev/null
@@ -1,80 +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(SVG)
-#include "V8SVGElementInstance.h"
-
-#include "EventListener.h"
-#include "SVGElementInstance.h"
-
-#include "V8Binding.h"
-#include "V8CustomEventListener.h"
-#include "V8SVGPODTypeWrapper.h"
-#include "V8Proxy.h"
-
-namespace WebCore {
-
-v8::Handle<v8::Value> V8SVGElementInstance::addEventListenerCallback(const v8::Arguments& args)
-{
- INC_STATS("DOM.SVGElementInstance.AddEventListener()");
- SVGElementInstance* instance = V8SVGElementInstance::toNative(args.Holder());
-
- RefPtr<EventListener> listener = V8DOMWrapper::getEventListener(instance, args[1], false, ListenerFindOrCreate);
- if (listener) {
- String type = toWebCoreString(args[0]);
- bool useCapture = args[2]->BooleanValue();
- instance->addEventListener(type, listener, useCapture);
- createHiddenDependency(args.Holder(), args[1], cacheIndex);
- }
-
- return v8::Undefined();
-}
-
-v8::Handle<v8::Value> V8SVGElementInstance::removeEventListenerCallback(const v8::Arguments& args)
-{
- INC_STATS("DOM.SVGElementInstance.RemoveEventListener()");
- SVGElementInstance* instance = V8SVGElementInstance::toNative(args.Holder());
-
- RefPtr<EventListener> listener = V8DOMWrapper::getEventListener(instance, args[1], false, ListenerFindOnly);
- if (listener) {
- String type = toWebCoreString(args[0]);
- bool useCapture = args[2]->BooleanValue();
- instance->removeEventListener(type, listener.get(), useCapture);
- removeHiddenDependency(args.Holder(), args[1], cacheIndex);
- }
-
- return v8::Undefined();
-}
-
-} // namespace WebCore
-
-#endif
diff --git a/WebCore/bindings/v8/custom/V8SVGPathSegCustom.cpp b/WebCore/bindings/v8/custom/V8SVGPathSegCustom.cpp
index a96d55e..5544f83 100644
--- a/WebCore/bindings/v8/custom/V8SVGPathSegCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8SVGPathSegCustom.cpp
@@ -29,6 +29,8 @@
*/
#include "config.h"
+
+#if ENABLE(SVG)
#include "V8SVGPathSeg.h"
#include "V8DOMWindow.h"
@@ -104,3 +106,5 @@ v8::Handle<v8::Value> toV8(SVGPathSeg* impl)
}
} // namespace WebCore
+
+#endif
diff --git a/WebCore/bindings/v8/custom/V8BarInfoCustom.cpp b/WebCore/bindings/v8/custom/V8ScriptProfileCustom.cpp
index 44f0b62..ddaabb0 100644
--- a/WebCore/bindings/v8/custom/V8BarInfoCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8ScriptProfileCustom.cpp
@@ -29,45 +29,33 @@
*/
#include "config.h"
-#include "V8BarInfo.h"
+#include "V8ScriptProfile.h"
-#include "V8DOMWindow.h"
-#include "V8DOMWrapper.h"
+#include "ScriptProfile.h"
+#include "V8Binding.h"
+#include "V8Proxy.h"
+
+#include <v8-profiler.h>
namespace WebCore {
-v8::Handle<v8::Value> toV8(BarInfo* impl)
+v8::Handle<v8::Value> toV8(ScriptProfile* impl)
{
if (!impl)
return v8::Null();
- v8::Handle<v8::Object> wrapper = getDOMObjectMap().get(impl);
- if (wrapper.IsEmpty()) {
- wrapper = V8BarInfo::wrap(impl);
- if (!wrapper.IsEmpty()) {
- Frame* frame = impl->frame();
- switch (impl->type()) {
- case BarInfo::Locationbar:
- V8DOMWrapper::setHiddenWindowReference(frame, V8DOMWindow::locationbarIndex, wrapper);
- break;
- case BarInfo::Menubar:
- V8DOMWrapper::setHiddenWindowReference(frame, V8DOMWindow::menubarIndex, wrapper);
- break;
- case BarInfo::Personalbar:
- V8DOMWrapper::setHiddenWindowReference(frame, V8DOMWindow::personalbarIndex, wrapper);
- break;
- case BarInfo::Scrollbars:
- V8DOMWrapper::setHiddenWindowReference(frame, V8DOMWindow::scrollbarsIndex, wrapper);
- break;
- case BarInfo::Statusbar:
- V8DOMWrapper::setHiddenWindowReference(frame, V8DOMWindow::statusbarIndex, wrapper);
- break;
- case BarInfo::Toolbar:
- V8DOMWrapper::setHiddenWindowReference(frame, V8DOMWindow::toolbarIndex, wrapper);
- break;
- }
- }
+ v8::Local<v8::Function> function = V8ScriptProfile::GetTemplate()->GetFunction();
+ if (function.IsEmpty()) {
+ // Return if allocation failed.
+ return v8::Local<v8::Object>();
+ }
+ v8::Local<v8::Object> instance = SafeAllocation::newInstance(function);
+ if (instance.IsEmpty()) {
+ // Avoid setting the wrapper if allocation failed.
+ return v8::Local<v8::Object>();
}
- return wrapper;
+ impl->ref();
+ V8DOMWrapper::setDOMWrapper(instance, &V8ScriptProfile::info, impl);
+ return instance;
}
} // namespace WebCore
diff --git a/WebCore/bindings/v8/custom/V8ScriptProfileNodeCustom.cpp b/WebCore/bindings/v8/custom/V8ScriptProfileNodeCustom.cpp
new file mode 100644
index 0000000..a4deeeb
--- /dev/null
+++ b/WebCore/bindings/v8/custom/V8ScriptProfileNodeCustom.cpp
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "V8ScriptProfileNode.h"
+
+#include "ScriptProfileNode.h"
+#include "V8Binding.h"
+#include "V8Proxy.h"
+
+#include <v8-profiler.h>
+
+namespace WebCore {
+
+v8::Handle<v8::Value> V8ScriptProfileNode::childrenAccessorGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info)
+{
+ INC_STATS("DOM.ScriptProfileNode.childrenAccessorGetter");
+ ScriptProfileNode* imp = V8ScriptProfileNode::toNative(info.Holder());
+ const ProfileNodesList& children = imp->children();
+ v8::Handle<v8::Array> result = v8::Array::New(children.size());
+ int index = 0;
+ ProfileNodesList::const_iterator end = children.end();
+ for (ProfileNodesList::const_iterator iter = children.begin(); iter != end; ++iter)
+ result->Set(v8::Integer::New(index++), toV8(iter->get()));
+ return result;
+}
+
+v8::Handle<v8::Value> V8ScriptProfileNode::callUIDAccessorGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info)
+{
+ INC_STATS("DOM.ScriptProfileNode.callUIDAccessorGetter");
+ ScriptProfileNode* imp = V8ScriptProfileNode::toNative(info.Holder());
+ return v8::Number::New(imp->callUID());
+}
+
+v8::Handle<v8::Value> toV8(ScriptProfileNode* impl)
+{
+ if (!impl)
+ return v8::Null();
+ v8::Local<v8::Function> function = V8ScriptProfileNode::GetTemplate()->GetFunction();
+ if (function.IsEmpty()) {
+ // Return if allocation failed.
+ return v8::Local<v8::Object>();
+ }
+ v8::Local<v8::Object> instance = SafeAllocation::newInstance(function);
+ if (instance.IsEmpty()) {
+ // Avoid setting the wrapper if allocation failed.
+ return v8::Local<v8::Object>();
+ }
+ impl->ref();
+ V8DOMWrapper::setDOMWrapper(instance, &V8ScriptProfileNode::info, impl);
+ return instance;
+}
+
+} // namespace WebCore
diff --git a/WebCore/bindings/v8/custom/V8SharedWorkerCustom.cpp b/WebCore/bindings/v8/custom/V8SharedWorkerCustom.cpp
index f69675a..2d72c37 100644
--- a/WebCore/bindings/v8/custom/V8SharedWorkerCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8SharedWorkerCustom.cpp
@@ -80,7 +80,7 @@ v8::Handle<v8::Value> V8SharedWorker::constructorCallback(const v8::Arguments& a
// Setup the standard wrapper object internal fields.
v8::Handle<v8::Object> wrapperObject = args.Holder();
- V8DOMWrapper::setDOMWrapper(wrapperObject, V8ClassIndex::SHAREDWORKER, obj.get());
+ V8DOMWrapper::setDOMWrapper(wrapperObject, &info, obj.get());
obj->ref();
V8DOMWrapper::setJSWrapperForActiveDOMObject(obj.get(), v8::Persistent<v8::Object>::New(wrapperObject));
diff --git a/WebCore/bindings/v8/custom/V8StyleSheetCustom.cpp b/WebCore/bindings/v8/custom/V8StyleSheetCustom.cpp
index b062cdc..b3f6ff7 100644
--- a/WebCore/bindings/v8/custom/V8StyleSheetCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8StyleSheetCustom.cpp
@@ -31,6 +31,7 @@
#include "config.h"
#include "V8StyleSheet.h"
+#include "V8DOMWrapper.h"
#include "V8CSSStyleSheet.h"
#include "V8Node.h"
@@ -45,10 +46,8 @@ v8::Handle<v8::Value> toV8(StyleSheet* impl)
v8::Handle<v8::Object> wrapper = V8StyleSheet::wrap(impl);
// Add a hidden reference from stylesheet object to its owner node.
Node* ownerNode = impl->ownerNode();
- if (ownerNode && !wrapper.IsEmpty()) {
- v8::Handle<v8::Object> owner = v8::Handle<v8::Object>::Cast(toV8(ownerNode));
- wrapper->SetInternalField(V8StyleSheet::ownerNodeIndex, owner);
- }
+ if (ownerNode && !wrapper.IsEmpty())
+ V8DOMWrapper::setHiddenReference(wrapper, toV8(ownerNode));
return wrapper;
}
diff --git a/WebCore/bindings/v8/custom/V8WebGLArrayBufferCustom.cpp b/WebCore/bindings/v8/custom/V8WebGLArrayBufferCustom.cpp
index 5b54563..d3e6cb5 100644
--- a/WebCore/bindings/v8/custom/V8WebGLArrayBufferCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8WebGLArrayBufferCustom.cpp
@@ -72,9 +72,13 @@ v8::Handle<v8::Value> V8WebGLArrayBuffer::constructorCallback(const v8::Argument
len = toInt32(args[0]);
}
- RefPtr<WebGLArrayBuffer> buffer = WebGLArrayBuffer::create(len);
+ RefPtr<WebGLArrayBuffer> buffer = WebGLArrayBuffer::create(len, 1);
+ if (!buffer.get()) {
+ V8Proxy::setDOMException(INDEX_SIZE_ERR);
+ return v8::Undefined();
+ }
// Transform the holder into a wrapper object for the array.
- V8DOMWrapper::setDOMWrapper(args.Holder(), V8ClassIndex::ToInt(V8ClassIndex::WEBGLARRAYBUFFER), buffer.get());
+ V8DOMWrapper::setDOMWrapper(args.Holder(), &info, buffer.get());
return toV8(buffer.release(), args.Holder());
}
diff --git a/WebCore/bindings/v8/custom/V8WebGLArrayCustom.cpp b/WebCore/bindings/v8/custom/V8WebGLArrayCustom.cpp
index a92e4f2..e15fa11 100644
--- a/WebCore/bindings/v8/custom/V8WebGLArrayCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8WebGLArrayCustom.cpp
@@ -33,6 +33,8 @@
#if ENABLE(3D_CANVAS)
#include "V8WebGLArray.h"
+#include "V8Binding.h"
+#include "V8Proxy.h"
#include "V8WebGLByteArray.h"
#include "V8WebGLFloatArray.h"
#include "V8WebGLIntArray.h"
@@ -64,6 +66,30 @@ v8::Handle<v8::Value> toV8(WebGLArray* impl)
return v8::Handle<v8::Value>();
}
+v8::Handle<v8::Value> V8WebGLArray::sliceCallback(const v8::Arguments& args)
+{
+ INC_STATS("DOM.WebGLArray.slice");
+ // Forms:
+ // * slice(long start, long end);
+
+ WebGLArray* imp = V8WebGLArray::toNative(args.Holder());
+ int start, end;
+ switch (args.Length()) {
+ case 0:
+ start = 0;
+ end = imp->length();
+ break;
+ case 1:
+ start = toInt32(args[0]);
+ end = imp->length();
+ break;
+ default:
+ start = toInt32(args[0]);
+ end = toInt32(args[1]);
+ }
+ return toV8(imp->slice(start, end));
+}
+
} // namespace WebCore
#endif // ENABLE(3D_CANVAS)
diff --git a/WebCore/bindings/v8/custom/V8WebGLArrayCustom.h b/WebCore/bindings/v8/custom/V8WebGLArrayCustom.h
index beea8e6..02bce9c 100644
--- a/WebCore/bindings/v8/custom/V8WebGLArrayCustom.h
+++ b/WebCore/bindings/v8/custom/V8WebGLArrayCustom.h
@@ -41,9 +41,8 @@
namespace WebCore {
// Template function used by the WebGLArray*Constructor callbacks.
-template<class ArrayClass>
-v8::Handle<v8::Value> constructWebGLArray(const v8::Arguments& args,
- int classIndex)
+template<class ArrayClass, class ElementType>
+v8::Handle<v8::Value> constructWebGLArray(const v8::Arguments& args, WrapperTypeInfo* type, v8::ExternalArrayType arrayType)
{
if (!args.IsConstructCall())
return throwError("DOM object constructor cannot be called as a function.");
@@ -71,96 +70,64 @@ v8::Handle<v8::Value> constructWebGLArray(const v8::Arguments& args,
// 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 = V8WebGLArrayBuffer::toNative(args[0]->ToObject());
- if (buf == NULL)
+ if (!buf)
return throwError("Could not convert argument 0 to a WebGLArrayBuffer");
bool ok;
- int offset = 0;
+ uint32_t offset = 0;
if (argLen > 1) {
- offset = toInt32(args[1], ok);
+ offset = toUInt32(args[1], ok);
if (!ok)
- return throwError("Could not convert argument 1 to an integer");
+ return throwError("Could not convert argument 1 to a number");
}
- int length = buf->byteLength() - offset;
+ uint32_t length = (buf->byteLength() - offset) / sizeof(ElementType);
if (argLen > 2) {
- length = toInt32(args[2], ok);
+ length = toUInt32(args[2], ok);
if (!ok)
- return throwError("Could not convert argument 2 to an integer");
+ return throwError("Could not convert argument 2 to a number");
}
- 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)");
+ if (!array)
+ return throwError("Out-of-range offset and/or length");
// 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());
+ V8DOMWrapper::setDOMWrapper(args.Holder(), type, array.get());
+ args.Holder()->SetIndexedPropertiesToExternalArrayData(array.get()->baseAddress(), arrayType, array.get()->length());
return toV8(array.release(), args.Holder());
}
- int len = 0;
+ uint32_t 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]);
+ len = toUInt32(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")));
+ return throwError("Could not convert argument 0 to an array");
+ len = toUInt32(srcArray->Get(v8::String::New("length")));
} else
- return throwError("Could not convert argument 0 to either an int32 or an object");
+ return throwError("Could not convert argument 0 to either a number or an array");
RefPtr<ArrayClass> array = ArrayClass::create(len);
+ if (!array.get()) {
+ V8Proxy::setDOMException(INDEX_SIZE_ERR);
+ return v8::Undefined();
+ }
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));
+ for (unsigned i = 0; i < len; i++) {
+ v8::Local<v8::Value> val = srcArray->Get(v8::Integer::NewFromUnsigned(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());
+ V8DOMWrapper::setDOMWrapper(args.Holder(), type, array.get());
+ args.Holder()->SetIndexedPropertiesToExternalArrayData(array.get()->baseAddress(), arrayType, 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 = reinterpret_cast<T*>(args.Holder()->GetPointerFromInternalField(v8DOMWrapperObjectIndex));
- 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)
{
@@ -169,21 +136,23 @@ v8::Handle<v8::Value> setWebGLArrayFromArray(T* webGLArray, const v8::Arguments&
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")));
- if (offset + length > webGLArray->length())
+ offset = toUInt32(args[1]);
+ uint32_t length = toUInt32(array->Get(v8::String::New("length")));
+ if (offset > webGLArray->length() ||
+ offset + length > webGLArray->length() ||
+ offset + length < offset)
+ // Out of range offset or overflow
V8Proxy::setDOMException(INDEX_SIZE_ERR);
else
for (uint32_t i = 0; i < length; i++)
- webGLArray->set(offset + i, array->Get(v8::Integer::New(i))->NumberValue());
+ webGLArray->set(offset + i, array->Get(v8::Integer::NewFromUnsigned(i))->NumberValue());
}
return v8::Undefined();
}
template <class CPlusPlusArrayType, class JavaScriptWrapperArrayType>
-v8::Handle<v8::Value> setWebGLArray(const v8::Arguments& args,
- V8ClassIndex::V8WrapperType wrapperType)
+v8::Handle<v8::Value> setWebGLArray(const v8::Arguments& args)
{
if (args.Length() < 1 || args.Length() > 2) {
V8Proxy::setDOMException(SYNTAX_ERR);
@@ -192,9 +161,10 @@ v8::Handle<v8::Value> setWebGLArray(const v8::Arguments& args,
CPlusPlusArrayType* array = JavaScriptWrapperArrayType::toNative(args.Holder());
+ // FIXME: change to IsUInt32() when available
if (args.Length() == 2 && args[0]->IsInt32()) {
// void set(in unsigned long index, in {long|float} value);
- uint32_t index = toInt32(args[0]);
+ uint32_t index = toUInt32(args[0]);
array->set(index, args[1]->NumberValue());
return v8::Undefined();
}
@@ -204,7 +174,7 @@ v8::Handle<v8::Value> setWebGLArray(const v8::Arguments& args,
CPlusPlusArrayType* src = JavaScriptWrapperArrayType::toNative(args[0]->ToObject());
uint32_t offset = 0;
if (args.Length() == 2)
- offset = toInt32(args[1]);
+ offset = toUInt32(args[1]);
ExceptionCode ec = 0;
array->set(src, offset, ec);
V8Proxy::setDOMException(ec);
diff --git a/WebCore/bindings/v8/custom/V8WebGLByteArrayCustom.cpp b/WebCore/bindings/v8/custom/V8WebGLByteArrayCustom.cpp
index dd6163a..8487ace 100644
--- a/WebCore/bindings/v8/custom/V8WebGLByteArrayCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8WebGLByteArrayCustom.cpp
@@ -47,19 +47,13 @@ v8::Handle<v8::Value> V8WebGLByteArray::constructorCallback(const v8::Arguments&
{
INC_STATS("DOM.WebGLByteArray.Contructor");
- return constructWebGLArray<WebGLByteArray>(args, V8ClassIndex::ToInt(V8ClassIndex::WEBGLBYTEARRAY));
-}
-
-v8::Handle<v8::Value> V8WebGLByteArray::getCallback(const v8::Arguments& args)
-{
- INC_STATS("DOM.WebGLByteArray.get()");
- return getWebGLArrayElement<WebGLByteArray, signed char>(args, V8ClassIndex::WEBGLBYTEARRAY);
+ return constructWebGLArray<WebGLByteArray, signed char>(args, &info, v8::kExternalByteArray);
}
v8::Handle<v8::Value> V8WebGLByteArray::setCallback(const v8::Arguments& args)
{
INC_STATS("DOM.WebGLByteArray.set()");
- return setWebGLArray<WebGLByteArray, V8WebGLByteArray>(args, V8ClassIndex::WEBGLBYTEARRAY);
+ return setWebGLArray<WebGLByteArray, V8WebGLByteArray>(args);
}
v8::Handle<v8::Value> toV8(WebGLByteArray* impl)
diff --git a/WebCore/bindings/v8/custom/V8WebGLFloatArrayCustom.cpp b/WebCore/bindings/v8/custom/V8WebGLFloatArrayCustom.cpp
index 3fb8865..77223ea 100644
--- a/WebCore/bindings/v8/custom/V8WebGLFloatArrayCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8WebGLFloatArrayCustom.cpp
@@ -47,19 +47,13 @@ v8::Handle<v8::Value> V8WebGLFloatArray::constructorCallback(const v8::Arguments
{
INC_STATS("DOM.WebGLFloatArray.Contructor");
- return constructWebGLArray<WebGLFloatArray>(args, V8ClassIndex::ToInt(V8ClassIndex::WEBGLFLOATARRAY));
-}
-
-v8::Handle<v8::Value> V8WebGLFloatArray::getCallback(const v8::Arguments& args)
-{
- INC_STATS("DOM.WebGLFloatArray.get()");
- return getWebGLArrayElement<WebGLFloatArray, float>(args, V8ClassIndex::WEBGLFLOATARRAY);
+ return constructWebGLArray<WebGLFloatArray, float>(args, &info, v8::kExternalFloatArray);
}
v8::Handle<v8::Value> V8WebGLFloatArray::setCallback(const v8::Arguments& args)
{
INC_STATS("DOM.WebGLFloatArray.set()");
- return setWebGLArray<WebGLFloatArray, V8WebGLFloatArray>(args, V8ClassIndex::WEBGLFLOATARRAY);
+ return setWebGLArray<WebGLFloatArray, V8WebGLFloatArray>(args);
}
v8::Handle<v8::Value> toV8(WebGLFloatArray* impl)
diff --git a/WebCore/bindings/v8/custom/V8WebGLIntArrayCustom.cpp b/WebCore/bindings/v8/custom/V8WebGLIntArrayCustom.cpp
index 0141a0b..532bdef 100644
--- a/WebCore/bindings/v8/custom/V8WebGLIntArrayCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8WebGLIntArrayCustom.cpp
@@ -47,19 +47,13 @@ v8::Handle<v8::Value> V8WebGLIntArray::constructorCallback(const v8::Arguments&
{
INC_STATS("DOM.WebGLIntArray.Contructor");
- return constructWebGLArray<WebGLIntArray>(args, V8ClassIndex::ToInt(V8ClassIndex::WEBGLINTARRAY));
-}
-
-v8::Handle<v8::Value> V8WebGLIntArray::getCallback(const v8::Arguments& args)
-{
- INC_STATS("DOM.WebGLIntArray.get()");
- return getWebGLArrayElement<WebGLIntArray, int>(args, V8ClassIndex::WEBGLINTARRAY);
+ return constructWebGLArray<WebGLIntArray, int>(args, &info, v8::kExternalIntArray);
}
v8::Handle<v8::Value> V8WebGLIntArray::setCallback(const v8::Arguments& args)
{
INC_STATS("DOM.WebGLIntArray.set()");
- return setWebGLArray<WebGLIntArray, V8WebGLIntArray>(args, V8ClassIndex::WEBGLINTARRAY);
+ return setWebGLArray<WebGLIntArray, V8WebGLIntArray>(args);
}
v8::Handle<v8::Value> toV8(WebGLIntArray* impl)
diff --git a/WebCore/bindings/v8/custom/V8WebGLRenderingContextCustom.cpp b/WebCore/bindings/v8/custom/V8WebGLRenderingContextCustom.cpp
index 78de5e6..1b8936d 100644
--- a/WebCore/bindings/v8/custom/V8WebGLRenderingContextCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8WebGLRenderingContextCustom.cpp
@@ -2,7 +2,7 @@
* 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
+ * modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
@@ -429,10 +429,6 @@ v8::Handle<v8::Value> V8WebGLRenderingContext::getUniformCallback(const v8::Argu
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);
@@ -786,10 +782,6 @@ static v8::Handle<v8::Value> vertexAttribAndUniformHelperf(const v8::Arguments&
WebGLRenderingContext* context = V8WebGLRenderingContext::toNative(args.Holder());
- if (!ok) {
- V8Proxy::setDOMException(SYNTAX_ERR);
- return notHandledByInterceptor();
- }
if (V8WebGLFloatArray::HasInstance(args[1])) {
WebGLFloatArray* array = V8WebGLFloatArray::toNative(args[1]->ToObject());
ASSERT(array != NULL);
@@ -862,10 +854,6 @@ static v8::Handle<v8::Value> uniformHelperi(const v8::Arguments& args,
bool ok = false;
WebGLUniformLocation* location = toWebGLUniformLocation(args[0], ok);
- if (!ok) {
- V8Proxy::setDOMException(SYNTAX_ERR);
- return notHandledByInterceptor();
- }
if (V8WebGLIntArray::HasInstance(args[1])) {
WebGLIntArray* array = V8WebGLIntArray::toNative(args[1]->ToObject());
ASSERT(array != NULL);
@@ -979,10 +967,6 @@ static v8::Handle<v8::Value> uniformMatrixHelper(const v8::Arguments& args,
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 = V8WebGLFloatArray::toNative(args[2]->ToObject());
diff --git a/WebCore/bindings/v8/custom/V8WebGLShortArrayCustom.cpp b/WebCore/bindings/v8/custom/V8WebGLShortArrayCustom.cpp
index 5a2408e..328f227 100644
--- a/WebCore/bindings/v8/custom/V8WebGLShortArrayCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8WebGLShortArrayCustom.cpp
@@ -47,19 +47,13 @@ v8::Handle<v8::Value> V8WebGLShortArray::constructorCallback(const v8::Arguments
{
INC_STATS("DOM.WebGLShortArray.Contructor");
- return constructWebGLArray<WebGLShortArray>(args, V8ClassIndex::ToInt(V8ClassIndex::WEBGLSHORTARRAY));
-}
-
-v8::Handle<v8::Value> V8WebGLShortArray::getCallback(const v8::Arguments& args)
-{
- INC_STATS("DOM.WebGLShortArray.get()");
- return getWebGLArrayElement<WebGLShortArray, short>(args, V8ClassIndex::WEBGLSHORTARRAY);
+ return constructWebGLArray<WebGLShortArray, short>(args, &info, v8::kExternalShortArray);
}
v8::Handle<v8::Value> V8WebGLShortArray::setCallback(const v8::Arguments& args)
{
INC_STATS("DOM.WebGLShortArray.set()");
- return setWebGLArray<WebGLShortArray, V8WebGLShortArray>(args, V8ClassIndex::WEBGLSHORTARRAY);
+ return setWebGLArray<WebGLShortArray, V8WebGLShortArray>(args);
}
v8::Handle<v8::Value> toV8(WebGLShortArray* impl)
diff --git a/WebCore/bindings/v8/custom/V8WebGLUnsignedByteArrayCustom.cpp b/WebCore/bindings/v8/custom/V8WebGLUnsignedByteArrayCustom.cpp
index 5a30ace..5185298 100644
--- a/WebCore/bindings/v8/custom/V8WebGLUnsignedByteArrayCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8WebGLUnsignedByteArrayCustom.cpp
@@ -47,19 +47,13 @@ v8::Handle<v8::Value> V8WebGLUnsignedByteArray::constructorCallback(const v8::Ar
{
INC_STATS("DOM.WebGLUnsignedByteArray.Contructor");
- return constructWebGLArray<WebGLUnsignedByteArray>(args, V8ClassIndex::ToInt(V8ClassIndex::WEBGLUNSIGNEDBYTEARRAY));
-}
-
-v8::Handle<v8::Value> V8WebGLUnsignedByteArray::getCallback(const v8::Arguments& args)
-{
- INC_STATS("DOM.WebGLUnsignedByteArray.get()");
- return getWebGLArrayElement<WebGLUnsignedByteArray, unsigned char>(args, V8ClassIndex::WEBGLUNSIGNEDBYTEARRAY);
+ return constructWebGLArray<WebGLUnsignedByteArray, unsigned char>(args, &info, v8::kExternalUnsignedByteArray);
}
v8::Handle<v8::Value> V8WebGLUnsignedByteArray::setCallback(const v8::Arguments& args)
{
INC_STATS("DOM.WebGLUnsignedByteArray.set()");
- return setWebGLArray<WebGLUnsignedByteArray, V8WebGLUnsignedByteArray>(args, V8ClassIndex::WEBGLUNSIGNEDBYTEARRAY);
+ return setWebGLArray<WebGLUnsignedByteArray, V8WebGLUnsignedByteArray>(args);
}
v8::Handle<v8::Value> toV8(WebGLUnsignedByteArray* impl)
diff --git a/WebCore/bindings/v8/custom/V8WebGLUnsignedIntArrayCustom.cpp b/WebCore/bindings/v8/custom/V8WebGLUnsignedIntArrayCustom.cpp
index cefc60e..14aa1bb 100644
--- a/WebCore/bindings/v8/custom/V8WebGLUnsignedIntArrayCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8WebGLUnsignedIntArrayCustom.cpp
@@ -47,19 +47,13 @@ v8::Handle<v8::Value> V8WebGLUnsignedIntArray::constructorCallback(const v8::Arg
{
INC_STATS("DOM.WebGLUnsignedIntArray.Contructor");
- return constructWebGLArray<WebGLUnsignedIntArray>(args, V8ClassIndex::ToInt(V8ClassIndex::WEBGLUNSIGNEDINTARRAY));
-}
-
-v8::Handle<v8::Value> V8WebGLUnsignedIntArray::getCallback(const v8::Arguments& args)
-{
- INC_STATS("DOM.WebGLUnsignedIntArray.get()");
- return getWebGLArrayElement<WebGLUnsignedIntArray, unsigned int>(args, V8ClassIndex::WEBGLUNSIGNEDINTARRAY);
+ return constructWebGLArray<WebGLUnsignedIntArray, unsigned int>(args, &info, v8::kExternalUnsignedIntArray);
}
v8::Handle<v8::Value> V8WebGLUnsignedIntArray::setCallback(const v8::Arguments& args)
{
INC_STATS("DOM.WebGLUnsignedIntArray.set()");
- return setWebGLArray<WebGLUnsignedIntArray, V8WebGLUnsignedIntArray>(args, V8ClassIndex::WEBGLUNSIGNEDINTARRAY);
+ return setWebGLArray<WebGLUnsignedIntArray, V8WebGLUnsignedIntArray>(args);
}
v8::Handle<v8::Value> toV8(WebGLUnsignedIntArray* impl)
diff --git a/WebCore/bindings/v8/custom/V8WebGLUnsignedShortArrayCustom.cpp b/WebCore/bindings/v8/custom/V8WebGLUnsignedShortArrayCustom.cpp
index 56e34b8..e9ebb4f 100644
--- a/WebCore/bindings/v8/custom/V8WebGLUnsignedShortArrayCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8WebGLUnsignedShortArrayCustom.cpp
@@ -47,19 +47,13 @@ v8::Handle<v8::Value> V8WebGLUnsignedShortArray::constructorCallback(const v8::A
{
INC_STATS("DOM.WebGLUnsignedShortArray.Contructor");
- return constructWebGLArray<WebGLUnsignedShortArray>(args, V8ClassIndex::ToInt(V8ClassIndex::WEBGLUNSIGNEDSHORTARRAY));
-}
-
-v8::Handle<v8::Value> V8WebGLUnsignedShortArray::getCallback(const v8::Arguments& args)
-{
- INC_STATS("DOM.WebGLUnsignedShortArray.get()");
- return getWebGLArrayElement<WebGLUnsignedShortArray, unsigned short>(args, V8ClassIndex::WEBGLUNSIGNEDSHORTARRAY);
+ return constructWebGLArray<WebGLUnsignedShortArray, unsigned short>(args, &info, v8::kExternalUnsignedShortArray);
}
v8::Handle<v8::Value> V8WebGLUnsignedShortArray::setCallback(const v8::Arguments& args)
{
INC_STATS("DOM.WebGLUnsignedShortArray.set()");
- return setWebGLArray<WebGLUnsignedShortArray, V8WebGLUnsignedShortArray>(args, V8ClassIndex::WEBGLUNSIGNEDSHORTARRAY);
+ return setWebGLArray<WebGLUnsignedShortArray, V8WebGLUnsignedShortArray>(args);
}
v8::Handle<v8::Value> toV8(WebGLUnsignedShortArray* impl)
diff --git a/WebCore/bindings/v8/custom/V8WebKitCSSMatrixConstructor.cpp b/WebCore/bindings/v8/custom/V8WebKitCSSMatrixConstructor.cpp
index 55518d2..b97d0e8 100644
--- a/WebCore/bindings/v8/custom/V8WebKitCSSMatrixConstructor.cpp
+++ b/WebCore/bindings/v8/custom/V8WebKitCSSMatrixConstructor.cpp
@@ -63,7 +63,7 @@ v8::Handle<v8::Value> V8WebKitCSSMatrix::constructorCallback(const v8::Arguments
throwError(ec);
// Transform the holder into a wrapper object for the matrix.
- V8DOMWrapper::setDOMWrapper(args.Holder(), V8ClassIndex::ToInt(V8ClassIndex::WEBKITCSSMATRIX), matrix.get());
+ V8DOMWrapper::setDOMWrapper(args.Holder(), &info, matrix.get());
return toV8(matrix.release(), args.Holder());
}
diff --git a/WebCore/bindings/v8/custom/V8WebKitPointConstructor.cpp b/WebCore/bindings/v8/custom/V8WebKitPointConstructor.cpp
index 1959454..cb29f82 100755
--- a/WebCore/bindings/v8/custom/V8WebKitPointConstructor.cpp
+++ b/WebCore/bindings/v8/custom/V8WebKitPointConstructor.cpp
@@ -33,8 +33,8 @@
#include "V8Binding.h"
#include "V8DOMWrapper.h"
-#include "V8Index.h"
#include "V8Proxy.h"
+#include "WrapperTypeInfo.h"
#include <wtf/MathExtras.h>
@@ -63,7 +63,7 @@ v8::Handle<v8::Value> V8WebKitPoint::constructorCallback(const v8::Arguments& ar
}
PassRefPtr<WebKitPoint> point = WebKitPoint::create(x, y);
point->ref();
- V8DOMWrapper::setDOMWrapper(args.Holder(), V8ClassIndex::WEBKITPOINT, point.get());
+ V8DOMWrapper::setDOMWrapper(args.Holder(), &info, point.get());
return args.Holder();
}
diff --git a/WebCore/bindings/v8/custom/V8WebSocketCustom.cpp b/WebCore/bindings/v8/custom/V8WebSocketCustom.cpp
index 2451b90..b931053 100644
--- a/WebCore/bindings/v8/custom/V8WebSocketCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8WebSocketCustom.cpp
@@ -45,37 +45,6 @@
namespace WebCore {
-v8::Handle<v8::Value> V8WebSocket::addEventListenerCallback(const v8::Arguments& args)
-{
- INC_STATS("DOM.WebSocket.addEventListener()");
- WebSocket* webSocket = V8WebSocket::toNative(args.Holder());
-
- RefPtr<EventListener> listener = V8DOMWrapper::getEventListener(webSocket, args[1], false, ListenerFindOrCreate);
- if (listener) {
- String type = toWebCoreString(args[0]);
- bool useCapture = args[2]->BooleanValue();
- webSocket->addEventListener(type, listener, useCapture);
-
- createHiddenDependency(args.Holder(), args[1], cacheIndex);
- }
- return v8::Undefined();
-}
-
-v8::Handle<v8::Value> V8WebSocket::removeEventListenerCallback(const v8::Arguments& args)
-{
- INC_STATS("DOM.WebSocket.removeEventListener()");
- WebSocket* webSocket = V8WebSocket::toNative(args.Holder());
-
- RefPtr<EventListener> listener = V8DOMWrapper::getEventListener(webSocket, args[1], false, ListenerFindOnly);
- if (listener) {
- String type = toWebCoreString(args[0]);
- bool useCapture = args[2]->BooleanValue();
- webSocket->removeEventListener(type, listener.get(), useCapture);
- removeHiddenDependency(args.Holder(), args[1], cacheIndex);
- }
- return v8::Undefined();
-}
-
v8::Handle<v8::Value> V8WebSocket::constructorCallback(const v8::Arguments& args)
{
INC_STATS("DOM.WebSocket.Constructor");
@@ -115,7 +84,7 @@ v8::Handle<v8::Value> V8WebSocket::constructorCallback(const v8::Arguments& args
return throwError(ec);
// Setup the standard wrapper object internal fields.
- V8DOMWrapper::setDOMWrapper(args.Holder(), V8ClassIndex::ToInt(V8ClassIndex::WEBSOCKET), webSocket.get());
+ V8DOMWrapper::setDOMWrapper(args.Holder(), &info, webSocket.get());
// Add object to the wrapper map.
webSocket->ref();
diff --git a/WebCore/bindings/v8/custom/V8WorkerContextCustom.cpp b/WebCore/bindings/v8/custom/V8WorkerContextCustom.cpp
index 7677e27..46bd966 100755
--- a/WebCore/bindings/v8/custom/V8WorkerContextCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8WorkerContextCustom.cpp
@@ -58,7 +58,11 @@ v8::Handle<v8::Value> SetTimeoutOrInterval(const v8::Arguments& args, bool singl
int32_t timeout = argumentCount >= 2 ? args[1]->Int32Value() : 0;
int timerId;
- v8::Handle<v8::Context> v8Context = workerContext->script()->proxy()->context();
+ WorkerContextExecutionProxy* proxy = workerContext->script()->proxy();
+ if (!proxy)
+ return v8::Undefined();
+
+ v8::Handle<v8::Context> v8Context = proxy->context();
if (function->IsString()) {
WebCore::String stringFunction = toWebCoreString(function);
timerId = DOMTimer::install(workerContext, new ScheduledAction(v8Context, stringFunction, workerContext->url()), timeout, singleShot);
@@ -86,14 +90,6 @@ v8::Handle<v8::Value> V8WorkerContext::importScriptsCallback(const v8::Arguments
if (!args.Length())
return v8::Undefined();
- 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++) {
v8::TryCatch tryCatch;
@@ -106,7 +102,7 @@ v8::Handle<v8::Value> V8WorkerContext::importScriptsCallback(const v8::Arguments
WorkerContext* workerContext = V8WorkerContext::toNative(args.Holder());
ExceptionCode ec = 0;
- workerContext->importScripts(urls, callerURL, callerLine, ec);
+ workerContext->importScripts(urls, ec);
if (ec)
return throwError(ec);
@@ -126,44 +122,16 @@ v8::Handle<v8::Value> V8WorkerContext::setIntervalCallback(const v8::Arguments&
return SetTimeoutOrInterval(args, false);
}
-v8::Handle<v8::Value> V8WorkerContext::addEventListenerCallback(const v8::Arguments& args)
-{
- INC_STATS(L"DOM.WorkerContext.addEventListener()");
- WorkerContext* workerContext = V8WorkerContext::toNative(args.Holder());
-
- RefPtr<EventListener> listener = V8DOMWrapper::getEventListener(workerContext, args[1], false, ListenerFindOrCreate);
- if (listener) {
- String type = toWebCoreString(args[0]);
- bool useCapture = args[2]->BooleanValue();
- workerContext->addEventListener(type, listener, useCapture);
-
- createHiddenDependency(args.Holder(), args[1], cacheIndex);
- }
- return v8::Undefined();
-}
-
-v8::Handle<v8::Value> V8WorkerContext::removeEventListenerCallback(const v8::Arguments& args)
-{
- INC_STATS(L"DOM.WorkerContext.removeEventListener()");
- WorkerContext* workerContext = V8WorkerContext::toNative(args.Holder());
-
- RefPtr<EventListener> listener = V8DOMWrapper::getEventListener(workerContext, args[1], false, ListenerFindOnly);
- if (listener) {
- String type = toWebCoreString(args[0]);
- bool useCapture = args[2]->BooleanValue();
- workerContext->removeEventListener(type, listener.get(), useCapture);
-
- removeHiddenDependency(args.Holder(), args[1], cacheIndex);
- }
- return v8::Undefined();
-}
-
v8::Handle<v8::Value> toV8(WorkerContext* impl)
{
if (!impl)
return v8::Null();
- v8::Handle<v8::Object> global = impl->script()->proxy()->context()->Global();
+ WorkerContextExecutionProxy* proxy = impl->script()->proxy();
+ if (!proxy)
+ return v8::Null();
+
+ v8::Handle<v8::Object> global = proxy->context()->Global();
ASSERT(!global.IsEmpty());
return global;
}
diff --git a/WebCore/bindings/v8/custom/V8WorkerCustom.cpp b/WebCore/bindings/v8/custom/V8WorkerCustom.cpp
index 6b41246..fdc6815 100755
--- a/WebCore/bindings/v8/custom/V8WorkerCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8WorkerCustom.cpp
@@ -79,7 +79,7 @@ v8::Handle<v8::Value> V8Worker::constructorCallback(const v8::Arguments& args)
// Setup the standard wrapper object internal fields.
v8::Handle<v8::Object> wrapperObject = args.Holder();
- V8DOMWrapper::setDOMWrapper(wrapperObject, V8ClassIndex::WORKER, obj.get());
+ V8DOMWrapper::setDOMWrapper(wrapperObject, &info, obj.get());
obj->ref();
V8DOMWrapper::setJSWrapperForActiveDOMObject(obj.get(), v8::Persistent<v8::Object>::New(wrapperObject));
@@ -91,7 +91,10 @@ v8::Handle<v8::Value> V8Worker::postMessageCallback(const v8::Arguments& args)
{
INC_STATS("DOM.Worker.postMessage");
Worker* worker = V8Worker::toNative(args.Holder());
- RefPtr<SerializedScriptValue> message = SerializedScriptValue::create(args[0]);
+ bool didThrow = false;
+ RefPtr<SerializedScriptValue> message = SerializedScriptValue::create(args[0], didThrow);
+ if (didThrow)
+ return v8::Undefined();
MessagePortArray portArray;
if (args.Length() > 1) {
if (!getMessagePortArray(args[1], portArray))
diff --git a/WebCore/bindings/v8/custom/V8XMLHttpRequestConstructor.cpp b/WebCore/bindings/v8/custom/V8XMLHttpRequestConstructor.cpp
index f50248b..6b5b64f 100644
--- a/WebCore/bindings/v8/custom/V8XMLHttpRequestConstructor.cpp
+++ b/WebCore/bindings/v8/custom/V8XMLHttpRequestConstructor.cpp
@@ -53,7 +53,7 @@ v8::Handle<v8::Value> V8XMLHttpRequest::constructorCallback(const v8::Arguments&
if (!context)
return throwError("XMLHttpRequest constructor's associated context is not available", V8Proxy::ReferenceError);
RefPtr<XMLHttpRequest> xmlHttpRequest = XMLHttpRequest::create(context);
- V8DOMWrapper::setDOMWrapper(args.Holder(), V8ClassIndex::ToInt(V8ClassIndex::XMLHTTPREQUEST), xmlHttpRequest.get());
+ V8DOMWrapper::setDOMWrapper(args.Holder(), &info, xmlHttpRequest.get());
// Add object to the wrapper map.
xmlHttpRequest->ref();
diff --git a/WebCore/bindings/v8/custom/V8XMLHttpRequestCustom.cpp b/WebCore/bindings/v8/custom/V8XMLHttpRequestCustom.cpp
index d10c418..4e9c715 100644
--- a/WebCore/bindings/v8/custom/V8XMLHttpRequestCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8XMLHttpRequestCustom.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008, 2009 Google Inc. All rights reserved.
+ * Copyright (C) 2008, 2009, 2010 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -34,6 +34,7 @@
#include "Frame.h"
#include "V8Binding.h"
#include "V8Blob.h"
+#include "V8DOMFormData.h"
#include "V8Document.h"
#include "V8HTMLDocument.h"
#include "V8Proxy.h"
@@ -51,39 +52,6 @@ v8::Handle<v8::Value> V8XMLHttpRequest::responseTextAccessorGetter(v8::Local<v8:
return xmlHttpRequest->responseText().v8StringOrNull();
}
-v8::Handle<v8::Value> V8XMLHttpRequest::addEventListenerCallback(const v8::Arguments& args)
-{
- INC_STATS("DOM.XMLHttpRequest.addEventListener()");
- XMLHttpRequest* xmlHttpRequest = V8XMLHttpRequest::toNative(args.Holder());
-
- RefPtr<EventListener> listener = V8DOMWrapper::getEventListener(xmlHttpRequest, args[1], false, ListenerFindOrCreate);
- if (listener) {
- String type = toWebCoreString(args[0]);
- bool useCapture = args[2]->BooleanValue();
- xmlHttpRequest->addEventListener(type, listener, useCapture);
-
- createHiddenDependency(args.Holder(), args[1], cacheIndex);
- }
- return v8::Undefined();
-}
-
-v8::Handle<v8::Value> V8XMLHttpRequest::removeEventListenerCallback(const v8::Arguments& args)
-{
- INC_STATS("DOM.XMLHttpRequest.removeEventListener()");
- XMLHttpRequest* xmlHttpRequest = V8XMLHttpRequest::toNative(args.Holder());
-
- RefPtr<EventListener> listener = V8DOMWrapper::getEventListener(xmlHttpRequest, args[1], false, ListenerFindOnly);
- if (listener) {
- String type = toWebCoreString(args[0]);
- bool useCapture = args[2]->BooleanValue();
- xmlHttpRequest->removeEventListener(type, listener.get(), useCapture);
-
- removeHiddenDependency(args.Holder(), args[1], cacheIndex);
- }
-
- return v8::Undefined();
-}
-
v8::Handle<v8::Value> V8XMLHttpRequest::openCallback(const v8::Arguments& args)
{
INC_STATS("DOM.XMLHttpRequest.open()");
@@ -106,20 +74,23 @@ v8::Handle<v8::Value> V8XMLHttpRequest::openCallback(const v8::Arguments& args)
KURL url = context->completeURL(urlstring);
- bool async = (args.Length() < 3) ? true : args[2]->BooleanValue();
-
ExceptionCode ec = 0;
- String user, passwd;
- if (args.Length() >= 4 && !args[3]->IsUndefined()) {
- user = toWebCoreStringWithNullCheck(args[3]);
- if (args.Length() >= 5 && !args[4]->IsUndefined()) {
- passwd = toWebCoreStringWithNullCheck(args[4]);
- xmlHttpRequest->open(method, url, async, user, passwd, ec);
+ if (args.Length() >= 3) {
+ bool async = args[2]->BooleanValue();
+
+ if (args.Length() >= 4 && !args[3]->IsUndefined()) {
+ String user = toWebCoreStringWithNullCheck(args[3]);
+
+ if (args.Length() >= 5 && !args[4]->IsUndefined()) {
+ String passwd = toWebCoreStringWithNullCheck(args[4]);
+ xmlHttpRequest->open(method, url, async, user, passwd, ec);
+ } else
+ xmlHttpRequest->open(method, url, async, user, ec);
} else
- xmlHttpRequest->open(method, url, async, user, ec);
+ xmlHttpRequest->open(method, url, async, ec);
} else
- xmlHttpRequest->open(method, url, async, ec);
+ xmlHttpRequest->open(method, url, ec);
if (ec)
return throwError(ec);
@@ -127,7 +98,7 @@ v8::Handle<v8::Value> V8XMLHttpRequest::openCallback(const v8::Arguments& args)
return v8::Undefined();
}
-static bool IsDocumentType(v8::Handle<v8::Value> value)
+static bool isDocumentType(v8::Handle<v8::Value> value)
{
// FIXME: add other document types.
return V8Document::HasInstance(value) || V8HTMLDocument::HasInstance(value);
@@ -143,7 +114,9 @@ v8::Handle<v8::Value> V8XMLHttpRequest::sendCallback(const v8::Arguments& args)
xmlHttpRequest->send(ec);
else {
v8::Handle<v8::Value> arg = args[0];
- if (IsDocumentType(arg)) {
+ if (isUndefinedOrNull(arg))
+ xmlHttpRequest->send(ec);
+ else if (isDocumentType(arg)) {
v8::Handle<v8::Object> object = v8::Handle<v8::Object>::Cast(arg);
Document* document = V8Document::toNative(object);
ASSERT(document);
@@ -153,6 +126,11 @@ v8::Handle<v8::Value> V8XMLHttpRequest::sendCallback(const v8::Arguments& args)
Blob* blob = V8Blob::toNative(object);
ASSERT(blob);
xmlHttpRequest->send(blob, ec);
+ } else if (V8DOMFormData::HasInstance(arg)) {
+ v8::Handle<v8::Object> object = v8::Handle<v8::Object>::Cast(arg);
+ DOMFormData* domFormData = V8DOMFormData::toNative(object);
+ ASSERT(domFormData);
+ xmlHttpRequest->send(domFormData, ec);
} else
xmlHttpRequest->send(toWebCoreStringWithNullCheck(arg), ec);
}
@@ -206,10 +184,4 @@ v8::Handle<v8::Value> V8XMLHttpRequest::overrideMimeTypeCallback(const v8::Argum
return v8::Undefined();
}
-v8::Handle<v8::Value> V8XMLHttpRequest::dispatchEventCallback(const v8::Arguments& args)
-{
- INC_STATS("DOM.XMLHttpRequest.dispatchEvent()");
- return v8::Undefined();
-}
-
} // namespace WebCore
diff --git a/WebCore/bindings/v8/custom/V8XMLHttpRequestUploadCustom.cpp b/WebCore/bindings/v8/custom/V8XMLHttpRequestUploadCustom.cpp
deleted file mode 100644
index c6c31bf..0000000
--- a/WebCore/bindings/v8/custom/V8XMLHttpRequestUploadCustom.cpp
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright (C) 2008, 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 "V8XMLHttpRequestUpload.h"
-
-#include "ExceptionCode.h"
-#include "V8Binding.h"
-#include "V8Proxy.h"
-#include "V8Utilities.h"
-#include "XMLHttpRequest.h"
-#include "XMLHttpRequestUpload.h"
-
-#include <wtf/Assertions.h>
-
-namespace WebCore {
-
-v8::Handle<v8::Value> V8XMLHttpRequestUpload::addEventListenerCallback(const v8::Arguments& args)
-{
- INC_STATS("DOM.XMLHttpRequestUpload.addEventListener()");
- XMLHttpRequestUpload* xmlHttpRequestUpload = V8XMLHttpRequestUpload::toNative(args.Holder());
-
- XMLHttpRequest* xmlHttpRequest = xmlHttpRequestUpload->associatedXMLHttpRequest();
-
- RefPtr<EventListener> listener = V8DOMWrapper::getEventListener(xmlHttpRequest, args[1], false, ListenerFindOrCreate);
- if (listener) {
- String type = toWebCoreString(args[0]);
- bool useCapture = args[2]->BooleanValue();
- xmlHttpRequestUpload->addEventListener(type, listener, useCapture);
-
- createHiddenDependency(args.Holder(), args[1], cacheIndex);
- }
- return v8::Undefined();
-}
-
-v8::Handle<v8::Value> V8XMLHttpRequestUpload::removeEventListenerCallback(const v8::Arguments& args)
-{
- INC_STATS("DOM.XMLHttpRequestUpload.removeEventListener()");
- XMLHttpRequestUpload* xmlHttpRequestUpload = V8XMLHttpRequestUpload::toNative(args.Holder());
-
- XMLHttpRequest* xmlHttpRequest = xmlHttpRequestUpload->associatedXMLHttpRequest();
-
- RefPtr<EventListener> listener = V8DOMWrapper::getEventListener(xmlHttpRequest, args[1], false, ListenerFindOnly);
- if (listener) {
- String type = toWebCoreString(args[0]);
- bool useCapture = args[2]->BooleanValue();
- xmlHttpRequestUpload->removeEventListener(type, listener.get(), useCapture);
-
- removeHiddenDependency(args.Holder(), args[1], cacheIndex);
- }
-
- return v8::Undefined();
-}
-
-v8::Handle<v8::Value> V8XMLHttpRequestUpload::dispatchEventCallback(const v8::Arguments& args)
-{
- INC_STATS("DOM.XMLHttpRequestUpload.dispatchEvent()");
- return throwError(NOT_SUPPORTED_ERR);
-}
-
-} // namespace WebCore
diff --git a/WebCore/bindings/v8/custom/V8XSLTProcessorCustom.cpp b/WebCore/bindings/v8/custom/V8XSLTProcessorCustom.cpp
index 89f804c..b624fcf 100644
--- a/WebCore/bindings/v8/custom/V8XSLTProcessorCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8XSLTProcessorCustom.cpp
@@ -49,7 +49,7 @@ namespace WebCore {
v8::Handle<v8::Value> V8XSLTProcessor::constructorCallback(const v8::Arguments& args)
{
INC_STATS("DOM.XSLTProcessor.Constructor");
- return V8Proxy::constructDOMObject<V8ClassIndex::XSLTPROCESSOR, XSLTProcessor>(args);
+ return V8Proxy::constructDOMObject<XSLTProcessor>(args, &info);
}
diff --git a/WebCore/bindings/v8/test/TestObj.idl b/WebCore/bindings/v8/test/TestObj.idl
new file mode 100644
index 0000000..662ac64
--- /dev/null
+++ b/WebCore/bindings/v8/test/TestObj.idl
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary formstrArg, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIEstrArg, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// This IDL file is for testing the V8 generator and for tracking changes
+// in its ouput.
+module test {
+ interface TestObj {
+ // Attributes
+ readonly attribute long readOnlyIntAttr;
+ readonly attribute DOMString readOnlyStringAttr;
+ readonly attribute TestObj readOnlyTestObjAttr;
+ attribute long intAttr;
+ attribute DOMString stringAttr;
+ attribute TestObj testObjAttr;
+
+ // Methods
+ void voidMethod();
+ void voidMethodWithArgs(in long intArg, in DOMString strArg, in TestObj objArg);
+ long intMethod();
+ long intMethodWithArgs(in long intArg, in DOMString strArg, in TestObj objArg);
+ TestObj objMethod();
+ TestObj objMethodWithArgs(in long intArg, in DOMString strArg, in TestObj objArg);
+
+ // Exceptions
+ void methodWithException() raises(DOMException);
+ attribute long attrWithException raises(DOMException);
+ attribute long attrWithSetterException getraises(DOMException);
+ attribute long attrWithGetterException setraises(DOMException);
+
+ // 'Custom' extended attribute
+ attribute [Custom] long customAttr;
+ [Custom] void customMethod();
+ [Custom] void customMethodWithArgs(in long intArg, in DOMString strArg, in TestObj objArg);
+
+ // 'Optional' extended attribute
+ void methodWithOptionalArg(in [Optional] long opt);
+ void methodWithNonOptionalArgAndOptionalArg(in long nonOpt, in [Optional] long opt);
+ void methodWithNonOptionalArgAndTwoOptionalArgs(in long nonOpt, in [Optional] long opt1, in long opt2);
+
+ // Overloads
+ void overloadedMethod(in TestObj objArg, in DOMString strArg);
+ void overloadedMethod(in TestObj objArg, in [Optional] long intArg);
+ void overloadedMethod(in DOMString strArg);
+ void overloadedMethod(in long intArg);
+ };
+}
diff --git a/WebCore/bindings/v8/test/V8TestObj.cpp b/WebCore/bindings/v8/test/V8TestObj.cpp
new file mode 100644
index 0000000..d51884e
--- /dev/null
+++ b/WebCore/bindings/v8/test/V8TestObj.cpp
@@ -0,0 +1,459 @@
+/*
+ This file is part of the WebKit open source project.
+ This file has been generated by generate-bindings.pl. DO NOT MODIFY!
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#include "config.h"
+#include "V8TestObj.h"
+
+#include "ExceptionCode.h"
+#include "RuntimeEnabledFeatures.h"
+#include "V8Binding.h"
+#include "V8BindingState.h"
+#include "V8DOMWrapper.h"
+#include "V8IsolatedContext.h"
+#include "V8Proxy.h"
+#include <wtf/GetPtr.h>
+#include <wtf/RefCounted.h>
+#include <wtf/RefPtr.h>
+
+namespace WebCore {
+
+WrapperTypeInfo V8TestObj::info = { V8TestObj::GetTemplate, V8TestObj::derefObject, 0 };
+
+namespace TestObjInternal {
+
+template <typename T> void V8_USE(T) { }
+
+static v8::Handle<v8::Value> readOnlyIntAttrAttrGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info)
+{
+ INC_STATS("DOM.TestObj.readOnlyIntAttr._get");
+ TestObj* imp = V8TestObj::toNative(info.Holder());
+ return v8::Integer::New(imp->readOnlyIntAttr());
+}
+
+static v8::Handle<v8::Value> readOnlyStringAttrAttrGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info)
+{
+ INC_STATS("DOM.TestObj.readOnlyStringAttr._get");
+ TestObj* imp = V8TestObj::toNative(info.Holder());
+ return v8String(imp->readOnlyStringAttr());
+}
+
+static v8::Handle<v8::Value> readOnlyTestObjAttrAttrGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info)
+{
+ INC_STATS("DOM.TestObj.readOnlyTestObjAttr._get");
+ TestObj* imp = V8TestObj::toNative(info.Holder());
+ RefPtr<TestObj> result = imp->readOnlyTestObjAttr();
+ v8::Handle<v8::Value> wrapper = result.get() ? getDOMObjectMap().get(result.get()) : v8::Handle<v8::Value>();
+ if (wrapper.IsEmpty()) {
+ wrapper = toV8(result.get());
+ if (!wrapper.IsEmpty())
+ V8DOMWrapper::setHiddenReference(info.Holder(), wrapper);
+ }
+ return wrapper;
+}
+
+static v8::Handle<v8::Value> intAttrAttrGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info)
+{
+ INC_STATS("DOM.TestObj.intAttr._get");
+ TestObj* imp = V8TestObj::toNative(info.Holder());
+ return v8::Integer::New(imp->intAttr());
+}
+
+static void intAttrAttrSetter(v8::Local<v8::String> name, v8::Local<v8::Value> value, const v8::AccessorInfo& info)
+{
+ INC_STATS("DOM.TestObj.intAttr._set");
+ TestObj* imp = V8TestObj::toNative(info.Holder());
+ int v = toInt32(value);
+ imp->setIntAttr(v);
+ return;
+}
+
+static v8::Handle<v8::Value> stringAttrAttrGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info)
+{
+ INC_STATS("DOM.TestObj.stringAttr._get");
+ TestObj* imp = V8TestObj::toNative(info.Holder());
+ return v8String(imp->stringAttr());
+}
+
+static void stringAttrAttrSetter(v8::Local<v8::String> name, v8::Local<v8::Value> value, const v8::AccessorInfo& info)
+{
+ INC_STATS("DOM.TestObj.stringAttr._set");
+ TestObj* imp = V8TestObj::toNative(info.Holder());
+ V8Parameter<> v = value;
+ imp->setStringAttr(v);
+ return;
+}
+
+static v8::Handle<v8::Value> testObjAttrAttrGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info)
+{
+ INC_STATS("DOM.TestObj.testObjAttr._get");
+ TestObj* imp = V8TestObj::toNative(info.Holder());
+ return toV8(imp->testObjAttr());
+}
+
+static void testObjAttrAttrSetter(v8::Local<v8::String> name, v8::Local<v8::Value> value, const v8::AccessorInfo& info)
+{
+ INC_STATS("DOM.TestObj.testObjAttr._set");
+ TestObj* imp = V8TestObj::toNative(info.Holder());
+ TestObj* v = V8TestObj::HasInstance(value) ? V8TestObj::toNative(v8::Handle<v8::Object>::Cast(value)) : 0;
+ imp->setTestObjAttr(WTF::getPtr(v));
+ return;
+}
+
+static v8::Handle<v8::Value> attrWithExceptionAttrGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info)
+{
+ INC_STATS("DOM.TestObj.attrWithException._get");
+ TestObj* imp = V8TestObj::toNative(info.Holder());
+ return v8::Integer::New(imp->attrWithException());
+}
+
+static void attrWithExceptionAttrSetter(v8::Local<v8::String> name, v8::Local<v8::Value> value, const v8::AccessorInfo& info)
+{
+ INC_STATS("DOM.TestObj.attrWithException._set");
+ TestObj* imp = V8TestObj::toNative(info.Holder());
+ int v = toInt32(value);
+ imp->setAttrWithException(v);
+ return;
+}
+
+static v8::Handle<v8::Value> attrWithSetterExceptionAttrGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info)
+{
+ INC_STATS("DOM.TestObj.attrWithSetterException._get");
+ TestObj* imp = V8TestObj::toNative(info.Holder());
+ return v8::Integer::New(imp->attrWithSetterException());
+}
+
+static void attrWithSetterExceptionAttrSetter(v8::Local<v8::String> name, v8::Local<v8::Value> value, const v8::AccessorInfo& info)
+{
+ INC_STATS("DOM.TestObj.attrWithSetterException._set");
+ TestObj* imp = V8TestObj::toNative(info.Holder());
+ int v = toInt32(value);
+ imp->setAttrWithSetterException(v);
+ return;
+}
+
+static v8::Handle<v8::Value> attrWithGetterExceptionAttrGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info)
+{
+ INC_STATS("DOM.TestObj.attrWithGetterException._get");
+ TestObj* imp = V8TestObj::toNative(info.Holder());
+ return v8::Integer::New(imp->attrWithGetterException());
+}
+
+static void attrWithGetterExceptionAttrSetter(v8::Local<v8::String> name, v8::Local<v8::Value> value, const v8::AccessorInfo& info)
+{
+ INC_STATS("DOM.TestObj.attrWithGetterException._set");
+ TestObj* imp = V8TestObj::toNative(info.Holder());
+ int v = toInt32(value);
+ imp->setAttrWithGetterException(v);
+ return;
+}
+
+static v8::Handle<v8::Value> voidMethodCallback(const v8::Arguments& args)
+{
+ INC_STATS("DOM.TestObj.voidMethod");
+ TestObj* imp = V8TestObj::toNative(args.Holder());
+ imp->voidMethod();
+ return v8::Handle<v8::Value>();
+}
+
+static v8::Handle<v8::Value> voidMethodWithArgsCallback(const v8::Arguments& args)
+{
+ INC_STATS("DOM.TestObj.voidMethodWithArgs");
+ TestObj* imp = V8TestObj::toNative(args.Holder());
+ int intArg = toInt32(args[0]);
+ V8Parameter<> strArg = args[1];
+ TestObj* objArg = V8TestObj::HasInstance(args[2]) ? V8TestObj::toNative(v8::Handle<v8::Object>::Cast(args[2])) : 0;
+ imp->voidMethodWithArgs(intArg, strArg, objArg);
+ return v8::Handle<v8::Value>();
+}
+
+static v8::Handle<v8::Value> intMethodCallback(const v8::Arguments& args)
+{
+ INC_STATS("DOM.TestObj.intMethod");
+ TestObj* imp = V8TestObj::toNative(args.Holder());
+ return v8::Integer::New(imp->intMethod());
+}
+
+static v8::Handle<v8::Value> intMethodWithArgsCallback(const v8::Arguments& args)
+{
+ INC_STATS("DOM.TestObj.intMethodWithArgs");
+ TestObj* imp = V8TestObj::toNative(args.Holder());
+ int intArg = toInt32(args[0]);
+ V8Parameter<> strArg = args[1];
+ TestObj* objArg = V8TestObj::HasInstance(args[2]) ? V8TestObj::toNative(v8::Handle<v8::Object>::Cast(args[2])) : 0;
+ return v8::Integer::New(imp->intMethodWithArgs(intArg, strArg, objArg));
+}
+
+static v8::Handle<v8::Value> objMethodCallback(const v8::Arguments& args)
+{
+ INC_STATS("DOM.TestObj.objMethod");
+ TestObj* imp = V8TestObj::toNative(args.Holder());
+ return toV8(imp->objMethod());
+}
+
+static v8::Handle<v8::Value> objMethodWithArgsCallback(const v8::Arguments& args)
+{
+ INC_STATS("DOM.TestObj.objMethodWithArgs");
+ TestObj* imp = V8TestObj::toNative(args.Holder());
+ int intArg = toInt32(args[0]);
+ V8Parameter<> strArg = args[1];
+ TestObj* objArg = V8TestObj::HasInstance(args[2]) ? V8TestObj::toNative(v8::Handle<v8::Object>::Cast(args[2])) : 0;
+ return toV8(imp->objMethodWithArgs(intArg, strArg, objArg));
+}
+
+static v8::Handle<v8::Value> methodWithExceptionCallback(const v8::Arguments& args)
+{
+ INC_STATS("DOM.TestObj.methodWithException");
+ TestObj* imp = V8TestObj::toNative(args.Holder());
+ ExceptionCode ec = 0;
+ {
+ imp->methodWithException(ec);
+ if (UNLIKELY(ec))
+ goto fail;
+ return v8::Handle<v8::Value>();
+ }
+ fail:
+ V8Proxy::setDOMException(ec);
+ return v8::Handle<v8::Value>();
+}
+
+static v8::Handle<v8::Value> methodWithOptionalArgCallback(const v8::Arguments& args)
+{
+ INC_STATS("DOM.TestObj.methodWithOptionalArg");
+ TestObj* imp = V8TestObj::toNative(args.Holder());
+ if (args.Length() <= 0) {
+ imp->methodWithOptionalArg();
+ return v8::Handle<v8::Value>();
+ }
+ int opt = toInt32(args[0]);
+ imp->methodWithOptionalArg(opt);
+ return v8::Handle<v8::Value>();
+}
+
+static v8::Handle<v8::Value> methodWithNonOptionalArgAndOptionalArgCallback(const v8::Arguments& args)
+{
+ INC_STATS("DOM.TestObj.methodWithNonOptionalArgAndOptionalArg");
+ TestObj* imp = V8TestObj::toNative(args.Holder());
+ int nonOpt = toInt32(args[0]);
+ if (args.Length() <= 1) {
+ imp->methodWithNonOptionalArgAndOptionalArg(nonOpt);
+ return v8::Handle<v8::Value>();
+ }
+ int opt = toInt32(args[1]);
+ imp->methodWithNonOptionalArgAndOptionalArg(nonOpt, opt);
+ return v8::Handle<v8::Value>();
+}
+
+static v8::Handle<v8::Value> methodWithNonOptionalArgAndTwoOptionalArgsCallback(const v8::Arguments& args)
+{
+ INC_STATS("DOM.TestObj.methodWithNonOptionalArgAndTwoOptionalArgs");
+ TestObj* imp = V8TestObj::toNative(args.Holder());
+ int nonOpt = toInt32(args[0]);
+ if (args.Length() <= 1) {
+ imp->methodWithNonOptionalArgAndTwoOptionalArgs(nonOpt);
+ return v8::Handle<v8::Value>();
+ }
+ int opt1 = toInt32(args[1]);
+ int opt2 = toInt32(args[2]);
+ imp->methodWithNonOptionalArgAndTwoOptionalArgs(nonOpt, opt1, opt2);
+ return v8::Handle<v8::Value>();
+}
+
+static v8::Handle<v8::Value> overloadedMethod1Callback(const v8::Arguments& args)
+{
+ INC_STATS("DOM.TestObj.overloadedMethod1");
+ TestObj* imp = V8TestObj::toNative(args.Holder());
+ TestObj* objArg = V8TestObj::HasInstance(args[0]) ? V8TestObj::toNative(v8::Handle<v8::Object>::Cast(args[0])) : 0;
+ V8Parameter<> strArg = args[1];
+ imp->overloadedMethod(objArg, strArg);
+ return v8::Handle<v8::Value>();
+}
+
+static v8::Handle<v8::Value> overloadedMethod2Callback(const v8::Arguments& args)
+{
+ INC_STATS("DOM.TestObj.overloadedMethod2");
+ TestObj* imp = V8TestObj::toNative(args.Holder());
+ TestObj* objArg = V8TestObj::HasInstance(args[0]) ? V8TestObj::toNative(v8::Handle<v8::Object>::Cast(args[0])) : 0;
+ if (args.Length() <= 1) {
+ imp->overloadedMethod(objArg);
+ return v8::Handle<v8::Value>();
+ }
+ int intArg = toInt32(args[1]);
+ imp->overloadedMethod(objArg, intArg);
+ return v8::Handle<v8::Value>();
+}
+
+static v8::Handle<v8::Value> overloadedMethod3Callback(const v8::Arguments& args)
+{
+ INC_STATS("DOM.TestObj.overloadedMethod3");
+ TestObj* imp = V8TestObj::toNative(args.Holder());
+ V8Parameter<> strArg = args[0];
+ imp->overloadedMethod(strArg);
+ return v8::Handle<v8::Value>();
+}
+
+static v8::Handle<v8::Value> overloadedMethod4Callback(const v8::Arguments& args)
+{
+ INC_STATS("DOM.TestObj.overloadedMethod4");
+ TestObj* imp = V8TestObj::toNative(args.Holder());
+ int intArg = toInt32(args[0]);
+ imp->overloadedMethod(intArg);
+ return v8::Handle<v8::Value>();
+}
+
+static v8::Handle<v8::Value> overloadedMethodCallback(const v8::Arguments& args)
+{
+ INC_STATS("DOM.TestObj.overloadedMethod");
+ if ((args.Length() == 2 && (args[0]->IsNull() || V8TestObj::HasInstance(args[0])) && (args[1]->IsNull() || args[1]->IsUndefined() || args[1]->IsString() || args[1]->IsObject())))
+ return overloadedMethod1Callback(args);
+ if ((args.Length() == 1 && (args[0]->IsNull() || V8TestObj::HasInstance(args[0]))) || (args.Length() == 2 && (args[0]->IsNull() || V8TestObj::HasInstance(args[0]))))
+ return overloadedMethod2Callback(args);
+ if ((args.Length() == 1 && (args[0]->IsNull() || args[0]->IsUndefined() || args[0]->IsString() || args[0]->IsObject())))
+ return overloadedMethod3Callback(args);
+ if (args.Length() == 1)
+ return overloadedMethod4Callback(args);
+ V8Proxy::setDOMException(SYNTAX_ERR);
+ return notHandledByInterceptor();
+}
+
+} // namespace TestObjInternal
+
+static const BatchedAttribute TestObjAttrs[] = {
+ // Attribute 'readOnlyIntAttr' (Type: 'readonly attribute' ExtAttr: '')
+ {"readOnlyIntAttr", TestObjInternal::readOnlyIntAttrAttrGetter, 0, 0 /* no data */, static_cast<v8::AccessControl>(v8::DEFAULT), static_cast<v8::PropertyAttribute>(v8::None), 0 /* on instance */},
+ // Attribute 'readOnlyStringAttr' (Type: 'readonly attribute' ExtAttr: '')
+ {"readOnlyStringAttr", TestObjInternal::readOnlyStringAttrAttrGetter, 0, 0 /* no data */, static_cast<v8::AccessControl>(v8::DEFAULT), static_cast<v8::PropertyAttribute>(v8::None), 0 /* on instance */},
+ // Attribute 'readOnlyTestObjAttr' (Type: 'readonly attribute' ExtAttr: '')
+ {"readOnlyTestObjAttr", TestObjInternal::readOnlyTestObjAttrAttrGetter, 0, 0 /* no data */, static_cast<v8::AccessControl>(v8::DEFAULT), static_cast<v8::PropertyAttribute>(v8::None), 0 /* on instance */},
+ // Attribute 'intAttr' (Type: 'attribute' ExtAttr: '')
+ {"intAttr", TestObjInternal::intAttrAttrGetter, TestObjInternal::intAttrAttrSetter, 0 /* no data */, static_cast<v8::AccessControl>(v8::DEFAULT), static_cast<v8::PropertyAttribute>(v8::None), 0 /* on instance */},
+ // Attribute 'stringAttr' (Type: 'attribute' ExtAttr: '')
+ {"stringAttr", TestObjInternal::stringAttrAttrGetter, TestObjInternal::stringAttrAttrSetter, 0 /* no data */, static_cast<v8::AccessControl>(v8::DEFAULT), static_cast<v8::PropertyAttribute>(v8::None), 0 /* on instance */},
+ // Attribute 'testObjAttr' (Type: 'attribute' ExtAttr: '')
+ {"testObjAttr", TestObjInternal::testObjAttrAttrGetter, TestObjInternal::testObjAttrAttrSetter, 0 /* no data */, static_cast<v8::AccessControl>(v8::DEFAULT), static_cast<v8::PropertyAttribute>(v8::None), 0 /* on instance */},
+ // Attribute 'attrWithException' (Type: 'attribute' ExtAttr: '')
+ {"attrWithException", TestObjInternal::attrWithExceptionAttrGetter, TestObjInternal::attrWithExceptionAttrSetter, 0 /* no data */, static_cast<v8::AccessControl>(v8::DEFAULT), static_cast<v8::PropertyAttribute>(v8::None), 0 /* on instance */},
+ // Attribute 'attrWithSetterException' (Type: 'attribute' ExtAttr: '')
+ {"attrWithSetterException", TestObjInternal::attrWithSetterExceptionAttrGetter, TestObjInternal::attrWithSetterExceptionAttrSetter, 0 /* no data */, static_cast<v8::AccessControl>(v8::DEFAULT), static_cast<v8::PropertyAttribute>(v8::None), 0 /* on instance */},
+ // Attribute 'attrWithGetterException' (Type: 'attribute' ExtAttr: '')
+ {"attrWithGetterException", TestObjInternal::attrWithGetterExceptionAttrGetter, TestObjInternal::attrWithGetterExceptionAttrSetter, 0 /* no data */, static_cast<v8::AccessControl>(v8::DEFAULT), static_cast<v8::PropertyAttribute>(v8::None), 0 /* on instance */},
+ // Attribute 'customAttr' (Type: 'attribute' ExtAttr: 'Custom')
+ {"customAttr", V8TestObj::customAttrAccessorGetter, V8TestObj::customAttrAccessorSetter, 0 /* no data */, static_cast<v8::AccessControl>(v8::DEFAULT), static_cast<v8::PropertyAttribute>(v8::None), 0 /* on instance */},
+};
+static const BatchedCallback TestObjCallbacks[] = {
+ {"voidMethod", TestObjInternal::voidMethodCallback},
+ {"intMethod", TestObjInternal::intMethodCallback},
+ {"objMethod", TestObjInternal::objMethodCallback},
+ {"methodWithException", TestObjInternal::methodWithExceptionCallback},
+ {"customMethod", V8TestObj::customMethodCallback},
+ {"customMethodWithArgs", V8TestObj::customMethodWithArgsCallback},
+ {"methodWithOptionalArg", TestObjInternal::methodWithOptionalArgCallback},
+ {"methodWithNonOptionalArgAndOptionalArg", TestObjInternal::methodWithNonOptionalArgAndOptionalArgCallback},
+ {"methodWithNonOptionalArgAndTwoOptionalArgs", TestObjInternal::methodWithNonOptionalArgAndTwoOptionalArgsCallback},
+ {"overloadedMethod", TestObjInternal::overloadedMethodCallback},
+};
+static v8::Persistent<v8::FunctionTemplate> ConfigureV8TestObjTemplate(v8::Persistent<v8::FunctionTemplate> desc)
+{
+ v8::Local<v8::Signature> defaultSignature = configureTemplate(desc, "TestObj", v8::Persistent<v8::FunctionTemplate>(), V8TestObj::internalFieldCount,
+ TestObjAttrs, sizeof(TestObjAttrs) / sizeof(*TestObjAttrs),
+ TestObjCallbacks, sizeof(TestObjCallbacks) / sizeof(*TestObjCallbacks));
+ v8::Local<v8::ObjectTemplate> instance = desc->InstanceTemplate();
+ v8::Local<v8::ObjectTemplate> proto = desc->PrototypeTemplate();
+
+
+ // Custom Signature 'voidMethodWithArgs'
+ const int voidMethodWithArgsArgc = 3;
+ v8::Handle<v8::FunctionTemplate> voidMethodWithArgsArgv[voidMethodWithArgsArgc] = { v8::Handle<v8::FunctionTemplate>(), v8::Handle<v8::FunctionTemplate>(), V8TestObj::GetRawTemplate() };
+ v8::Handle<v8::Signature> voidMethodWithArgsSignature = v8::Signature::New(desc, voidMethodWithArgsArgc, voidMethodWithArgsArgv);
+ proto->Set(v8::String::New("voidMethodWithArgs"), v8::FunctionTemplate::New(TestObjInternal::voidMethodWithArgsCallback, v8::Handle<v8::Value>(), voidMethodWithArgsSignature));
+
+ // Custom Signature 'intMethodWithArgs'
+ const int intMethodWithArgsArgc = 3;
+ v8::Handle<v8::FunctionTemplate> intMethodWithArgsArgv[intMethodWithArgsArgc] = { v8::Handle<v8::FunctionTemplate>(), v8::Handle<v8::FunctionTemplate>(), V8TestObj::GetRawTemplate() };
+ v8::Handle<v8::Signature> intMethodWithArgsSignature = v8::Signature::New(desc, intMethodWithArgsArgc, intMethodWithArgsArgv);
+ proto->Set(v8::String::New("intMethodWithArgs"), v8::FunctionTemplate::New(TestObjInternal::intMethodWithArgsCallback, v8::Handle<v8::Value>(), intMethodWithArgsSignature));
+
+ // Custom Signature 'objMethodWithArgs'
+ const int objMethodWithArgsArgc = 3;
+ v8::Handle<v8::FunctionTemplate> objMethodWithArgsArgv[objMethodWithArgsArgc] = { v8::Handle<v8::FunctionTemplate>(), v8::Handle<v8::FunctionTemplate>(), V8TestObj::GetRawTemplate() };
+ v8::Handle<v8::Signature> objMethodWithArgsSignature = v8::Signature::New(desc, objMethodWithArgsArgc, objMethodWithArgsArgv);
+ proto->Set(v8::String::New("objMethodWithArgs"), v8::FunctionTemplate::New(TestObjInternal::objMethodWithArgsCallback, v8::Handle<v8::Value>(), objMethodWithArgsSignature));
+
+ // Custom toString template
+ desc->Set(getToStringName(), getToStringTemplate());
+ return desc;
+}
+
+v8::Persistent<v8::FunctionTemplate> V8TestObj::GetRawTemplate()
+{
+ static v8::Persistent<v8::FunctionTemplate> V8TestObjRawCache = createRawTemplate();
+ return V8TestObjRawCache;
+}
+
+v8::Persistent<v8::FunctionTemplate> V8TestObj::GetTemplate()
+{
+ static v8::Persistent<v8::FunctionTemplate> V8TestObjCache = ConfigureV8TestObjTemplate(GetRawTemplate());
+ return V8TestObjCache;
+}
+
+TestObj* V8TestObj::toNative(v8::Handle<v8::Object> object)
+{
+ return reinterpret_cast<TestObj*>(object->GetPointerFromInternalField(v8DOMWrapperObjectIndex));
+}
+
+bool V8TestObj::HasInstance(v8::Handle<v8::Value> value)
+{
+ return GetRawTemplate()->HasInstance(value);
+}
+
+
+v8::Handle<v8::Object> V8TestObj::wrap(TestObj* impl)
+{
+ v8::Handle<v8::Object> wrapper;
+ V8Proxy* proxy = 0;
+ wrapper = getDOMObjectMap().get(impl);
+ if (!wrapper.IsEmpty())
+ return wrapper;
+ wrapper = V8DOMWrapper::instantiateV8Object(proxy, &info, impl);
+ if (wrapper.IsEmpty())
+ return wrapper;
+
+ impl->ref();
+ getDOMObjectMap().set(impl, v8::Persistent<v8::Object>::New(wrapper));
+ return wrapper;
+}
+
+v8::Handle<v8::Value> toV8(PassRefPtr<TestObj > impl)
+{
+ return toV8(impl.get());
+}
+
+v8::Handle<v8::Value> toV8(TestObj* impl)
+{
+ if (!impl)
+ return v8::Null();
+ return V8TestObj::wrap(impl);
+}
+
+void V8TestObj::derefObject(void* object)
+{
+ static_cast<TestObj*>(object)->deref();
+}
+
+} // namespace WebCore
diff --git a/WebCore/bindings/v8/test/V8TestObj.h b/WebCore/bindings/v8/test/V8TestObj.h
new file mode 100644
index 0000000..5d6770a
--- /dev/null
+++ b/WebCore/bindings/v8/test/V8TestObj.h
@@ -0,0 +1,53 @@
+/*
+ This file is part of the WebKit open source project.
+ This file has been generated by generate-bindings.pl. DO NOT MODIFY!
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef V8TestObj_h
+#define V8TestObj_h
+
+#include "StringHash.h"
+#include "TestObj.h"
+#include "WrapperTypeInfo.h"
+#include <v8.h>
+#include <wtf/HashMap.h>
+
+namespace WebCore {
+
+class V8TestObj {
+
+public:
+ static bool HasInstance(v8::Handle<v8::Value> value);
+ static v8::Persistent<v8::FunctionTemplate> GetRawTemplate();
+ static v8::Persistent<v8::FunctionTemplate> GetTemplate();
+ static TestObj* toNative(v8::Handle<v8::Object>);
+ static v8::Handle<v8::Object> wrap(TestObj*);
+ static void derefObject(void*);
+ static WrapperTypeInfo info;
+ static v8::Handle<v8::Value> customMethodCallback(const v8::Arguments&);
+ static v8::Handle<v8::Value> customMethodWithArgsCallback(const v8::Arguments&);
+ static v8::Handle<v8::Value> customAttrAccessorGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info);
+ static void customAttrAccessorSetter(v8::Local<v8::String> name, v8::Local<v8::Value> value, const v8::AccessorInfo& info);
+ static const int internalFieldCount = v8DefaultWrapperInternalFieldCount + 0;
+};
+
+v8::Handle<v8::Value> toV8(TestObj*);
+v8::Handle<v8::Value> toV8(PassRefPtr<TestObj >);
+}
+
+#endif // V8TestObj_h
diff --git a/WebCore/bindings/v8/test/run_tests.py b/WebCore/bindings/v8/test/run_tests.py
new file mode 100644
index 0000000..e27d559
--- /dev/null
+++ b/WebCore/bindings/v8/test/run_tests.py
@@ -0,0 +1,58 @@
+#!/usr/bin/python
+#
+# Copyright (C) 2010 Google Inc. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+# OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+# This script generates h and cpp file for TestObj.idl using the V8 code
+# generator. Please execute the script whenever changes are made to
+# CodeGeneratorV8.pm, and submit the changes in V8TestObj.h/cpp in the same
+# patch. This makes it easier to track and review changes in generated code.
+# To execute, invoke: 'python run_tests.py'
+
+import os
+import sys
+
+
+def test(idlFilePath):
+ cmd = ['perl', '-w',
+ '-I../../scripts',
+ '../../scripts/generate-bindings.pl',
+ # idl include directories (path relative to generate-bindings.pl)
+ '--include .',
+ # place holder for defines (generate-bindings.pl requires it)
+ '--defines xxx',
+ '--generator V8',
+ '--outputDir .',
+ idlFilePath]
+ os.system(' '.join(cmd))
+
+
+def main(argv):
+ scriptDir = os.path.dirname(__file__)
+ os.chdir(scriptDir)
+ test('TestObj.idl')
+
+
+if __name__ == '__main__':
+ sys.exit(main(sys.argv))