summaryrefslogtreecommitdiffstats
path: root/chromium/third_party/WebKit/Source/bindings
diff options
context:
space:
mode:
authorJocelyn Turcotte <jocelyn.turcotte@digia.com>2014-08-08 14:30:41 +0200
committerJocelyn Turcotte <jocelyn.turcotte@digia.com>2014-08-12 13:49:54 +0200
commitab0a50979b9eb4dfa3320eff7e187e41efedf7a9 (patch)
tree498dfb8a97ff3361a9f7486863a52bb4e26bb898 /chromium/third_party/WebKit/Source/bindings
parent4ce69f7403811819800e7c5ae1318b2647e778d1 (diff)
Update Chromium to beta version 37.0.2062.68
Change-Id: I188e3b5aff1bec75566014291b654eb19f5bc8ca Reviewed-by: Andras Becsi <andras.becsi@digia.com>
Diffstat (limited to 'chromium/third_party/WebKit/Source/bindings')
-rw-r--r--chromium/third_party/WebKit/Source/bindings/BUILD.gn105
-rw-r--r--chromium/third_party/WebKit/Source/bindings/IDLExtendedAttributes.txt37
-rw-r--r--chromium/third_party/WebKit/Source/bindings/OWNERS1
-rw-r--r--chromium/third_party/WebKit/Source/bindings/PRESUBMIT.py9
-rw-r--r--chromium/third_party/WebKit/Source/bindings/__init__.py0
-rw-r--r--chromium/third_party/WebKit/Source/bindings/bindings.gni51
-rw-r--r--chromium/third_party/WebKit/Source/bindings/bindings.gypi283
-rw-r--r--chromium/third_party/WebKit/Source/bindings/core/BUILD.gn18
-rw-r--r--chromium/third_party/WebKit/Source/bindings/core/core.gni8
-rw-r--r--chromium/third_party/WebKit/Source/bindings/core/core.gypi15
-rw-r--r--chromium/third_party/WebKit/Source/bindings/core/generated.gyp72
-rw-r--r--chromium/third_party/WebKit/Source/bindings/core/generated.gypi24
-rw-r--r--chromium/third_party/WebKit/Source/bindings/core/idl.gni57
-rw-r--r--chromium/third_party/WebKit/Source/bindings/core/idl.gypi71
-rw-r--r--chromium/third_party/WebKit/Source/bindings/core/v8/BUILD.gn32
-rw-r--r--chromium/third_party/WebKit/Source/bindings/core/v8/generated.gni35
-rw-r--r--chromium/third_party/WebKit/Source/bindings/core/v8/generated.gyp135
-rw-r--r--chromium/third_party/WebKit/Source/bindings/core/v8/generated.gypi41
-rw-r--r--chromium/third_party/WebKit/Source/bindings/derived_sources.gyp316
-rw-r--r--chromium/third_party/WebKit/Source/bindings/idl.gni21
-rw-r--r--chromium/third_party/WebKit/Source/bindings/modules/BUILD.gn120
-rw-r--r--chromium/third_party/WebKit/Source/bindings/modules/generated.gyp242
-rw-r--r--chromium/third_party/WebKit/Source/bindings/modules/generated.gypi34
-rw-r--r--chromium/third_party/WebKit/Source/bindings/modules/idl.gni42
-rw-r--r--chromium/third_party/WebKit/Source/bindings/modules/idl.gypi72
-rw-r--r--chromium/third_party/WebKit/Source/bindings/modules/modules.gni8
-rw-r--r--chromium/third_party/WebKit/Source/bindings/modules/modules.gypi13
-rw-r--r--chromium/third_party/WebKit/Source/bindings/modules/v8/BUILD.gn32
-rw-r--r--chromium/third_party/WebKit/Source/bindings/modules/v8/generated.gni35
-rw-r--r--chromium/third_party/WebKit/Source/bindings/modules/v8/generated.gyp121
-rw-r--r--chromium/third_party/WebKit/Source/bindings/modules/v8/generated.gypi41
-rw-r--r--chromium/third_party/WebKit/Source/bindings/scripts/BUILD.gn48
-rw-r--r--chromium/third_party/WebKit/Source/bindings/scripts/__init__.py0
-rwxr-xr-xchromium/third_party/WebKit/Source/bindings/scripts/aggregate_generated_bindings.py229
-rw-r--r--chromium/third_party/WebKit/Source/bindings/scripts/blink_idl_lexer.py (renamed from chromium/third_party/WebKit/Source/bindings/scripts/unstable/blink_idl_lexer.py)49
-rw-r--r--chromium/third_party/WebKit/Source/bindings/scripts/blink_idl_parser.py (renamed from chromium/third_party/WebKit/Source/bindings/scripts/unstable/blink_idl_parser.py)124
-rw-r--r--chromium/third_party/WebKit/Source/bindings/scripts/code_generator_v8.pm6351
-rw-r--r--chromium/third_party/WebKit/Source/bindings/scripts/code_generator_v8.py222
-rwxr-xr-xchromium/third_party/WebKit/Source/bindings/scripts/compute_dependencies.py404
-rwxr-xr-xchromium/third_party/WebKit/Source/bindings/scripts/compute_global_objects.py113
-rwxr-xr-xchromium/third_party/WebKit/Source/bindings/scripts/compute_interfaces_info_individual.py192
-rwxr-xr-xchromium/third_party/WebKit/Source/bindings/scripts/compute_interfaces_info_overall.py264
-rwxr-xr-xchromium/third_party/WebKit/Source/bindings/scripts/generate_bindings.pl309
-rwxr-xr-xchromium/third_party/WebKit/Source/bindings/scripts/generate_event_interfaces.py122
-rwxr-xr-xchromium/third_party/WebKit/Source/bindings/scripts/generate_global_constructors.py184
-rw-r--r--chromium/third_party/WebKit/Source/bindings/scripts/global_constructors.gypi73
-rw-r--r--chromium/third_party/WebKit/Source/bindings/scripts/global_objects.gypi64
-rwxr-xr-xchromium/third_party/WebKit/Source/bindings/scripts/idl_compiler.py143
-rw-r--r--chromium/third_party/WebKit/Source/bindings/scripts/idl_definitions.py756
-rw-r--r--chromium/third_party/WebKit/Source/bindings/scripts/idl_parser.pm2222
-rw-r--r--chromium/third_party/WebKit/Source/bindings/scripts/idl_reader.py109
-rw-r--r--chromium/third_party/WebKit/Source/bindings/scripts/idl_serializer.pm126
-rw-r--r--chromium/third_party/WebKit/Source/bindings/scripts/idl_types.py321
-rw-r--r--chromium/third_party/WebKit/Source/bindings/scripts/idl_validator.py (renamed from chromium/third_party/WebKit/Source/bindings/scripts/unstable/idl_validator.py)32
-rw-r--r--chromium/third_party/WebKit/Source/bindings/scripts/interface_dependency_resolver.py179
-rw-r--r--chromium/third_party/WebKit/Source/bindings/scripts/interfaces_info_individual.gypi70
-rw-r--r--chromium/third_party/WebKit/Source/bindings/scripts/interfaces_info_overall.gypi56
-rw-r--r--chromium/third_party/WebKit/Source/bindings/scripts/scripts.gni202
-rw-r--r--chromium/third_party/WebKit/Source/bindings/scripts/scripts.gyp75
-rw-r--r--chromium/third_party/WebKit/Source/bindings/scripts/scripts.gypi59
-rw-r--r--chromium/third_party/WebKit/Source/bindings/scripts/unstable/code_generator_v8.py156
-rwxr-xr-xchromium/third_party/WebKit/Source/bindings/scripts/unstable/idl_compiler.py129
-rw-r--r--chromium/third_party/WebKit/Source/bindings/scripts/unstable/idl_definitions.py446
-rw-r--r--chromium/third_party/WebKit/Source/bindings/scripts/unstable/idl_definitions_builder.py511
-rw-r--r--chromium/third_party/WebKit/Source/bindings/scripts/unstable/idl_reader.py80
-rw-r--r--chromium/third_party/WebKit/Source/bindings/scripts/unstable/interface_dependency_resolver.py211
-rw-r--r--chromium/third_party/WebKit/Source/bindings/scripts/unstable/v8_attributes.py331
-rw-r--r--chromium/third_party/WebKit/Source/bindings/scripts/unstable/v8_interface.py406
-rw-r--r--chromium/third_party/WebKit/Source/bindings/scripts/unstable/v8_methods.py232
-rw-r--r--chromium/third_party/WebKit/Source/bindings/scripts/unstable/v8_types.py583
-rw-r--r--chromium/third_party/WebKit/Source/bindings/scripts/utilities.py171
-rw-r--r--chromium/third_party/WebKit/Source/bindings/scripts/v8_attributes.py436
-rw-r--r--chromium/third_party/WebKit/Source/bindings/scripts/v8_callback_interface.py (renamed from chromium/third_party/WebKit/Source/bindings/scripts/unstable/v8_callback_interface.py)81
-rw-r--r--chromium/third_party/WebKit/Source/bindings/scripts/v8_globals.py (renamed from chromium/third_party/WebKit/Source/bindings/scripts/unstable/v8_globals.py)3
-rw-r--r--chromium/third_party/WebKit/Source/bindings/scripts/v8_interface.py1087
-rw-r--r--chromium/third_party/WebKit/Source/bindings/scripts/v8_methods.py349
-rw-r--r--chromium/third_party/WebKit/Source/bindings/scripts/v8_types.py691
-rw-r--r--chromium/third_party/WebKit/Source/bindings/scripts/v8_utilities.py (renamed from chromium/third_party/WebKit/Source/bindings/scripts/unstable/v8_utilities.py)123
-rw-r--r--chromium/third_party/WebKit/Source/bindings/templates/attributes.cpp271
-rw-r--r--chromium/third_party/WebKit/Source/bindings/templates/callback_interface.cpp73
-rw-r--r--chromium/third_party/WebKit/Source/bindings/templates/callback_interface.h51
-rw-r--r--chromium/third_party/WebKit/Source/bindings/templates/interface.cpp909
-rw-r--r--chromium/third_party/WebKit/Source/bindings/templates/interface.h148
-rw-r--r--chromium/third_party/WebKit/Source/bindings/templates/interface_base.cpp89
-rw-r--r--chromium/third_party/WebKit/Source/bindings/templates/methods.cpp492
-rw-r--r--chromium/third_party/WebKit/Source/bindings/templates/templates.gni17
-rw-r--r--chromium/third_party/WebKit/Source/bindings/templates/templates.gypi17
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/ArrayValue.cpp2
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/BindingSecurity.cpp44
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/BindingSecurity.h12
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/CallbackPromiseAdapter.h32
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/CustomElementBinding.cpp2
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/CustomElementBinding.h6
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/CustomElementConstructorBuilder.cpp102
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/CustomElementConstructorBuilder.h3
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/CustomElementWrapper.cpp20
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/CustomElementWrapper.h3
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/DOMDataStore.cpp27
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/DOMDataStore.h108
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/DOMRequestState.h85
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/DOMWrapperMap.h134
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/DOMWrapperWorld.cpp144
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/DOMWrapperWorld.h83
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/DebuggerScript.js179
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/Dictionary.cpp191
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/Dictionary.h131
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/ExceptionMessages.cpp83
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/ExceptionMessages.h115
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/ExceptionState.cpp53
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/ExceptionState.h57
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/ExceptionStatePlaceholder.cpp4
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/ExceptionStatePlaceholder.h29
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/IDBBindingUtilities.cpp181
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/IDBBindingUtilities.h24
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/IDBBindingUtilitiesTest.cpp131
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/NPV8Object.cpp126
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/NPV8Object.h6
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/Nullable.h51
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/PageScriptDebugServer.cpp114
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/PageScriptDebugServer.h36
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/RetainedDOMInfo.h17
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/ScheduledAction.cpp53
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/ScheduledAction.h17
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/ScopedPersistent.h7
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/ScriptCallStackFactory.cpp26
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/ScriptCallStackFactory.h8
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/ScriptController.cpp334
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/ScriptController.h38
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/ScriptDebugServer.cpp268
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/ScriptDebugServer.h49
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/ScriptEventListener.cpp78
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/ScriptEventListener.h9
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/ScriptFunction.cpp32
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/ScriptFunction.h (renamed from chromium/third_party/WebKit/Source/bindings/v8/custom/V8MIDIInputCustom.cpp)32
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/ScriptFunctionCall.cpp113
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/ScriptFunctionCall.h26
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/ScriptGCEvent.cpp2
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/ScriptGCEvent.h3
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/ScriptHeapSnapshot.cpp18
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/ScriptHeapSnapshot.h9
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/ScriptObject.h66
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/ScriptPreprocessor.cpp46
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/ScriptPreprocessor.h7
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/ScriptProfiler.cpp85
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/ScriptProfiler.h10
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/ScriptPromise.cpp104
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/ScriptPromise.h45
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/ScriptPromiseResolver.cpp74
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/ScriptPromiseResolver.h139
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/ScriptPromiseResolverTest.cpp184
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/ScriptPromiseResolverWithContext.cpp101
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/ScriptPromiseResolverWithContext.h145
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/ScriptPromiseTest.cpp260
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/ScriptRegexp.cpp25
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/ScriptScope.cpp58
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/ScriptScope.h55
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/ScriptSourceCode.h2
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/ScriptState.cpp148
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/ScriptState.h179
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/ScriptString.cpp45
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/ScriptString.h27
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/ScriptValue.cpp96
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/ScriptValue.h89
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/ScriptWrappable.h169
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/SerializedScriptValue.cpp1139
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/SerializedScriptValue.h37
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/UnsafePersistent.h129
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/V8AbstractEventListener.cpp89
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/V8AbstractEventListener.h30
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/V8Binding.cpp670
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/V8Binding.h1340
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/V8BindingMacros.h115
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/V8Callback.cpp8
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/V8Callback.h14
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/V8CustomElementLifecycleCallbacks.cpp97
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/V8CustomElementLifecycleCallbacks.h12
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/V8DOMActivityLogger.cpp72
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/V8DOMActivityLogger.h26
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/V8DOMConfiguration.cpp49
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/V8DOMConfiguration.h23
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/V8DOMWrapper.cpp68
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/V8DOMWrapper.h96
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/V8ErrorHandler.cpp42
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/V8ErrorHandler.h16
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/V8EventListener.cpp24
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/V8EventListener.h11
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/V8EventListenerList.cpp17
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/V8EventListenerList.h37
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/V8GCController.cpp207
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/V8GCController.h3
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/V8GCForContextDispose.cpp5
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/V8GCForContextDispose.h1
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/V8GarbageCollected.h (renamed from chromium/third_party/WebKit/Source/bindings/v8/ScriptObject.cpp)87
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/V8HiddenPropertyName.cpp79
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/V8HiddenPropertyName.h83
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/V8HiddenValue.cpp46
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/V8HiddenValue.h61
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/V8Initializer.cpp101
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/V8LazyEventListener.cpp113
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/V8LazyEventListener.h16
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/V8MutationCallback.cpp37
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/V8MutationCallback.h17
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/V8NPObject.cpp156
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/V8NPObject.h3
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/V8NPUtils.cpp6
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/V8NodeFilterCondition.cpp42
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/V8NodeFilterCondition.h15
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/V8ObjectConstructor.cpp28
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/V8ObjectConstructor.h23
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/V8PerContextData.cpp79
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/V8PerContextData.h119
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/V8PerIsolateData.cpp157
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/V8PerIsolateData.h102
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/V8PersistentValueMap.h128
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/V8PersistentValueVector.h (renamed from chromium/third_party/WebKit/Source/bindings/v8/custom/V8NodeListCustom.cpp)59
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/V8RecursionScope.cpp7
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/V8RecursionScope.h41
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/V8ScriptRunner.cpp142
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/V8ScriptRunner.h16
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/V8StringResource.cpp85
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/V8StringResource.h59
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/V8ThrowException.cpp4
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/V8ThrowException.h4
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/V8Utilities.cpp181
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/V8Utilities.h72
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/V8ValueCache.cpp55
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/V8ValueCache.h42
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/V8WindowShell.cpp248
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/V8WindowShell.h40
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/V8WorkerGlobalScopeEventListener.cpp66
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/V8WorkerGlobalScopeEventListener.h14
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/WorkerScriptController.cpp157
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/WorkerScriptController.h36
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/WorkerScriptDebugServer.cpp21
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/WorkerScriptDebugServer.h18
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/WrapperTypeInfo.h85
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/custom/V8AlgorithmCustom.cpp78
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/custom/V8ArrayBufferCustom.cpp28
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/custom/V8ArrayBufferCustom.h17
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/custom/V8ArrayBufferViewCustom.cpp4
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/custom/V8ArrayBufferViewCustom.h7
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/custom/V8ArrayBufferViewCustomScript.js36
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/custom/V8AudioNodeCustom.cpp36
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/custom/V8BiquadFilterNodeCustom.cpp60
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/custom/V8BlobCustom.cpp13
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/custom/V8BlobCustomHelpers.cpp47
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/custom/V8BlobCustomHelpers.h10
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/custom/V8CSSRuleCustom.cpp29
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/custom/V8CSSStyleDeclarationCustom.cpp132
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/custom/V8CSSValueCustom.cpp20
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/custom/V8CanvasRenderingContext2DCustom.cpp45
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/custom/V8CanvasRenderingContextCustom.cpp51
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/custom/V8ClientCustom.cpp39
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/custom/V8CryptoCustom.cpp11
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/custom/V8CustomEventCustom.cpp25
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/custom/V8CustomSQLStatementErrorCallback.cpp23
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/custom/V8CustomXPathNSResolver.cpp28
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/custom/V8CustomXPathNSResolver.h6
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/custom/V8DataViewCustom.cpp2
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/custom/V8DataViewCustom.h4
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/custom/V8DedicatedWorkerGlobalScopeCustom.cpp17
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/custom/V8DeviceMotionEventCustom.cpp40
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/custom/V8DeviceOrientationEventCustom.cpp10
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/custom/V8DocumentCustom.cpp40
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/custom/V8ElementCustom.cpp236
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/custom/V8EntryCustom.cpp8
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/custom/V8EntrySyncCustom.cpp8
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/custom/V8ErrorEventCustom.cpp12
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/custom/V8EventCustom.cpp12
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/custom/V8EventTargetCustom.cpp9
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/custom/V8FileCustom.cpp15
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/custom/V8FileReaderCustom.cpp10
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/custom/V8Float32ArrayCustom.h4
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/custom/V8Float64ArrayCustom.h4
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/custom/V8FormDataCustom.cpp71
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/custom/V8GeolocationCustom.cpp80
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/custom/V8HTMLAllCollectionCustom.cpp46
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/custom/V8HTMLCanvasElementCustom.cpp55
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/custom/V8HTMLCollectionCustom.cpp16
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/custom/V8HTMLDocumentCustom.cpp27
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/custom/V8HTMLElementCustom.cpp4
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/custom/V8HTMLFormControlsCollectionCustom.cpp71
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/custom/V8HTMLFrameElementCustom.cpp59
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/custom/V8HTMLOptionsCollectionCustom.cpp56
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/custom/V8HTMLPlugInElementCustom.cpp34
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/custom/V8HistoryCustom.cpp40
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/custom/V8ImageDataCustom.cpp2
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/custom/V8InjectedScriptHostCustom.cpp151
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/custom/V8InjectedScriptManager.cpp45
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/custom/V8InspectorFrontendHostCustom.cpp13
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/custom/V8Int16ArrayCustom.h4
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/custom/V8Int32ArrayCustom.h4
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/custom/V8Int8ArrayCustom.h4
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/custom/V8JavaScriptCallFrameCustom.cpp2
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/custom/V8LocationCustom.cpp2
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/custom/V8MIDIOutputCustom.cpp52
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/custom/V8MessageChannelCustom.cpp15
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/custom/V8MessageEventCustom.cpp92
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/custom/V8MessagePortCustom.cpp16
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/custom/V8MutationObserverCustom.cpp19
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/custom/V8NodeCustom.cpp67
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/custom/V8OscillatorNodeCustom.cpp60
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/custom/V8PannerNodeCustom.cpp84
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/custom/V8PerformanceEntryCustom.cpp8
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/custom/V8PopStateEventCustom.cpp16
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/custom/V8PromiseCustom.cpp794
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/custom/V8PromiseCustom.h136
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/custom/V8SQLResultSetRowListCustom.cpp17
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/custom/V8SQLTransactionCustom.cpp42
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/custom/V8SQLTransactionSyncCustom.cpp26
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/custom/V8SVGElementCustom.cpp4
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/custom/V8SVGLengthCustom.cpp102
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/custom/V8SVGPathSegCustom.cpp42
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/custom/V8ServiceWorkerCustom.cpp38
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/custom/V8StyleSheetCustom.cpp6
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/custom/V8SubtleCryptoCustom.cpp125
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/custom/V8TextCustom.cpp4
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/custom/V8TextTrackCueCustom.cpp31
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/custom/V8TrackEventCustom.cpp14
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/custom/V8TypedArrayCustom.h17
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/custom/V8Uint16ArrayCustom.h4
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/custom/V8Uint32ArrayCustom.h4
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/custom/V8Uint8ArrayCustom.h4
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/custom/V8Uint8ClampedArrayCustom.h4
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/custom/V8WebGLRenderingContextCustom.cpp449
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/custom/V8WebKitPointCustom.cpp4
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/custom/V8WindowCustom.cpp242
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/custom/V8WorkerCryptoCustom.cpp43
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/custom/V8WorkerCustom.cpp16
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/custom/V8WorkerGlobalScopeCustom.cpp22
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/custom/V8XMLHttpRequestCustom.cpp60
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/custom/V8XSLTProcessorCustom.cpp34
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/custom/custom.gypi92
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/npruntime.cpp4
-rw-r--r--chromium/third_party/WebKit/Source/bindings/v8/v8.gypi165
335 files changed, 18697 insertions, 22464 deletions
diff --git a/chromium/third_party/WebKit/Source/bindings/BUILD.gn b/chromium/third_party/WebKit/Source/bindings/BUILD.gn
new file mode 100644
index 00000000000..14c48c29542
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/bindings/BUILD.gn
@@ -0,0 +1,105 @@
+# Copyright 2014 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import("//third_party/WebKit/Source/bindings/bindings.gni")
+import("//third_party/WebKit/Source/build/scripts/scripts.gni")
+import("//third_party/WebKit/Source/core/core.gni")
+import("//third_party/WebKit/Source/modules/modules.gni")
+
+visibility = "//third_party/WebKit/*"
+
+# Main interface IDL files (excluding dependencies and testing)
+# are included as properties on global objects, and in aggregate bindings.
+main_interface_idl_files = core_idl_files + modules_idl_files
+
+main_interface_idl_files_list = "$target_gen_dir/main_interface_idl_files.tmp"
+write_file(main_interface_idl_files_list,
+ rebase_path(main_interface_idl_files, root_build_dir))
+
+generated_global_constructors_idl_files = [
+ "$blink_output_dir/WindowConstructors.idl",
+ "$blink_output_dir/SharedWorkerGlobalScopeConstructors.idl",
+ "$blink_output_dir/DedicatedWorkerGlobalScopeConstructors.idl",
+ "$blink_output_dir/ServiceWorkerGlobalScopeConstructors.idl",
+]
+generated_global_constructors_header_files = [
+ "$blink_output_dir/WindowConstructors.h",
+ "$blink_output_dir/SharedWorkerGlobalScopeConstructors.h",
+ "$blink_output_dir/DedicatedWorkerGlobalScopeConstructors.h",
+ "$blink_output_dir/ServiceWorkerGlobalScopeConstructors.h",
+]
+
+# FIXME: Generate separate core_global_objects
+# http://crbug.com/358074
+# GYP version: generated.gyp:global_objects
+action("global_objects") {
+ script = "scripts/compute_global_objects.py"
+
+ source_prereqs = [
+ "scripts/utilities.py",
+ # Only look in main IDL files (exclude dependencies and testing,
+ # which should not define global objects).
+ main_interface_idl_files_list,
+ ] + main_interface_idl_files
+
+ outputs = [
+ "$bindings_output_dir/GlobalObjects.pickle",
+ ]
+
+ args = [
+ "--idl-files-list",
+ rebase_path(main_interface_idl_files_list, root_build_dir),
+ "--write-file-only-if-changed=1", # Always true for Ninja. FIXME: remove
+ # when everything switched to GN.
+ "--",
+ rebase_path("$bindings_output_dir/GlobalObjects.pickle", root_build_dir),
+ ]
+}
+
+# GYP version: generated.gyp:global_constructors_idls
+action("global_constructors_idls") {
+ script = "scripts/generate_global_constructors.py"
+
+ source_prereqs = [
+ "scripts/generate_global_constructors.py",
+ "scripts/utilities.py",
+ "$bindings_output_dir/GlobalObjects.pickle",
+ # Only includes main IDL files (exclude dependencies and testing,
+ # which should not appear on global objects).
+ main_interface_idl_files_list,
+ ] + main_interface_idl_files
+
+ outputs = generated_global_constructors_idl_files +
+ generated_global_constructors_header_files
+
+ args = [
+ "--idl-files-list",
+ rebase_path(main_interface_idl_files_list, root_build_dir),
+ "--global-objects-file",
+ rebase_path("$bindings_output_dir/GlobalObjects.pickle", root_build_dir),
+ "--write-file-only-if-changed=1", # Always true for Ninja.
+ "--",
+ "Window",
+ rebase_path("$blink_output_dir/WindowConstructors.idl", root_build_dir),
+ "SharedWorkerGlobalScope",
+ rebase_path("$blink_output_dir/SharedWorkerGlobalScopeConstructors.idl",
+ root_build_dir),
+ "DedicatedWorkerGlobalScope",
+ rebase_path("$blink_output_dir/DedicatedWorkerGlobalScopeConstructors.idl",
+ root_build_dir),
+ "ServiceWorkerGlobalScope",
+ rebase_path("$blink_output_dir/ServiceWorkerGlobalScopeConstructors.idl",
+ root_build_dir),
+ ]
+
+ deps = [ ":global_objects" ]
+}
+
+# GYP version: generated.gyp:generated_idls
+group("generated_idls") {
+ deps = [
+ ":global_constructors_idls",
+ "//third_party/WebKit/Source/core:generated_testing_idls",
+ ]
+}
diff --git a/chromium/third_party/WebKit/Source/bindings/IDLExtendedAttributes.txt b/chromium/third_party/WebKit/Source/bindings/IDLExtendedAttributes.txt
index d361d4854d1..4d6bdca2849 100644
--- a/chromium/third_party/WebKit/Source/bindings/IDLExtendedAttributes.txt
+++ b/chromium/third_party/WebKit/Source/bindings/IDLExtendedAttributes.txt
@@ -25,7 +25,7 @@
# Note that including an empty value in the list, as in [Attr=X||Y],
# is NOT valid: the value is optional, but empty values are not allowed.
# - "Attr=*" means that Attr takes a required value, which can be
-# arbitrary and combinations thereof, e.g. [Attr=IndexedDB],
+# arbitrary, and combinations thereof, e.g. [Attr=IndexedDB],
# [Attr=DeleteFunction], [Attr=X|Y].
# - "Attr=|*" means that Attr takes an optional value, which can be
# arbitrary, e.g. [Attr], [Attr=X].
@@ -34,7 +34,6 @@
#
ActiveDOMObject
-ActivityLogging=ForAllWorlds|GetterForAllWorlds|SetterForAllWorlds|ForIsolatedWorlds|GetterForIsolatedWorlds|SetterForIsolatedWorlds
CachedAttribute=*
CallWith=ExecutionContext|ScriptState|ScriptArguments|ActiveWindow|FirstWindow|ThisValue
CheckSecurity=Frame|Node
@@ -44,11 +43,10 @@ Constructor
# FIXME: remove [ConstructorCallWith=Document], as can instead use
# [ConstructorCallWith=ExecutionContext] + toDocument(executionContext)
ConstructorCallWith=ExecutionContext|Document
-Custom=|Getter|Setter|LegacyCallAsFunction|ToV8|VisitDOMWrapper|Wrap
+Custom=|Getter|Setter|LegacyCallAsFunction|ToV8|VisitDOMWrapper|Wrap|PropertyGetter|PropertyEnumerator|PropertyQuery
CustomConstructor
CustomElementCallbacks
-CustomEnumerateProperty
-Default=NullString|Undefined
+Default=Undefined
DependentLifetime
DeprecateAs=*
DoNotCheckConstants
@@ -57,36 +55,47 @@ DoNotCheckSignature
EnforceRange
EventConstructor
ExposeJSAccessors
-GenerateVisitDOMWrapper=document|element|owner|ownerNode
-GlobalContext=Window|WorkerGlobalScope|SharedWorkerGlobalScope|DedicatedWorkerGlobalScope|ServiceWorkerGlobalScope
+Exposed=*
+GarbageCollected
+Global=|*
Immutable
ImplementedAs=*
InitializedByEventConstructor
-# FIXME: We should remove this extended attribute once the needed refactoring is complete.
-LegacyImplementedInBaseClass
+LegacyTreatAsPartialInterface
+LogActivity=|GetterOnly|SetterOnly
+LogAllWorlds
+LogPreviousValue
MeasureAs=*
NamedConstructor=*
NoInterfaceObject
NotEnumerable
OverrideBuiltins
+PartialInterfaceImplementedAs=*
# Valid values for [PerContextEnabled] are Context Features, in
# ContextFeatures::FeatureType in Source/core/dom/ContextFeatures.h
PerContextEnabled=*
PerWorldBindings
+PrimaryGlobal=|*
PutForwards=*
RaisesException=|Getter|Setter|Constructor
ReadOnly
Reflect=|*
+ReflectEmpty=*
+ReflectInvalid=*
+ReflectMissing=*
+ReflectOnly=*
Replaceable
# Valid values for [RuntimeEnabled] are the Runtime Enabled Features, listed in
# Source/core/page/RuntimeEnabledFeatures.in
RuntimeEnabled=*
-SetReference=*
-SetterCallWith=ExecutionContext|ScriptState|ScriptArguments|ActiveWindow|FirstWindow
+SetWrapperReferenceFrom=*
+SetWrapperReferenceTo=*
+SetterCallWith=ExecutionContext|ScriptArguments|ActiveWindow|FirstWindow
SpecialWrapFor=*
-StrictTypeChecking
-TreatNullAs=NullString|*
+TreatNullAs=NullString
TreatReturnedNullStringAs=Null|Undefined
-TreatUndefinedAs=NullString|*
+TreatUndefinedAs=NullString
+TypeChecking=Interface|Nullable|Unrestricted
URL
Unforgeable
+WillBeGarbageCollected
diff --git a/chromium/third_party/WebKit/Source/bindings/OWNERS b/chromium/third_party/WebKit/Source/bindings/OWNERS
index adf3dd03ebf..fa13cd3bd64 100644
--- a/chromium/third_party/WebKit/Source/bindings/OWNERS
+++ b/chromium/third_party/WebKit/Source/bindings/OWNERS
@@ -10,5 +10,6 @@ japhet@chromium.org
jochen@chromium.org
marja@chromium.org
mkwst@chromium.org
+nbarth@chromium.org
pfeldman@chromium.org
yurys@chromium.org
diff --git a/chromium/third_party/WebKit/Source/bindings/PRESUBMIT.py b/chromium/third_party/WebKit/Source/bindings/PRESUBMIT.py
index dc3cc1f57a9..605322d3dd3 100644
--- a/chromium/third_party/WebKit/Source/bindings/PRESUBMIT.py
+++ b/chromium/third_party/WebKit/Source/bindings/PRESUBMIT.py
@@ -32,8 +32,17 @@ See http://dev.chromium.org/developers/how-tos/depottools/presubmit-scripts
for more details about the presubmit API built into gcl.
"""
+# Changes to v8/ do not change generated code or tests, so exclude from
+# _RunBindingsTests
+BLACK_LIST = (r'.*\bv8[\\\/].*',)
def _RunBindingsTests(input_api, output_api):
+ # Skip if nothing to do
+ source_filter = lambda x: input_api.FilterSourceFile(
+ x, black_list=input_api.DEFAULT_BLACK_LIST + BLACK_LIST)
+ if not input_api.AffectedFiles(file_filter=source_filter):
+ return []
+
if input_api.is_committing:
message_type = output_api.PresubmitError
else:
diff --git a/chromium/third_party/WebKit/Source/bindings/__init__.py b/chromium/third_party/WebKit/Source/bindings/__init__.py
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/bindings/__init__.py
diff --git a/chromium/third_party/WebKit/Source/bindings/bindings.gni b/chromium/third_party/WebKit/Source/bindings/bindings.gni
new file mode 100644
index 00000000000..73b987df4f3
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/bindings/bindings.gni
@@ -0,0 +1,51 @@
+# Copyright 2014 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# All paths in this file should be absolute so it can be imported into
+# different contexts.
+
+# v8/custom/custom.gypi --------------------------------------------------------
+
+# These paths are relative to v8/custom.
+_v8_custom_gypi = exec_script(
+ "//build/gypi_to_gn.py",
+ [ rebase_path("v8/custom/custom.gypi") ],
+ "scope",
+ [ "v8/custom/custom.gypi" ])
+
+bindings_v8_custom_dir = get_path_info("v8/custom", "abspath")
+bindings_v8_custom_files = get_path_info(
+ rebase_path(_v8_custom_gypi.bindings_v8_custom_files, ".",
+ bindings_v8_custom_dir),
+ "abspath")
+
+# v8/v8.gypi -------------------------------------------------------------------
+
+# These paths are relative to v8.
+_v8_gypi = exec_script(
+ "//build/gypi_to_gn.py",
+ [ rebase_path("v8/v8.gypi") ],
+ "scope",
+ [ "v8/v8.gypi" ])
+
+bindings_v8_dir = get_path_info("v8", "abspath")
+
+# v8.gypi references includes a reference to the custom_files list. Manually
+# expand that.
+_rel_bindings_v8_files = _v8_gypi.bindings_v8_files
+_rel_bindings_v8_files -= [ "<@(bindings_v8_custom_files)" ]
+bindings_v8_files = get_path_info(
+ rebase_path(_rel_bindings_v8_files, ".", "v8"),
+ "abspath")
+bindings_v8_files += bindings_v8_custom_files
+
+# bindings.gypi ----------------------------------------------------------------
+
+bindings_dir = get_path_info(".", "abspath")
+blink_output_dir = "$root_gen_dir/blink"
+bindings_output_dir = "$root_gen_dir/blink/bindings"
+
+bindings_unittest_files = get_path_info(
+ rebase_path(_v8_gypi.bindings_v8_unittest_files, ".", bindings_v8_dir),
+ "abspath")
diff --git a/chromium/third_party/WebKit/Source/bindings/bindings.gypi b/chromium/third_party/WebKit/Source/bindings/bindings.gypi
index 78b7a9bb640..354b185c083 100644
--- a/chromium/third_party/WebKit/Source/bindings/bindings.gypi
+++ b/chromium/third_party/WebKit/Source/bindings/bindings.gypi
@@ -1,280 +1,15 @@
+# Copyright 2014 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
{
+ 'includes': [
+ 'v8/v8.gypi',
+ ],
'variables': {
- 'bindings_dir': ['.'],
- 'bindings_files': [
- 'v8/ActiveDOMCallback.cpp',
- 'v8/ActiveDOMCallback.h',
- 'v8/ArrayValue.cpp',
- 'v8/ArrayValue.h',
- 'v8/BindingSecurity.cpp',
- 'v8/BindingSecurity.h',
- 'v8/CallbackPromiseAdapter.h',
- 'v8/CustomElementBinding.cpp',
- 'v8/CustomElementBinding.h',
- 'v8/CustomElementConstructorBuilder.cpp',
- 'v8/CustomElementConstructorBuilder.h',
- 'v8/CustomElementWrapper.cpp',
- 'v8/CustomElementWrapper.h',
- 'v8/DOMDataStore.cpp',
- 'v8/DOMDataStore.h',
- 'v8/DOMRequestState.h',
- 'v8/DOMWrapperMap.h',
- 'v8/DOMWrapperWorld.cpp',
- 'v8/DOMWrapperWorld.h',
- 'v8/Dictionary.cpp',
- 'v8/Dictionary.h',
- 'v8/ExceptionMessages.h',
- 'v8/ExceptionMessages.cpp',
- 'v8/ExceptionState.h',
- 'v8/ExceptionState.cpp',
- 'v8/ExceptionStatePlaceholder.h',
- 'v8/ExceptionStatePlaceholder.cpp',
- 'v8/IDBBindingUtilities.cpp',
- 'v8/IDBBindingUtilities.h',
- 'v8/NPV8Object.cpp',
- 'v8/NPV8Object.h',
- 'v8/PageScriptDebugServer.cpp',
- 'v8/PageScriptDebugServer.h',
- 'v8/RetainedDOMInfo.cpp',
- 'v8/RetainedDOMInfo.h',
- 'v8/RetainedObjectInfo.h',
- 'v8/ScheduledAction.cpp',
- 'v8/ScheduledAction.h',
- 'v8/ScopedPersistent.h',
- 'v8/ScriptCallStackFactory.cpp',
- 'v8/ScriptCallStackFactory.h',
- 'v8/ScriptController.cpp',
- 'v8/ScriptController.h',
- 'v8/ScriptDebugServer.cpp',
- 'v8/ScriptDebugServer.h',
- 'v8/ScriptEventListener.cpp',
- 'v8/ScriptEventListener.h',
- 'v8/ScriptFunctionCall.cpp',
- 'v8/ScriptFunctionCall.h',
- 'v8/ScriptGCEvent.cpp',
- 'v8/ScriptGCEvent.h',
- 'v8/ScriptHeapSnapshot.cpp',
- 'v8/ScriptHeapSnapshot.h',
- 'v8/ScriptObject.cpp',
- 'v8/ScriptObject.h',
- 'v8/ScriptPreprocessor.cpp',
- 'v8/ScriptPreprocessor.h',
- 'v8/ScriptProfiler.cpp',
- 'v8/ScriptProfiler.h',
- 'v8/ScriptPromise.cpp',
- 'v8/ScriptPromise.h',
- 'v8/ScriptPromiseResolver.cpp',
- 'v8/ScriptPromiseResolver.h',
- 'v8/ScriptRegexp.cpp',
- 'v8/ScriptRegexp.h',
- 'v8/ScriptScope.cpp',
- 'v8/ScriptScope.h',
- 'v8/ScriptSourceCode.h',
- 'v8/ScriptState.cpp',
- 'v8/ScriptState.h',
- 'v8/ScriptString.cpp',
- 'v8/ScriptString.h',
- 'v8/ScriptValue.cpp',
- 'v8/ScriptValue.h',
- 'v8/ScriptWrappable.h',
- 'v8/SerializedScriptValue.cpp',
- 'v8/SerializedScriptValue.h',
- 'v8/SharedPersistent.h',
- 'v8/UnsafePersistent.h',
- 'v8/V8AbstractEventListener.cpp',
- 'v8/V8AbstractEventListener.h',
- 'v8/V8Binding.cpp',
- 'v8/V8Binding.h',
- 'v8/V8BindingMacros.h',
- 'v8/V8Callback.cpp',
- 'v8/V8Callback.h',
- 'v8/V8CustomElementLifecycleCallbacks.cpp',
- 'v8/V8CustomElementLifecycleCallbacks.h',
- 'v8/V8DOMActivityLogger.h',
- 'v8/V8DOMConfiguration.cpp',
- 'v8/V8DOMConfiguration.h',
- 'v8/V8ErrorHandler.cpp',
- 'v8/V8ErrorHandler.h',
- 'v8/V8DOMWrapper.cpp',
- 'v8/V8DOMWrapper.h',
- 'v8/V8EventListener.cpp',
- 'v8/V8EventListener.h',
- 'v8/V8EventListenerList.cpp',
- 'v8/V8EventListenerList.h',
- 'v8/V8GCController.cpp',
- 'v8/V8GCController.h',
- 'v8/V8GCForContextDispose.cpp',
- 'v8/V8GCForContextDispose.h',
- 'v8/V8HiddenPropertyName.cpp',
- 'v8/V8HiddenPropertyName.h',
- 'v8/V8Initializer.cpp',
- 'v8/V8Initializer.h',
- 'v8/V8LazyEventListener.cpp',
- 'v8/V8LazyEventListener.h',
- 'v8/V8MutationCallback.cpp',
- 'v8/V8MutationCallback.h',
- 'v8/V8NPObject.cpp',
- 'v8/V8NPObject.h',
- 'v8/V8NPUtils.cpp',
- 'v8/V8NPUtils.h',
- 'v8/V8NodeFilterCondition.cpp',
- 'v8/V8NodeFilterCondition.h',
- 'v8/V8ObjectConstructor.cpp',
- 'v8/V8ObjectConstructor.h',
- 'v8/V8PerContextData.cpp',
- 'v8/V8PerContextData.h',
- 'v8/V8PerIsolateData.cpp',
- 'v8/V8PerIsolateData.h',
- 'v8/V8RecursionScope.cpp',
- 'v8/V8RecursionScope.h',
- 'v8/V8ScriptRunner.cpp',
- 'v8/V8ScriptRunner.h',
- 'v8/V8StringResource.cpp',
- 'v8/V8StringResource.h',
- 'v8/V8ThrowException.cpp',
- 'v8/V8ThrowException.h',
- 'v8/V8Utilities.cpp',
- 'v8/V8Utilities.h',
- 'v8/V8ValueCache.cpp',
- 'v8/V8ValueCache.h',
- 'v8/V8WindowShell.cpp',
- 'v8/V8WindowShell.h',
- 'v8/V8WorkerGlobalScopeEventListener.cpp',
- 'v8/V8WorkerGlobalScopeEventListener.h',
- 'v8/WorkerScriptController.cpp',
- 'v8/WorkerScriptController.h',
- 'v8/WorkerScriptDebugServer.cpp',
- 'v8/WorkerScriptDebugServer.h',
- 'v8/WrapperTypeInfo.h',
- 'v8/custom/V8AlgorithmCustom.cpp',
- 'v8/custom/V8ArrayBufferCustom.cpp',
- 'v8/custom/V8ArrayBufferCustom.h',
- 'v8/custom/V8ArrayBufferViewCustom.cpp',
- 'v8/custom/V8ArrayBufferViewCustom.h',
- 'v8/custom/V8AudioNodeCustom.cpp',
- 'v8/custom/V8BiquadFilterNodeCustom.cpp',
- 'v8/custom/V8BlobCustom.cpp',
- 'v8/custom/V8BlobCustomHelpers.cpp',
- 'v8/custom/V8BlobCustomHelpers.h',
- 'v8/custom/V8CSSRuleCustom.cpp',
- 'v8/custom/V8CSSStyleDeclarationCustom.cpp',
- 'v8/custom/V8CSSValueCustom.cpp',
- 'v8/custom/V8CanvasRenderingContext2DCustom.cpp',
- 'v8/custom/V8CanvasRenderingContextCustom.cpp',
- 'v8/custom/V8CryptoCustom.cpp',
- 'v8/custom/V8CustomEventCustom.cpp',
- 'v8/custom/V8CustomSQLStatementErrorCallback.cpp',
- 'v8/custom/V8CustomXPathNSResolver.cpp',
- 'v8/custom/V8CustomXPathNSResolver.h',
- 'v8/custom/V8DataViewCustom.cpp',
- 'v8/custom/V8DataViewCustom.h',
- 'v8/custom/V8DedicatedWorkerGlobalScopeCustom.cpp',
- 'v8/custom/V8DeviceMotionEventCustom.cpp',
- 'v8/custom/V8DeviceOrientationEventCustom.cpp',
- 'v8/custom/V8DocumentCustom.cpp',
- 'v8/custom/V8EntryCustom.cpp',
- 'v8/custom/V8EntrySyncCustom.cpp',
- 'v8/custom/V8EventCustom.cpp',
- 'v8/custom/V8EventTargetCustom.cpp',
- 'v8/custom/V8ErrorEventCustom.cpp',
- 'v8/custom/V8FileCustom.cpp',
- 'v8/custom/V8FileReaderCustom.cpp',
- 'v8/custom/V8Float32ArrayCustom.h',
- 'v8/custom/V8Float64ArrayCustom.h',
- 'v8/custom/V8FormDataCustom.cpp',
- 'v8/custom/V8GeolocationCustom.cpp',
- 'v8/custom/V8HTMLAllCollectionCustom.cpp',
- 'v8/custom/V8HTMLCanvasElementCustom.cpp',
- 'v8/custom/V8HTMLCollectionCustom.cpp',
- 'v8/custom/V8HTMLDocumentCustom.cpp',
- 'v8/custom/V8HTMLElementCustom.cpp',
- 'v8/custom/V8HTMLFormControlsCollectionCustom.cpp',
- 'v8/custom/V8HTMLFrameElementCustom.cpp',
- 'v8/custom/V8HTMLOptionsCollectionCustom.cpp',
- 'v8/custom/V8HTMLPlugInElementCustom.cpp',
- 'v8/custom/V8HistoryCustom.cpp',
- 'v8/custom/V8ImageDataCustom.cpp',
- 'v8/custom/V8InjectedScriptHostCustom.cpp',
- 'v8/custom/V8InjectedScriptManager.cpp',
- 'v8/custom/V8InspectorFrontendHostCustom.cpp',
- 'v8/custom/V8Int8ArrayCustom.h',
- 'v8/custom/V8Int16ArrayCustom.h',
- 'v8/custom/V8Int32ArrayCustom.h',
- 'v8/custom/V8JavaScriptCallFrameCustom.cpp',
- 'v8/custom/V8LocationCustom.cpp',
- 'v8/custom/V8MIDIInputCustom.cpp',
- 'v8/custom/V8MIDIOutputCustom.cpp',
- 'v8/custom/V8MessageChannelCustom.cpp',
- 'v8/custom/V8MessageEventCustom.cpp',
- 'v8/custom/V8MessagePortCustom.cpp',
- 'v8/custom/V8MutationObserverCustom.cpp',
- 'v8/custom/V8NodeCustom.cpp',
- 'v8/custom/V8NodeListCustom.cpp',
- 'v8/custom/V8OscillatorNodeCustom.cpp',
- 'v8/custom/V8PannerNodeCustom.cpp',
- 'v8/custom/V8PerformanceEntryCustom.cpp',
- 'v8/custom/V8PopStateEventCustom.cpp',
- 'v8/custom/V8PromiseCustom.cpp',
- 'v8/custom/V8SQLResultSetRowListCustom.cpp',
- 'v8/custom/V8SQLTransactionCustom.cpp',
- 'v8/custom/V8SQLTransactionSyncCustom.cpp',
- 'v8/custom/V8SVGElementCustom.cpp',
- 'v8/custom/V8SVGLengthCustom.cpp',
- 'v8/custom/V8SVGPathSegCustom.cpp',
- 'v8/custom/V8StyleSheetCustom.cpp',
- 'v8/custom/V8TextCustom.cpp',
- 'v8/custom/V8TextTrackCueCustom.cpp',
- 'v8/custom/V8TrackEventCustom.cpp',
- 'v8/custom/V8TypedArrayCustom.h',
- 'v8/custom/V8Uint8ArrayCustom.h',
- 'v8/custom/V8Uint8ClampedArrayCustom.h',
- 'v8/custom/V8Uint16ArrayCustom.h',
- 'v8/custom/V8Uint32ArrayCustom.h',
- 'v8/custom/V8WebGLRenderingContextCustom.cpp',
- 'v8/custom/V8WebKitPointCustom.cpp',
- 'v8/custom/V8WindowCustom.cpp',
- 'v8/custom/V8WorkerGlobalScopeCustom.cpp',
- 'v8/custom/V8WorkerCryptoCustom.cpp',
- 'v8/custom/V8WorkerCustom.cpp',
- 'v8/custom/V8XMLHttpRequestCustom.cpp',
- 'v8/custom/V8XSLTProcessorCustom.cpp',
- 'v8/npruntime.cpp',
- 'v8/npruntime_impl.h',
- 'v8/npruntime_priv.h',
- ],
+ 'bindings_dir': '.',
'bindings_unittest_files': [
- 'v8/IDBBindingUtilitiesTest.cpp',
- 'v8/ScriptPromiseResolverTest.cpp',
- ],
- 'conditions': [
- ['OS=="win" and buildtype=="Official"', {
- # On windows official release builds, we try to preserve symbol space.
- 'derived_sources_aggregate_files': [
- '<(SHARED_INTERMEDIATE_DIR)/blink/bindings/V8DerivedSourcesAll.cpp',
- ],
- },{
- 'derived_sources_aggregate_files': [
- '<(SHARED_INTERMEDIATE_DIR)/blink/bindings/V8DerivedSources01.cpp',
- '<(SHARED_INTERMEDIATE_DIR)/blink/bindings/V8DerivedSources02.cpp',
- '<(SHARED_INTERMEDIATE_DIR)/blink/bindings/V8DerivedSources03.cpp',
- '<(SHARED_INTERMEDIATE_DIR)/blink/bindings/V8DerivedSources04.cpp',
- '<(SHARED_INTERMEDIATE_DIR)/blink/bindings/V8DerivedSources05.cpp',
- '<(SHARED_INTERMEDIATE_DIR)/blink/bindings/V8DerivedSources06.cpp',
- '<(SHARED_INTERMEDIATE_DIR)/blink/bindings/V8DerivedSources07.cpp',
- '<(SHARED_INTERMEDIATE_DIR)/blink/bindings/V8DerivedSources08.cpp',
- '<(SHARED_INTERMEDIATE_DIR)/blink/bindings/V8DerivedSources09.cpp',
- '<(SHARED_INTERMEDIATE_DIR)/blink/bindings/V8DerivedSources10.cpp',
- '<(SHARED_INTERMEDIATE_DIR)/blink/bindings/V8DerivedSources11.cpp',
- '<(SHARED_INTERMEDIATE_DIR)/blink/bindings/V8DerivedSources12.cpp',
- '<(SHARED_INTERMEDIATE_DIR)/blink/bindings/V8DerivedSources13.cpp',
- '<(SHARED_INTERMEDIATE_DIR)/blink/bindings/V8DerivedSources14.cpp',
- '<(SHARED_INTERMEDIATE_DIR)/blink/bindings/V8DerivedSources15.cpp',
- '<(SHARED_INTERMEDIATE_DIR)/blink/bindings/V8DerivedSources16.cpp',
- '<(SHARED_INTERMEDIATE_DIR)/blink/bindings/V8DerivedSources17.cpp',
- '<(SHARED_INTERMEDIATE_DIR)/blink/bindings/V8DerivedSources18.cpp',
- '<(SHARED_INTERMEDIATE_DIR)/blink/bindings/V8DerivedSources19.cpp',
- ],
- }],
+ '<@(bindings_v8_unittest_files)',
],
},
}
diff --git a/chromium/third_party/WebKit/Source/bindings/core/BUILD.gn b/chromium/third_party/WebKit/Source/bindings/core/BUILD.gn
new file mode 100644
index 00000000000..3f85f3c7fd6
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/bindings/core/BUILD.gn
@@ -0,0 +1,18 @@
+# Copyright 2014 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import("//third_party/WebKit/Source/bindings/core/core.gni")
+import("//third_party/WebKit/Source/bindings/core/idl.gni")
+import("//third_party/WebKit/Source/bindings/scripts/scripts.gni")
+
+visibility = "//third_party/WebKit/*"
+
+# GYP version: Source/bindings/core/generated.gyp:interfaces_info_individual_core
+compute_interfaces_info_individual("interfaces_info_individual_core") {
+ sources_static = core_static_idl_files
+ sources_generated = core_generated_idl_files
+ component_dir = "core"
+ output_file =
+ "$bindings_core_output_dir/InterfacesInfoCoreIndividual.pickle"
+}
diff --git a/chromium/third_party/WebKit/Source/bindings/core/core.gni b/chromium/third_party/WebKit/Source/bindings/core/core.gni
new file mode 100644
index 00000000000..8cfaf086e26
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/bindings/core/core.gni
@@ -0,0 +1,8 @@
+# Copyright 2014 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# FIXME: factor out bindings_core http://crbug.com/358074
+import("//third_party/WebKit/Source/bindings/bindings.gni")
+
+bindings_core_output_dir = "$bindings_output_dir/core"
diff --git a/chromium/third_party/WebKit/Source/bindings/core/core.gypi b/chromium/third_party/WebKit/Source/bindings/core/core.gypi
new file mode 100644
index 00000000000..5e36cb5386b
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/bindings/core/core.gypi
@@ -0,0 +1,15 @@
+# Copyright 2014 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+{
+ 'includes': [
+ '../modules/v8/generated.gypi', # FIXME: remove once core scripts generate qualified includes correctly: http://crbug.com/358074
+ '../v8/v8.gypi', # FIXME: should be v8/v8.gypi: http://crbug.com/358074
+ 'v8/generated.gypi',
+ ],
+
+ 'variables': {
+ 'bindings_core_output_dir': '<(SHARED_INTERMEDIATE_DIR)/blink/bindings/core',
+ },
+}
diff --git a/chromium/third_party/WebKit/Source/bindings/core/generated.gyp b/chromium/third_party/WebKit/Source/bindings/core/generated.gyp
new file mode 100644
index 00000000000..2492486fe30
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/bindings/core/generated.gyp
@@ -0,0 +1,72 @@
+# Copyright 2014 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# Generate IDL interfaces info for core, used to generate bindings
+#
+# Design doc: http://www.chromium.org/developers/design-documents/idl-build
+
+{
+ 'includes': [
+ # ../.. == Source
+ '../../bindings/scripts/scripts.gypi',
+ '../../core/core.gypi',
+ 'core.gypi',
+ 'generated.gypi',
+ 'idl.gypi',
+ ],
+
+ 'targets': [
+################################################################################
+ {
+ 'target_name': 'core_global_objects',
+ 'variables': {
+ 'idl_files': '<(core_idl_files)',
+ 'output_file': '<(bindings_core_output_dir)/GlobalObjectsCore.pickle',
+ },
+ 'includes': ['../../bindings/scripts/global_objects.gypi'],
+ },
+################################################################################
+ {
+ 'target_name': 'core_global_constructors_idls',
+ 'dependencies': [
+ 'core_global_objects',
+ ],
+ 'variables': {
+ 'idl_files': '<(core_idl_files)',
+ 'global_objects_file':
+ '<(bindings_core_output_dir)/GlobalObjectsCore.pickle',
+ 'global_names_idl_files': [
+ 'Window',
+ '<(blink_core_output_dir)/WindowCoreConstructors.idl',
+ 'SharedWorkerGlobalScope',
+ '<(blink_core_output_dir)/SharedWorkerGlobalScopeCoreConstructors.idl',
+ 'DedicatedWorkerGlobalScope',
+ '<(blink_core_output_dir)/DedicatedWorkerGlobalScopeCoreConstructors.idl',
+ ],
+ 'outputs': [
+ '<@(core_global_constructors_generated_idl_files)',
+ '<@(core_global_constructors_generated_header_files)',
+ ],
+ },
+ 'includes': ['../../bindings/scripts/global_constructors.gypi'],
+ },
+################################################################################
+ {
+ 'target_name': 'interfaces_info_individual_core',
+ 'dependencies': [
+ '../../core/core_generated.gyp:generated_testing_idls',
+ 'core_global_constructors_idls',
+ ],
+ 'variables': {
+ 'static_idl_files': '<(core_static_idl_files)',
+ 'generated_idl_files': '<(core_generated_idl_files)',
+ 'component_dir': 'core',
+ 'output_file':
+ '<(bindings_core_output_dir)/InterfacesInfoCoreIndividual.pickle',
+ },
+ 'includes': ['../../bindings/scripts/interfaces_info_individual.gypi'],
+ },
+################################################################################
+ ], # targets
+}
diff --git a/chromium/third_party/WebKit/Source/bindings/core/generated.gypi b/chromium/third_party/WebKit/Source/bindings/core/generated.gypi
new file mode 100644
index 00000000000..e3d457b66a9
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/bindings/core/generated.gypi
@@ -0,0 +1,24 @@
+# Copyright 2014 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+{
+ 'includes': [
+ '../../core/core_generated.gypi',
+ ],
+
+ 'variables': {
+ # Global constructors
+ 'core_global_constructors_generated_idl_files': [
+ '<(blink_core_output_dir)/WindowCoreConstructors.idl',
+ '<(blink_core_output_dir)/SharedWorkerGlobalScopeCoreConstructors.idl',
+ '<(blink_core_output_dir)/DedicatedWorkerGlobalScopeCoreConstructors.idl',
+ ],
+
+ 'core_global_constructors_generated_header_files': [
+ '<(blink_core_output_dir)/WindowCoreConstructors.h',
+ '<(blink_core_output_dir)/SharedWorkerGlobalScopeCoreConstructors.h',
+ '<(blink_core_output_dir)/DedicatedWorkerGlobalScopeCoreConstructors.h',
+ ],
+ },
+}
diff --git a/chromium/third_party/WebKit/Source/bindings/core/idl.gni b/chromium/third_party/WebKit/Source/bindings/core/idl.gni
new file mode 100644
index 00000000000..39cb5fff5ad
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/bindings/core/idl.gni
@@ -0,0 +1,57 @@
+# Copyright 2014 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import("//third_party/WebKit/Source/bindings/idl.gni")
+import("//third_party/WebKit/Source/core/core.gni")
+
+# Don't actually read idl.gypi since that just defines variables in terms of
+# others, which gypi_to_gn doesn't handle.
+
+# IDL file lists; see: http://www.chromium.org/developers/web-idl-interfaces
+# Interface IDL files: generate individual bindings (includes testing)
+core_interface_idl_files =
+ core_idl_files +
+ webcore_testing_idl_files +
+ generated_webcore_testing_idl_files
+
+# Static IDL files
+core_static_interface_idl_files =
+ core_idl_files +
+ webcore_testing_idl_files
+core_static_dependency_idl_files =
+ core_dependency_idl_files
+
+# Generated IDL files
+core_generated_interface_idl_files =
+ generated_webcore_testing_idl_files # interfaces
+core_generated_dependency_idl_files =
+ # FIXME: Generate separate core_global_constructors_idls
+ # http://crbug.com/358074
+ generated_global_constructors_idl_files # partial interfaces
+
+# Static IDL files / Generated IDL files
+#
+# In GYP, paths need to be passed separately for static and generated files, as
+# static files are listed in a temporary file (b/c too long for command line),
+# but generated files must be passed at the command line, as their paths are
+# not fixed at GYP time, when the temporary file is generated, because their
+# paths depend on the build directory, which varies.
+#
+# FIXME: GN does not have this restriction and we can combine them. While GYP
+# is still supported, we match its behavior for easier maintenance but this can
+# be simplified.
+core_static_idl_files =
+ core_static_interface_idl_files +
+ core_static_dependency_idl_files
+core_generated_idl_files =
+ core_generated_interface_idl_files +
+ core_generated_dependency_idl_files
+
+# Dependency IDL files: don't generate individual bindings, but do process
+# in IDL dependency computation, and count as build dependencies
+# 'core_dependency_idl_files' is already used in Source/core, so avoid
+# collision
+core_all_dependency_idl_files =
+ core_static_dependency_idl_files +
+ core_generated_dependency_idl_files
diff --git a/chromium/third_party/WebKit/Source/bindings/core/idl.gypi b/chromium/third_party/WebKit/Source/bindings/core/idl.gypi
new file mode 100644
index 00000000000..b4d1842b90d
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/bindings/core/idl.gypi
@@ -0,0 +1,71 @@
+# Copyright 2014 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# IDL file lists; see: http://www.chromium.org/developers/web-idl-interfaces
+
+{
+ 'includes': [
+ '../../core/core.gypi',
+ 'generated.gypi',
+ ],
+
+ 'variables': {
+ # IDL file lists; see: http://www.chromium.org/developers/web-idl-interfaces
+ # Interface IDL files: generate individual bindings (includes testing)
+ 'core_interface_idl_files': [
+ '<@(core_idl_files)',
+ '<@(webcore_testing_idl_files)',
+ '<@(generated_webcore_testing_idl_files)',
+ ],
+
+ # Write lists of main IDL files to a file, so that the command lines don't
+ # exceed OS length limits.
+ 'core_idl_files_list': '<|(core_idl_files_list.tmp <@(core_idl_files))',
+
+ # Dependency IDL files: don't generate individual bindings, but do process
+ # in IDL dependency computation, and count as build dependencies
+ # 'core_dependency_idl_files' is already used in Source/core, so avoid
+ # collision
+ 'core_all_dependency_idl_files': [
+ '<@(core_static_dependency_idl_files)',
+ '<@(core_generated_dependency_idl_files)',
+ ],
+
+ # Static IDL files / Generated IDL files
+ # Paths need to be passed separately for static and generated files, as
+ # static files are listed in a temporary file (b/c too long for command
+ # line), but generated files must be passed at the command line, as their
+ # paths are not fixed at GYP time, when the temporary file is generated,
+ # because their paths depend on the build directory, which varies.
+ 'core_static_idl_files': [
+ '<@(core_static_interface_idl_files)',
+ '<@(core_static_dependency_idl_files)',
+ ],
+ 'core_static_idl_files_list':
+ '<|(core_static_idl_files_list.tmp <@(core_static_idl_files))',
+
+ 'core_generated_idl_files': [
+ '<@(core_generated_interface_idl_files)',
+ '<@(core_generated_dependency_idl_files)',
+ ],
+
+ # Static IDL files
+ 'core_static_interface_idl_files': [
+ '<@(core_idl_files)',
+ '<@(webcore_testing_idl_files)',
+ ],
+ 'core_static_dependency_idl_files': [
+ '<@(core_dependency_idl_files)',
+ ],
+
+ # Generated IDL files
+ 'core_generated_interface_idl_files': [
+ '<@(generated_webcore_testing_idl_files)', # interfaces
+ ],
+
+ 'core_generated_dependency_idl_files': [
+ '<@(core_global_constructors_generated_idl_files)', # partial interfaces
+ ],
+ },
+}
diff --git a/chromium/third_party/WebKit/Source/bindings/core/v8/BUILD.gn b/chromium/third_party/WebKit/Source/bindings/core/v8/BUILD.gn
new file mode 100644
index 00000000000..6223986ca19
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/bindings/core/v8/BUILD.gn
@@ -0,0 +1,32 @@
+# Copyright 2014 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import("//third_party/WebKit/Source/bindings/core/idl.gni")
+
+import("//third_party/WebKit/Source/bindings/core/v8/generated.gni")
+import("//third_party/WebKit/Source/bindings/scripts/scripts.gni")
+import("//third_party/WebKit/Source/core/core.gni")
+
+visibility = "//third_party/WebKit/Source/*"
+
+# bindings_core_v8_generated in core/v8/generated.gyp
+group("bindings_core_v8_generated") {
+ deps = [
+ ":bindings_core_v8_generated_aggregate",
+ ":bindings_core_v8_generated_individual",
+ ]
+}
+
+# bindings_core_generated_aggregate in core/v8/generated.gyp
+aggregate_generated_bindings("bindings_core_v8_generated_aggregate") {
+ sources = core_idl_files
+ component_dir = "core"
+ outputs = bindings_core_generated_aggregate_files
+}
+
+# bindings_core_v8_generated_individual in core/v8/generated.gyp
+idl_compiler("bindings_core_v8_generated_individual") {
+ sources = core_interface_idl_files
+ output_dir = bindings_core_v8_output_dir
+}
diff --git a/chromium/third_party/WebKit/Source/bindings/core/v8/generated.gni b/chromium/third_party/WebKit/Source/bindings/core/v8/generated.gni
new file mode 100644
index 00000000000..516022d1c91
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/bindings/core/v8/generated.gni
@@ -0,0 +1,35 @@
+# Copyright 2014 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import("//third_party/WebKit/Source/bindings/bindings.gni")
+
+bindings_core_v8_output_dir = "$bindings_output_dir/core/v8"
+
+if (is_win && is_official_build) {
+ bindings_core_generated_aggregate_files = [
+ "$bindings_core_v8_output_dir/V8GeneratedCoreBindings.cpp",
+ ]
+} else {
+ bindings_core_generated_aggregate_files = [
+ "$bindings_core_v8_output_dir/V8GeneratedCoreBindings01.cpp",
+ "$bindings_core_v8_output_dir/V8GeneratedCoreBindings02.cpp",
+ "$bindings_core_v8_output_dir/V8GeneratedCoreBindings03.cpp",
+ "$bindings_core_v8_output_dir/V8GeneratedCoreBindings04.cpp",
+ "$bindings_core_v8_output_dir/V8GeneratedCoreBindings05.cpp",
+ "$bindings_core_v8_output_dir/V8GeneratedCoreBindings06.cpp",
+ "$bindings_core_v8_output_dir/V8GeneratedCoreBindings07.cpp",
+ "$bindings_core_v8_output_dir/V8GeneratedCoreBindings08.cpp",
+ "$bindings_core_v8_output_dir/V8GeneratedCoreBindings09.cpp",
+ "$bindings_core_v8_output_dir/V8GeneratedCoreBindings10.cpp",
+ "$bindings_core_v8_output_dir/V8GeneratedCoreBindings11.cpp",
+ "$bindings_core_v8_output_dir/V8GeneratedCoreBindings12.cpp",
+ "$bindings_core_v8_output_dir/V8GeneratedCoreBindings13.cpp",
+ "$bindings_core_v8_output_dir/V8GeneratedCoreBindings14.cpp",
+ "$bindings_core_v8_output_dir/V8GeneratedCoreBindings15.cpp",
+ "$bindings_core_v8_output_dir/V8GeneratedCoreBindings16.cpp",
+ "$bindings_core_v8_output_dir/V8GeneratedCoreBindings17.cpp",
+ "$bindings_core_v8_output_dir/V8GeneratedCoreBindings18.cpp",
+ "$bindings_core_v8_output_dir/V8GeneratedCoreBindings19.cpp",
+ ]
+}
diff --git a/chromium/third_party/WebKit/Source/bindings/core/v8/generated.gyp b/chromium/third_party/WebKit/Source/bindings/core/v8/generated.gyp
new file mode 100644
index 00000000000..6a61c2e7a4d
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/bindings/core/v8/generated.gyp
@@ -0,0 +1,135 @@
+# Copyright 2014 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# Generate IDL bindings for core, plus aggregate bindings files.
+#
+# Design doc: http://www.chromium.org/developers/design-documents/idl-build
+
+{
+ 'includes': [
+ # ../../.. == Source
+ '../../../bindings/bindings.gypi',
+ '../../../bindings/core/generated.gypi',
+ '../../../bindings/core/idl.gypi',
+ # FIXME: need info about modules IDL files because some core IDL files
+ # depend on modules IDL files http://crbug.com/358074
+ '../../../bindings/modules/idl.gypi',
+ '../../../bindings/modules/modules.gypi',
+ '../../../bindings/scripts/scripts.gypi',
+ '../../../core/core.gypi',
+ 'generated.gypi',
+ ],
+
+ 'targets': [
+################################################################################
+ {
+ # GN version: //third_party/WebKit/Source/bindings/core/v8:bindings_core_v8_generated_individual
+ 'target_name': 'bindings_core_v8_generated_individual',
+ 'type': 'none',
+ # The 'binding' rule generates .h files, so mark as hard_dependency, per:
+ # https://code.google.com/p/gyp/wiki/InputFormatReference#Linking_Dependencies
+ 'hard_dependency': 1,
+ 'dependencies': [
+ '../../../core/core_generated.gyp:generated_testing_idls',
+ '../generated.gyp:core_global_constructors_idls',
+ # FIXME: should not depend on modules, but partial interface definitions
+ # in modules change bindings for core http://crbug.com/358074
+ '../../modules/generated.gyp:modules_global_constructors_idls',
+ '<(bindings_scripts_dir)/scripts.gyp:cached_jinja_templates',
+ '<(bindings_scripts_dir)/scripts.gyp:cached_lex_yacc_tables',
+ # FIXME: should be interfaces_info_core (w/o modules)
+ # http://crbug.com/358074
+ '../../modules/generated.gyp:interfaces_info',
+ ],
+ 'sources': [
+ '<@(core_interface_idl_files)',
+ ],
+ 'rules': [{
+ 'rule_name': 'binding',
+ 'extension': 'idl',
+ 'msvs_external_rule': 1,
+ 'inputs': [
+ '<@(idl_lexer_parser_files)', # to be explicit (covered by parsetab)
+ '<@(idl_compiler_files)',
+ '<(bindings_scripts_output_dir)/lextab.py',
+ '<(bindings_scripts_output_dir)/parsetab.pickle',
+ '<(bindings_scripts_output_dir)/cached_jinja_templates.stamp',
+ '<(bindings_dir)/IDLExtendedAttributes.txt',
+ # If the dependency structure or public interface info (e.g.,
+ # [ImplementedAs]) changes, we rebuild all files, since we're not
+ # computing dependencies file-by-file in the build.
+ # This data is generally stable.
+ '<(bindings_modules_output_dir)/InterfacesInfoModules.pickle',
+ # Further, if any dependency (partial interface or implemented
+ # interface) changes, rebuild everything, since every IDL potentially
+ # depends on them, because we're not computing dependencies
+ # file-by-file.
+ # FIXME: This is too conservative, and causes excess rebuilds:
+ # compute this file-by-file. http://crbug.com/341748
+ # FIXME: should be core_all_dependency_idl_files only, but some core IDL
+ # files depend on modules IDL files http://crbug.com/358074
+ '<@(all_dependency_idl_files)',
+ ],
+ 'outputs': [
+ '<(bindings_core_v8_output_dir)/V8<(RULE_INPUT_ROOT).cpp',
+ '<(bindings_core_v8_output_dir)/V8<(RULE_INPUT_ROOT).h',
+ ],
+ # sanitize-win-build-log.sed uses a regex which matches this command
+ # line (Python script + .idl file being processed).
+ # Update that regex if command line changes (other than changing flags)
+ 'action': [
+ 'python',
+ '-S', # skip 'import site' to speed up startup
+ '<(bindings_scripts_dir)/idl_compiler.py',
+ '--cache-dir',
+ '<(bindings_scripts_output_dir)',
+ '--output-dir',
+ '<(bindings_core_v8_output_dir)',
+ '--interfaces-info',
+ '<(bindings_modules_output_dir)/InterfacesInfoModules.pickle',
+ '--write-file-only-if-changed',
+ '<(write_file_only_if_changed)',
+ '<(RULE_INPUT_PATH)',
+ ],
+ 'message': 'Generating binding from <(RULE_INPUT_PATH)',
+ }],
+ },
+################################################################################
+ {
+ # GN version: //third_party/WebKit/Source/bindings/core/v8:bindings_core_v8_generated_aggregate
+ 'target_name': 'bindings_core_v8_generated_aggregate',
+ 'type': 'none',
+ 'actions': [{
+ 'action_name': 'generate_aggregate_bindings_core_v8',
+ 'inputs': [
+ '<(bindings_scripts_dir)/aggregate_generated_bindings.py',
+ '<(core_idl_files_list)',
+ ],
+ 'outputs': [
+ '<@(bindings_core_v8_generated_aggregate_files)',
+ ],
+ 'action': [
+ 'python',
+ '<(bindings_scripts_dir)/aggregate_generated_bindings.py',
+ 'core',
+ '<(core_idl_files_list)',
+ '--',
+ '<@(bindings_core_v8_generated_aggregate_files)',
+ ],
+ 'message': 'Generating aggregate generated core V8 bindings files',
+ }],
+ },
+################################################################################
+ {
+ # GN version: //third_party/WebKit/Source/bindings/core/v8:bindings_core_v8_generated
+ 'target_name': 'bindings_core_v8_generated',
+ 'type': 'none',
+ 'dependencies': [
+ 'bindings_core_v8_generated_aggregate',
+ 'bindings_core_v8_generated_individual',
+ ],
+ },
+################################################################################
+ ], # targets
+}
diff --git a/chromium/third_party/WebKit/Source/bindings/core/v8/generated.gypi b/chromium/third_party/WebKit/Source/bindings/core/v8/generated.gypi
new file mode 100644
index 00000000000..a599286ad05
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/bindings/core/v8/generated.gypi
@@ -0,0 +1,41 @@
+# Copyright 2014 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+{
+ 'variables': {
+ 'bindings_core_v8_output_dir': '<(SHARED_INTERMEDIATE_DIR)/blink/bindings/core/v8',
+
+ 'conditions': [
+ ['OS=="win" and buildtype=="Official"', {
+ # On Windows Official release builds, we try to preserve symbol
+ # space.
+ 'bindings_core_v8_generated_aggregate_files': [
+ '<(bindings_core_v8_output_dir)/V8GeneratedCoreBindings.cpp',
+ ],
+ }, {
+ 'bindings_core_v8_generated_aggregate_files': [
+ '<(bindings_core_v8_output_dir)/V8GeneratedCoreBindings01.cpp',
+ '<(bindings_core_v8_output_dir)/V8GeneratedCoreBindings02.cpp',
+ '<(bindings_core_v8_output_dir)/V8GeneratedCoreBindings03.cpp',
+ '<(bindings_core_v8_output_dir)/V8GeneratedCoreBindings04.cpp',
+ '<(bindings_core_v8_output_dir)/V8GeneratedCoreBindings05.cpp',
+ '<(bindings_core_v8_output_dir)/V8GeneratedCoreBindings06.cpp',
+ '<(bindings_core_v8_output_dir)/V8GeneratedCoreBindings07.cpp',
+ '<(bindings_core_v8_output_dir)/V8GeneratedCoreBindings08.cpp',
+ '<(bindings_core_v8_output_dir)/V8GeneratedCoreBindings09.cpp',
+ '<(bindings_core_v8_output_dir)/V8GeneratedCoreBindings10.cpp',
+ '<(bindings_core_v8_output_dir)/V8GeneratedCoreBindings11.cpp',
+ '<(bindings_core_v8_output_dir)/V8GeneratedCoreBindings12.cpp',
+ '<(bindings_core_v8_output_dir)/V8GeneratedCoreBindings13.cpp',
+ '<(bindings_core_v8_output_dir)/V8GeneratedCoreBindings14.cpp',
+ '<(bindings_core_v8_output_dir)/V8GeneratedCoreBindings15.cpp',
+ '<(bindings_core_v8_output_dir)/V8GeneratedCoreBindings16.cpp',
+ '<(bindings_core_v8_output_dir)/V8GeneratedCoreBindings17.cpp',
+ '<(bindings_core_v8_output_dir)/V8GeneratedCoreBindings18.cpp',
+ '<(bindings_core_v8_output_dir)/V8GeneratedCoreBindings19.cpp',
+ ],
+ }],
+ ],
+ },
+}
diff --git a/chromium/third_party/WebKit/Source/bindings/derived_sources.gyp b/chromium/third_party/WebKit/Source/bindings/derived_sources.gyp
deleted file mode 100644
index 20f34614da0..00000000000
--- a/chromium/third_party/WebKit/Source/bindings/derived_sources.gyp
+++ /dev/null
@@ -1,316 +0,0 @@
-#
-# Copyright (C) 2013 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.
-#
-
-{
- 'includes': [
- '../build/scripts/scripts.gypi',
- '../build/win/precompile.gypi',
- '../build/scripts/scripts.gypi',
- '../core/core.gypi',
- '../modules/modules.gypi',
- 'bindings.gypi',
- ],
-
- 'variables': {
- 'main_idl_files': [
- '<@(core_idl_files)',
- '<@(modules_idl_files)',
- '<@(svg_idl_files)',
- ],
- 'support_idl_files': [
- '<@(webcore_testing_support_idl_files)',
- '<@(modules_testing_support_idl_files)',
- ],
- 'generated_support_idl_files': [
- '<@(generated_webcore_testing_support_idl_files)',
- ],
- 'compiler_module_files': [
- 'scripts/idl_compiler.py',
- '<(DEPTH)/third_party/ply/lex.py',
- '<(DEPTH)/third_party/ply/yacc.py',
- # jinja2/__init__.py contains version string, so sufficient for package
- '<(DEPTH)/third_party/jinja2/__init__.py',
- '<(DEPTH)/third_party/markupsafe/__init__.py', # jinja2 dep
- '<(DEPTH)/tools/idl_parser/idl_lexer.py',
- '<(DEPTH)/tools/idl_parser/idl_node.py',
- '<(DEPTH)/tools/idl_parser/idl_parser.py',
- 'scripts/blink_idl_lexer.py',
- 'scripts/blink_idl_parser.py',
- 'scripts/code_generator_v8.py',
- 'scripts/idl_definitions.py',
- 'scripts/idl_definitions_builder.py',
- 'scripts/idl_reader.py',
- 'scripts/idl_validator.py',
- 'scripts/interface_dependency_resolver.py',
- 'scripts/v8_attributes.py',
- 'scripts/v8_callback_interface.py',
- 'scripts/v8_interface.py',
- 'scripts/v8_types.py',
- 'scripts/v8_utilities.py',
- ],
- 'code_generator_template_files': [
- 'templates/attributes.cpp',
- 'templates/callback_interface.cpp',
- 'templates/callback_interface.h',
- 'templates/interface_base.cpp',
- 'templates/interface.cpp',
- 'templates/interface.h',
- ],
-
- 'bindings_output_dir': '<(SHARED_INTERMEDIATE_DIR)/blink/bindings',
- 'generated_global_constructors_idl_files': [
- '<(SHARED_INTERMEDIATE_DIR)/blink/WindowConstructors.idl',
- '<(SHARED_INTERMEDIATE_DIR)/blink/WorkerGlobalScopeConstructors.idl',
- '<(SHARED_INTERMEDIATE_DIR)/blink/SharedWorkerGlobalScopeConstructors.idl',
- '<(SHARED_INTERMEDIATE_DIR)/blink/DedicatedWorkerGlobalScopeConstructors.idl',
- '<(SHARED_INTERMEDIATE_DIR)/ServiceWorkerGlobalScopeConstructors.idl',
- ],
-
- 'conditions': [
- ['OS=="win" and buildtype=="Official"', {
- # On windows official release builds, we try to preserve symbol space.
- 'derived_sources_aggregate_files': [
- '<(bindings_output_dir)/V8DerivedSourcesAll.cpp',
- ],
- },{
- 'derived_sources_aggregate_files': [
- '<(bindings_output_dir)/V8DerivedSources01.cpp',
- '<(bindings_output_dir)/V8DerivedSources02.cpp',
- '<(bindings_output_dir)/V8DerivedSources03.cpp',
- '<(bindings_output_dir)/V8DerivedSources04.cpp',
- '<(bindings_output_dir)/V8DerivedSources05.cpp',
- '<(bindings_output_dir)/V8DerivedSources06.cpp',
- '<(bindings_output_dir)/V8DerivedSources07.cpp',
- '<(bindings_output_dir)/V8DerivedSources08.cpp',
- '<(bindings_output_dir)/V8DerivedSources09.cpp',
- '<(bindings_output_dir)/V8DerivedSources10.cpp',
- '<(bindings_output_dir)/V8DerivedSources11.cpp',
- '<(bindings_output_dir)/V8DerivedSources12.cpp',
- '<(bindings_output_dir)/V8DerivedSources13.cpp',
- '<(bindings_output_dir)/V8DerivedSources14.cpp',
- '<(bindings_output_dir)/V8DerivedSources15.cpp',
- '<(bindings_output_dir)/V8DerivedSources16.cpp',
- '<(bindings_output_dir)/V8DerivedSources17.cpp',
- '<(bindings_output_dir)/V8DerivedSources18.cpp',
- '<(bindings_output_dir)/V8DerivedSources19.cpp',
- ],
- }],
- # The bindings generator can not write generated files if they are identical
- # to the already existing file – that way they don't need to be recompiled.
- # However, a reverse dependency having a newer timestamp than a
- # generated binding can confuse some build systems, so only use this on
- # ninja which explicitly supports this use case (gyp turns all actions into
- # ninja restat rules).
- ['"<(GENERATOR)"=="ninja"', {
- 'write_file_only_if_changed': '--write-file-only-if-changed 1',
- },{
- 'write_file_only_if_changed': '--write-file-only-if-changed 0',
- }],
- ],
- },
-
- 'target_defaults': {
- 'variables': {
- 'optimize': 'max',
- },
- },
-
- 'targets': [{
- 'target_name': 'interface_dependencies',
- 'type': 'none',
- 'actions': [{
- 'action_name': 'compute_interface_dependencies',
- 'variables': {
- # Write sources into a file, so that the action command line won't
- # exceed OS limits.
- 'main_idl_files_list': '<|(main_idl_files_list.tmp <@(main_idl_files))',
- 'support_idl_files_list': '<|(support_idl_files_list.tmp <@(support_idl_files))',
- },
- 'inputs': [
- 'scripts/compute_dependencies.py',
- '<(main_idl_files_list)',
- '<@(main_idl_files)',
- '<(support_idl_files_list)',
- '<@(support_idl_files)',
- ],
- 'outputs': [
- '<(SHARED_INTERMEDIATE_DIR)/blink/InterfaceDependencies.txt',
- '<(SHARED_INTERMEDIATE_DIR)/blink/BindingsDerivedSources.txt',
- '<@(generated_global_constructors_idl_files)',
- '<(SHARED_INTERMEDIATE_DIR)/blink/EventInterfaces.in',
- ],
- 'msvs_cygwin_shell': 0,
- 'action': [
- 'python',
- 'scripts/compute_dependencies.py',
- '--main-idl-files-list',
- '<(main_idl_files_list)',
- '--support-idl-files-list',
- '<(support_idl_files_list)',
- '--interface-dependencies-file',
- '<(SHARED_INTERMEDIATE_DIR)/blink/InterfaceDependencies.txt',
- '--bindings-derived-sources-file',
- '<(SHARED_INTERMEDIATE_DIR)/blink/BindingsDerivedSources.txt',
- '--window-constructors-file',
- '<(SHARED_INTERMEDIATE_DIR)/blink/WindowConstructors.idl',
- '--workerglobalscope-constructors-file',
- '<(SHARED_INTERMEDIATE_DIR)/blink/WorkerGlobalScopeConstructors.idl',
- '--sharedworkerglobalscope-constructors-file',
- '<(SHARED_INTERMEDIATE_DIR)/blink/SharedWorkerGlobalScopeConstructors.idl',
- '--dedicatedworkerglobalscope-constructors-file',
- '<(SHARED_INTERMEDIATE_DIR)/blink/DedicatedWorkerGlobalScopeConstructors.idl',
- '--serviceworkerglobalscope-constructors-file',
- '<(SHARED_INTERMEDIATE_DIR)/ServiceWorkerGlobalScopeConstructors.idl',
- '--event-names-file',
- '<(SHARED_INTERMEDIATE_DIR)/blink/EventInterfaces.in',
- '<@(write_file_only_if_changed)',
- ],
- 'message': 'Resolving partial interfaces dependencies in all IDL files',
- }]
- },
- {
- 'target_name': 'bindings_sources',
- 'type': 'none',
- # The 'binding' rule generates .h files, so mark as hard_dependency, per:
- # https://code.google.com/p/gyp/wiki/InputFormatReference#Linking_Dependencies
- 'hard_dependency': 1,
- 'dependencies': [
- 'interface_dependencies',
- '../config.gyp:config',
- '../core/core_derived_sources.gyp:generate_test_support_idls',
- ],
- 'sources': [
- '<@(main_idl_files)',
- '<@(support_idl_files)',
- '<@(generated_support_idl_files)',
- ],
- 'rules': [{
- 'rule_name': 'binding',
- 'extension': 'idl',
- 'msvs_external_rule': 1,
- 'inputs': [
- 'scripts/generate_bindings.pl',
- 'scripts/code_generator_v8.pm',
- 'scripts/idl_parser.pm',
- 'scripts/idl_serializer.pm',
- '../build/scripts/preprocessor.pm',
- 'IDLExtendedAttributes.txt',
- # FIXME: If the dependency structure changes, we rebuild all files,
- # since we're not computing dependencies file-by-file in the build.
- '<(SHARED_INTERMEDIATE_DIR)/blink/InterfaceDependencies.txt',
- # FIXME: Similarly, if any partial interface changes, rebuild
- # everything, since every IDL potentially depends on them, because
- # we're not computing dependencies file-by-file.
- #
- # If a new partial interface is added, need to regyp to update these
- # dependencies, as these are computed statically at gyp runtime.
- '<!@pymod_do_main(list_idl_files_with_partial_interface <@(main_idl_files) <@(support_idl_files))',
- # Generated IDLs are all partial interfaces, hence everything
- # potentially depends on them.
- '<@(generated_global_constructors_idl_files)',
- ],
- 'outputs': [
- '<(bindings_output_dir)/V8<(RULE_INPUT_ROOT).cpp',
- '<(bindings_output_dir)/V8<(RULE_INPUT_ROOT).h',
- ],
- 'variables': {
- # IDL include paths. The generator will search recursively for IDL
- # files under these locations.
- 'generator_include_dirs': [
- '--include', '../core',
- '--include', '../modules',
- '--include', '<(SHARED_INTERMEDIATE_DIR)/blink',
- ],
- # Hook for embedders to specify extra directories to find IDL files.
- 'extra_blink_generator_include_dirs%': [],
- },
- 'msvs_cygwin_shell': 0,
- # sanitize-win-build-log.sed uses a regex which matches this command
- # line (Perl script + .idl file being processed).
- # Update that regex if command line changes (other than changing flags)
- 'action': [
- '<(perl_exe)',
- '-w',
- '-Iscripts',
- '-I../build/scripts',
- '-I<(DEPTH)/third_party/JSON/out/lib/perl5',
- 'scripts/generate_bindings.pl',
- '--outputDir',
- '<(bindings_output_dir)',
- '--idlAttributesFile',
- 'IDLExtendedAttributes.txt',
- '<@(generator_include_dirs)',
- '<@(extra_blink_generator_include_dirs)',
- '--interfaceDependenciesFile',
- '<(SHARED_INTERMEDIATE_DIR)/blink/InterfaceDependencies.txt',
- '--additionalIdlFiles',
- # Generated IDL files aren't listed in InterfaceDependencies.txt,
- # b/c they aren't available at GYP run time, so we need to sort them
- # manually, depending on whether they are (main) interface files,
- # for which we generate bindings, or dependencies, for which we don't.
- # generated_support_idl_files are main interfaces, so generate
- # bindings, but generated_global_constructors_idl_files are all
- # partial interfaces, so don't (b/c generated by dependents).
- '<(generated_support_idl_files)',
- '<@(preprocessor)',
- '<@(write_file_only_if_changed)',
- '<(RULE_INPUT_PATH)',
- ],
- 'message': 'Generating binding from <(RULE_INPUT_PATH)',
- }],
- },
- {
- 'target_name': 'bindings_derived_sources',
- 'type': 'none',
- 'dependencies': [
- 'interface_dependencies',
- 'bindings_sources',
- ],
- 'actions': [{
- 'action_name': 'derived_sources_all_in_one',
- 'inputs': [
- '../build/scripts/action_derivedsourcesallinone.py',
- '<(SHARED_INTERMEDIATE_DIR)/blink/BindingsDerivedSources.txt',
- ],
- 'outputs': [
- '<@(derived_sources_aggregate_files)',
- ],
- 'action': [
- 'python',
- '../build/scripts/action_derivedsourcesallinone.py',
- '<(SHARED_INTERMEDIATE_DIR)/blink/BindingsDerivedSources.txt',
- '--',
- '<@(derived_sources_aggregate_files)',
- ],
- 'message': 'Generating bindings derived sources',
- }],
- },
- ],
-}
diff --git a/chromium/third_party/WebKit/Source/bindings/idl.gni b/chromium/third_party/WebKit/Source/bindings/idl.gni
new file mode 100644
index 00000000000..cc12a67ba3d
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/bindings/idl.gni
@@ -0,0 +1,21 @@
+# Copyright 2014 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import("//third_party/WebKit/Source/bindings/bindings.gni")
+
+# Global constructors
+# FIXME: Split into core vs. modules http://crbug.com/358074
+generated_global_constructors_idl_files = [
+ "$blink_output_dir/WindowConstructors.idl",
+ "$blink_output_dir/SharedWorkerGlobalScopeConstructors.idl",
+ "$blink_output_dir/DedicatedWorkerGlobalScopeConstructors.idl",
+ "$blink_output_dir/ServiceWorkerGlobalScopeConstructors.idl",
+]
+
+generated_global_constructors_header_files = [
+ "$blink_output_dir/WindowConstructors.h",
+ "$blink_output_dir/SharedWorkerGlobalScopeConstructors.h",
+ "$blink_output_dir/DedicatedWorkerGlobalScopeConstructors.h",
+ "$blink_output_dir/ServiceWorkerGlobalScopeConstructors.h",
+]
diff --git a/chromium/third_party/WebKit/Source/bindings/modules/BUILD.gn b/chromium/third_party/WebKit/Source/bindings/modules/BUILD.gn
new file mode 100644
index 00000000000..5fad650cd1c
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/bindings/modules/BUILD.gn
@@ -0,0 +1,120 @@
+# Copyright 2014 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import("//third_party/WebKit/Source/modules/modules.gni")
+import("//third_party/WebKit/Source/bindings/core/core.gni")
+import("//third_party/WebKit/Source/bindings/modules/modules.gni")
+import("//third_party/WebKit/Source/bindings/scripts/scripts.gni")
+import("//third_party/WebKit/Source/build/scripts/scripts.gni")
+
+visibility = "//third_party/WebKit/*"
+
+# GYP version: Source/bindings/modules/generated.gyp:bindings_modules_generated
+group("bindings_modules_generated") {
+ deps = [
+ ":modules_bindings_generated_event_interfaces",
+ ":bindings_modules_generated_event_modules_factory",
+ ":bindings_modules_generated_event_modules_names",
+ ":bindings_modules_generated_event_target_modules_factory",
+ ":bindings_modules_generated_event_target_modules_names",
+ ]
+}
+
+# GYP version: event_interfaces action in bindings_modules_generated
+generate_event_interfaces("modules_bindings_generated_event_interfaces") {
+ sources = modules_event_idl_files
+ output_file = "EventModulesInterfaces.in"
+ suffix = "Modules"
+}
+
+# GYP version: EventModulesFactory action in bindings_modules_generated
+make_event_factory("bindings_modules_generated_event_modules_factory") {
+ in_files = [
+ "$root_gen_dir/blink/EventModulesInterfaces.in",
+ ]
+ outputs = [
+ "$blink_modules_output_dir/EventModules.cpp",
+ "$blink_modules_output_dir/EventModulesHeaders.h",
+ "$blink_modules_output_dir/EventModulesInterfaces.h",
+ ]
+}
+
+# GYP version: EventModulesNames action in bindings_modules_generated
+make_names("bindings_modules_generated_event_modules_names") {
+ in_files = [
+ "$root_gen_dir/blink/EventModulesInterfaces.in",
+ ]
+ outputs = [
+ "$blink_modules_output_dir/EventModulesNames.cpp",
+ "$blink_modules_output_dir/EventModulesNames.h",
+ ]
+}
+
+# GYP version: EventTargetModulesFactory action in bindings_modules_generated
+make_event_factory("bindings_modules_generated_event_target_modules_factory") {
+ in_files = [
+ "../../modules/EventTargetModulesFactory.in",
+ ]
+ outputs = [
+ "$blink_modules_output_dir/EventTargetModulesHeaders.h",
+ "$blink_modules_output_dir/EventTargetModulesInterfaces.h",
+ ]
+}
+
+# GYP version: EventTargetModulesNames action in bindings_modules_generated
+make_names("bindings_modules_generated_event_target_modules_names") {
+ in_files = [
+ "../../modules/EventTargetModulesFactory.in",
+ ]
+ outputs = [
+ "$blink_modules_output_dir/EventTargetModulesNames.cpp",
+ "$blink_modules_output_dir/EventTargetModulesNames.h",
+ ]
+}
+
+# ------------------------------------------------------------------------------
+
+# GYP version: Source/bindings/modules/generated.gyp:interfaces_info_individual_modules
+compute_interfaces_info_individual("interfaces_info_individual_modules") {
+ sources_static = modules_static_idl_files
+ # No generated files currently, will add with constructors
+ sources_generated = []
+ component_dir = "modules"
+ output_file =
+ "$bindings_modules_output_dir/InterfacesInfoModulesIndividual.pickle"
+}
+
+# GYP version: Source/bindings/modules/generated.gyp:interfaces_info
+action("interfaces_info") {
+ script = "$bindings_scripts_dir/compute_interfaces_info_overall.py"
+
+ source_prereqs = [
+ "$bindings_core_output_dir/InterfacesInfoCoreIndividual.pickle",
+ "$bindings_modules_output_dir/InterfacesInfoModulesIndividual.pickle",
+ ]
+ outputs = [
+ "$bindings_modules_output_dir/InterfacesInfoModules.pickle",
+ ]
+
+ args = [
+ "--write-file-only-if-changed=1",
+ "--",
+ rebase_path(
+ "$bindings_core_output_dir/InterfacesInfoCoreIndividual.pickle",
+ root_build_dir),
+ rebase_path(
+ "$bindings_modules_output_dir/InterfacesInfoModulesIndividual.pickle",
+ root_build_dir),
+ rebase_path(
+ "$bindings_modules_output_dir/InterfacesInfoModules.pickle",
+ root_build_dir),
+ ]
+
+ deps = [
+ ":interfaces_info_individual_modules",
+ "//third_party/WebKit/Source/bindings/core:interfaces_info_individual_core",
+ ]
+}
+
+
diff --git a/chromium/third_party/WebKit/Source/bindings/modules/generated.gyp b/chromium/third_party/WebKit/Source/bindings/modules/generated.gyp
new file mode 100644
index 00000000000..9b697541a52
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/bindings/modules/generated.gyp
@@ -0,0 +1,242 @@
+# Copyright 2014 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# Generate IDL interfaces info for modules, used to generate bindings
+#
+# Design doc: http://www.chromium.org/developers/design-documents/idl-build
+
+{
+ 'includes': [
+ # ../.. == Source
+ '../../bindings/core/core.gypi',
+ '../../bindings/scripts/scripts.gypi',
+ '../../build/scripts/scripts.gypi', # FIXME: Needed for event files, should be in modules, not bindings_modules http://crbug.com/358074
+ '../../modules/modules.gypi',
+ 'generated.gypi',
+ 'idl.gypi',
+ 'modules.gypi',
+ ],
+
+ 'targets': [
+################################################################################
+ {
+ # GN version: //third_party/WebKit/Source/bindings/modules:bindings_modules_generated
+ # FIXME: Should be in modules, not bindings_modules http://crbug.com/358074
+ 'target_name': 'modules_event_generated',
+ 'type': 'none',
+ 'actions': [
+ {
+ # GN version: //third_party/WebKit/Source/bindings/modules:modules_bindings_generated_event_interfaces
+ 'action_name': 'event_interfaces',
+ 'variables': {
+ 'event_idl_files': [
+ '<@(modules_event_idl_files)',
+ ],
+ 'event_idl_files_list':
+ '<|(event_idl_files_list.tmp <@(event_idl_files))',
+ },
+ 'inputs': [
+ '<(bindings_scripts_dir)/generate_event_interfaces.py',
+ '<(bindings_scripts_dir)/utilities.py',
+ '<(event_idl_files_list)',
+ '<@(event_idl_files)',
+ ],
+ 'outputs': [
+ '<(blink_modules_output_dir)/EventModulesInterfaces.in',
+ ],
+ 'action': [
+ 'python',
+ '<(bindings_scripts_dir)/generate_event_interfaces.py',
+ '--event-idl-files-list',
+ '<(event_idl_files_list)',
+ '--event-interfaces-file',
+ '<(blink_modules_output_dir)/EventModulesInterfaces.in',
+ '--write-file-only-if-changed',
+ '<(write_file_only_if_changed)',
+ '--suffix',
+ 'Modules',
+ ],
+ },
+ {
+ # GN version: //third_party/WebKit/Source/bindings/modules:bindings_modules_generated_event_modules_factory
+ 'action_name': 'EventModulesFactory',
+ 'inputs': [
+ '<@(make_event_factory_files)',
+ '<(blink_modules_output_dir)/EventModulesInterfaces.in',
+ ],
+ 'outputs': [
+ '<(blink_modules_output_dir)/EventModules.cpp',
+ '<(blink_modules_output_dir)/EventModulesHeaders.h',
+ '<(blink_modules_output_dir)/EventModulesInterfaces.h',
+ ],
+ 'action': [
+ 'python',
+ '../../build/scripts/make_event_factory.py',
+ '<(blink_modules_output_dir)/EventModulesInterfaces.in',
+ '--output_dir',
+ '<(blink_modules_output_dir)',
+ ],
+ },
+ {
+ # GN version: //third_party/WebKit/Source/bindings/modules:bindings_modules_generated_event_modules_names
+ 'action_name': 'EventModulesNames',
+ 'inputs': [
+ '<@(make_names_files)',
+ '<(blink_modules_output_dir)/EventModulesInterfaces.in',
+ ],
+ 'outputs': [
+ '<(blink_modules_output_dir)/EventModulesNames.cpp',
+ '<(blink_modules_output_dir)/EventModulesNames.h',
+ ],
+ 'action': [
+ 'python',
+ '../../build/scripts/make_names.py',
+ '<(blink_modules_output_dir)/EventModulesInterfaces.in',
+ '--output_dir',
+ '<(blink_modules_output_dir)',
+ ],
+ },
+ {
+ # GN version: //third_party/WebKit/Source/bindings/modules:bindings_modules_generated_event_target_modules_factory
+ 'action_name': 'EventTargetModulesFactory',
+ 'inputs': [
+ '<@(make_event_factory_files)',
+ '../../modules/EventTargetModulesFactory.in',
+ ],
+ 'outputs': [
+ '<(blink_modules_output_dir)/EventTargetModulesHeaders.h',
+ '<(blink_modules_output_dir)/EventTargetModulesInterfaces.h',
+ ],
+ 'action': [
+ 'python',
+ '../../build/scripts/make_event_factory.py',
+ '../../modules/EventTargetModulesFactory.in',
+ '--output_dir',
+ '<(blink_modules_output_dir)',
+ ],
+ },
+ {
+ # GN version: //third_party/WebKit/Source/bindings/modules:bindings_modules_generated_event_target_modules_names
+ 'action_name': 'EventTargetModulesNames',
+ 'inputs': [
+ '<@(make_names_files)',
+ '../../modules/EventTargetModulesFactory.in',
+ ],
+ 'outputs': [
+ '<(blink_modules_output_dir)/EventTargetModulesNames.cpp',
+ '<(blink_modules_output_dir)/EventTargetModulesNames.h',
+ ],
+ 'action': [
+ 'python',
+ '../../build/scripts/make_names.py',
+ '../../modules/EventTargetModulesFactory.in',
+ '--output_dir',
+ '<(blink_modules_output_dir)',
+ ],
+ },
+ ],
+ },
+################################################################################
+ {
+ 'target_name': 'modules_global_objects',
+ 'dependencies': [
+ '../core/generated.gyp:core_global_objects',
+ ],
+ 'variables': {
+ 'idl_files': '<(modules_idl_files)',
+ 'input_files': [
+ '<(bindings_core_output_dir)/GlobalObjectsCore.pickle',
+ ],
+ 'output_file':
+ '<(bindings_modules_output_dir)/GlobalObjectsModules.pickle',
+ },
+ 'includes': ['../../bindings/scripts/global_objects.gypi'],
+ },
+################################################################################
+ {
+ # Global constructors for global objects in modules (ServiceWorker)
+ # but interfaces in core.
+ 'target_name': 'modules_core_global_constructors_idls',
+ 'dependencies': [
+ 'modules_global_objects',
+ ],
+ 'variables': {
+ 'idl_files': '<(core_idl_files)',
+ 'global_objects_file':
+ '<(bindings_modules_output_dir)/GlobalObjectsModules.pickle',
+ 'global_names_idl_files': [
+ 'ServiceWorkerGlobalScope',
+ '<(blink_modules_output_dir)/ServiceWorkerGlobalScopeCoreConstructors.idl',
+ ],
+ 'outputs': [
+ '<@(modules_core_global_constructors_generated_idl_files)',
+ '<@(modules_core_global_constructors_generated_header_files)',
+ ],
+ },
+ 'includes': ['../../bindings/scripts/global_constructors.gypi'],
+ },
+################################################################################
+ {
+ 'target_name': 'modules_global_constructors_idls',
+ 'dependencies': [
+ 'modules_global_objects',
+ ],
+ 'variables': {
+ 'idl_files': '<(modules_idl_files)',
+ 'global_objects_file':
+ '<(bindings_modules_output_dir)/GlobalObjectsModules.pickle',
+ 'global_names_idl_files': [
+ 'Window',
+ '<(blink_modules_output_dir)/WindowModulesConstructors.idl',
+ 'SharedWorkerGlobalScope',
+ '<(blink_modules_output_dir)/SharedWorkerGlobalScopeModulesConstructors.idl',
+ 'DedicatedWorkerGlobalScope',
+ '<(blink_modules_output_dir)/DedicatedWorkerGlobalScopeModulesConstructors.idl',
+ 'ServiceWorkerGlobalScope',
+ '<(blink_modules_output_dir)/ServiceWorkerGlobalScopeModulesConstructors.idl',
+ ],
+ 'outputs': [
+ '<@(modules_global_constructors_generated_idl_files)',
+ '<@(modules_global_constructors_generated_header_files)',
+ ],
+ },
+ 'includes': ['../../bindings/scripts/global_constructors.gypi'],
+ },
+################################################################################
+ {
+ 'target_name': 'interfaces_info_individual_modules',
+ 'dependencies': [
+ 'modules_core_global_constructors_idls',
+ 'modules_global_constructors_idls',
+ ],
+ 'variables': {
+ 'static_idl_files': '<(modules_static_idl_files)',
+ 'generated_idl_files': '<(modules_generated_idl_files)',
+ 'component_dir': 'modules',
+ 'output_file':
+ '<(bindings_modules_output_dir)/InterfacesInfoModulesIndividual.pickle',
+ },
+ 'includes': ['../../bindings/scripts/interfaces_info_individual.gypi'],
+ },
+################################################################################
+ {
+ # GN version: //third_party/WebKit/Source/bindings/modules:interfaces_info
+ 'target_name': 'interfaces_info',
+ 'dependencies': [
+ '../core/generated.gyp:interfaces_info_individual_core',
+ 'interfaces_info_individual_modules',
+ ],
+ 'variables': {
+ 'input_files': [
+ '<(bindings_core_output_dir)/InterfacesInfoCoreIndividual.pickle',
+ '<(bindings_modules_output_dir)/InterfacesInfoModulesIndividual.pickle',
+ ],
+ 'output_file':
+ '<(bindings_modules_output_dir)/InterfacesInfoModules.pickle',
+ },
+ 'includes': ['../../bindings/scripts/interfaces_info_overall.gypi'],
+ },
+################################################################################
+ ], # targets
+}
diff --git a/chromium/third_party/WebKit/Source/bindings/modules/generated.gypi b/chromium/third_party/WebKit/Source/bindings/modules/generated.gypi
new file mode 100644
index 00000000000..0cd8bdf4226
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/bindings/modules/generated.gypi
@@ -0,0 +1,34 @@
+# Copyright 2014 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+{
+ 'includes': [
+ '../../modules/modules_generated.gypi',
+ ],
+
+ 'variables': {
+ # Global constructors
+ # Global object in modules, constructors for interfaces in core
+ 'modules_core_global_constructors_generated_idl_files': [
+ '<(blink_modules_output_dir)/ServiceWorkerGlobalScopeCoreConstructors.idl',
+ ],
+ 'modules_core_global_constructors_generated_header_files': [
+ '<(blink_modules_output_dir)/ServiceWorkerGlobalScopeCoreConstructors.h',
+ ],
+
+ # Global object in modules, constructors for interfaces in modules
+ 'modules_global_constructors_generated_idl_files': [
+ '<(blink_modules_output_dir)/WindowModulesConstructors.idl',
+ '<(blink_modules_output_dir)/SharedWorkerGlobalScopeModulesConstructors.idl',
+ '<(blink_modules_output_dir)/DedicatedWorkerGlobalScopeModulesConstructors.idl',
+ '<(blink_modules_output_dir)/ServiceWorkerGlobalScopeModulesConstructors.idl',
+ ],
+ 'modules_global_constructors_generated_header_files': [
+ '<(blink_modules_output_dir)/WindowModulesConstructors.h',
+ '<(blink_modules_output_dir)/SharedWorkerGlobalScopeModulesConstructors.h',
+ '<(blink_modules_output_dir)/DedicatedWorkerGlobalScopeModulesConstructors.h',
+ '<(blink_modules_output_dir)/ServiceWorkerGlobalScopeModulesConstructors.h',
+ ],
+ },
+}
diff --git a/chromium/third_party/WebKit/Source/bindings/modules/idl.gni b/chromium/third_party/WebKit/Source/bindings/modules/idl.gni
new file mode 100644
index 00000000000..433c325ba3e
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/bindings/modules/idl.gni
@@ -0,0 +1,42 @@
+# Copyright 2014 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import("//third_party/WebKit/Source/bindings/core/idl.gni")
+import("//third_party/WebKit/Source/modules/modules.gni")
+
+# IDL file lists; see: http://www.chromium.org/developers/web-idl-interfaces
+
+# Static IDL files
+modules_static_interface_idl_files =
+ modules_idl_files
+modules_static_dependency_idl_files =
+ modules_dependency_idl_files +
+ modules_testing_dependency_idl_files
+
+# Static IDL files / Generated IDL files
+#
+# In GYP, paths need to be passed separately for static and generated files, as
+# static files are listed in a temporary file (b/c too long for command line),
+# but generated files must be passed at the command line, as their paths are
+# not fixed at GYP time, when the temporary file is generated, because their
+# paths depend on the build directory, which varies.
+#
+# FIXME: GN does not have this limitation and we can combine the lists.
+# Currently we keep the GYP/GN builds in sync for simplicity, but this can be
+# cleaned up once GYP is not used.
+modules_static_idl_files =
+ modules_static_interface_idl_files +
+ modules_static_dependency_idl_files
+
+# 'modules_dependency_idl_files' is already used in Source/modules, so avoid
+# collision
+modules_all_dependency_idl_files =
+ modules_static_dependency_idl_files
+ #+ modules_generated_dependency_idl_files
+
+# Dependency IDL files: don't generate individual bindings, but do process
+# in IDL dependency computation, and count as build dependencies
+all_dependency_idl_files =
+ core_all_dependency_idl_files +
+ modules_all_dependency_idl_files
diff --git a/chromium/third_party/WebKit/Source/bindings/modules/idl.gypi b/chromium/third_party/WebKit/Source/bindings/modules/idl.gypi
new file mode 100644
index 00000000000..8814be0a4e7
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/bindings/modules/idl.gypi
@@ -0,0 +1,72 @@
+# Copyright 2014 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# IDL file lists; see: http://www.chromium.org/developers/web-idl-interfaces
+
+{
+ 'includes': [
+ '../../modules/modules.gypi',
+ '../core/idl.gypi',
+ 'generated.gypi',
+ ],
+
+ 'variables': {
+ # IDL file lists; see: http://www.chromium.org/developers/web-idl-interfaces
+
+ # Interface IDL files: generate individual bindings (includes testing)
+ 'modules_interface_idl_files': [
+ # No testing or generated interface IDL files in modules currently
+ '<@(modules_idl_files)',
+ ],
+
+ # Write lists of main IDL files to a file, so that the command lines don't
+ # exceed OS length limits.
+ 'modules_idl_files_list': '<|(modules_idl_files_list.tmp <@(modules_idl_files))',
+
+ # Dependency IDL files: don't generate individual bindings, but do process
+ # in IDL dependency computation, and count as build dependencies
+ 'all_dependency_idl_files': [
+ '<@(core_all_dependency_idl_files)',
+ '<@(modules_all_dependency_idl_files)',
+ ],
+ # 'modules_dependency_idl_files' is already used in Source/modules, so avoid
+ # collision
+ 'modules_all_dependency_idl_files': [
+ '<@(modules_static_dependency_idl_files)',
+ '<@(modules_generated_dependency_idl_files)',
+ ],
+
+ # Static IDL files / Generated IDL files
+ # Paths need to be passed separately for static and generated files, as
+ # static files are listed in a temporary file (b/c too long for command
+ # line), but generated files must be passed at the command line, as their
+ # paths are not fixed at GYP time, when the temporary file is generated,
+ # because their paths depend on the build directory, which varies.
+ 'modules_static_idl_files': [
+ '<@(modules_static_interface_idl_files)',
+ '<@(modules_static_dependency_idl_files)',
+ ],
+ 'modules_static_idl_files_list':
+ '<|(modules_static_idl_files_list.tmp <@(modules_static_idl_files))',
+
+ 'modules_generated_idl_files': [
+ '<@(modules_generated_dependency_idl_files)',
+ ],
+
+ # Static IDL files
+ 'modules_static_interface_idl_files': [
+ '<@(modules_idl_files)',
+ ],
+ 'modules_static_dependency_idl_files': [
+ '<@(modules_dependency_idl_files)',
+ '<@(modules_testing_dependency_idl_files)',
+ ],
+
+ # Generated IDL files
+ 'modules_generated_dependency_idl_files': [
+ '<@(modules_core_global_constructors_generated_idl_files)', # partial interfaces
+ '<@(modules_global_constructors_generated_idl_files)', # partial interfaces
+ ],
+ },
+}
diff --git a/chromium/third_party/WebKit/Source/bindings/modules/modules.gni b/chromium/third_party/WebKit/Source/bindings/modules/modules.gni
new file mode 100644
index 00000000000..649abde724a
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/bindings/modules/modules.gni
@@ -0,0 +1,8 @@
+# Copyright 2014 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# FIXME: factor out bindings_core http://crbug.com/358074
+import("//third_party/WebKit/Source/bindings/bindings.gni")
+
+bindings_modules_output_dir = "$bindings_output_dir/bindings/modules"
diff --git a/chromium/third_party/WebKit/Source/bindings/modules/modules.gypi b/chromium/third_party/WebKit/Source/bindings/modules/modules.gypi
new file mode 100644
index 00000000000..700655e81e6
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/bindings/modules/modules.gypi
@@ -0,0 +1,13 @@
+# Copyright 2014 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+{
+ 'includes': [
+ 'v8/generated.gypi',
+ ],
+
+ 'variables': {
+ 'bindings_modules_output_dir': '<(SHARED_INTERMEDIATE_DIR)/blink/bindings/modules',
+ },
+}
diff --git a/chromium/third_party/WebKit/Source/bindings/modules/v8/BUILD.gn b/chromium/third_party/WebKit/Source/bindings/modules/v8/BUILD.gn
new file mode 100644
index 00000000000..7dc2ffb56fb
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/bindings/modules/v8/BUILD.gn
@@ -0,0 +1,32 @@
+# Copyright 2014 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import("//third_party/WebKit/Source/bindings/modules/v8/generated.gni")
+import("//third_party/WebKit/Source/bindings/scripts/scripts.gni")
+import("//third_party/WebKit/Source/modules/modules.gni")
+
+visibility = "//third_party/WebKit/*"
+
+# bindings_modules_generated in modules/v8/generated.gyp
+group("bindings_modules_generated") {
+ deps = [
+ ":bindings_modules_generated_aggregate",
+ ":bindings_modules_generated_individual",
+ ]
+}
+
+# bindings_modules_generated_aggregate in modules/v8/generated.gyp
+aggregate_generated_bindings("bindings_modules_generated_aggregate") {
+ sources = modules_idl_files
+ component_dir = "modules"
+ outputs = bindings_modules_generated_aggregate_files
+}
+
+# bindings_modules_generated_individual in modules/v8/generated.gyp
+idl_compiler("bindings_modules_generated_individual") {
+ # Note in GYP this is modules_interface_idl_files but this variable is just
+ # defined to modules_idl_files.
+ sources = modules_idl_files
+ output_dir = bindings_modules_v8_output_dir
+}
diff --git a/chromium/third_party/WebKit/Source/bindings/modules/v8/generated.gni b/chromium/third_party/WebKit/Source/bindings/modules/v8/generated.gni
new file mode 100644
index 00000000000..bdea030fafb
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/bindings/modules/v8/generated.gni
@@ -0,0 +1,35 @@
+# Copyright 2014 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import("//third_party/WebKit/Source/bindings/bindings.gni")
+
+bindings_modules_v8_output_dir = "$bindings_output_dir/modules/v8"
+
+if (is_win && is_official_build) {
+ bindings_modules_generated_aggregate_files = [
+ "$bindings_modules_v8_output_dir/V8GeneratedModulesBindings.cpp",
+ ]
+} else {
+ bindings_modules_generated_aggregate_files = [
+ "$bindings_modules_v8_output_dir/V8GeneratedModulesBindings01.cpp",
+ "$bindings_modules_v8_output_dir/V8GeneratedModulesBindings02.cpp",
+ "$bindings_modules_v8_output_dir/V8GeneratedModulesBindings03.cpp",
+ "$bindings_modules_v8_output_dir/V8GeneratedModulesBindings04.cpp",
+ "$bindings_modules_v8_output_dir/V8GeneratedModulesBindings05.cpp",
+ "$bindings_modules_v8_output_dir/V8GeneratedModulesBindings06.cpp",
+ "$bindings_modules_v8_output_dir/V8GeneratedModulesBindings07.cpp",
+ "$bindings_modules_v8_output_dir/V8GeneratedModulesBindings08.cpp",
+ "$bindings_modules_v8_output_dir/V8GeneratedModulesBindings09.cpp",
+ "$bindings_modules_v8_output_dir/V8GeneratedModulesBindings10.cpp",
+ "$bindings_modules_v8_output_dir/V8GeneratedModulesBindings11.cpp",
+ "$bindings_modules_v8_output_dir/V8GeneratedModulesBindings12.cpp",
+ "$bindings_modules_v8_output_dir/V8GeneratedModulesBindings13.cpp",
+ "$bindings_modules_v8_output_dir/V8GeneratedModulesBindings14.cpp",
+ "$bindings_modules_v8_output_dir/V8GeneratedModulesBindings15.cpp",
+ "$bindings_modules_v8_output_dir/V8GeneratedModulesBindings16.cpp",
+ "$bindings_modules_v8_output_dir/V8GeneratedModulesBindings17.cpp",
+ "$bindings_modules_v8_output_dir/V8GeneratedModulesBindings18.cpp",
+ "$bindings_modules_v8_output_dir/V8GeneratedModulesBindings19.cpp",
+ ]
+}
diff --git a/chromium/third_party/WebKit/Source/bindings/modules/v8/generated.gyp b/chromium/third_party/WebKit/Source/bindings/modules/v8/generated.gyp
new file mode 100644
index 00000000000..ffe504b1769
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/bindings/modules/v8/generated.gyp
@@ -0,0 +1,121 @@
+# Copyright 2014 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# Generate IDL bindings for modules, plus aggregate bindings files.
+#
+# Design doc: http://www.chromium.org/developers/design-documents/idl-build
+
+{
+ 'includes': [
+ # ../../.. == Source
+ '../../../bindings/bindings.gypi',
+ '../../../bindings/modules/idl.gypi',
+ '../../../bindings/modules/modules.gypi',
+ '../../../bindings/scripts/scripts.gypi',
+ '../../../modules/modules.gypi',
+ 'generated.gypi',
+ ],
+
+ 'targets': [
+################################################################################
+ {
+ 'target_name': 'bindings_modules_v8_generated_individual',
+ 'type': 'none',
+ # The 'binding' rule generates .h files, so mark as hard_dependency, per:
+ # https://code.google.com/p/gyp/wiki/InputFormatReference#Linking_Dependencies
+ 'hard_dependency': 1,
+ 'dependencies': [
+ '../../core/generated.gyp:core_global_constructors_idls',
+ '../generated.gyp:modules_global_constructors_idls',
+ '../generated.gyp:interfaces_info',
+ '<(bindings_scripts_dir)/scripts.gyp:cached_jinja_templates',
+ '<(bindings_scripts_dir)/scripts.gyp:cached_lex_yacc_tables',
+ ],
+ 'sources': [
+ '<@(modules_interface_idl_files)',
+ ],
+ 'rules': [{
+ 'rule_name': 'binding',
+ 'extension': 'idl',
+ 'msvs_external_rule': 1,
+ 'inputs': [
+ '<@(idl_lexer_parser_files)', # to be explicit (covered by parsetab)
+ '<@(idl_compiler_files)',
+ '<(bindings_scripts_output_dir)/lextab.py',
+ '<(bindings_scripts_output_dir)/parsetab.pickle',
+ '<(bindings_scripts_output_dir)/cached_jinja_templates.stamp',
+ '<(bindings_dir)/IDLExtendedAttributes.txt',
+ # If the dependency structure or public interface info (e.g.,
+ # [ImplementedAs]) changes, we rebuild all files, since we're not
+ # computing dependencies file-by-file in the build.
+ # This data is generally stable.
+ '<(bindings_modules_output_dir)/InterfacesInfoModules.pickle',
+ # Further, if any dependency (partial interface or implemented
+ # interface) changes, rebuild everything, since every IDL potentially
+ # depends on them, because we're not computing dependencies
+ # file-by-file.
+ # FIXME: This is too conservative, and causes excess rebuilds:
+ # compute this file-by-file. http://crbug.com/341748
+ '<@(all_dependency_idl_files)',
+ ],
+ 'outputs': [
+ '<(bindings_modules_v8_output_dir)/V8<(RULE_INPUT_ROOT).cpp',
+ '<(bindings_modules_v8_output_dir)/V8<(RULE_INPUT_ROOT).h',
+ ],
+ # sanitize-win-build-log.sed uses a regex which matches this command
+ # line (Python script + .idl file being processed).
+ # Update that regex if command line changes (other than changing flags)
+ 'action': [
+ 'python',
+ '-S', # skip 'import site' to speed up startup
+ '<(bindings_scripts_dir)/idl_compiler.py',
+ '--cache-dir',
+ '<(bindings_scripts_output_dir)',
+ '--output-dir',
+ '<(bindings_modules_v8_output_dir)',
+ '--interfaces-info',
+ '<(bindings_modules_output_dir)/InterfacesInfoModules.pickle',
+ '--write-file-only-if-changed',
+ '<(write_file_only_if_changed)',
+ '<(RULE_INPUT_PATH)',
+ ],
+ 'message': 'Generating binding from <(RULE_INPUT_PATH)',
+ }],
+ },
+################################################################################
+ {
+ 'target_name': 'bindings_modules_v8_generated_aggregate',
+ 'type': 'none',
+ 'actions': [{
+ 'action_name': 'generate_aggregate_bindings_modules_v8',
+ 'inputs': [
+ '<(bindings_scripts_dir)/aggregate_generated_bindings.py',
+ '<(modules_idl_files_list)',
+ ],
+ 'outputs': [
+ '<@(bindings_modules_v8_generated_aggregate_files)',
+ ],
+ 'action': [
+ 'python',
+ '<(bindings_scripts_dir)/aggregate_generated_bindings.py',
+ 'modules',
+ '<(modules_idl_files_list)',
+ '--',
+ '<@(bindings_modules_v8_generated_aggregate_files)',
+ ],
+ 'message': 'Generating aggregate generated modules V8 bindings files',
+ }],
+ },
+################################################################################
+ {
+ 'target_name': 'bindings_modules_v8_generated',
+ 'type': 'none',
+ 'dependencies': [
+ 'bindings_modules_v8_generated_aggregate',
+ 'bindings_modules_v8_generated_individual',
+ ],
+ },
+################################################################################
+ ], # targets
+}
diff --git a/chromium/third_party/WebKit/Source/bindings/modules/v8/generated.gypi b/chromium/third_party/WebKit/Source/bindings/modules/v8/generated.gypi
new file mode 100644
index 00000000000..eb00db7b1fd
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/bindings/modules/v8/generated.gypi
@@ -0,0 +1,41 @@
+# Copyright 2014 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+{
+ 'variables': {
+ 'bindings_modules_v8_output_dir': '<(SHARED_INTERMEDIATE_DIR)/blink/bindings/modules/v8',
+
+ 'conditions': [
+ ['OS=="win" and buildtype=="Official"', {
+ # On Windows Official release builds, we try to preserve symbol
+ # space.
+ 'bindings_modules_v8_generated_aggregate_files': [
+ '<(bindings_modules_v8_output_dir)/V8GeneratedModulesBindings.cpp',
+ ],
+ }, {
+ 'bindings_modules_v8_generated_aggregate_files': [
+ '<(bindings_modules_v8_output_dir)/V8GeneratedModulesBindings01.cpp',
+ '<(bindings_modules_v8_output_dir)/V8GeneratedModulesBindings02.cpp',
+ '<(bindings_modules_v8_output_dir)/V8GeneratedModulesBindings03.cpp',
+ '<(bindings_modules_v8_output_dir)/V8GeneratedModulesBindings04.cpp',
+ '<(bindings_modules_v8_output_dir)/V8GeneratedModulesBindings05.cpp',
+ '<(bindings_modules_v8_output_dir)/V8GeneratedModulesBindings06.cpp',
+ '<(bindings_modules_v8_output_dir)/V8GeneratedModulesBindings07.cpp',
+ '<(bindings_modules_v8_output_dir)/V8GeneratedModulesBindings08.cpp',
+ '<(bindings_modules_v8_output_dir)/V8GeneratedModulesBindings09.cpp',
+ '<(bindings_modules_v8_output_dir)/V8GeneratedModulesBindings10.cpp',
+ '<(bindings_modules_v8_output_dir)/V8GeneratedModulesBindings11.cpp',
+ '<(bindings_modules_v8_output_dir)/V8GeneratedModulesBindings12.cpp',
+ '<(bindings_modules_v8_output_dir)/V8GeneratedModulesBindings13.cpp',
+ '<(bindings_modules_v8_output_dir)/V8GeneratedModulesBindings14.cpp',
+ '<(bindings_modules_v8_output_dir)/V8GeneratedModulesBindings15.cpp',
+ '<(bindings_modules_v8_output_dir)/V8GeneratedModulesBindings16.cpp',
+ '<(bindings_modules_v8_output_dir)/V8GeneratedModulesBindings17.cpp',
+ '<(bindings_modules_v8_output_dir)/V8GeneratedModulesBindings18.cpp',
+ '<(bindings_modules_v8_output_dir)/V8GeneratedModulesBindings19.cpp',
+ ],
+ }],
+ ],
+ },
+}
diff --git a/chromium/third_party/WebKit/Source/bindings/scripts/BUILD.gn b/chromium/third_party/WebKit/Source/bindings/scripts/BUILD.gn
new file mode 100644
index 00000000000..1d5c639c3e1
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/bindings/scripts/BUILD.gn
@@ -0,0 +1,48 @@
+# Copyright 2014 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import("//third_party/WebKit/Source/bindings/bindings.gni")
+import("//third_party/WebKit/Source/bindings/scripts/scripts.gni")
+import("//third_party/WebKit/Source/bindings/templates/templates.gni")
+
+visibility = "//third_party/WebKit/*"
+
+# A separate pre-caching step is *not required* to use lex/parse table
+# caching in PLY, as the caches are concurrency-safe.
+# However, pre-caching ensures that all compiler processes use the cached
+# files (hence maximizing speed), instead of early processes building the
+# tables themselves (as they've not yet been written when they start).
+#
+# GYP version: scripts.gyp:cached_lex_yacc_tables
+action("cached_lex_yacc_tables") {
+ script = "blink_idl_parser.py"
+
+ source_prereqs = idl_lexer_parser_files
+ outputs = [
+ "$bindings_scripts_output_dir/lextab.py",
+ "$bindings_scripts_output_dir/parsetab.pickle",
+ ]
+
+ args = [ rebase_path(bindings_output_dir, root_build_dir) ]
+}
+
+# A separate pre-caching step is *required* to use bytecode caching in
+# Jinja (which improves speed significantly), as the bytecode cache is
+# not concurrency-safe on write; details in code_generator_v8.py.
+#
+# GYP version: scripts.gyp:cached_jinja_templates
+action("cached_jinja_templates") {
+ script = "code_generator_v8.py"
+
+ source_prereqs = jinja_module_files + [ "code_generator_v8.py" ] +
+ code_generator_template_files
+ # Dummy file to track dependency.
+ stamp_file = "$bindings_scripts_output_dir/cached_jinja_templates.stamp"
+ outputs = [ stamp_file ]
+
+ args = [
+ rebase_path(bindings_scripts_output_dir, root_build_dir),
+ rebase_path(stamp_file, root_build_dir),
+ ]
+}
diff --git a/chromium/third_party/WebKit/Source/bindings/scripts/__init__.py b/chromium/third_party/WebKit/Source/bindings/scripts/__init__.py
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/bindings/scripts/__init__.py
diff --git a/chromium/third_party/WebKit/Source/bindings/scripts/aggregate_generated_bindings.py b/chromium/third_party/WebKit/Source/bindings/scripts/aggregate_generated_bindings.py
new file mode 100755
index 00000000000..c6d3e3a5ed3
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/bindings/scripts/aggregate_generated_bindings.py
@@ -0,0 +1,229 @@
+#!/usr/bin/python
+#
+# 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.
+#
+# Copyright (c) 2009 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""Generate aggregate .cpp files that include multiple V8 binding .cpp files.
+
+This can be a single output file, to preserve symbol space; or multiple output
+files, to reduce maximum compilation unit size and allow parallel compilation.
+
+Usage:
+aggregate_generated_bindings.py COMPONENT_DIR IDL_FILES_LIST -- OUTPUT_FILE1 OUTPUT_FILE2 ...
+
+COMPONENT_DIR is the relative directory of a component, e.g., 'core', 'modules'.
+IDL_FILES_LIST is a text file containing the IDL file paths, so the command
+line doesn't exceed OS length limits.
+OUTPUT_FILE1 etc. are filenames of output files.
+
+Design doc: http://www.chromium.org/developers/design-documents/idl-build
+"""
+
+import errno
+import os
+import re
+import subprocess
+import sys
+
+from utilities import idl_filename_to_interface_name
+
+# A regexp for finding Conditional attributes in interface definitions.
+CONDITIONAL_PATTERN = re.compile(
+ r'\['
+ r'[^\]]*'
+ r'Conditional=([\_0-9a-zA-Z&|]*)'
+ r'[^\]]*'
+ r'\]\s*'
+ r'((callback|partial)\s+)?'
+ r'interface\s+'
+ r'\w+\s*'
+ r'(:\s*\w+\s*)?'
+ r'{',
+ re.MULTILINE)
+
+COPYRIGHT_TEMPLATE = """/*
+ * THIS FILE WAS AUTOMATICALLY GENERATED, DO NOT EDIT.
+ *
+ * This file was generated by the action_derivedsourcesallinone.py script.
+ *
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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.
+ */
+"""
+
+
+def format_conditional(conditional):
+ """Wraps conditional with ENABLE() and replace '&','|' with '&&','||' if
+ more than one conditional is specified."""
+ def wrap_with_enable(s):
+ if s in ['|', '&']:
+ return s * 2
+ return 'ENABLE(' + s + ')'
+ return ' '.join(map(wrap_with_enable, conditional))
+
+
+def extract_conditional(idl_file_path):
+ """Find [Conditional] interface extended attribute."""
+ with open(idl_file_path) as idl_file:
+ idl_contents = idl_file.read()
+
+ match = CONDITIONAL_PATTERN.search(idl_contents)
+ if not match:
+ return None
+ conditional = match.group(1)
+ return re.split('([|&])', conditional)
+
+
+def extract_meta_data(file_paths):
+ """Extracts conditional and interface name from each IDL file."""
+ meta_data_list = []
+
+ for file_path in file_paths:
+ if not file_path.endswith('.idl'):
+ print 'WARNING: non-IDL file passed: "%s"' % file_path
+ continue
+ if not os.path.exists(file_path):
+ print 'WARNING: file not found: "%s"' % file_path
+ continue
+
+ # Extract interface name from file name
+ interface_name = idl_filename_to_interface_name(file_path)
+
+ meta_data = {
+ 'conditional': extract_conditional(file_path),
+ 'name': interface_name,
+ }
+ meta_data_list.append(meta_data)
+
+ return meta_data_list
+
+
+def generate_content(component_dir, files_meta_data_this_partition):
+ # Add fixed content.
+ output = [COPYRIGHT_TEMPLATE,
+ '#define NO_IMPLICIT_ATOMICSTRING\n\n']
+
+ # List all includes segmented by if and endif.
+ prev_conditional = None
+ files_meta_data_this_partition.sort(key=lambda e: e['conditional'])
+ for meta_data in files_meta_data_this_partition:
+ conditional = meta_data['conditional']
+ if prev_conditional != conditional:
+ if prev_conditional:
+ output.append('#endif\n')
+ if conditional:
+ output.append('\n#if %s\n' % format_conditional(conditional))
+ prev_conditional = conditional
+
+ output.append('#include "bindings/%s/v8/V8%s.cpp"\n' %
+ (component_dir, meta_data['name']))
+
+ if prev_conditional:
+ output.append('#endif\n')
+
+ return ''.join(output)
+
+
+def write_content(content, output_file_name):
+ parent_path, file_name = os.path.split(output_file_name)
+ if not os.path.exists(parent_path):
+ print 'Creating directory: %s' % parent_path
+ os.makedirs(parent_path)
+ with open(output_file_name, 'w') as f:
+ f.write(content)
+
+
+def resolve_cygpath(cygdrive_names):
+ if not cygdrive_names:
+ return []
+ cmd = ['cygpath', '-f', '-', '-wa']
+ process = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
+ idl_file_names = []
+ for file_name in cygdrive_names:
+ process.stdin.write('%s\n' % file_name)
+ process.stdin.flush()
+ idl_file_names.append(process.stdout.readline().rstrip())
+ process.stdin.close()
+ process.wait()
+ return idl_file_names
+
+
+def main(args):
+ if len(args) <= 4:
+ raise Exception('Expected at least 5 arguments.')
+ component_dir = args[1]
+ input_file_name = args[2]
+ in_out_break_index = args.index('--')
+ output_file_names = args[in_out_break_index + 1:]
+
+ with open(input_file_name) as input_file:
+ file_names = sorted([os.path.realpath(line.rstrip('\n'))
+ for line in input_file])
+ idl_file_names = [file_name for file_name in file_names
+ if not file_name.startswith('/cygdrive')]
+ cygdrive_names = [file_name for file_name in file_names
+ if file_name.startswith('/cygdrive')]
+ idl_file_names.extend(resolve_cygpath(cygdrive_names))
+
+ files_meta_data = extract_meta_data(idl_file_names)
+ total_partitions = len(output_file_names)
+ for partition, file_name in enumerate(output_file_names):
+ files_meta_data_this_partition = [
+ meta_data for meta_data in files_meta_data
+ if hash(meta_data['name']) % total_partitions == partition]
+ file_contents = generate_content(component_dir,
+ files_meta_data_this_partition)
+ write_content(file_contents, file_name)
+
+
+if __name__ == '__main__':
+ sys.exit(main(sys.argv))
diff --git a/chromium/third_party/WebKit/Source/bindings/scripts/unstable/blink_idl_lexer.py b/chromium/third_party/WebKit/Source/bindings/scripts/blink_idl_lexer.py
index 4e6aa291e32..bbde34268b4 100644
--- a/chromium/third_party/WebKit/Source/bindings/scripts/unstable/blink_idl_lexer.py
+++ b/chromium/third_party/WebKit/Source/bindings/scripts/blink_idl_lexer.py
@@ -46,6 +46,9 @@ Web IDL Grammar:
http://www.w3.org/TR/WebIDL/#idl-grammar
PLY:
http://www.dabeaz.com/ply/
+
+Design doc:
+http://www.chromium.org/developers/design-documents/idl-compiler#TOC-Front-end
"""
# Disable attribute validation, as lint can't import parent class to check
@@ -54,11 +57,16 @@ PLY:
import os.path
import sys
-# Base lexer is in Chromium src/tools/idl_parser
+# PLY is in Chromium src/third_party/ply
module_path, module_name = os.path.split(__file__)
-tools_dir = os.path.join(module_path, os.pardir, os.pardir, os.pardir, os.pardir, os.pardir, os.pardir, 'tools')
-sys.path.append(tools_dir)
+third_party = os.path.join(module_path, os.pardir, os.pardir, os.pardir, os.pardir)
+# Insert at front to override system libraries, and after path[0] == script dir
+sys.path.insert(1, third_party)
+from ply import lex
+# Base lexer is in Chromium src/tools/idl_parser
+tools_dir = os.path.join(third_party, os.pardir, 'tools')
+sys.path.append(tools_dir)
from idl_parser.idl_lexer import IDLLexer
REMOVE_TOKENS = ['COMMENT']
@@ -80,11 +88,40 @@ class BlinkIDLLexer(IDLLexer):
for token in tokens:
self._RemoveToken(token)
- def __init__(self):
+ def __init__(self, debug=False, optimize=True, outputdir=None):
+ if debug:
+ # Turn off optimization and caching to help debugging
+ optimize = False
+ outputdir = None
+ if outputdir:
+ # Need outputdir in path because lex imports the cached lex table
+ # as a Python module
+ sys.path.append(outputdir)
+
IDLLexer.__init__(self)
+ # Overrides to parent class
self._RemoveTokens(REMOVE_TOKENS)
+ # Optimized mode substantially decreases startup time (by disabling
+ # error checking), and also allows use of Python's optimized mode.
+ # See: Optimized Mode
+ # http://www.dabeaz.com/ply/ply.html#ply_nn15
+ self._lexobj = lex.lex(object=self,
+ debug=debug,
+ optimize=optimize,
+ outputdir=outputdir)
+
+
+################################################################################
+
+def main(argv):
+ # If file itself executed, build and cache lex table
+ try:
+ outputdir = argv[1]
+ except IndexError as err:
+ print 'Usage: %s OUTPUT_DIR' % argv[0]
+ return 1
+ lexer = BlinkIDLLexer(outputdir=outputdir)
-# If run by itself, attempt to build the lexer
if __name__ == '__main__':
- lexer = BlinkIDLLexer()
+ sys.exit(main(sys.argv))
diff --git a/chromium/third_party/WebKit/Source/bindings/scripts/unstable/blink_idl_parser.py b/chromium/third_party/WebKit/Source/bindings/scripts/blink_idl_parser.py
index 3418c9f37be..6b205f2421c 100644
--- a/chromium/third_party/WebKit/Source/bindings/scripts/unstable/blink_idl_parser.py
+++ b/chromium/third_party/WebKit/Source/bindings/scripts/blink_idl_parser.py
@@ -40,6 +40,9 @@ Web IDL Grammar:
http://www.w3.org/TR/WebIDL/#idl-grammar
PLY:
http://www.dabeaz.com/ply/
+
+Design doc:
+http://www.chromium.org/developers/design-documents/idl-compiler#TOC-Front-end
"""
# Disable check for line length and Member as Function due to how grammar rules
@@ -56,13 +59,13 @@ import sys
# PLY is in Chromium src/third_party/ply
module_path, module_name = os.path.split(__file__)
-third_party = os.path.join(module_path, os.pardir, os.pardir, os.pardir, os.pardir, os.pardir)
+third_party = os.path.join(module_path, os.pardir, os.pardir, os.pardir, os.pardir)
# Insert at front to override system libraries, and after path[0] == script dir
sys.path.insert(1, third_party)
from ply import yacc
# Base parser is in Chromium src/tools/idl_parser
-tools_dir = os.path.join(module_path, os.pardir, os.pardir, os.pardir, os.pardir, os.pardir, os.pardir, 'tools')
+tools_dir = os.path.join(module_path, os.pardir, os.pardir, os.pardir, os.pardir, os.pardir, 'tools')
sys.path.append(tools_dir)
from idl_parser.idl_parser import IDLParser, ListFromConcat
from idl_parser.idl_parser import ParseFile as parse_file
@@ -86,6 +89,12 @@ REMOVED_RULES = ['Top', # [0]
'CommentsRest', # [0.2]
]
+# Remove rules from base class
+# FIXME: add a class method upstream: @classmethod IDLParser._RemoveRules
+for rule in REMOVED_RULES:
+ production_name = 'p_' + rule
+ delattr(IDLParser, production_name)
+
class BlinkIDLParser(IDLParser):
# [1]
@@ -231,30 +240,6 @@ class BlinkIDLParser(IDLParser):
p[0] = ListFromConcat(self.BuildAttribute('TYPE', 'DOMString'),
self.BuildAttribute('NAME', p[1]))
- # [b30] Add StaticAttribute
- def p_AttributeOrOperation(self, p):
- """AttributeOrOperation : STRINGIFIER StringifierAttributeOrOperation
- | Attribute
- | StaticAttribute
- | Operation"""
- # Standard is (no StaticAttribute):
- # AttributeOrOperation : STRINGIFIER StringifierAttributeOrOperation
- # | Attribute
- # | Operation
- if len(p) > 2:
- # FIXME: Clearer to add stringifier property here, as:
- # p[2].AddChildren(self.BuildTrue('STRINGIFIER'))
- # Fix when actually implementing stringifiers.
- p[0] = p[2]
- else:
- p[0] = p[1]
-
- # [b30.1]
- def p_StaticAttribute(self, p):
- """StaticAttribute : STATIC Attribute"""
- p[2].AddChildren(self.BuildTrue('STATIC'))
- p[0] = p[2]
-
# [b47]
def p_ExceptionMember(self, p):
"""ExceptionMember : Const
@@ -305,6 +290,7 @@ class BlinkIDLParser(IDLParser):
| ExtendedAttributeArgList
| ExtendedAttributeIdent
| ExtendedAttributeIdentList
+ | ExtendedAttributeStringLiteralList
| ExtendedAttributeNamedArgList"""
p[0] = p[1]
@@ -371,24 +357,69 @@ class BlinkIDLParser(IDLParser):
else:
p[0] = p[1]
- def __dir__(self):
- # Remove REMOVED_RULES from listing so yacc doesn't parse them
- # FIXME: Upstream
- keys = set(self.__dict__.keys() + dir(self.__class__))
- for rule in REMOVED_RULES:
- production_name = 'p_' + rule
- if production_name in keys:
- keys.remove(production_name)
- return list(keys)
-
- def __init__(self, lexer=None, verbose=False, debug=False, mute_error=False, outputdir=''):
- lexer = lexer or BlinkIDLLexer()
+ # Blink extension: Add support for compound Extended Attribute values over string literals ("A"|"B")
+ def p_ExtendedAttributeStringLiteralList(self, p):
+ """ExtendedAttributeStringLiteralList : identifier '=' StringLiteralOrList"""
+ value = self.BuildAttribute('VALUE', p[3])
+ p[0] = self.BuildNamed('ExtAttribute', p, 1, value)
+
+ # Blink extension: one or more string literals. The values aren't propagated as literals,
+ # but their by their value only.
+ def p_StringLiteralOrList(self, p):
+ """StringLiteralOrList : StringLiteral '|' StringLiteralOrList
+ | StringLiteral"""
+ def unwrap_string(ls):
+ """Reach in and grab the string literal's "NAME"."""
+ return ls[1].value
+
+ if len(p) > 3:
+ p[0] = unwrap_string(p[1]) + p[2] + p[3]
+ else:
+ p[0] = unwrap_string(p[1])
+
+ def __init__(self,
+ # common parameters
+ debug=False,
+ # idl_parser parameters
+ lexer=None, verbose=False, mute_error=False,
+ # yacc parameters
+ outputdir='', optimize=True, write_tables=False,
+ picklefile=None):
+ if debug:
+ # Turn off optimization and caching, and write out tables,
+ # to help debugging
+ optimize = False
+ outputdir = None
+ picklefile = None
+ write_tables = True
+ if outputdir:
+ picklefile = picklefile or os.path.join(outputdir, 'parsetab.pickle')
+
+ lexer = lexer or BlinkIDLLexer(debug=debug,
+ outputdir=outputdir,
+ optimize=optimize)
self.lexer = lexer
self.tokens = lexer.KnownTokens()
# Using SLR (instead of LALR) generates the table faster,
# but produces the same output. This is ok b/c Web IDL (and Blink IDL)
# is an SLR grammar (as is often the case for simple LL(1) grammars).
- self.yaccobj = yacc.yacc(module=self, start=STARTING_SYMBOL, method='SLR', debug=debug, outputdir=outputdir)
+ #
+ # Optimized mode substantially decreases startup time (by disabling
+ # error checking), and also allows use of Python's optimized mode.
+ # See: Using Python's Optimized Mode
+ # http://www.dabeaz.com/ply/ply.html#ply_nn38
+ #
+ # |picklefile| allows simpler importing than |tabmodule| (parsetab.py),
+ # as we don't need to modify sys.path; virtually identical speed.
+ # See: CHANGES, Version 3.2
+ # http://ply.googlecode.com/svn/trunk/CHANGES
+ self.yaccobj = yacc.yacc(module=self,
+ start=STARTING_SYMBOL,
+ method='SLR',
+ debug=debug,
+ optimize=optimize,
+ write_tables=write_tables,
+ picklefile=picklefile)
self.parse_debug = debug
self.verbose = verbose
self.mute_error = mute_error
@@ -399,6 +430,17 @@ class BlinkIDLParser(IDLParser):
self._last_error_pos = 0
-# If run by itself, attempt to build the parser
+################################################################################
+
+def main(argv):
+ # If file itself executed, cache parse table
+ try:
+ outputdir = argv[1]
+ except IndexError as err:
+ print 'Usage: %s OUTPUT_DIR' % argv[0]
+ return 1
+ parser = BlinkIDLParser(outputdir=outputdir)
+
+
if __name__ == '__main__':
- parser = BlinkIDLParser()
+ sys.exit(main(sys.argv))
diff --git a/chromium/third_party/WebKit/Source/bindings/scripts/code_generator_v8.pm b/chromium/third_party/WebKit/Source/bindings/scripts/code_generator_v8.pm
deleted file mode 100644
index e19e9aa9015..00000000000
--- a/chromium/third_party/WebKit/Source/bindings/scripts/code_generator_v8.pm
+++ /dev/null
@@ -1,6351 +0,0 @@
-# Copyright (C) 2005, 2006 Nikolas Zimmermann <zimmermann@kde.org>
-# Copyright (C) 2006 Anders Carlsson <andersca@mac.com>
-# Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com>
-# Copyright (C) 2006 Alexey Proskuryakov <ap@webkit.org>
-# Copyright (C) 2006 Apple Computer, Inc.
-# Copyright (C) 2007, 2008, 2009, 2012 Google Inc.
-# Copyright (C) 2009 Cameron McCormack <cam@mcc.id.au>
-# Copyright (C) Research In Motion Limited 2010. All rights reserved.
-# Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
-# Copyright (C) 2012 Ericsson AB. All rights reserved.
-# Copyright (C) 2013 Samsung Electronics. All rights reserved.
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Library General Public
-# License as published by the Free Software Foundation; either
-# version 2 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Library General Public License for more details.
-#
-# You should have received a copy of the GNU Library General Public License
-# along with this library; see the file COPYING.LIB. If not, write to
-# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-# Boston, MA 02111-1307, USA.
-#
-
-package Block;
-
-# Sample code:
-# my $outer = new Block("Free Name 1", "namespace Foo {", "} // namespace Foo");
-# $outer->add(" void foo() {}");
-# my $inner = new Block("Free Name 2", "namespace Bar {", "} // namespace Bar");
-# $inner->add(" void bar() {}");
-# $outer->add($inner);
-# print $outer->toString();
-#
-# Output code:
-# namespace Foo {
-# void foo() {}
-# namespace Bar {
-# void bar() {}
-# } // namespace Bar
-# } // namespace Foo
-
-sub new
-{
- my $package = shift;
- my $name = shift || "Anonymous block";
- my $header = shift || "";
- my $footer = shift || "";
-
- my $object = {
- "name" => $name,
- "header" => [$header],
- "footer" => [$footer],
- "contents" => [],
- };
- bless $object, $package;
- return $object;
-}
-
-sub addHeader
-{
- my $object = shift;
- my $header = shift || "";
-
- push(@{$object->{header}}, $header);
-}
-
-sub addFooter
-{
- my $object = shift;
- my $footer = shift || "";
-
- push(@{$object->{footer}}, $footer);
-}
-
-sub add
-{
- my $object = shift;
- my $content = shift || "";
-
- push(@{$object->{contents}}, $content);
-}
-
-sub toString
-{
- my $object = shift;
-
- my $header = join "", @{$object->{header}};
- my $footer = join "", @{$object->{footer}};
- my $code = "";
- $code .= "/* BEGIN " . $object->{name} . " */\n" if $verbose;
- $code .= $header . "\n" if $header;
- for my $content (@{$object->{contents}}) {
- if (ref($content) eq "Block") {
- $code .= $content->toString();
- } else {
- $code .= $content;
- }
- }
- $code .= $footer . "\n" if $footer;
- $code .= "/* END " . $object->{name} . " */\n" if $verbose;
- return $code;
-}
-
-
-package code_generator_v8;
-
-use strict;
-use Cwd;
-use File::Basename;
-use File::Find;
-use File::Spec;
-
-my $idlDocument;
-my $idlDirectories;
-my $preprocessor;
-my $verbose;
-my $interfaceIdlFiles;
-my $writeFileOnlyIfChanged;
-my $sourceRoot;
-
-# Cache of IDL file pathnames.
-my $idlFiles;
-my $cachedInterfaces = {};
-
-my %implIncludes = ();
-my %headerIncludes = ();
-
-# Header code structure:
-# Root ... Copyright, include duplication check
-# Conditional ... #if FEATURE ... #endif (to be removed soon)
-# Includes
-# NameSpaceWebCore
-# Class
-# ClassPublic
-# ClassPrivate
-my %header;
-
-# Implementation code structure:
-# Root ... Copyright
-# Conditional ... #if FEATURE ... #endif (to be removed soon)
-# Includes
-# NameSpaceWebCore
-# NameSpaceInternal ... namespace ${implClassName}V8Internal in case of non-callback
-my %implementation;
-
-# Promise is not yet in the Web IDL spec but is going to be speced
-# as primitive types in the future.
-# Since V8 dosn't provide Promise primitive object currently,
-# primitiveTypeHash doesn't contain Promise.
-my %primitiveTypeHash = ("Date" => 1,
- "DOMString" => 1,
- "DOMTimeStamp" => 1, # typedef unsigned long long
- "boolean" => 1,
- "void" => 1,
- "byte" => 1,
- "octet" => 1,
- "short" => 1,
- "long" => 1,
- "long long" => 1,
- "unsigned short" => 1,
- "unsigned long" => 1,
- "unsigned long long" => 1,
- "float" => 1,
- "double" => 1,
- );
-
-my %integerTypeHash = ("byte" => 1,
- "octet" => 1,
- "short" => 1,
- "long" => 1,
- "long long" => 1,
- "unsigned short" => 1,
- "unsigned long" => 1,
- "unsigned long long" => 1,
- );
-
-my %nonWrapperTypes = ("CompareHow" => 1,
- "Dictionary" => 1,
- "EventListener" => 1,
- "EventHandler" => 1,
- "MediaQueryListListener" => 1,
- "NodeFilter" => 1,
- "SerializedScriptValue" => 1,
- "any" => 1,
- );
-
-my %typedArrayHash = ("ArrayBuffer" => [],
- "ArrayBufferView" => [],
- "Uint8Array" => ["unsigned char", "v8::kExternalUnsignedByteArray"],
- "Uint8ClampedArray" => ["unsigned char", "v8::kExternalPixelArray"],
- "Uint16Array" => ["unsigned short", "v8::kExternalUnsignedShortArray"],
- "Uint32Array" => ["unsigned int", "v8::kExternalUnsignedIntArray"],
- "Int8Array" => ["signed char", "v8::kExternalByteArray"],
- "Int16Array" => ["short", "v8::kExternalShortArray"],
- "Int32Array" => ["int", "v8::kExternalIntArray"],
- "Float32Array" => ["float", "v8::kExternalFloatArray"],
- "Float64Array" => ["double", "v8::kExternalDoubleArray"],
- );
-
-my %callbackFunctionTypeHash = ();
-
-my %enumTypeHash = ();
-
-my %svgAttributesInHTMLHash = ("class" => 1, "id" => 1, "onabort" => 1, "onclick" => 1,
- "onerror" => 1, "onload" => 1, "onmousedown" => 1,
- "onmouseenter" => 1, "onmouseleave" => 1,
- "onmousemove" => 1, "onmouseout" => 1, "onmouseover" => 1,
- "onmouseup" => 1, "onresize" => 1, "onscroll" => 1,
- "onunload" => 1);
-
-my %svgTypeNeedingTearOff = (
- "SVGAngle" => "SVGPropertyTearOff<SVGAngle>",
- "SVGLength" => "SVGPropertyTearOff<SVGLength>",
- "SVGLengthList" => "SVGListPropertyTearOff<SVGLengthList>",
- "SVGMatrix" => "SVGMatrixTearOff",
- "SVGNumber" => "SVGPropertyTearOff<SVGNumber>",
- "SVGNumberList" => "SVGListPropertyTearOff<SVGNumberList>",
- "SVGPathSegList" => "SVGPathSegListPropertyTearOff",
- "SVGPoint" => "SVGPropertyTearOff<SVGPoint>",
- "SVGPointList" => "SVGListPropertyTearOff<SVGPointList>",
- "SVGPreserveAspectRatio" => "SVGPropertyTearOff<SVGPreserveAspectRatio>",
- "SVGRect" => "SVGPropertyTearOff<SVGRect>",
- "SVGStringList" => "SVGStaticListPropertyTearOff<SVGStringList>",
- "SVGTransform" => "SVGPropertyTearOff<SVGTransform>",
- "SVGTransformList" => "SVGTransformListPropertyTearOff"
-);
-
-my %svgTypeWithWritablePropertiesNeedingTearOff = (
- "SVGPoint" => 1,
- "SVGMatrix" => 1
-);
-
-# Default license header
-my $licenseHeader = <<EOF;
-/*
- * Copyright (C) 2013 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.
- */
-
-// This file has been auto-generated by code_generator_v8.pm. DO NOT MODIFY!
-
-EOF
-
-sub new
-{
- my $object = shift;
- my $reference = { };
-
- $idlDocument = shift;
- $idlDirectories = shift;
- $preprocessor = shift;
- $verbose = shift;
- $interfaceIdlFiles = shift;
- $writeFileOnlyIfChanged = shift;
-
- $sourceRoot = dirname(dirname(dirname(Cwd::abs_path($0))));
-
- bless($reference, $object);
- return $reference;
-}
-
-
-sub IDLFileForInterface
-{
- my $interfaceName = shift;
-
- unless ($idlFiles) {
- my @directories = map { $_ = "$sourceRoot/$_" if -d "$sourceRoot/$_"; $_ } @$idlDirectories;
- push(@directories, ".");
-
- $idlFiles = { };
- foreach my $idlFile (@$interfaceIdlFiles) {
- $idlFiles->{fileparse(basename($idlFile), ".idl")} = $idlFile;
- }
-
- my $wanted = sub {
- $idlFiles->{$1} = $File::Find::name if /^([A-Z].*)\.idl$/;
- $File::Find::prune = 1 if /^\../;
- };
- find($wanted, @directories);
- }
-
- return $idlFiles->{$interfaceName};
-}
-
-sub ParseInterface
-{
- my $interfaceName = shift;
-
- if (exists $cachedInterfaces->{$interfaceName}) {
- return $cachedInterfaces->{$interfaceName};
- }
-
- # Step #1: Find the IDL file associated with 'interface'
- my $filename = IDLFileForInterface($interfaceName)
- or die("Could NOT find IDL file for interface \"$interfaceName\" $!\n");
-
- print " | |> Parsing parent IDL \"$filename\" for interface \"$interfaceName\"\n" if $verbose;
-
- # Step #2: Parse the found IDL file (in quiet mode).
- my $parser = idl_parser->new(1);
- my $document = $parser->Parse($filename, $preprocessor);
-
- foreach my $interface (@{$document->interfaces}) {
- if ($interface->name eq $interfaceName or $interface->isPartial) {
- $cachedInterfaces->{$interfaceName} = $interface;
- return $interface;
- }
- }
-
- die("Could NOT find interface definition for $interfaceName in $filename");
-}
-
-sub GenerateInterface
-{
- my $object = shift;
- my $interface = shift;
-
- %callbackFunctionTypeHash = map { $_->name => $_ } @{$idlDocument->callbackFunctions};
- %enumTypeHash = map { $_->name => $_->values } @{$idlDocument->enumerations};
- my $v8ClassName = GetV8ClassName($interface);
- my $defineName = $v8ClassName . "_h";
- my $internalNamespace = GetImplName($interface) . "V8Internal";
-
- my $conditionalString = GenerateConditionalString($interface);
- my $conditionalIf = "";
- my $conditionalEndif = "";
- if ($conditionalString) {
- $conditionalIf = "#if ${conditionalString}";
- $conditionalEndif = "#endif // ${conditionalString}";
- }
-
- $header{root} = new Block("ROOT", "", "");
- # FIXME: newlines should be generated by Block::toString().
- $header{conditional} = new Block("Conditional", "$conditionalIf", $conditionalEndif ? "$conditionalEndif" : "");
- $header{includes} = new Block("Includes", "", "");
- $header{nameSpaceWebCore} = new Block("Namespace WebCore", "\nnamespace WebCore {\n", "}");
- $header{class} = new Block("Class definition", "", "");
- $header{classPublic} = new Block("Class public:", "public:", "");
- $header{classPrivate} = new Block("Class private:", "private:", "");
-
- $header{root}->add($header{conditional});
- $header{conditional}->add($header{includes});
- $header{conditional}->add($header{nameSpaceWebCore});
- $header{nameSpaceWebCore}->add($header{class});
- $header{class}->add($header{classPublic});
- $header{class}->add($header{classPrivate});
-
- # - Add default header template
- $header{root}->addHeader($licenseHeader);
- $header{root}->addHeader("#ifndef $defineName\n#define $defineName\n");
- $header{root}->addFooter("#endif // $defineName");
-
- $implementation{root} = new Block("ROOT", "", "");
- $implementation{conditional} = new Block("Conditional", $conditionalIf, $conditionalEndif);
- $implementation{includes} = new Block("Includes", "", "");
-
- # FIXME: newlines should be generated by Block::toString().
- my $nameSpaceWebCoreBegin = "namespace WebCore {\n";
- my $nameSpaceWebCoreEnd = "} // namespace WebCore";
- $nameSpaceWebCoreBegin = "$nameSpaceWebCoreBegin\n" if !$interface->isCallback;
- $implementation{nameSpaceWebCore} = new Block("Namespace WebCore", $nameSpaceWebCoreBegin, $nameSpaceWebCoreEnd);
- $implementation{nameSpaceInternal} = new Block("Internal namespace", "namespace $internalNamespace {\n", "} // namespace $internalNamespace\n");
-
- $implementation{root}->add($implementation{conditional});
- $implementation{conditional}->add($implementation{includes});
- $implementation{conditional}->add($implementation{nameSpaceWebCore});
- if (!$interface->isCallback) {
- $implementation{nameSpaceWebCore}->add($implementation{nameSpaceInternal});
- }
-
- # - Add default header template
- $implementation{root}->addHeader($licenseHeader);
- $implementation{root}->addHeader("#include \"config.h\"");
- $implementation{includes}->add("#include \"${v8ClassName}.h\"\n\n");
-
- # Start actual generation
- if ($interface->isCallback) {
- $object->GenerateCallbackHeader($interface);
- $object->GenerateCallbackImplementation($interface);
- } else {
- $object->GenerateHeader($interface);
- $object->GenerateImplementation($interface);
- }
-}
-
-sub AddToImplIncludes
-{
- my $header = shift;
- $implIncludes{$header} = 1;
-}
-
-sub AddToHeaderIncludes
-{
- my @includes = @_;
-
- for my $include (@includes) {
- $headerIncludes{$include} = 1;
- }
-}
-
-sub AddIncludesForType
-{
- my $type = shift;
-
- return if IsPrimitiveType($type) or IsEnumType($type) or $type eq "object";
-
- $type = $1 if $type =~ /SVG\w+TearOff<(\w+)>/;
-
- # Default includes
- if ($type eq "SerializedScriptValue") {
- AddToImplIncludes("bindings/v8/SerializedScriptValue.h");
- } elsif ($type eq "any" || IsCallbackFunctionType($type)) {
- AddToImplIncludes("bindings/v8/ScriptValue.h");
- } elsif ($type eq "Promise") {
- AddToImplIncludes("bindings/v8/ScriptPromise.h");
- } elsif ($type eq "EventHandler") {
- AddToImplIncludes("bindings/v8/V8AbstractEventListener.h");
- AddToImplIncludes("bindings/v8/V8EventListenerList.h");
- } elsif ($type eq "Dictionary") {
- AddToImplIncludes("bindings/v8/Dictionary.h");
- } elsif (IsTypedArrayType($type)) {
- AddToImplIncludes("bindings/v8/custom/V8${type}Custom.h");
- } elsif (my $arrayType = GetArrayType($type)) {
- AddIncludesForType($arrayType);
- } else {
- AddToImplIncludes("V8${type}.h");
- }
-}
-
-sub HeaderFilesForInterface
-{
- my $interfaceName = shift;
- my $implClassName = shift;
-
- my @includes = ();
- if (IsPrimitiveType($interfaceName) or IsEnumType($interfaceName) or IsCallbackFunctionType($interfaceName)) {
- # Not interface type, no header files
- } elsif (IsTypedArrayType($interfaceName)) {
- push(@includes, "wtf/${interfaceName}.h");
- } else {
- my $idlFilename = Cwd::abs_path(IDLFileForInterface($interfaceName)) or die("Could NOT find IDL file for interface \"$interfaceName\" $!\n");
- my $idlRelPath = File::Spec->abs2rel($idlFilename, $sourceRoot);
- push(@includes, dirname($idlRelPath) . "/" . $implClassName . ".h");
- }
- return @includes;
-}
-
-sub NeedsVisitDOMWrapper
-{
- my $interface = shift;
- return $interface->extendedAttributes->{"GenerateVisitDOMWrapper"} || ExtendedAttributeContains($interface->extendedAttributes->{"Custom"}, "VisitDOMWrapper") || $interface->extendedAttributes->{"SetReference"} || SVGTypeNeedsToHoldContextElement($interface->name);
-}
-
-sub GenerateVisitDOMWrapper
-{
- my $interface = shift;
- my $implClassName = GetImplName($interface);
- my $v8ClassName = GetV8ClassName($interface);
-
- if (ExtendedAttributeContains($interface->extendedAttributes->{"Custom"}, "VisitDOMWrapper")) {
- return;
- }
-
- my $nativeType = GetNativeTypeForConversions($interface);
- my $code = <<END;
-void ${v8ClassName}::visitDOMWrapper(void* object, const v8::Persistent<v8::Object>& wrapper, v8::Isolate* isolate)
-{
- ${nativeType}* impl = fromInternalPointer(object);
-END
- my $needSetWrapperReferenceContext = SVGTypeNeedsToHoldContextElement($interface->name) || $interface->extendedAttributes->{"SetReference"};
- if ($needSetWrapperReferenceContext) {
- $code .= <<END;
- v8::Local<v8::Object> creationContext = v8::Local<v8::Object>::New(isolate, wrapper);
- V8WrapperInstantiationScope scope(creationContext, isolate);
-END
- }
- if (SVGTypeNeedsToHoldContextElement($interface->name)) {
- AddToImplIncludes("V8SVGPathElement.h");
- $code .= <<END;
- if (impl->contextElement()) {
- if (!DOMDataStore::containsWrapper<V8SVGElement>(impl->contextElement(), isolate))
- wrap(impl->contextElement(), creationContext, isolate);
- DOMDataStore::setWrapperReference<V8SVGElement>(wrapper, impl->contextElement(), isolate);
- }
-END
- }
- for my $setReference (@{$interface->extendedAttributes->{"SetReference"}}) {
- my $setReferenceType = $setReference->type;
- my $setReferenceV8Type = "V8".$setReferenceType;
-
- my ($svgPropertyType, $svgListPropertyType, $svgNativeType) = GetSVGPropertyTypes($setReferenceType);
- if ($svgPropertyType) {
- $setReferenceType = $svgNativeType;
- }
-
- my $setReferenceName = $setReference->name;
-
- AddIncludesForType($setReferenceType);
- $code .= <<END;
- ${setReferenceType}* ${setReferenceName} = impl->${setReferenceName}();
- if (${setReferenceName}) {
- if (!DOMDataStore::containsWrapper<${setReferenceV8Type}>(${setReferenceName}, isolate))
- wrap(${setReferenceName}, creationContext, isolate);
- DOMDataStore::setWrapperReference<${setReferenceV8Type}>(wrapper, ${setReferenceName}, isolate);
- }
-END
- }
-
- my $isReachableMethod = $interface->extendedAttributes->{"GenerateVisitDOMWrapper"};
- if ($isReachableMethod) {
- AddToImplIncludes("bindings/v8/V8GCController.h");
- AddToImplIncludes("core/dom/Element.h");
- $code .= <<END;
- if (Node* owner = impl->${isReachableMethod}()) {
- setObjectGroup(V8GCController::opaqueRootForGC(owner, isolate), wrapper, isolate);
- return;
- }
-END
- }
-
- $code .= <<END;
- setObjectGroup(object, wrapper, isolate);
-}
-
-END
- $implementation{nameSpaceWebCore}->add($code);
-}
-
-sub GetSVGPropertyTypes
-{
- my $implType = shift;
-
- my $svgPropertyType;
- my $svgListPropertyType;
- my $svgNativeType;
-
- return ($svgPropertyType, $svgListPropertyType, $svgNativeType) if not $implType =~ /SVG/;
-
- $svgNativeType = GetSVGTypeNeedingTearOff($implType);
- return ($svgPropertyType, $svgListPropertyType, $svgNativeType) if not $svgNativeType;
-
- # Append space to avoid compilation errors when using PassRefPtr<$svgNativeType>
- $svgNativeType = "$svgNativeType ";
-
- my $svgWrappedNativeType = GetSVGWrappedTypeNeedingTearOff($implType);
- if ($svgNativeType =~ /SVGPropertyTearOff/) {
- $svgPropertyType = $svgWrappedNativeType;
- AddToHeaderIncludes("core/svg/properties/SVGAnimatedPropertyTearOff.h");
- } elsif ($svgNativeType =~ /SVGMatrixTearOff/) {
- $svgPropertyType = $svgWrappedNativeType;
- AddToHeaderIncludes("core/svg/properties/SVGMatrixTearOff.h");
- AddToHeaderIncludes("core/svg/properties/SVGAnimatedPropertyTearOff.h");
- } elsif ($svgNativeType =~ /SVGListPropertyTearOff/ or $svgNativeType =~ /SVGStaticListPropertyTearOff/ or $svgNativeType =~ /SVGTransformListPropertyTearOff/) {
- $svgListPropertyType = $svgWrappedNativeType;
- AddToHeaderIncludes("core/svg/properties/SVGAnimatedListPropertyTearOff.h");
- } elsif ($svgNativeType =~ /SVGPathSegListPropertyTearOff/) {
- $svgListPropertyType = $svgWrappedNativeType;
- AddToHeaderIncludes("core/svg/properties/SVGPathSegListPropertyTearOff.h");
- }
-
- return ($svgPropertyType, $svgListPropertyType, $svgNativeType);
-}
-
-sub GetIndexedGetterFunction
-{
- my $interface = shift;
-
- # FIXME: Expose indexed getter of CSSMixFunctionValue by removing this special case
- # because CSSValueList(which is parent of CSSMixFunctionValue) has indexed property getter.
- if ($interface->name eq "CSSMixFunctionValue") {
- return 0;
- }
-
- return GetSpecialAccessorFunctionForType($interface, "getter", "unsigned long", 1);
-}
-
-sub GetIndexedSetterFunction
-{
- my $interface = shift;
-
- return GetSpecialAccessorFunctionForType($interface, "setter", "unsigned long", 2);
-}
-
-sub GetIndexedDeleterFunction
-{
- my $interface = shift;
-
- return GetSpecialAccessorFunctionForType($interface, "deleter", "unsigned long", 1);
-}
-
-sub GetNamedGetterFunction
-{
- my $interface = shift;
- return GetSpecialAccessorFunctionForType($interface, "getter", "DOMString", 1);
-}
-
-sub GetNamedSetterFunction
-{
- my $interface = shift;
- return GetSpecialAccessorFunctionForType($interface, "setter", "DOMString", 2);
-}
-
-sub GetNamedDeleterFunction
-{
- my $interface = shift;
- return GetSpecialAccessorFunctionForType($interface, "deleter", "DOMString", 1);
-}
-
-sub GetSpecialAccessorFunctionForType
-{
- my $interface = shift;
- my $special = shift;
- my $firstParameterType = shift;
- my $numberOfParameters = shift;
-
- foreach my $function (@{$interface->functions}) {
- my $specials = $function->specials;
- my $specialExists = grep { $_ eq $special } @$specials;
- my $parameters = $function->parameters;
- if ($specialExists and scalar(@$parameters) == $numberOfParameters and $parameters->[0]->type eq $firstParameterType) {
- return $function;
- }
- }
-
- return 0;
-}
-
-sub GetV8StringResourceMode
-{
- my $extendedAttributes = shift;
-
- # Blink uses the non-standard identifier NullString instead of Web IDL
- # standard EmptyString, in [TreatNullAs=NullString] and [TreatUndefinedAs=NullString],
- # and does not support [TreatUndefinedAs=Null] or [TreatUndefinedAs=Missing]
- # https://sites.google.com/a/chromium.org/dev/blink/webidl/blink-idl-extended-attributes#TOC-TreatNullAs-a-p-TreatUndefinedAs-a-p-
- my $mode = "";
- if (($extendedAttributes->{"TreatNullAs"} and $extendedAttributes->{"TreatNullAs"} eq "NullString") and ($extendedAttributes->{"TreatUndefinedAs"} and $extendedAttributes->{"TreatUndefinedAs"} eq "NullString")) {
- $mode = "WithUndefinedOrNullCheck";
- } elsif ($extendedAttributes->{"TreatNullAs"} and $extendedAttributes->{"TreatNullAs"} eq "NullString") {
- $mode = "WithNullCheck";
- }
- return $mode;
-}
-
-sub GenerateHeader
-{
- my $object = shift;
- my $interface = shift;
-
- my $interfaceName = $interface->name;
- my $implClassName = GetImplName($interface);
- my $v8ClassName = GetV8ClassName($interface);
-
- LinkOverloadedFunctions($interface);
-
- # Ensure the IsDOMNodeType function is in sync.
- die("IsDOMNodeType is out of date with respect to $interfaceName") if IsDOMNodeType($interfaceName) != InheritsInterface($interface, "Node");
-
- my ($svgPropertyType, $svgListPropertyType, $svgNativeType) = GetSVGPropertyTypes($interfaceName);
-
- my $parentInterface = $interface->parent;
- AddToHeaderIncludes("V8${parentInterface}.h") if $parentInterface;
- AddToHeaderIncludes("bindings/v8/WrapperTypeInfo.h");
- AddToHeaderIncludes("bindings/v8/V8Binding.h");
- AddToHeaderIncludes("bindings/v8/V8DOMWrapper.h");
- AddToHeaderIncludes(HeaderFilesForInterface($interfaceName, $implClassName));
- foreach my $headerInclude (sort keys(%headerIncludes)) {
- $header{includes}->add("#include \"${headerInclude}\"\n");
- }
-
- $header{nameSpaceWebCore}->addHeader("\ntemplate<typename PropertyType> class SVGPropertyTearOff;\n") if $svgPropertyType;
- if ($svgNativeType) {
- if ($svgNativeType =~ /SVGStaticListPropertyTearOff/) {
- $header{nameSpaceWebCore}->addHeader("\ntemplate<typename PropertyType> class SVGStaticListPropertyTearOff;\n");
- } else {
- $header{nameSpaceWebCore}->addHeader("\ntemplate<typename PropertyType> class SVGListPropertyTearOff;\n");
- }
- }
-
- $header{nameSpaceWebCore}->addHeader("\nclass Dictionary;") if $interface->extendedAttributes->{"EventConstructor"};
-
- my $nativeType = GetNativeTypeForConversions($interface);
- if ($interface->extendedAttributes->{"NamedConstructor"}) {
- $header{nameSpaceWebCore}->addHeader(<<END);
-
-class V8${nativeType}Constructor {
-public:
- static v8::Handle<v8::FunctionTemplate> domTemplate(v8::Isolate*, WrapperWorldType);
- static const WrapperTypeInfo wrapperTypeInfo;
-};
-END
- }
-
- $header{class}->addHeader("class $v8ClassName {");
- $header{class}->addFooter("};");
-
- $header{classPublic}->add(<<END);
- static bool hasInstance(v8::Handle<v8::Value>, v8::Isolate*, WrapperWorldType);
- static bool hasInstanceInAnyWorld(v8::Handle<v8::Value>, v8::Isolate*);
- static v8::Handle<v8::FunctionTemplate> domTemplate(v8::Isolate*, WrapperWorldType);
- static ${nativeType}* toNative(v8::Handle<v8::Object> object)
- {
- return fromInternalPointer(object->GetAlignedPointerFromInternalField(v8DOMWrapperObjectIndex));
- }
- static void derefObject(void*);
- static const WrapperTypeInfo wrapperTypeInfo;
-END
-
- if (NeedsVisitDOMWrapper($interface)) {
- $header{classPublic}->add(" static void visitDOMWrapper(void*, const v8::Persistent<v8::Object>&, v8::Isolate*);\n");
- }
-
- if (InheritsExtendedAttribute($interface, "ActiveDOMObject")) {
- $header{classPublic}->add(" static ActiveDOMObject* toActiveDOMObject(v8::Handle<v8::Object>);\n");
- }
-
- if (InheritsInterface($interface, "EventTarget")) {
- $header{classPublic}->add(" static EventTarget* toEventTarget(v8::Handle<v8::Object>);\n");
- }
-
- if ($interfaceName eq "Window") {
- $header{classPublic}->add(<<END);
- static v8::Handle<v8::ObjectTemplate> GetShadowObjectTemplate(v8::Isolate*, WrapperWorldType);
-END
- }
-
- my @perContextEnabledFunctions;
- foreach my $function (@{$interface->functions}) {
- my $name = $function->name;
- next if $name eq "";
- my $attrExt = $function->extendedAttributes;
-
- if (HasCustomMethod($attrExt) && $function->{overloadIndex} == 1) {
- my $conditionalString = GenerateConditionalString($function);
- $header{classPublic}->add("#if ${conditionalString}\n") if $conditionalString;
- $header{classPublic}->add(<<END);
- static void ${name}MethodCustom(const v8::FunctionCallbackInfo<v8::Value>&);
-END
- $header{classPublic}->add("#endif // ${conditionalString}\n") if $conditionalString;
- }
- if ($attrExt->{"PerContextEnabled"}) {
- push(@perContextEnabledFunctions, $function);
- }
- }
-
- if (IsConstructable($interface)) {
- $header{classPublic}->add(" static void constructorCallback(const v8::FunctionCallbackInfo<v8::Value>&);\n");
-END
- }
- if (HasCustomConstructor($interface)) {
- $header{classPublic}->add(" static void constructorCustom(const v8::FunctionCallbackInfo<v8::Value>&);\n");
- }
-
- my @perContextEnabledAttributes;
- foreach my $attribute (@{$interface->attributes}) {
- my $name = $attribute->name;
- my $attrExt = $attribute->extendedAttributes;
- my $conditionalString = GenerateConditionalString($attribute);
- if (HasCustomGetter($attrExt) && !$attrExt->{"ImplementedBy"}) {
- $header{classPublic}->add("#if ${conditionalString}\n") if $conditionalString;
- $header{classPublic}->add(<<END);
- static void ${name}AttributeGetterCustom(const v8::PropertyCallbackInfo<v8::Value>&);
-END
- $header{classPublic}->add("#endif // ${conditionalString}\n") if $conditionalString;
- }
- if (HasCustomSetter($attribute) && !$attrExt->{"ImplementedBy"}) {
- $header{classPublic}->add("#if ${conditionalString}\n") if $conditionalString;
- $header{classPublic}->add(<<END);
- static void ${name}AttributeSetterCustom(v8::Local<v8::Value>, const v8::PropertyCallbackInfo<void>&);
-END
- $header{classPublic}->add("#endif // ${conditionalString}\n") if $conditionalString;
- }
- if ($attrExt->{"PerContextEnabled"}) {
- push(@perContextEnabledAttributes, $attribute);
- }
- }
-
- GenerateHeaderNamedAndIndexedPropertyAccessors($interface);
- GenerateHeaderLegacyCallAsFunction($interface);
- GenerateHeaderCustomInternalFieldIndices($interface);
-
- my $toWrappedType;
- my $fromWrappedType;
- if ($interface->parent) {
- my $v8ParentClassName = "V8" . $interface->parent;
- $toWrappedType = "${v8ParentClassName}::toInternalPointer(impl)";
- $fromWrappedType = "static_cast<${nativeType}*>(${v8ParentClassName}::fromInternalPointer(object))";
- } else {
- $toWrappedType = "impl";
- $fromWrappedType = "static_cast<${nativeType}*>(object)";
- }
-
- $header{classPublic}->add(<<END);
- static inline void* toInternalPointer(${nativeType}* impl)
- {
- return $toWrappedType;
- }
-
- static inline ${nativeType}* fromInternalPointer(void* object)
- {
- return $fromWrappedType;
- }
-END
-
- if ($interface->name eq "Window") {
- $header{classPublic}->add(<<END);
- static bool namedSecurityCheckCustom(v8::Local<v8::Object> host, v8::Local<v8::Value> key, v8::AccessType, v8::Local<v8::Value> data);
- static bool indexedSecurityCheckCustom(v8::Local<v8::Object> host, uint32_t index, v8::AccessType, v8::Local<v8::Value> data);
-END
- }
-
- if (@perContextEnabledAttributes) {
- $header{classPublic}->add(<<END);
- static void installPerContextEnabledProperties(v8::Handle<v8::Object>, ${nativeType}*, v8::Isolate*);
-END
- } else {
- $header{classPublic}->add(<<END);
- static void installPerContextEnabledProperties(v8::Handle<v8::Object>, ${nativeType}*, v8::Isolate*) { }
-END
- }
-
- if (@perContextEnabledFunctions) {
- $header{classPublic}->add(<<END);
- static void installPerContextEnabledMethods(v8::Handle<v8::Object>, v8::Isolate*);
-END
- } else {
- $header{classPublic}->add(<<END);
- static void installPerContextEnabledMethods(v8::Handle<v8::Object>, v8::Isolate*) { }
-END
- }
-
- if ($interfaceName eq "HTMLElement") {
- $header{classPublic}->add(<<END);
- friend v8::Handle<v8::Object> createV8HTMLWrapper(HTMLElement*, v8::Handle<v8::Object> creationContext, v8::Isolate*);
- friend v8::Handle<v8::Object> createV8HTMLDirectWrapper(HTMLElement*, v8::Handle<v8::Object> creationContext, v8::Isolate*);
-END
- } elsif ($interfaceName eq "SVGElement") {
- $header{classPublic}->add(<<END);
- friend v8::Handle<v8::Object> createV8SVGWrapper(SVGElement*, v8::Handle<v8::Object> creationContext, v8::Isolate*);
- friend v8::Handle<v8::Object> createV8SVGDirectWrapper(SVGElement*, v8::Handle<v8::Object> creationContext, v8::Isolate*);
- friend v8::Handle<v8::Object> createV8SVGFallbackWrapper(SVGElement*, v8::Handle<v8::Object> creationContext, v8::Isolate*);
-END
- } elsif ($interfaceName eq "HTMLUnknownElement") {
- $header{classPublic}->add(<<END);
- friend v8::Handle<v8::Object> createV8HTMLFallbackWrapper(HTMLUnknownElement*, v8::Handle<v8::Object> creationContext, v8::Isolate*);
-END
- } elsif ($interfaceName eq "Element") {
- $header{classPublic}->add(<<END);
- // This is a performance optimization hack. See V8Element::wrap.
- friend v8::Handle<v8::Object> wrap(Node*, v8::Handle<v8::Object> creationContext, v8::Isolate*);
-END
- }
- $header{classPublic}->add("\n"); # blank line to separate classPrivate
-
- my $customToV8 = ExtendedAttributeContains($interface->extendedAttributes->{"Custom"}, "ToV8");
- if (!$customToV8) {
- my $createWrapperArgumentType = GetPassRefPtrType($nativeType);
- $header{classPrivate}->add(<<END);
- friend v8::Handle<v8::Object> wrap(${nativeType}*, v8::Handle<v8::Object> creationContext, v8::Isolate*);
- static v8::Handle<v8::Object> createWrapper(${createWrapperArgumentType}, v8::Handle<v8::Object> creationContext, v8::Isolate*);
-END
- }
-
- $header{nameSpaceWebCore}->add(<<END);
-
-template<>
-class WrapperTypeTraits<${nativeType} > {
-public:
- static const WrapperTypeInfo* wrapperTypeInfo() { return &${v8ClassName}::wrapperTypeInfo; }
-};
-END
-
- my $customWrap = NeedsSpecialWrap($interface);
- if ($customToV8) {
- $header{nameSpaceWebCore}->add(<<END);
-
-class ${nativeType};
-v8::Handle<v8::Value> toV8(${nativeType}*, v8::Handle<v8::Object> creationContext, v8::Isolate*);
-
-template<class CallbackInfo>
-inline void v8SetReturnValue(const CallbackInfo& callbackInfo, ${nativeType}* impl)
-{
- v8SetReturnValue(callbackInfo, toV8(impl, callbackInfo.Holder(), callbackInfo.GetIsolate()));
-}
-
-template<class CallbackInfo>
-inline void v8SetReturnValueForMainWorld(const CallbackInfo& callbackInfo, ${nativeType}* impl)
-{
- v8SetReturnValue(callbackInfo, toV8(impl, callbackInfo.Holder(), callbackInfo.GetIsolate()));
-}
-
-template<class CallbackInfo, class Wrappable>
-inline void v8SetReturnValueFast(const CallbackInfo& callbackInfo, ${nativeType}* impl, Wrappable*)
-{
- v8SetReturnValue(callbackInfo, toV8(impl, callbackInfo.Holder(), callbackInfo.GetIsolate()));
-}
-END
- } else {
- if ($customWrap) {
- $header{nameSpaceWebCore}->add(<<END);
-
-v8::Handle<v8::Object> wrap(${nativeType}* impl, v8::Handle<v8::Object> creationContext, v8::Isolate*);
-END
- } else {
- $header{nameSpaceWebCore}->add(<<END);
-
-inline v8::Handle<v8::Object> wrap(${nativeType}* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
-{
- ASSERT(impl);
- ASSERT(!DOMDataStore::containsWrapper<${v8ClassName}>(impl, isolate));
- return ${v8ClassName}::createWrapper(impl, creationContext, isolate);
-}
-END
- }
-
- $header{nameSpaceWebCore}->add(<<END);
-
-inline v8::Handle<v8::Value> toV8(${nativeType}* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
-{
- if (UNLIKELY(!impl))
- return v8::Null(isolate);
- v8::Handle<v8::Value> wrapper = DOMDataStore::getWrapper<${v8ClassName}>(impl, isolate);
- if (!wrapper.IsEmpty())
- return wrapper;
- return wrap(impl, creationContext, isolate);
-}
-
-template<typename CallbackInfo>
-inline void v8SetReturnValue(const CallbackInfo& callbackInfo, ${nativeType}* impl)
-{
- if (UNLIKELY(!impl)) {
- v8SetReturnValueNull(callbackInfo);
- return;
- }
- if (DOMDataStore::setReturnValueFromWrapper<${v8ClassName}>(callbackInfo.GetReturnValue(), impl))
- return;
- v8::Handle<v8::Object> wrapper = wrap(impl, callbackInfo.Holder(), callbackInfo.GetIsolate());
- v8SetReturnValue(callbackInfo, wrapper);
-}
-
-template<typename CallbackInfo>
-inline void v8SetReturnValueForMainWorld(const CallbackInfo& callbackInfo, ${nativeType}* impl)
-{
- ASSERT(worldType(callbackInfo.GetIsolate()) == MainWorld);
- if (UNLIKELY(!impl)) {
- v8SetReturnValueNull(callbackInfo);
- return;
- }
- if (DOMDataStore::setReturnValueFromWrapperForMainWorld<${v8ClassName}>(callbackInfo.GetReturnValue(), impl))
- return;
- v8::Handle<v8::Value> wrapper = wrap(impl, callbackInfo.Holder(), callbackInfo.GetIsolate());
- v8SetReturnValue(callbackInfo, wrapper);
-}
-
-template<class CallbackInfo, class Wrappable>
-inline void v8SetReturnValueFast(const CallbackInfo& callbackInfo, ${nativeType}* impl, Wrappable* wrappable)
-{
- if (UNLIKELY(!impl)) {
- v8SetReturnValueNull(callbackInfo);
- return;
- }
- if (DOMDataStore::setReturnValueFromWrapperFast<${v8ClassName}>(callbackInfo.GetReturnValue(), impl, callbackInfo.Holder(), wrappable))
- return;
- v8::Handle<v8::Object> wrapper = wrap(impl, callbackInfo.Holder(), callbackInfo.GetIsolate());
- v8SetReturnValue(callbackInfo, wrapper);
-}
-END
- }
-
- $header{nameSpaceWebCore}->add(<<END);
-
-inline v8::Handle<v8::Value> toV8(PassRefPtr<${nativeType} > impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
-{
- return toV8(impl.get(), creationContext, isolate);
-}
-
-template<class CallbackInfo>
-inline void v8SetReturnValue(const CallbackInfo& callbackInfo, PassRefPtr<${nativeType} > impl)
-{
- v8SetReturnValue(callbackInfo, impl.get());
-}
-
-template<class CallbackInfo>
-inline void v8SetReturnValueForMainWorld(const CallbackInfo& callbackInfo, PassRefPtr<${nativeType} > impl)
-{
- v8SetReturnValueForMainWorld(callbackInfo, impl.get());
-}
-
-template<class CallbackInfo, class Wrappable>
-inline void v8SetReturnValueFast(const CallbackInfo& callbackInfo, PassRefPtr<${nativeType} > impl, Wrappable* wrappable)
-{
- v8SetReturnValueFast(callbackInfo, impl.get(), wrappable);
-}
-
-END
-
- if ($interface->extendedAttributes->{"EventConstructor"}) {
- $header{nameSpaceWebCore}->add("bool initialize${implClassName}(${implClassName}Init&, const Dictionary&, ExceptionState&, const String& = \"\");\n\n");
- }
-}
-
-sub GetInternalFields
-{
- my $interface = shift;
-
- my @customInternalFields = ();
- # Event listeners on DOM nodes are explicitly supported in the GC controller.
- if (!InheritsInterface($interface, "Node") &&
- InheritsInterface($interface, "EventTarget")) {
- push(@customInternalFields, "eventListenerCacheIndex");
- }
- return @customInternalFields;
-}
-
-sub GenerateHeaderCustomInternalFieldIndices
-{
- my $interface = shift;
- my @customInternalFields = GetInternalFields($interface);
- my $customFieldCounter = 0;
- foreach my $customInternalField (@customInternalFields) {
- $header{classPublic}->add(<<END);
- static const int ${customInternalField} = v8DefaultWrapperInternalFieldCount + ${customFieldCounter};
-END
- $customFieldCounter++;
- }
- $header{classPublic}->add(<<END);
- static const int internalFieldCount = v8DefaultWrapperInternalFieldCount + ${customFieldCounter};
-END
-}
-
-sub GenerateHeaderNamedAndIndexedPropertyAccessors
-{
- my $interface = shift;
-
- my $indexedGetterFunction = GetIndexedGetterFunction($interface);
- my $hasCustomIndexedGetter = $indexedGetterFunction && $indexedGetterFunction->extendedAttributes->{"Custom"};
-
- my $indexedSetterFunction = GetIndexedSetterFunction($interface);
- my $hasCustomIndexedSetter = $indexedSetterFunction && $indexedSetterFunction->extendedAttributes->{"Custom"};
-
- my $indexedDeleterFunction = GetIndexedDeleterFunction($interface);
- my $hasCustomIndexedDeleters = $indexedDeleterFunction && $indexedDeleterFunction->extendedAttributes->{"Custom"};
-
- my $namedGetterFunction = GetNamedGetterFunction($interface);
- my $hasCustomNamedGetter = $namedGetterFunction && $namedGetterFunction->extendedAttributes->{"Custom"};
-
- my $namedSetterFunction = GetNamedSetterFunction($interface);
- my $hasCustomNamedSetter = $namedSetterFunction && $namedSetterFunction->extendedAttributes->{"Custom"};
-
- my $namedDeleterFunction = GetNamedDeleterFunction($interface);
- my $hasCustomNamedDeleter = $namedDeleterFunction && $namedDeleterFunction->extendedAttributes->{"Custom"};
-
- my $namedEnumeratorFunction = $namedGetterFunction && !$namedGetterFunction->extendedAttributes->{"NotEnumerable"};
- my $hasCustomNamedEnumerator = $namedGetterFunction && $namedGetterFunction->extendedAttributes->{"CustomEnumerateProperty"};
-
- if ($hasCustomIndexedGetter) {
- $header{classPublic}->add(" static void indexedPropertyGetterCustom(uint32_t, const v8::PropertyCallbackInfo<v8::Value>&);\n");
- }
-
- if ($hasCustomIndexedSetter) {
- $header{classPublic}->add(" static void indexedPropertySetterCustom(uint32_t, v8::Local<v8::Value>, const v8::PropertyCallbackInfo<v8::Value>&);\n");
- }
-
- if ($hasCustomIndexedDeleters) {
- $header{classPublic}->add(" static void indexedPropertyDeleterCustom(uint32_t, const v8::PropertyCallbackInfo<v8::Boolean>&);\n");
- }
-
- if ($hasCustomNamedGetter) {
- $header{classPublic}->add(" static void namedPropertyGetterCustom(v8::Local<v8::String>, const v8::PropertyCallbackInfo<v8::Value>&);\n");
- }
-
- if ($hasCustomNamedSetter) {
- $header{classPublic}->add(" static void namedPropertySetterCustom(v8::Local<v8::String>, v8::Local<v8::Value>, const v8::PropertyCallbackInfo<v8::Value>&);\n");
- }
-
- if ($hasCustomNamedDeleter) {
- $header{classPublic}->add(" static void namedPropertyDeleterCustom(v8::Local<v8::String>, const v8::PropertyCallbackInfo<v8::Boolean>&);\n");
- }
-
- if ($hasCustomNamedEnumerator) {
- $header{classPublic}->add(" static void namedPropertyEnumeratorCustom(const v8::PropertyCallbackInfo<v8::Array>&);\n");
- $header{classPublic}->add(" static void namedPropertyQueryCustom(v8::Local<v8::String>, const v8::PropertyCallbackInfo<v8::Integer>&);\n");
- }
-}
-
-sub GenerateHeaderLegacyCallAsFunction
-{
- my $interface = shift;
-
- if (ExtendedAttributeContains($interface->extendedAttributes->{"Custom"}, "LegacyCallAsFunction")) {
- $header{classPublic}->add(" static void legacyCallCustom(const v8::FunctionCallbackInfo<v8::Value>&);\n");
- }
-}
-
-sub HasActivityLogging
-{
- my $forMainWorldSuffix = shift;
- my $attrExt = shift;
- my $access = shift;
-
- if (!$attrExt->{"ActivityLogging"}) {
- return 0;
- }
- my $logAllAccess = ($attrExt->{"ActivityLogging"} =~ /^For/); # No prefix, starts with For*Worlds suffix
- my $logGetter = ($attrExt->{"ActivityLogging"} =~ /^Getter/);
- my $logSetter = ($attrExt->{"ActivityLogging"} =~ /^Setter/);
- my $logOnlyIsolatedWorlds = ($attrExt->{"ActivityLogging"} =~ /ForIsolatedWorlds$/);
-
- if ($logOnlyIsolatedWorlds && $forMainWorldSuffix eq "ForMainWorld") {
- return 0;
- }
- return $logAllAccess || ($logGetter && $access eq "Getter") || ($logSetter && $access eq "Setter");
-}
-
-sub IsConstructable
-{
- my $interface = shift;
-
- return $interface->extendedAttributes->{"CustomConstructor"} || $interface->extendedAttributes->{"Constructor"} || $interface->extendedAttributes->{"EventConstructor"};
-}
-
-sub HasCustomConstructor
-{
- my $interface = shift;
-
- return $interface->extendedAttributes->{"CustomConstructor"};
-}
-
-sub HasCustomGetter
-{
- my $attrExt = shift;
- my $custom = $attrExt->{"Custom"};
- return $custom && ($custom eq "VALUE_IS_MISSING" || $custom eq "Getter");
-}
-
-sub HasCustomSetter
-{
- my $attribute = shift;
- my $custom = $attribute->extendedAttributes->{"Custom"};
- return $custom && ($custom eq "VALUE_IS_MISSING" || $custom eq "Setter") && !IsReadonly($attribute);
-}
-
-sub HasCustomMethod
-{
- my $attrExt = shift;
- return $attrExt->{"Custom"};
-}
-
-sub IsReadonly
-{
- my $attribute = shift;
- my $attrExt = $attribute->extendedAttributes;
- return $attribute->isReadOnly && !$attrExt->{"Replaceable"} && !$attrExt->{"PutForwards"};
-}
-
-sub GetV8ClassName
-{
- my $interface = shift;
- return "V8" . $interface->name;
-}
-
-sub GetImplName
-{
- my $interfaceOrAttributeOrFunction = shift;
- return $interfaceOrAttributeOrFunction->extendedAttributes->{"ImplementedAs"} || $interfaceOrAttributeOrFunction->name;
-}
-
-sub GetImplNameFromImplementedBy
-{
- my $implementedBy = shift;
-
- my $interface = ParseInterface($implementedBy);
-
- return $interface->extendedAttributes->{"ImplementedAs"} || $implementedBy;
-}
-
-sub GenerateDomainSafeFunctionGetter
-{
- my $function = shift;
- my $interface = shift;
- my $forMainWorldSuffix = shift;
-
- my $implClassName = GetImplName($interface);
- my $v8ClassName = GetV8ClassName($interface);
- my $funcName = $function->name;
-
- my $functionLength = GetFunctionLength($function);
- my $signature = "v8::Signature::New(info.GetIsolate(), V8PerIsolateData::from(info.GetIsolate())->rawDOMTemplate(&" . $v8ClassName . "::wrapperTypeInfo, currentWorldType))";
- if ($function->extendedAttributes->{"DoNotCheckSignature"}) {
- $signature = "v8::Local<v8::Signature>()";
- }
-
- my $newTemplateParams = "${implClassName}V8Internal::${funcName}MethodCallback${forMainWorldSuffix}, v8Undefined(), $signature";
-
- AddToImplIncludes("bindings/v8/BindingSecurity.h");
- $implementation{nameSpaceInternal}->add(<<END);
-static void ${funcName}OriginSafeMethodGetter${forMainWorldSuffix}(const v8::PropertyCallbackInfo<v8::Value>& info)
-{
- // This is only for getting a unique pointer which we can pass to privateTemplate.
- static int privateTemplateUniqueKey;
- WrapperWorldType currentWorldType = worldType(info.GetIsolate());
- V8PerIsolateData* data = V8PerIsolateData::from(info.GetIsolate());
- v8::Handle<v8::FunctionTemplate> privateTemplate = data->privateTemplate(currentWorldType, &privateTemplateUniqueKey, $newTemplateParams, $functionLength);
-
- v8::Handle<v8::Object> holder = info.This()->FindInstanceInPrototypeChain(${v8ClassName}::domTemplate(info.GetIsolate(), currentWorldType));
- if (holder.IsEmpty()) {
- // This is only reachable via |object.__proto__.func|, in which case it
- // has already passed the same origin security check
- v8SetReturnValue(info, privateTemplate->GetFunction());
- return;
- }
- ${implClassName}* imp = ${v8ClassName}::toNative(holder);
- if (!BindingSecurity::shouldAllowAccessToFrame(imp->frame(), DoNotReportSecurityError)) {
- static int sharedTemplateUniqueKey;
- v8::Handle<v8::FunctionTemplate> sharedTemplate = data->privateTemplate(currentWorldType, &sharedTemplateUniqueKey, $newTemplateParams, $functionLength);
- v8SetReturnValue(info, sharedTemplate->GetFunction());
- return;
- }
-
- v8::Local<v8::Value> hiddenValue = info.This()->GetHiddenValue(v8::String::NewFromUtf8(info.GetIsolate(), "${funcName}", v8::String::kInternalizedString));
- if (!hiddenValue.IsEmpty()) {
- v8SetReturnValue(info, hiddenValue);
- return;
- }
-
- v8SetReturnValue(info, privateTemplate->GetFunction());
-}
-
-END
- $implementation{nameSpaceInternal}->add(<<END);
-static void ${funcName}OriginSafeMethodGetterCallback${forMainWorldSuffix}(v8::Local<v8::String>, const v8::PropertyCallbackInfo<v8::Value>& info)
-{
- TRACE_EVENT_SET_SAMPLING_STATE("Blink", "DOMGetter");
- ${implClassName}V8Internal::${funcName}OriginSafeMethodGetter${forMainWorldSuffix}(info);
- TRACE_EVENT_SET_SAMPLING_STATE("V8", "Execution");
-}
-
-END
-}
-
-sub GenerateDomainSafeFunctionSetter
-{
- my $interface = shift;
-
- my $interfaceName = $interface->name();
- my $implClassName = GetImplName($interface);
- my $v8ClassName = GetV8ClassName($interface);
-
- AddToImplIncludes("bindings/v8/BindingSecurity.h");
- $implementation{nameSpaceInternal}->add(<<END);
-static void ${implClassName}OriginSafeMethodSetter(v8::Local<v8::String> name, v8::Local<v8::Value> jsValue, const v8::PropertyCallbackInfo<void>& info)
-{
- v8::Handle<v8::Object> holder = info.This()->FindInstanceInPrototypeChain(${v8ClassName}::domTemplate(info.GetIsolate(), worldType(info.GetIsolate())));
- if (holder.IsEmpty())
- return;
- ${implClassName}* imp = ${v8ClassName}::toNative(holder);
- v8::String::Utf8Value attributeName(name);
- ExceptionState exceptionState(ExceptionState::SetterContext, *attributeName, "${interfaceName}", info.Holder(), info.GetIsolate());
- if (!BindingSecurity::shouldAllowAccessToFrame(imp->frame(), exceptionState)) {
- exceptionState.throwIfNeeded();
- return;
- }
-
- info.This()->SetHiddenValue(name, jsValue);
-}
-
-static void ${implClassName}OriginSafeMethodSetterCallback(v8::Local<v8::String> name, v8::Local<v8::Value> jsValue, const v8::PropertyCallbackInfo<void>& info)
-{
- TRACE_EVENT_SET_SAMPLING_STATE("Blink", "DOMSetter");
- ${implClassName}V8Internal::${implClassName}OriginSafeMethodSetter(name, jsValue, info);
- TRACE_EVENT_SET_SAMPLING_STATE("V8", "Execution");
-}
-
-END
-}
-
-sub GenerateConstructorGetter
-{
- my $interface = shift;
- my $implClassName = GetImplName($interface);
-
- $implementation{nameSpaceInternal}->add(<<END);
-static void ${implClassName}ConstructorGetter(v8::Local<v8::String>, const v8::PropertyCallbackInfo<v8::Value>& info)
-{
- v8::Handle<v8::Value> data = info.Data();
- ASSERT(data->IsExternal());
- V8PerContextData* perContextData = V8PerContextData::from(info.Holder()->CreationContext());
- if (!perContextData)
- return;
- v8SetReturnValue(info, perContextData->constructorForType(WrapperTypeInfo::unwrap(data)));
-}
-
-END
-}
-
-sub GenerateFeatureObservation
-{
- my $measureAs = shift;
-
- if ($measureAs) {
- AddToImplIncludes("core/frame/UseCounter.h");
- return " UseCounter::count(activeDOMWindow(), UseCounter::${measureAs});\n";
- }
-
- return "";
-}
-
-sub GenerateDeprecationNotification
-{
- my $deprecateAs = shift;
- if ($deprecateAs) {
- AddToImplIncludes("core/frame/UseCounter.h");
- return " UseCounter::countDeprecation(activeExecutionContext(), UseCounter::${deprecateAs});\n";
- }
- return "";
-}
-
-sub GenerateActivityLogging
-{
- my $accessType = shift;
- my $interface = shift;
- my $propertyName = shift;
-
- my $interfaceName = $interface->name;
-
- AddToImplIncludes("bindings/v8/V8DOMActivityLogger.h");
-
- my $code = "";
- if ($accessType eq "Method") {
- $code .= <<END;
- V8PerContextData* contextData = V8PerContextData::from(info.GetIsolate()->GetCurrentContext());
- if (contextData && contextData->activityLogger()) {
- Vector<v8::Handle<v8::Value> > loggerArgs = toNativeArguments<v8::Handle<v8::Value> >(info, 0);
- contextData->activityLogger()->log("${interfaceName}.${propertyName}", info.Length(), loggerArgs.data(), "${accessType}");
- }
-END
- } elsif ($accessType eq "Setter") {
- $code .= <<END;
- V8PerContextData* contextData = V8PerContextData::from(info.GetIsolate()->GetCurrentContext());
- if (contextData && contextData->activityLogger()) {
- v8::Handle<v8::Value> loggerArg[] = { jsValue };
- contextData->activityLogger()->log("${interfaceName}.${propertyName}", 1, &loggerArg[0], "${accessType}");
- }
-END
- } elsif ($accessType eq "Getter") {
- $code .= <<END;
- V8PerContextData* contextData = V8PerContextData::from(info.GetIsolate()->GetCurrentContext());
- if (contextData && contextData->activityLogger())
- contextData->activityLogger()->log("${interfaceName}.${propertyName}", 0, 0, "${accessType}");
-END
- } else {
- die "Unrecognized activity logging access type";
- }
-
- return $code;
-}
-
-sub GenerateNormalAttributeGetterCallback
-{
- my $attribute = shift;
- my $interface = shift;
- my $forMainWorldSuffix = shift;
- my $exposeJSAccessors = shift;
-
- my $implClassName = GetImplName($interface);
- my $v8ClassName = GetV8ClassName($interface);
- my $attrExt = $attribute->extendedAttributes;
- my $attrName = $attribute->name;
-
- my $conditionalString = GenerateConditionalString($attribute);
- my $code = "";
- $code .= "#if ${conditionalString}\n" if $conditionalString;
-
- if ($exposeJSAccessors) {
- $code .= "static void ${attrName}AttributeGetterCallback${forMainWorldSuffix}(const v8::FunctionCallbackInfo<v8::Value>& info)\n";
- } else {
- $code .= "static void ${attrName}AttributeGetterCallback${forMainWorldSuffix}(v8::Local<v8::String>, const v8::PropertyCallbackInfo<v8::Value>& info)\n";
- }
- $code .= "{\n";
- $code .= " TRACE_EVENT_SET_SAMPLING_STATE(\"Blink\", \"DOMGetter\");\n";
- $code .= GenerateFeatureObservation($attrExt->{"MeasureAs"});
- $code .= GenerateDeprecationNotification($attrExt->{"DeprecateAs"});
- if (HasActivityLogging($forMainWorldSuffix, $attrExt, "Getter")) {
- $code .= GenerateActivityLogging("Getter", $interface, "${attrName}");
- }
- if (HasCustomGetter($attrExt)) {
- $code .= " ${v8ClassName}::${attrName}AttributeGetterCustom(info);\n";
- } else {
- $code .= " ${implClassName}V8Internal::${attrName}AttributeGetter${forMainWorldSuffix}(info);\n";
- }
- $code .= " TRACE_EVENT_SET_SAMPLING_STATE(\"V8\", \"Execution\");\n";
- $code .= "}\n";
- $code .= "#endif // ${conditionalString}\n" if $conditionalString;
- $code .= "\n";
-
- $implementation{nameSpaceInternal}->add($code);
-}
-
-sub GetCachedAttribute
-{
- my $attribute = shift;
- my $attrExt = $attribute->extendedAttributes;
- if (($attribute->type eq "any" || $attribute->type eq "SerializedScriptValue") && $attrExt->{"CachedAttribute"}) {
- return $attrExt->{"CachedAttribute"};
- }
- return "";
-}
-
-sub GenerateNormalAttributeGetter
-{
- my $attribute = shift;
- my $interface = shift;
- my $forMainWorldSuffix = shift;
- my $exposeJSAccessors = shift;
-
- my $interfaceName = $interface->name;
- my $implClassName = GetImplName($interface);
- my $v8ClassName = GetV8ClassName($interface);
- my $attrExt = $attribute->extendedAttributes;
- my $attrName = $attribute->name;
- my $attrType = $attribute->type;
- my $attrCached = GetCachedAttribute($attribute);
-
- if (HasCustomGetter($attrExt)) {
- return;
- }
-
- AssertNotSequenceType($attrType);
- my $nativeType = GetNativeType($attribute->type, $attribute->extendedAttributes, "");
- my $svgNativeType = GetSVGTypeNeedingTearOff($interfaceName);
-
- my $conditionalString = GenerateConditionalString($attribute);
- my $code = "";
- $code .= "#if ${conditionalString}\n" if $conditionalString;
- if ($exposeJSAccessors) {
- $code .= "static void ${attrName}AttributeGetter${forMainWorldSuffix}(const v8::FunctionCallbackInfo<v8::Value>& info)\n";
- } else {
- $code .= "static void ${attrName}AttributeGetter${forMainWorldSuffix}(const v8::PropertyCallbackInfo<v8::Value>& info)\n";
- }
- $code .= "{\n";
- if ($svgNativeType) {
- my $svgWrappedNativeType = GetSVGWrappedTypeNeedingTearOff($interfaceName);
- if ($svgWrappedNativeType =~ /List/) {
- $code .= <<END;
- $svgNativeType* imp = ${v8ClassName}::toNative(info.Holder());
-END
- } else {
- $code .= <<END;
- $svgNativeType* wrapper = ${v8ClassName}::toNative(info.Holder());
- $svgWrappedNativeType& impInstance = wrapper->propertyReference();
- $svgWrappedNativeType* imp = &impInstance;
-END
- }
- } elsif ($attrExt->{"OnPrototype"} || $attrExt->{"Unforgeable"}) {
- if ($interfaceName eq "Window") {
- $code .= <<END;
- v8::Handle<v8::Object> holder = info.Holder();
-END
- } else {
- # perform lookup first
- $code .= <<END;
- v8::Handle<v8::Object> holder = info.This()->FindInstanceInPrototypeChain(${v8ClassName}::domTemplate(info.GetIsolate(), worldType(info.GetIsolate())));
- if (holder.IsEmpty())
- return;
-END
- }
- $code .= <<END;
- ${implClassName}* imp = ${v8ClassName}::toNative(holder);
-END
- } else {
- my $reflect = $attribute->extendedAttributes->{"Reflect"};
- my $url = $attribute->extendedAttributes->{"URL"};
- if ($reflect && !$url && InheritsInterface($interface, "Node") && $attrType eq "DOMString") {
- # Generate super-compact call for regular attribute getter:
- my ($functionName, @arguments) = GetterExpression($interfaceName, $attribute);
- $code .= " Element* imp = V8Element::toNative(info.Holder());\n";
- $code .= " v8SetReturnValueString(info, imp->${functionName}(" . join(", ", @arguments) . "), info.GetIsolate());\n";
- $code .= "}\n";
- $code .= "#endif // ${conditionalString}\n" if $conditionalString;
- $code .= "\n";
- $implementation{nameSpaceInternal}->add($code);
- return;
- # Skip the rest of the function!
- }
- my $imp = 0;
- if ($attrCached) {
- $imp = 1;
- $code .= <<END;
- v8::Handle<v8::String> propertyName = v8::String::NewFromUtf8(info.GetIsolate(), "${attrName}", v8::String::kInternalizedString);
- ${implClassName}* imp = ${v8ClassName}::toNative(info.Holder());
- if (!imp->$attrCached()) {
- v8::Handle<v8::Value> jsValue = info.Holder()->GetHiddenValue(propertyName);
- if (!jsValue.IsEmpty()) {
- v8SetReturnValue(info, jsValue);
- return;
- }
- }
-END
- }
- if (!$attribute->isStatic && !$imp) {
- $code .= <<END;
- ${implClassName}* imp = ${v8ClassName}::toNative(info.Holder());
-END
- }
- }
-
- my $raisesException = $attribute->extendedAttributes->{"RaisesException"};
- my $useExceptions = 1 if $raisesException && ($raisesException eq "VALUE_IS_MISSING" or $raisesException eq "Getter");
- if ($useExceptions || $attribute->extendedAttributes->{"CheckSecurity"}) {
- $code .= " ExceptionState exceptionState(ExceptionState::GetterContext, \"${attrName}\", \"${interfaceName}\", info.Holder(), info.GetIsolate());\n";
- }
-
- # Generate security checks if necessary
- if ($attribute->extendedAttributes->{"CheckSecurity"}) {
- AddToImplIncludes("bindings/v8/BindingSecurity.h");
- $code .= " if (!BindingSecurity::shouldAllowAccessToNode(imp->" . GetImplName($attribute) . "(), exceptionState)) {\n";
- $code .= " v8SetReturnValueNull(info);\n";
- $code .= " exceptionState.throwIfNeeded();\n";
- $code .= " return;\n";
- $code .= " }\n";
- }
-
- my $isNullable = $attribute->isNullable;
- if ($isNullable) {
- $code .= " bool isNull = false;\n";
- }
-
- my $getterString;
- my ($functionName, @arguments) = GetterExpression($interfaceName, $attribute);
- push(@arguments, "isNull") if $isNullable;
- push(@arguments, "exceptionState") if $useExceptions;
- if ($attribute->extendedAttributes->{"ImplementedBy"}) {
- my $implementedBy = $attribute->extendedAttributes->{"ImplementedBy"};
- my $implementedByImplName = GetImplNameFromImplementedBy($implementedBy);
- AddToImplIncludes(HeaderFilesForInterface($implementedBy, $implementedByImplName));
- unshift(@arguments, "imp") if !$attribute->isStatic;
- $functionName = "${implementedByImplName}::${functionName}";
- } elsif ($attribute->isStatic) {
- $functionName = "${implClassName}::${functionName}";
- } else {
- $functionName = "imp->${functionName}";
- }
- my ($arg, $subCode) = GenerateCallWith($attribute->extendedAttributes->{"CallWith"}, " ", 0);
- $code .= $subCode;
- unshift(@arguments, @$arg);
- $getterString = "${functionName}(" . join(", ", @arguments) . ")";
-
- my $expression;
- if ($attribute->type eq "EventHandler" && $interface->name eq "Window") {
- $code .= " if (!imp->document())\n";
- $code .= " return;\n";
- }
-
- if ($useExceptions || $isNullable) {
- if ($nativeType =~ /^V8StringResource/) {
- $code .= " " . ConvertToV8StringResource($attribute, $nativeType, "cppValue", $getterString) . ";\n";
- } else {
- $code .= " $nativeType jsValue = $getterString;\n";
- }
-
- if ($isNullable) {
- $code .= " if (isNull) {\n";
- $code .= " v8SetReturnValueNull(info);\n";
- $code .= " return;\n";
- $code .= " }\n";
- }
-
- if ($useExceptions) {
- if ($useExceptions) {
- $code .= " if (UNLIKELY(exceptionState.throwIfNeeded()))\n";
- $code .= " return;\n";
- }
-
- if (ExtendedAttributeContains($attribute->extendedAttributes->{"CallWith"}, "ScriptState")) {
- $code .= " if (state.hadException()) {\n";
- $code .= " throwError(state.exception(), info.GetIsolate());\n";
- $code .= " return;\n";
- $code .= " }\n";
- }
- }
-
- $expression = "jsValue";
- $expression .= ".release()" if (IsRefPtrType($attrType));
- } else {
- # Can inline the function call into the return statement to avoid overhead of using a Ref<> temporary
- $expression = $getterString;
- # Fix amigious conversion problem, by casting to the base type first ($getterString returns a type that inherits from SVGAnimatedEnumeration, not the base class directly).
- $expression = "static_pointer_cast<SVGAnimatedEnumeration>($expression)" if $attrType eq "SVGAnimatedEnumeration";
- }
-
- if (ShouldKeepAttributeAlive($interface, $attribute, $attrType)) {
- my $arrayType = GetArrayType($attrType);
- if ($arrayType) {
- $code .= " v8SetReturnValue(info, v8Array(${getterString}, info.GetIsolate()));\n";
- $code .= "}\n\n";
- $implementation{nameSpaceInternal}->add($code);
- return;
- }
-
- AddToImplIncludes("bindings/v8/V8HiddenPropertyName.h");
- # 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.
- my $nativeReturnType = GetNativeType($attrType);
- my $v8ReturnType = "V8" . $attrType;
- $code .= " $nativeReturnType result = ${getterString};\n";
- if ($forMainWorldSuffix) {
- $code .= " if (result && DOMDataStore::setReturnValueFromWrapper${forMainWorldSuffix}<${v8ReturnType}>(info.GetReturnValue(), result.get()))\n";
- } else {
- $code .= " if (result && DOMDataStore::setReturnValueFromWrapper<${v8ReturnType}>(info.GetReturnValue(), result.get()))\n";
- }
- $code .= " return;\n";
- $code .= " v8::Handle<v8::Value> wrapper = toV8(result.get(), info.Holder(), info.GetIsolate());\n";
- $code .= " if (!wrapper.IsEmpty()) {\n";
- $code .= " V8HiddenPropertyName::setNamedHiddenReference(info.Holder(), \"${attrName}\", wrapper);\n";
- $code .= " v8SetReturnValue(info, wrapper);\n";
- $code .= " }\n";
- $code .= "}\n";
- $code .= "#endif // ${conditionalString}\n" if $conditionalString;
- $code .= "\n";
- $implementation{nameSpaceInternal}->add($code);
- return;
- }
-
- if ((IsSVGAnimatedType($interfaceName) or $interfaceName eq "SVGViewSpec") and IsSVGTypeNeedingTearOff($attrType)) {
- AddToImplIncludes("V8$attrType.h");
- my $svgNativeType = GetSVGTypeNeedingTearOff($attrType);
- # Convert from abstract SVGProperty to real type, so the right toJS() method can be invoked.
- if ($forMainWorldSuffix eq "ForMainWorld") {
- $code .= " v8SetReturnValueForMainWorld(info, static_cast<$svgNativeType*>($expression));\n";
- } else {
- $code .= " v8SetReturnValueFast(info, static_cast<$svgNativeType*>($expression), imp);\n";
- }
- } elsif (IsSVGTypeNeedingTearOff($attrType) and not $interfaceName =~ /List$/) {
- AddToImplIncludes("V8$attrType.h");
- AddToImplIncludes("core/svg/properties/SVGPropertyTearOff.h");
- my $tearOffType = GetSVGTypeNeedingTearOff($attrType);
- my $wrappedValue;
- if (IsSVGTypeWithWritablePropertiesNeedingTearOff($attrType) and not defined $attribute->extendedAttributes->{"Immutable"}) {
- my $getter = $expression;
- $getter =~ s/imp->//;
- $getter =~ s/\(\)//;
-
- my $updateMethod = "&${implClassName}::update" . FirstLetterToUpperCase($getter);
-
- my $selfIsTearOffType = IsSVGTypeNeedingTearOff($interfaceName);
- if ($selfIsTearOffType) {
- AddToImplIncludes("core/svg/properties/SVGMatrixTearOff.h");
- # FIXME: Don't create a new one everytime we access the matrix property. This means, e.g, === won't work.
- $wrappedValue = "WTF::getPtr(SVGMatrixTearOff::create(wrapper, $expression))";
- } else {
- AddToImplIncludes("core/svg/properties/SVGStaticPropertyTearOff.h");
- $tearOffType =~ s/SVGPropertyTearOff</SVGStaticPropertyTearOff<$implClassName, /;
-
- $wrappedValue = "WTF::getPtr(${tearOffType}::create(imp, $expression, $updateMethod))";
- }
- } elsif ($tearOffType =~ /SVGStaticListPropertyTearOff/) {
- $wrappedValue = "WTF::getPtr(${tearOffType}::create(imp, $expression))";
- } elsif ($tearOffType =~ /SVG(Point|PathSeg)List/) {
- $wrappedValue = "WTF::getPtr($expression)";
- } else {
- $wrappedValue = "WTF::getPtr(${tearOffType}::create($expression))";
- }
- if ($forMainWorldSuffix eq "ForMainWorld") {
- $code .= " v8SetReturnValueForMainWorld(info, $wrappedValue);\n";
- } else {
- $code .= " v8SetReturnValueFast(info, $wrappedValue, imp);\n";
- }
- } elsif ($attrCached) {
- if ($attribute->type eq "SerializedScriptValue") {
- $code .= <<END;
- RefPtr<SerializedScriptValue> serialized = $getterString;
- ScriptValue jsValue = serialized ? serialized->deserialize() : v8::Handle<v8::Value>(v8::Null(info.GetIsolate()));
- info.Holder()->SetHiddenValue(propertyName, jsValue);
- v8SetReturnValue(info, jsValue);
-END
- } else {
- if (!$useExceptions && !$isNullable) {
- $code .= <<END;
- ScriptValue jsValue = $getterString;
-END
- }
- $code .= <<END;
- info.Holder()->SetHiddenValue(propertyName, jsValue.v8Value());
- v8SetReturnValue(info, jsValue.v8Value());
-END
- }
- } elsif ($attribute->type eq "EventHandler") {
- AddToImplIncludes("bindings/v8/V8AbstractEventListener.h");
- # FIXME: Pass the main world ID for main-world-only getters.
- my ($functionName, @arguments) = GetterExpression($interfaceName, $attribute);
- my $implementedBy = $attribute->extendedAttributes->{"ImplementedBy"};
- if ($implementedBy) {
- my $implementedByImplName = GetImplNameFromImplementedBy($implementedBy);
- $functionName = "${implementedByImplName}::${functionName}";
- push(@arguments, "imp");
- } else {
- $functionName = "imp->${functionName}";
- }
- push(@arguments, "isolatedWorldForIsolate(info.GetIsolate())");
- $code .= " EventListener* jsValue = ${functionName}(" . join(", ", @arguments) . ");\n";
- $code .= " v8SetReturnValue(info, jsValue ? v8::Handle<v8::Value>(V8AbstractEventListener::cast(jsValue)->getListenerObject(imp->executionContext())) : v8::Handle<v8::Value>(v8::Null(info.GetIsolate())));\n";
- } else {
- my $nativeValue = NativeToJSValue($attribute->type, $attribute->extendedAttributes, $expression, " ", "", "info.GetIsolate()", "info", "imp", $forMainWorldSuffix, "return");
- $code .= "${nativeValue}\n";
- }
-
- $code .= "}\n"; # end of getter
- $code .= "#endif // ${conditionalString}\n" if $conditionalString;
- $code .= "\n";
- $implementation{nameSpaceInternal}->add($code);
-}
-
-sub ShouldKeepAttributeAlive
-{
- my ($interface, $attribute, $returnType) = @_;
- my $attrName = $attribute->name;
-
- # For readonly attributes (including Replaceable), as a general rule, for
- # performance reasons we keep the attribute wrapper alive while the owner
- # wrapper is alive, because the attribute never changes.
- return 0 if !IsWrapperType($returnType);
- return 0 if !IsReadonly($attribute) && !$attribute->extendedAttributes->{"Replaceable"};
-
- # However, there are a couple of exceptions.
-
- # Node lifetime is managed by object grouping.
- return 0 if InheritsInterface($interface, "Node");
- return 0 if IsDOMNodeType($returnType);
-
- # To avoid adding a reference to itself.
- # FIXME: Introduce [DoNotKeepAttributeAliveForGC] and remove this hack
- # depending on the attribute name.
- return 0 if $attrName eq "self";
-
- # FIXME: Remove these hard-coded hacks.
- return 0 if $returnType eq "EventTarget";
- return 0 if $returnType eq "SerializedScriptValue";
- return 0 if $returnType eq "Window";
- return 0 if $returnType =~ /SVG/;
- return 0 if $returnType =~ /HTML/;
-
- return 1;
-}
-
-sub GenerateReplaceableAttributeSetterCallback
-{
- my $interface = shift;
- my $implClassName = GetImplName($interface);
-
- my $code = "";
- $code .= "static void ${implClassName}ReplaceableAttributeSetterCallback(v8::Local<v8::String> name, v8::Local<v8::Value> jsValue, const v8::PropertyCallbackInfo<void>& info)\n";
- $code .= "{\n";
- $code .= GenerateFeatureObservation($interface->extendedAttributes->{"MeasureAs"});
- $code .= GenerateDeprecationNotification($interface->extendedAttributes->{"DeprecateAs"});
- $code .= GenerateCustomElementInvocationScopeIfNeeded($interface->extendedAttributes);
- if (HasActivityLogging("", $interface->extendedAttributes, "Setter")) {
- die "IDL error: ActivityLog attribute cannot exist on a ReplacableAttributeSetterCallback";
- }
- $code .= " ${implClassName}V8Internal::${implClassName}ReplaceableAttributeSetter(name, jsValue, info);\n";
- $code .= "}\n\n";
- $implementation{nameSpaceInternal}->add($code);
-}
-
-sub GenerateReplaceableAttributeSetter
-{
- my $interface = shift;
-
- my $interfaceName = $interface->name();
- my $implClassName = GetImplName($interface);
- my $v8ClassName = GetV8ClassName($interface);
-
- my $code = "";
- $code .= <<END;
-static void ${implClassName}ReplaceableAttributeSetter(v8::Local<v8::String> name, v8::Local<v8::Value> jsValue, const v8::PropertyCallbackInfo<void>& info)
-{
-END
- if ($interface->extendedAttributes->{"CheckSecurity"}) {
- AddToImplIncludes("bindings/v8/BindingSecurity.h");
- $code .= <<END;
- ${implClassName}* imp = ${v8ClassName}::toNative(info.Holder());
- v8::String::Utf8Value attributeName(name);
- ExceptionState exceptionState(ExceptionState::SetterContext, *attributeName, "${interfaceName}", info.Holder(), info.GetIsolate());
- if (!BindingSecurity::shouldAllowAccessToFrame(imp->frame(), exceptionState)) {
- exceptionState.throwIfNeeded();
- return;
- }
-END
- }
-
- $code .= <<END;
- info.This()->ForceSet(name, jsValue);
-}
-
-END
- $implementation{nameSpaceInternal}->add($code);
-}
-
-sub GenerateCustomElementInvocationScopeIfNeeded
-{
- my $code = "";
- my $ext = shift;
-
- if ($ext->{"CustomElementCallbacks"} or $ext->{"Reflect"}) {
- AddToImplIncludes("core/dom/custom/CustomElementCallbackDispatcher.h");
- $code .= <<END;
- CustomElementCallbackDispatcher::CallbackDeliveryScope deliveryScope;
-END
- }
- return $code;
-}
-
-sub GenerateNormalAttributeSetterCallback
-{
- my $attribute = shift;
- my $interface = shift;
- my $forMainWorldSuffix = shift;
- my $exposeJSAccessors = shift;
-
- my $implClassName = GetImplName($interface);
- my $v8ClassName = GetV8ClassName($interface);
- my $attrExt = $attribute->extendedAttributes;
- my $attrName = $attribute->name;
-
- my $conditionalString = GenerateConditionalString($attribute);
- my $code = "";
- $code .= "#if ${conditionalString}\n" if $conditionalString;
-
- if ($exposeJSAccessors) {
- $code .= "static void ${attrName}AttributeSetterCallback${forMainWorldSuffix}(const v8::FunctionCallbackInfo<v8::Value>& info)\n";
- $code .= "{\n";
- $code .= " v8::Local<v8::Value> jsValue = info[0];\n";
- } else {
- $code .= "static void ${attrName}AttributeSetterCallback${forMainWorldSuffix}(v8::Local<v8::String>, v8::Local<v8::Value> jsValue, const v8::PropertyCallbackInfo<void>& info)\n";
- $code .= "{\n";
- }
- $code .= " TRACE_EVENT_SET_SAMPLING_STATE(\"Blink\", \"DOMSetter\");\n";
- $code .= GenerateFeatureObservation($attrExt->{"MeasureAs"});
- $code .= GenerateDeprecationNotification($attrExt->{"DeprecateAs"});
- if (HasActivityLogging($forMainWorldSuffix, $attrExt, "Setter")) {
- $code .= GenerateActivityLogging("Setter", $interface, "${attrName}");
- }
- $code .= GenerateCustomElementInvocationScopeIfNeeded($attrExt);
- if (HasCustomSetter($attribute)) {
- $code .= " ${v8ClassName}::${attrName}AttributeSetterCustom(jsValue, info);\n";
- } else {
- $code .= " ${implClassName}V8Internal::${attrName}AttributeSetter${forMainWorldSuffix}(jsValue, info);\n";
- }
- $code .= " TRACE_EVENT_SET_SAMPLING_STATE(\"V8\", \"Execution\");\n";
- $code .= "}\n";
- $code .= "#endif // ${conditionalString}\n" if $conditionalString;
- $code .= "\n";
- $implementation{nameSpaceInternal}->add($code);
-}
-
-sub FindAttributeWithName
-{
- my $interface = shift;
- my $attrName = shift;
-
- foreach my $attribute (@{$interface->attributes}) {
- if ($attribute->name eq $attrName) {
- return $attribute;
- }
- }
-}
-
-sub GenerateNormalAttributeSetter
-{
- my $attribute = shift;
- my $interface = shift;
- my $forMainWorldSuffix = shift;
- my $exposeJSAccessors = shift;
-
- my $interfaceName = $interface->name;
- my $implClassName = GetImplName($interface);
- my $v8ClassName = GetV8ClassName($interface);
- my $attrName = $attribute->name;
- my $attrExt = $attribute->extendedAttributes;
- my $attrType = $attribute->type;
- my $attrCached = GetCachedAttribute($attribute);
-
- if (HasCustomSetter($attribute)) {
- return;
- }
-
- my $conditionalString = GenerateConditionalString($attribute);
- my $code = "";
- $code .= "#if ${conditionalString}\n" if $conditionalString;
- if ($exposeJSAccessors) {
- $code .= "static void ${attrName}AttributeSetter${forMainWorldSuffix}(v8::Local<v8::Value> jsValue, const v8::FunctionCallbackInfo<v8::Value>& info)\n";
- } else {
- $code .= "static void ${attrName}AttributeSetter${forMainWorldSuffix}(v8::Local<v8::Value> jsValue, const v8::PropertyCallbackInfo<void>& info)\n";
- }
- $code .= "{\n";
-
- my $raisesException = $attribute->extendedAttributes->{"RaisesException"};
- my $useExceptions = 1 if $raisesException && ($raisesException eq "VALUE_IS_MISSING" or $raisesException eq "Setter");
- my $hasStrictTypeChecking = 1 if $attribute->extendedAttributes->{"StrictTypeChecking"} && IsWrapperType($attrType); # Currently only actually check interface types
-
- # We throw exceptions using 'ExceptionState' if the attribute explicitly
- # claims that exceptions may be raised, or if a strict type check might
- # fail, or if we're dealing with SVG, which does strange things with
- # tearoffs and read-only wrappers.
- if ($useExceptions or $hasStrictTypeChecking or GetSVGTypeNeedingTearOff($interfaceName) or GetSVGTypeNeedingTearOff($attrType)) {
- $code .= " ExceptionState exceptionState(ExceptionState::SetterContext, \"${attrName}\", \"${interfaceName}\", info.Holder(), info.GetIsolate());\n";
- }
-
- # If the "StrictTypeChecking" extended attribute is present, and the
- # attribute's type is an interface type, then if the incoming value does not
- # implement that interface, a TypeError is thrown rather than silently
- # passing NULL to the C++ code.
- # Per the Web IDL and ECMAScript specifications, incoming values can always
- # be converted to both strings and numbers, so do not throw TypeError if the
- # attribute is of these types.
- if ($hasStrictTypeChecking) {
- $code .= " if (!isUndefinedOrNull(jsValue) && !V8${attrType}::hasInstance(jsValue, info.GetIsolate(), worldType(info.GetIsolate()))) {\n";
- $code .= " exceptionState.throwTypeError(\"The provided value is not of type '${attrType}'.\");\n";
- $code .= " exceptionState.throwIfNeeded();\n";
- $code .= " return;\n";
- $code .= " }\n";
- }
-
- my $svgNativeType = GetSVGTypeNeedingTearOff($interfaceName);
- if ($svgNativeType) {
- my $svgWrappedNativeType = GetSVGWrappedTypeNeedingTearOff($interfaceName);
- if ($svgWrappedNativeType =~ /List$/) {
- $code .= <<END;
- $svgNativeType* imp = ${v8ClassName}::toNative(info.Holder());
-END
- } else {
- $code .= " $svgNativeType* wrapper = ${v8ClassName}::toNative(info.Holder());\n";
- $code .= " if (wrapper->isReadOnly()) {\n";
- $code .= " exceptionState.throwDOMException(NoModificationAllowedError, \"The attribute is read-only.\");\n";
- $code .= " exceptionState.throwIfNeeded();\n";
- $code .= " return;\n";
- $code .= " }\n";
- $code .= " $svgWrappedNativeType& impInstance = wrapper->propertyReference();\n";
- $code .= " $svgWrappedNativeType* imp = &impInstance;\n";
- }
- } elsif ($attrExt->{"OnPrototype"}) {
- $code .= <<END;
- ${implClassName}* imp = ${v8ClassName}::toNative(info.Holder());
-END
- } elsif($attrExt->{"PutForwards"}) {
- my $destinationAttrName = $attrExt->{"PutForwards"};
- my $destinationInterface = ParseInterface($attrType);
- die "[PutForwards=x] value must be a wrapper type" unless $destinationInterface;
- my $destinationAttribute = FindAttributeWithName($destinationInterface, $destinationAttrName);
- die "[PutForwards=x] could not find $destinationAttrName in interface $attrType" unless $destinationAttribute;
- $code .= <<END;
- ${implClassName}* proxyImp = ${v8ClassName}::toNative(info.Holder());
- RefPtr<${attrType}> imp = proxyImp->${attrName}();
- if (!imp)
- return;
-END
- # Override attribute and fall through to forward setter call.
- $attribute = $destinationAttribute;
- $attrName = $attribute->name;
- $attrType = $attribute->type;
- $attrExt = $attribute->extendedAttributes;
- } else {
- my $reflect = $attribute->extendedAttributes->{"Reflect"};
- if ($reflect && InheritsInterface($interface, "Node") && $attrType eq "DOMString") {
- # Generate super-compact call for regular attribute setter:
- my $contentAttributeName = $reflect eq "VALUE_IS_MISSING" ? lc $attrName : $reflect;
- my $namespace = NamespaceForAttributeName($interfaceName, $contentAttributeName);
- my $mode = GetV8StringResourceMode($attribute->extendedAttributes);
- AddToImplIncludes("${namespace}.h");
- $code .= " Element* imp = V8Element::toNative(info.Holder());\n";
- $code .= " V8TRYCATCH_FOR_V8STRINGRESOURCE_VOID(V8StringResource<$mode>, stringResource, jsValue);\n";
- # Attr (not Attribute) used in content attributes
- $code .= " imp->setAttribute(${namespace}::${contentAttributeName}Attr, stringResource);\n";
- $code .= "}\n";
- $code .= "#endif // ${conditionalString}\n" if $conditionalString;
- $code .= "\n";
- $implementation{nameSpaceInternal}->add($code);
- return;
- # Skip the rest of the function!
- }
-
- if (!$attribute->isStatic) {
- $code .= <<END;
- ${implClassName}* imp = ${v8ClassName}::toNative(info.Holder());
-END
- }
- }
-
- my $nativeType = GetNativeType($attribute->type, $attribute->extendedAttributes, "parameter");
- if ($attribute->type eq "EventHandler") {
- if ($interface->name eq "Window") {
- $code .= " if (!imp->document())\n";
- $code .= " return;\n";
- }
- } else {
- my $asSetterValue = 0;
- $code .= JSValueToNativeStatement($attribute->type, $attribute->extendedAttributes, $asSetterValue, "jsValue", "cppValue", " ", "info.GetIsolate()");
- }
-
- if (IsEnumType($attrType)) {
- # setter ignores invalid enumeration values
- my @enumValues = ValidEnumValues($attrType);
- my @validEqualities = ();
- foreach my $enumValue (@enumValues) {
- push(@validEqualities, "string == \"$enumValue\"");
- }
- my $enumValidationExpression = join(" || ", @validEqualities);
- $code .= <<END;
- String string = cppValue;
- if (!($enumValidationExpression))
- return;
-END
- }
-
- my $expression = "cppValue";
- my $returnType = $attribute->type;
- if (IsRefPtrType($returnType) && !GetArrayType($returnType)) {
- $expression = "WTF::getPtr(" . $expression . ")";
- }
-
- $code .= GenerateCustomElementInvocationScopeIfNeeded($attribute->extendedAttributes);
-
- my $returnSvgNativeType = GetSVGTypeNeedingTearOff($returnType);
- if ($returnSvgNativeType) {
- $code .= <<END;
- if (!$expression) {
- exceptionState.throwTypeError(\"The provided value is not of type '$returnType'.\");
- exceptionState.throwIfNeeded();
- return;
- }
-END
- $expression = $expression . "->propertyReference()";
- }
-
- if ($attribute->type eq "EventHandler") {
- my $implementedBy = $attribute->extendedAttributes->{"ImplementedBy"};
- my $implementedByImplName;
- if ($implementedBy) {
- $implementedByImplName = GetImplNameFromImplementedBy($implementedBy);
- }
- if (!InheritsInterface($interface, "Node")) {
- my $attrImplName = GetImplName($attribute);
- my @arguments;
- if ($implementedBy) {
- $attrImplName = "${implementedByImplName}::${attrImplName}";
- push(@arguments, "imp");
- } else {
- $attrImplName = "imp->${attrImplName}";
- }
- push(@arguments, "isolatedWorldForIsolate(info.GetIsolate())");
- $code .= " transferHiddenDependency(info.Holder(), ${attrImplName}(" . join(", ", @arguments) . "), jsValue, ${v8ClassName}::eventListenerCacheIndex, info.GetIsolate());\n";
- }
- my ($functionName, @arguments) = SetterExpression($interfaceName, $attribute);
- if ($implementedBy) {
- $functionName = "${implementedByImplName}::${functionName}";
- push(@arguments, "imp");
- } else {
- $functionName = "imp->${functionName}";
- }
- if (($interfaceName eq "Window" or $interfaceName eq "WorkerGlobalScope") and $attribute->name eq "onerror") {
- AddToImplIncludes("bindings/v8/V8ErrorHandler.h");
- push(@arguments, "V8EventListenerList::findOrCreateWrapper<V8ErrorHandler>(jsValue, true, info.GetIsolate())");
- } else {
- push(@arguments, "V8EventListenerList::getEventListener(jsValue, true, ListenerFindOrCreate)");
- }
- push(@arguments, "isolatedWorldForIsolate(info.GetIsolate())");
- $code .= " ${functionName}(" . join(", ", @arguments) . ");\n";
- } else {
- my ($functionName, @arguments) = SetterExpression($interfaceName, $attribute);
- push(@arguments, $expression);
- push(@arguments, "exceptionState") if $useExceptions;
- if ($attribute->extendedAttributes->{"ImplementedBy"}) {
- my $implementedBy = $attribute->extendedAttributes->{"ImplementedBy"};
- my $implementedByImplName = GetImplNameFromImplementedBy($implementedBy);
- AddToImplIncludes(HeaderFilesForInterface($implementedBy, $implementedByImplName));
- unshift(@arguments, "imp") if !$attribute->isStatic;
- $functionName = "${implementedByImplName}::${functionName}";
- } elsif ($attribute->isStatic) {
- $functionName = "${implClassName}::${functionName}";
- } else {
- $functionName = "imp->${functionName}";
- }
- my ($arg, $subCode) = GenerateCallWith($attribute->extendedAttributes->{"SetterCallWith"} || $attribute->extendedAttributes->{"CallWith"}, " ", 1);
- $code .= $subCode;
- unshift(@arguments, @$arg);
- $code .= " ${functionName}(" . join(", ", @arguments) . ");\n";
- }
-
- if ($useExceptions) {
- $code .= " exceptionState.throwIfNeeded();\n";
- }
-
- if (ExtendedAttributeContains($attribute->extendedAttributes->{"CallWith"}, "ScriptState")) {
- $code .= " if (state.hadException())\n";
- $code .= " throwError(state.exception(), info.GetIsolate());\n";
- }
-
- if ($svgNativeType) {
- if ($useExceptions) {
- $code .= " if (!exceptionState.hadException())\n";
- $code .= " wrapper->commitChange();\n";
- } else {
- $code .= " wrapper->commitChange();\n";
- }
- }
-
- if ($attrCached) {
- $code .= <<END;
- info.Holder()->DeleteHiddenValue(v8::String::NewFromUtf8(info.GetIsolate(), "${attrName}", v8::String::kInternalizedString)); // Invalidate the cached value.
-END
- }
-
- $code .= "}\n"; # end of setter
- $code .= "#endif // ${conditionalString}\n" if $conditionalString;
- $code .= "\n";
- $implementation{nameSpaceInternal}->add($code);
-}
-
-sub GenerateParametersCheckExpression
-{
- my $numParameters = shift;
- my $function = shift;
-
- my @andExpression = ();
- push(@andExpression, "info.Length() == $numParameters");
- my $parameterIndex = 0;
- foreach my $parameter (@{$function->parameters}) {
- last if $parameterIndex >= $numParameters;
- my $value = "info[$parameterIndex]";
- my $type = $parameter->type;
-
- # Only DOMString or wrapper types are checked.
- # For DOMString with StrictTypeChecking only Null, Undefined and Object
- # are accepted for compatibility. Otherwise, no restrictions are made to
- # match the non-overloaded behavior.
- # FIXME: Implement WebIDL overload resolution algorithm.
- if ($type eq "DOMString") {
- if ($parameter->extendedAttributes->{"StrictTypeChecking"}) {
- push(@andExpression, "${value}->IsNull() || ${value}->IsUndefined() || ${value}->IsString() || ${value}->IsObject()");
- }
- } elsif (IsCallbackInterface($parameter->type)) {
- # For Callbacks only checks if the value is null or object.
- push(@andExpression, "${value}->IsNull() || ${value}->IsFunction()");
- } elsif (GetArrayOrSequenceType($type)) {
- if ($parameter->isNullable) {
- push(@andExpression, "${value}->IsNull() || ${value}->IsArray()");
- } else {
- push(@andExpression, "${value}->IsArray()");
- }
- } elsif (IsWrapperType($type)) {
- if ($parameter->isNullable) {
- push(@andExpression, "${value}->IsNull() || V8${type}::hasInstance($value, info.GetIsolate(), worldType(info.GetIsolate()))");
- } else {
- push(@andExpression, "V8${type}::hasInstance($value, info.GetIsolate(), worldType(info.GetIsolate()))");
- }
- }
-
- $parameterIndex++;
- }
- @andExpression = map { "($_)" } @andExpression;
- my $res = "(" . join(" && ", @andExpression) . ")";
- return $res;
-}
-
-# As per Web IDL specification, the length of a function Object is
-# its number of mandatory parameters.
-sub GetFunctionLength
-{
- my $function = shift;
-
- my $numMandatoryParams = 0;
- foreach my $parameter (@{$function->parameters}) {
- # Abort as soon as we find the first optional parameter as no mandatory
- # parameter can follow an optional one.
- last if $parameter->isOptional;
- $numMandatoryParams++;
- }
- return $numMandatoryParams;
-}
-
-sub GenerateFunctionParametersCheck
-{
- my $function = shift;
-
- my @orExpression = ();
- my $numParameters = 0;
- my $hasVariadic = 0;
- my $numMandatoryParams = @{$function->parameters};
- foreach my $parameter (@{$function->parameters}) {
- if ($parameter->isOptional) {
- push(@orExpression, GenerateParametersCheckExpression($numParameters, $function));
- $numMandatoryParams--;
- }
- if ($parameter->isVariadic) {
- $hasVariadic = 1;
- last;
- }
- $numParameters++;
- }
- if (!$hasVariadic) {
- push(@orExpression, GenerateParametersCheckExpression($numParameters, $function));
- }
- return ($numMandatoryParams, join(" || ", @orExpression));
-}
-
-sub GenerateOverloadedFunction
-{
- my $function = shift;
- my $interface = shift;
- my $forMainWorldSuffix = 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->name;
- my $interfaceName = $interface->name;
- my $implClassName = GetImplName($interface);
-
- my $conditionalString = GenerateConditionalString($function);
- my $leastNumMandatoryParams = 255;
-
- my $code = "";
- $code .= "#if ${conditionalString}\n\n" if $conditionalString;
- $code .= <<END;
-static void ${name}Method${forMainWorldSuffix}(const v8::FunctionCallbackInfo<v8::Value>& info)
-{
-END
- $code .= GenerateFeatureObservation($function->extendedAttributes->{"MeasureAs"});
- $code .= GenerateDeprecationNotification($function->extendedAttributes->{"DeprecateAs"});
-
- foreach my $overload (@{$function->{overloads}}) {
- my ($numMandatoryParams, $parametersCheck) = GenerateFunctionParametersCheck($overload);
- $leastNumMandatoryParams = $numMandatoryParams if ($numMandatoryParams < $leastNumMandatoryParams);
- $code .= " if ($parametersCheck) {\n";
- my $overloadedIndexString = $overload->{overloadIndex};
- $code .= " ${name}${overloadedIndexString}Method${forMainWorldSuffix}(info);\n";
- $code .= " return;\n";
- $code .= " }\n";
- }
- if ($leastNumMandatoryParams >= 1) {
- $code .= " ExceptionState exceptionState(ExceptionState::ExecutionContext, \"${name}\", \"${interfaceName}\", info.Holder(), info.GetIsolate());\n";
- $code .= " if (UNLIKELY(info.Length() < $leastNumMandatoryParams)) {\n";
- $code .= " exceptionState.throwTypeError(ExceptionMessages::notEnoughArguments($leastNumMandatoryParams, info.Length()));\n";
- $code .= " exceptionState.throwIfNeeded();\n";
- $code .= " return;\n";
- $code .= " }\n";
- $code .= <<END;
- exceptionState.throwTypeError(\"No function was found that matched the signature provided.\");
- exceptionState.throwIfNeeded();
-END
- } else {
- $code .=<<END;
- throwTypeError(ExceptionMessages::failedToExecute(\"${name}\", \"${interfaceName}\", \"No function was found that matched the signature provided.\"), info.GetIsolate());
-END
- }
- $code .= "}\n\n";
- $code .= "#endif // ${conditionalString}\n\n" if $conditionalString;
- $implementation{nameSpaceInternal}->add($code);
-}
-
-sub GenerateFunctionCallback
-{
- my $function = shift;
- my $interface = shift;
- my $forMainWorldSuffix = shift;
-
- my $implClassName = GetImplName($interface);
- my $v8ClassName = GetV8ClassName($interface);
- my $name = $function->name;
-
- if ($name eq "") {
- return;
- }
-
- my $conditionalString = GenerateConditionalString($function);
- my $code = "";
- $code .= "#if ${conditionalString}\n" if $conditionalString;
- $code .= <<END;
-static void ${name}MethodCallback${forMainWorldSuffix}(const v8::FunctionCallbackInfo<v8::Value>& info)
-{
-END
- $code .= " TRACE_EVENT_SET_SAMPLING_STATE(\"Blink\", \"DOMMethod\");\n";
- $code .= GenerateFeatureObservation($function->extendedAttributes->{"MeasureAs"});
- $code .= GenerateDeprecationNotification($function->extendedAttributes->{"DeprecateAs"});
- if (HasActivityLogging($forMainWorldSuffix, $function->extendedAttributes, "Access")) {
- $code .= GenerateActivityLogging("Method", $interface, "${name}");
- }
- if (HasCustomMethod($function->extendedAttributes)) {
- $code .= " ${v8ClassName}::${name}MethodCustom(info);\n";
- } else {
- $code .= " ${implClassName}V8Internal::${name}Method${forMainWorldSuffix}(info);\n";
- }
- $code .= " TRACE_EVENT_SET_SAMPLING_STATE(\"V8\", \"Execution\");\n";
- $code .= "}\n";
- $code .= "#endif // ${conditionalString}\n" if $conditionalString;
- $code .= "\n";
- $implementation{nameSpaceInternal}->add($code);
-}
-
-sub GenerateFunction
-{
- my $function = shift;
- my $interface = shift;
- my $forMainWorldSuffix = shift;
-
- my $interfaceName = $interface->name;
- my $implClassName = GetImplName($interface);
- my $v8ClassName = GetV8ClassName($interface);
- my $name = $function->name;
- my $unoverloadedName = $function->name;
- my $implName = GetImplName($function);
- my $funcExt = $function->extendedAttributes;
-
- if (HasCustomMethod($funcExt) || $name eq "") {
- return;
- }
-
- if (@{$function->{overloads}} > 1) {
- # Append a number to an overloaded method's name to make it unique:
- $name = $name . $function->{overloadIndex};
- }
-
- my $conditionalString = GenerateConditionalString($function);
- my $code = "";
- $code .= "#if ${conditionalString}\n" if $conditionalString;
- $code .= "static void ${name}Method${forMainWorldSuffix}(const v8::FunctionCallbackInfo<v8::Value>& info)\n";
- $code .= "{\n";
-
- # We throw exceptions using 'ExceptionState' if the function explicitly claims that exceptions
- # may be raised, or for event listeners, or for security-checking, and for weird SVG stuff.
- my $isEventListener = $name eq "addEventListener" || $name eq "removeEventListener";
- my $isEventDispatcher = $name eq "dispatchEvent";
- my $isSecurityCheckNecessary = $interface->extendedAttributes->{"CheckSecurity"} && !$function->extendedAttributes->{"DoNotCheckSecurity"};
- my $raisesExceptions = $function->extendedAttributes->{"RaisesException"};
- my ($svgPropertyType, $svgListPropertyType, $svgNativeType) = GetSVGPropertyTypes($interfaceName);
- my $isNonListSVGType = $svgNativeType && !($interfaceName =~ /List$/);
-
- my $hasExceptionState = 0;
- if ($raisesExceptions || $isEventListener || $isSecurityCheckNecessary || $isNonListSVGType) {
- $code .= " ExceptionState exceptionState(ExceptionState::ExecutionContext, \"${unoverloadedName}\", \"${interfaceName}\", info.Holder(), info.GetIsolate());\n";
- $hasExceptionState = 1;
- }
-
- if ($isEventListener || $isEventDispatcher) {
- AddToImplIncludes("bindings/v8/BindingSecurity.h");
- AddToImplIncludes("bindings/v8/V8EventListenerList.h");
- AddToImplIncludes("core/frame/DOMWindow.h");
- $code .= <<END;
- EventTarget* impl = ${v8ClassName}::toNative(info.Holder());
- if (DOMWindow* window = impl->toDOMWindow()) {
- if (!BindingSecurity::shouldAllowAccessToFrame(window->frame(), exceptionState)) {
- exceptionState.throwIfNeeded();
- return;
- }
- if (!window->document())
- return;
- }
-END
- }
- if ($isEventListener) {
- my $lookupType = ($name eq "addEventListener") ? "OrCreate" : "Only";
- my $passRefPtrHandling = ($name eq "addEventListener") ? "" : ".get()";
- my $hiddenDependencyAction = ($name eq "addEventListener") ? "create" : "remove";
-
- $code .= <<END;
- RefPtr<EventListener> listener = V8EventListenerList::getEventListener(info[1], false, ListenerFind${lookupType});
- if (listener) {
- V8TRYCATCH_FOR_V8STRINGRESOURCE_VOID(V8StringResource<WithNullCheck>, eventName, info[0]);
- impl->${implName}(eventName, listener${passRefPtrHandling}, info[2]->BooleanValue());
- if (!impl->toNode())
- ${hiddenDependencyAction}HiddenDependency(info.Holder(), info[1], ${v8ClassName}::eventListenerCacheIndex, info.GetIsolate());
- }
-}
-END
- $code .= "#endif // ${conditionalString}\n" if $conditionalString;
- $code .= "\n";
- $implementation{nameSpaceInternal}->add($code);
- return;
- }
-
- $code .= GenerateArgumentsCountCheck($function, $interface, $hasExceptionState);
-
- if ($svgNativeType) {
- my $nativeClassName = GetNativeType($interfaceName);
- if ($interfaceName =~ /List$/) {
- $code .= " $nativeClassName imp = ${v8ClassName}::toNative(info.Holder());\n";
- } else {
- AddToImplIncludes("core/dom/ExceptionCode.h");
- $code .= " $nativeClassName wrapper = ${v8ClassName}::toNative(info.Holder());\n";
- $code .= " if (wrapper->isReadOnly()) {\n";
- $code .= " exceptionState.throwDOMException(NoModificationAllowedError, \"The object is read-only.\");\n";
- $code .= " exceptionState.throwIfNeeded();\n";
- $code .= " return;\n";
- $code .= " }\n";
- my $svgWrappedNativeType = GetSVGWrappedTypeNeedingTearOff($interfaceName);
- $code .= " $svgWrappedNativeType& impInstance = wrapper->propertyReference();\n";
- $code .= " $svgWrappedNativeType* imp = &impInstance;\n";
- }
- } elsif (!$function->isStatic) {
- $code .= <<END;
- ${implClassName}* imp = ${v8ClassName}::toNative(info.Holder());
-END
- }
-
- $code .= GenerateCustomElementInvocationScopeIfNeeded($funcExt);
-
- # Check domain security if needed
- if ($isSecurityCheckNecessary) {
- # We have not find real use cases yet.
- AddToImplIncludes("bindings/v8/BindingSecurity.h");
- $code .= <<END;
- if (!BindingSecurity::shouldAllowAccessToFrame(imp->frame(), exceptionState)) {
- exceptionState.throwIfNeeded();
- return;
- }
-END
- }
-
- if ($function->extendedAttributes->{"CheckSecurity"}) {
- AddToImplIncludes("bindings/v8/BindingSecurity.h");
- $code .= " if (!BindingSecurity::shouldAllowAccessToNode(imp->" . GetImplName($function) . "(exceptionState), exceptionState)) {\n";
- $code .= " v8SetReturnValueNull(info);\n";
- $code .= " exceptionState.throwIfNeeded();\n";
- $code .= " return;\n";
- $code .= " }\n";
-END
- }
-
- my ($parameterCheckString, $paramIndex, %replacements) = GenerateParametersCheck($function, $interface, $forMainWorldSuffix);
- $code .= $parameterCheckString;
-
- # Build the function call string.
- $code .= GenerateFunctionCallString($function, $paramIndex, " ", $interface, $forMainWorldSuffix, %replacements);
- $code .= "}\n";
- $code .= "#endif // ${conditionalString}\n" if $conditionalString;
- $code .= "\n";
- $implementation{nameSpaceInternal}->add($code);
-}
-
-sub GenerateCallWith
-{
- my $callWith = shift;
- return ([], "") unless $callWith;
- my $indent = shift;
- my $returnVoid = shift;
- my $function = shift;
- my $code = "";
-
- my @callWithArgs;
- if (ExtendedAttributeContains($callWith, "ScriptState")) {
- $code .= $indent . "ScriptState* currentState = ScriptState::current();\n";
- $code .= $indent . "if (!currentState)\n";
- $code .= $indent . " return" . ($returnVoid ? "" : " v8Undefined()") . ";\n";
- $code .= $indent . "ScriptState& state = *currentState;\n";
- push(@callWithArgs, "&state");
- AddToImplIncludes("bindings/v8/ScriptState.h");
- }
- if (ExtendedAttributeContains($callWith, "ExecutionContext")) {
- $code .= $indent . "ExecutionContext* scriptContext = getExecutionContext();\n";
- push(@callWithArgs, "scriptContext");
- }
- if ($function and ExtendedAttributeContains($callWith, "ScriptArguments")) {
- $code .= $indent . "RefPtr<ScriptArguments> scriptArguments(createScriptArguments(info, " . @{$function->parameters} . "));\n";
- push(@callWithArgs, "scriptArguments.release()");
- AddToImplIncludes("bindings/v8/ScriptCallStackFactory.h");
- AddToImplIncludes("core/inspector/ScriptArguments.h");
- }
- if (ExtendedAttributeContains($callWith, "ActiveWindow")) {
- push(@callWithArgs, "activeDOMWindow()");
- }
- if (ExtendedAttributeContains($callWith, "FirstWindow")) {
- push(@callWithArgs, "firstDOMWindow()");
- }
- return ([@callWithArgs], $code);
-}
-
-sub GenerateArgumentsCountCheck
-{
- my $function = shift;
- my $interface = shift;
- my $hasExceptionState = shift;
-
- my $functionName = $function->name;
- my $interfaceName = $interface->name;
- my $implClassName = GetImplName($interface);
-
- my $numMandatoryParams = 0;
- my $allowNonOptional = 1;
- foreach my $param (@{$function->parameters}) {
- if ($param->isOptional or $param->isVariadic) {
- $allowNonOptional = 0;
- } else {
- die "An argument must not be declared to be optional unless all subsequent arguments to the operation are also optional." if !$allowNonOptional;
- $numMandatoryParams++;
- }
- }
-
- my $argumentsCountCheckString = "";
- if ($numMandatoryParams >= 1) {
- $argumentsCountCheckString .= " if (UNLIKELY(info.Length() < $numMandatoryParams)) {\n";
- if ($hasExceptionState) {
- $argumentsCountCheckString .= " exceptionState.throwTypeError(ExceptionMessages::notEnoughArguments($numMandatoryParams, info.Length()));\n";
- $argumentsCountCheckString .= " exceptionState.throwIfNeeded();\n";
- } else {
- $argumentsCountCheckString .= " throwTypeError(ExceptionMessages::failedToExecute(\"$functionName\", \"$interfaceName\", ExceptionMessages::notEnoughArguments($numMandatoryParams, info.Length())), info.GetIsolate());\n";
- }
- $argumentsCountCheckString .= " return;\n";
- $argumentsCountCheckString .= " }\n";
- }
- return $argumentsCountCheckString;
-}
-
-sub GenerateParametersCheck
-{
- my $function = shift;
- my $interface = shift;
- my $forMainWorldSuffix = shift;
- my $style = shift || "new";
-
- my $functionName = $function->name;
- my $interfaceName = $interface->name;
- my $implClassName = GetImplName($interface);
-
- my $parameterCheckString = "";
- my $paramIndex = 0;
- my %replacements = ();
-
- foreach my $parameter (@{$function->parameters}) {
- my $humanFriendlyIndex = $paramIndex + 1;
- my $nativeType = GetNativeType($parameter->type, $parameter->extendedAttributes, "parameter");
-
- # Optional arguments without [Default=...] should generate an early call with fewer arguments.
- # Optional Dictionary arguments always considered to have default of empty dictionary.
- if ($parameter->isOptional && !$parameter->extendedAttributes->{"Default"} && $nativeType ne "Dictionary" && !IsCallbackInterface($parameter->type)) {
- $parameterCheckString .= <<END;
- if (UNLIKELY(info.Length() <= $paramIndex)) {
-END
- $parameterCheckString .= GenerateFunctionCallString($function, $paramIndex, " " x 2, $interface, $forMainWorldSuffix, %replacements);
- $parameterCheckString .= <<END;
- return;
- }
-END
- }
-
- my $parameterName = $parameter->name;
- if (IsCallbackInterface($parameter->type)) {
- my $v8ClassName = "V8" . $parameter->type;
- AddToImplIncludes("$v8ClassName.h");
- if ($parameter->isOptional) {
- $parameterCheckString .= " OwnPtr<" . $parameter->type . "> $parameterName;\n";
- $parameterCheckString .= " if (info.Length() > $paramIndex && !info[$paramIndex]->IsNull() && !info[$paramIndex]->IsUndefined()) {\n";
- $parameterCheckString .= " if (!info[$paramIndex]->IsFunction()) {\n";
- $parameterCheckString .= " throwTypeError(ExceptionMessages::failedToExecute(\"$functionName\", \"$interfaceName\", \"The callback provided as parameter $humanFriendlyIndex is not a function.\"), info.GetIsolate());\n";
- $parameterCheckString .= " return;\n";
- $parameterCheckString .= " }\n";
- $parameterCheckString .= " $parameterName = ${v8ClassName}::create(v8::Handle<v8::Function>::Cast(info[$paramIndex]), getExecutionContext());\n";
- $parameterCheckString .= " }\n";
- } else {
- $parameterCheckString .= " if (info.Length() <= $paramIndex || ";
- if ($parameter->isNullable) {
- $parameterCheckString .= "!(info[$paramIndex]->IsFunction() || info[$paramIndex]->IsNull())";
- } else {
- $parameterCheckString .= "!info[$paramIndex]->IsFunction()";
- }
- $parameterCheckString .= ") {\n";
- $parameterCheckString .= " throwTypeError(ExceptionMessages::failedToExecute(\"$functionName\", \"$interfaceName\", \"The callback provided as parameter $humanFriendlyIndex is not a function.\"), info.GetIsolate());\n";
- $parameterCheckString .= " return;\n";
- $parameterCheckString .= " }\n";
- $parameterCheckString .= " OwnPtr<" . $parameter->type . "> $parameterName = ";
- $parameterCheckString .= "info[$paramIndex]->IsNull() ? nullptr : " if $parameter->isNullable;
- $parameterCheckString .= "${v8ClassName}::create(v8::Handle<v8::Function>::Cast(info[$paramIndex]), getExecutionContext());\n";
- }
- } elsif ($parameter->extendedAttributes->{"Clamp"}) {
- my $nativeValue = "${parameterName}NativeValue";
- my $idlType = $parameter->type;
- $parameterCheckString .= " $nativeType $parameterName = 0;\n";
- $parameterCheckString .= " V8TRYCATCH_VOID(double, $nativeValue, info[$paramIndex]->NumberValue());\n";
- $parameterCheckString .= " if (!std::isnan($nativeValue))\n";
- $parameterCheckString .= " $parameterName = clampTo<$idlType>($nativeValue);\n";
- } elsif ($parameter->type eq "SerializedScriptValue") {
- AddToImplIncludes("bindings/v8/SerializedScriptValue.h");
- $parameterCheckString .= " bool ${parameterName}DidThrow = false;\n";
- $parameterCheckString .= " $nativeType $parameterName = SerializedScriptValue::create(info[$paramIndex], 0, 0, ${parameterName}DidThrow, info.GetIsolate());\n";
- $parameterCheckString .= " if (${parameterName}DidThrow)\n";
- $parameterCheckString .= " return;\n";
- } elsif ($parameter->isVariadic) {
- my $nativeElementType = GetNativeType($parameter->type);
- if ($nativeElementType =~ />$/) {
- $nativeElementType .= " ";
- }
-
- my $argType = $parameter->type;
- if (IsWrapperType($argType)) {
- $parameterCheckString .= " Vector<$nativeElementType> $parameterName;\n";
- $parameterCheckString .= " for (int i = $paramIndex; i < info.Length(); ++i) {\n";
- $parameterCheckString .= " if (!V8${argType}::hasInstance(info[i], info.GetIsolate(), worldType(info.GetIsolate()))) {\n";
- $parameterCheckString .= " throwTypeError(ExceptionMessages::failedToExecute(\"$functionName\", \"$interfaceName\", \"parameter $humanFriendlyIndex is not of type \'$argType\'.\"), info.GetIsolate());\n";
- $parameterCheckString .= " return;\n";
- $parameterCheckString .= " }\n";
- $parameterCheckString .= " $parameterName.append(V8${argType}::toNative(v8::Handle<v8::Object>::Cast(info[i])));\n";
- $parameterCheckString .= " }\n";
- } else {
- $parameterCheckString .= " V8TRYCATCH_VOID(Vector<$nativeElementType>, $parameterName, toNativeArguments<$nativeElementType>(info, $paramIndex));\n";
- }
- } elsif ($nativeType =~ /^V8StringResource/) {
- my $default = defined $parameter->extendedAttributes->{"Default"} ? $parameter->extendedAttributes->{"Default"} : "";
- my $jsValue = $parameter->isOptional && $default eq "NullString" ? "argumentOrNull(info, $paramIndex)" : "info[$paramIndex]";
- my $stringResourceParameterName = $parameterName;
- my $isNullable = IsNullableParameter($parameter);
- if ($isNullable) {
- $parameterCheckString .= " bool ${parameterName}IsNull = $jsValue->IsNull();\n";
- $stringResourceParameterName .= "StringResource";
- }
- $parameterCheckString .= JSValueToNativeStatement($parameter->type, $parameter->extendedAttributes, $humanFriendlyIndex, $jsValue, $stringResourceParameterName, " ", "info.GetIsolate()");
- $parameterCheckString .= " String $parameterName = $stringResourceParameterName;\n" if $isNullable;
- if (IsEnumType($parameter->type)) {
- my @enumValues = ValidEnumValues($parameter->type);
- my @validEqualities = ();
- foreach my $enumValue (@enumValues) {
- push(@validEqualities, "string == \"$enumValue\"");
- }
- my $enumValidationExpression = join(" || ", @validEqualities);
- $parameterCheckString .= " String string = $parameterName;\n";
- $parameterCheckString .= " if (!($enumValidationExpression)) {\n";
- $parameterCheckString .= " throwTypeError(ExceptionMessages::failedToExecute(\"$functionName\", \"$interfaceName\", \"parameter $humanFriendlyIndex (\'\" + string + \"\') is not a valid enum value.\"), info.GetIsolate());\n";
- $parameterCheckString .= " return;\n";
- $parameterCheckString .= " }\n";
- }
- } else {
- # If the "StrictTypeChecking" extended attribute is present, and the argument's type is an
- # interface type, then if the incoming value does not implement that interface, a TypeError
- # is thrown rather than silently passing NULL to the C++ code.
- # Per the Web IDL and ECMAScript specifications, incoming values can always be converted
- # to both strings and numbers, so do not throw TypeError if the argument is of these
- # types.
- if ($function->extendedAttributes->{"StrictTypeChecking"}) {
- my $argValue = "info[$paramIndex]";
- my $argType = $parameter->type;
- if (IsWrapperType($argType)) {
- $parameterCheckString .= " if (info.Length() > $paramIndex && !isUndefinedOrNull($argValue) && !V8${argType}::hasInstance($argValue, info.GetIsolate(), worldType(info.GetIsolate()))) {\n";
- $parameterCheckString .= " throwTypeError(ExceptionMessages::failedToExecute(\"$functionName\", \"$interfaceName\", \"parameter $humanFriendlyIndex is not of type \'$argType\'.\"), info.GetIsolate());\n";
- $parameterCheckString .= " return;\n";
- $parameterCheckString .= " }\n";
- }
- }
- my $default = defined $parameter->extendedAttributes->{"Default"} ? $parameter->extendedAttributes->{"Default"} : "";
- my $jsValue = $parameter->isOptional && $default eq "NullString" ? "argumentOrNull(info, $paramIndex)" : "info[$paramIndex]";
- my $isNullable = IsNullableParameter($parameter);
- $parameterCheckString .= " bool ${parameterName}IsNull = $jsValue->IsNull();\n" if $isNullable;
- $parameterCheckString .= JSValueToNativeStatement($parameter->type, $parameter->extendedAttributes, $humanFriendlyIndex, $jsValue, $parameterName, " ", "info.GetIsolate()");
- if ($nativeType eq 'Dictionary' or $nativeType eq 'ScriptPromise') {
- $parameterCheckString .= " if (!$parameterName.isUndefinedOrNull() && !$parameterName.isObject()) {\n";
- if ($functionName eq "Constructor") {
- $parameterCheckString .= " throwTypeError(ExceptionMessages::failedToConstruct(\"$interfaceName\", \"parameter ${humanFriendlyIndex} ('${parameterName}') is not an object.\"), info.GetIsolate());\n";
- } else {
- $parameterCheckString .= " throwTypeError(ExceptionMessages::failedToExecute(\"$functionName\", \"$interfaceName\", \"parameter ${humanFriendlyIndex} ('${parameterName}') is not an object.\"), info.GetIsolate());\n";
- }
- $parameterCheckString .= " return;\n";
- $parameterCheckString .= " }\n";
- }
- }
-
- $paramIndex++;
- }
- return ($parameterCheckString, $paramIndex, %replacements);
-}
-
-sub GenerateOverloadedConstructorCallback
-{
- my $interface = shift;
- my $interfaceName = $interface->name;
- my $implClassName = GetImplName($interface);
-
- my $code .= <<END;
-static void constructor(const v8::FunctionCallbackInfo<v8::Value>& info)
-{
-END
- my $leastNumMandatoryParams = 255;
- foreach my $constructor (@{$interface->constructors}) {
- my $name = "constructor" . $constructor->overloadedIndex;
- my ($numMandatoryParams, $parametersCheck) = GenerateFunctionParametersCheck($constructor);
- $leastNumMandatoryParams = $numMandatoryParams if ($numMandatoryParams < $leastNumMandatoryParams);
- $code .= " if ($parametersCheck) {\n";
- $code .= " ${implClassName}V8Internal::${name}(info);\n";
- $code .= " return;\n";
- $code .= " }\n";
- }
- if ($leastNumMandatoryParams >= 1) {
- $code .= <<END;
- ExceptionState exceptionState(ExceptionState::ConstructionContext, \"${interfaceName}\", info.Holder(), info.GetIsolate());
- if (UNLIKELY(info.Length() < $leastNumMandatoryParams)) {
- exceptionState.throwTypeError(ExceptionMessages::notEnoughArguments($leastNumMandatoryParams, info.Length()));
- exceptionState.throwIfNeeded();
- return;
- }
- exceptionState.throwTypeError(\"No matching constructor signature.\");
- exceptionState.throwIfNeeded();
-END
- } else {
- $code .= <<END;
- throwTypeError(ExceptionMessages::failedToConstruct(\"${interfaceName}\", \"No matching constructor signature.\"), info.GetIsolate());
-END
- }
- $code .= "}\n\n";
- $implementation{nameSpaceInternal}->add($code);
-}
-
-sub GenerateSingleConstructorCallback
-{
- my $interface = shift;
- my $function = shift;
-
- my $interfaceName = $interface->name;
- my $implClassName = GetImplName($interface);
- my $v8ClassName = GetV8ClassName($interface);
- my $overloadedIndexString = "";
- if ($function->overloadedIndex > 0) {
- $overloadedIndexString .= $function->overloadedIndex;
- }
-
- my $constructorRaisesException = $interface->extendedAttributes->{"RaisesException"} && $interface->extendedAttributes->{"RaisesException"} eq "Constructor";
- my $raisesExceptions = $function->extendedAttributes->{"RaisesException"} || $constructorRaisesException;
-
- my @beforeArgumentList;
- my @afterArgumentList;
- my $code = "";
- $code .= <<END;
-static void constructor${overloadedIndexString}(const v8::FunctionCallbackInfo<v8::Value>& info)
-{
-END
-
- if ($function->overloadedIndex == 0) {
- my $hasExceptionState = 0;
- $code .= GenerateArgumentsCountCheck($function, $interface, $hasExceptionState);
- }
-
- if ($raisesExceptions) {
- $code .= " ExceptionState exceptionState(ExceptionState::ConstructionContext, \"${interfaceName}\", info.Holder(), info.GetIsolate());\n";
- }
-
- # FIXME: Currently [Constructor(...)] does not yet support optional arguments without [Default=...]
- my ($parameterCheckString, $paramIndex, %replacements) = GenerateParametersCheck($function, $interface, "");
- $code .= $parameterCheckString;
-
- if ($interface->extendedAttributes->{"ConstructorCallWith"}) {
- if (ExtendedAttributeContains($interface->extendedAttributes->{"ConstructorCallWith"}, "ExecutionContext")) {
- push(@beforeArgumentList, "context");
- $code .= " ExecutionContext* context = getExecutionContext();\n";
- }
- if (ExtendedAttributeContains($interface->extendedAttributes->{"ConstructorCallWith"}, "Document")) {
- push(@beforeArgumentList, "document");
- $code .= " Document& document = *toDocument(getExecutionContext());\n";
- }
- }
-
- if ($constructorRaisesException) {
- push(@afterArgumentList, "exceptionState");
- }
-
- my @argumentList;
- my $index = 0;
- foreach my $parameter (@{$function->parameters}) {
- last if $index eq $paramIndex;
- if ($replacements{$parameter->name}) {
- push(@argumentList, $replacements{$parameter->name});
- } else {
- push(@argumentList, $parameter->name);
- }
- $index++;
- }
-
- my $argumentString = join(", ", @beforeArgumentList, @argumentList, @afterArgumentList);
- $code .= " RefPtr<${implClassName}> impl = ${implClassName}::create(${argumentString});\n";
- $code .= " v8::Handle<v8::Object> wrapper = info.Holder();\n";
-
- if ($constructorRaisesException) {
- $code .= " if (exceptionState.throwIfNeeded())\n";
- $code .= " return;\n";
- }
-
- $code .= <<END;
-
- V8DOMWrapper::associateObjectWithWrapper<${v8ClassName}>(impl.release(), &${v8ClassName}::wrapperTypeInfo, wrapper, info.GetIsolate(), WrapperConfiguration::Dependent);
- v8SetReturnValue(info, wrapper);
-}
-
-END
- $implementation{nameSpaceInternal}->add($code);
-}
-
-# The Web IDL specification states that Interface objects for interfaces MUST have a property named
-# "length" that returns the length of the shortest argument list of the entries in the effective
-# overload set for constructors. In other words, use the lowest number of mandatory arguments among
-# all constructors.
-sub GetInterfaceLength
-{
- my $interface = shift;
-
- my $leastConstructorLength = 0;
- if ($interface->extendedAttributes->{"EventConstructor"}) {
- $leastConstructorLength = 1;
- } elsif ($interface->extendedAttributes->{"Constructor"} || $interface->extendedAttributes->{"CustomConstructor"}) {
- my @constructors = @{$interface->constructors};
- my @customConstructors = @{$interface->customConstructors};
- $leastConstructorLength = 255;
- foreach my $constructor (@constructors, @customConstructors) {
- my $constructorLength = GetFunctionLength($constructor);
- $leastConstructorLength = $constructorLength if ($constructorLength < $leastConstructorLength);
- }
- }
-
- return $leastConstructorLength;
-}
-
-sub GenerateConstructorCallback
-{
- my $interface = shift;
-
- my $implClassName = GetImplName($interface);
- my $v8ClassName = GetV8ClassName($interface);
- my $code = "";
- $code .= "void ${v8ClassName}::constructorCallback(const v8::FunctionCallbackInfo<v8::Value>& info)\n";
- $code .= "{\n";
- $code .= " TRACE_EVENT_SCOPED_SAMPLING_STATE(\"Blink\", \"DOMConstructor\");\n";
- $code .= GenerateFeatureObservation($interface->extendedAttributes->{"MeasureAs"});
- $code .= GenerateDeprecationNotification($interface->extendedAttributes->{"DeprecateAs"});
- $code .= GenerateConstructorHeader($interface->name);
- if (HasCustomConstructor($interface)) {
- $code .= " ${v8ClassName}::constructorCustom(info);\n";
- } else {
- $code .= " ${implClassName}V8Internal::constructor(info);\n";
- }
- $code .= "}\n\n";
- $implementation{nameSpaceWebCore}->add($code);
-}
-
-sub GenerateConstructor
-{
- my $interface = shift;
-
- if (@{$interface->constructors} == 1) {
- GenerateSingleConstructorCallback($interface, @{$interface->constructors}[0]);
- } else {
- foreach my $constructor (@{$interface->constructors}) {
- GenerateSingleConstructorCallback($interface, $constructor);
- }
- GenerateOverloadedConstructorCallback($interface);
- }
-}
-
-sub GenerateEventConstructor
-{
- my $interface = shift;
-
- my $interfaceName = $interface->name;
- my $implClassName = GetImplName($interface);
- my $v8ClassName = GetV8ClassName($interface);
-
- my $constructorRaisesException = $interface->extendedAttributes->{"RaisesException"} && $interface->extendedAttributes->{"RaisesException"} eq "Constructor";
-
- my @anyAttributeNames;
- foreach my $attribute (@{$interface->attributes}) {
- if ($attribute->type eq "any") {
- push(@anyAttributeNames, $attribute->name);
- }
- }
-
- AddToImplIncludes("bindings/v8/Dictionary.h");
- $implementation{nameSpaceInternal}->add(<<END);
-static void constructor(const v8::FunctionCallbackInfo<v8::Value>& info)
-{
- ExceptionState exceptionState(ExceptionState::ConstructionContext, \"${interfaceName}\", info.Holder(), info.GetIsolate());
- if (info.Length() < 1) {
- exceptionState.throwTypeError("An event name must be provided.");
- exceptionState.throwIfNeeded();
- return;
- }
-
- V8TRYCATCH_FOR_V8STRINGRESOURCE_VOID(V8StringResource<>, type, info[0]);
-END
-
- foreach my $attrName (@anyAttributeNames) {
- $implementation{nameSpaceInternal}->add(" v8::Local<v8::Value> ${attrName};\n");
- }
-
- $implementation{nameSpaceInternal}->add(<<END);
- ${implClassName}Init eventInit;
- if (info.Length() >= 2) {
- V8TRYCATCH_VOID(Dictionary, options, Dictionary(info[1], info.GetIsolate()));
- if (!initialize${implClassName}(eventInit, options, exceptionState)) {
- exceptionState.throwIfNeeded();
- return;
- }
-END
-
- # Store 'any'-typed properties on the wrapper to avoid leaking them between isolated worlds.
- foreach my $attrName (@anyAttributeNames) {
- $implementation{nameSpaceInternal}->add(<<END);
- options.get("${attrName}", ${attrName});
- if (!${attrName}.IsEmpty())
- info.Holder()->SetHiddenValue(V8HiddenPropertyName::${attrName}(info.GetIsolate()), ${attrName});
-END
- }
-
- $implementation{nameSpaceInternal}->add(<<END);
- }
-END
-
- my $exceptionStateArgument = "";
- if ($constructorRaisesException) {
- ${exceptionStateArgument} = ", exceptionState";
- }
-
- $implementation{nameSpaceInternal}->add(<<END);
- RefPtr<${implClassName}> event = ${implClassName}::create(type, eventInit${exceptionStateArgument});
-END
-
- if ($constructorRaisesException) {
- $implementation{nameSpaceInternal}->add(<<END);
- if (exceptionState.throwIfNeeded())
- return;
-END
- }
-
- if (@anyAttributeNames) {
- # Separate check to simplify Python code
- AddToImplIncludes("bindings/v8/SerializedScriptValue.h");
- }
- if (@anyAttributeNames && $interface->name ne 'ErrorEvent') {
- # If we're in an isolated world, create a SerializedScriptValue andi
- # store it in the event for later cloning if the property is accessed
- # from another world.
- # The main world case is handled lazily (in Custom code).
- #
- # We do not clone Error objects (exceptions), for 2 reasons:
- # 1) Errors carry a reference to the isolated world's global object,
- # and thus passing it around would cause leakage.
- # 2) Errors cannot be cloned (or serialized):
- # http://www.whatwg.org/specs/web-apps/current-work/multipage/common-dom-interfaces.html#safe-passing-of-structured-data
- $implementation{nameSpaceInternal}->add(" if (isolatedWorldForIsolate(info.GetIsolate())) {\n");
- foreach my $attrName (@anyAttributeNames) {
- my $setter = "setSerialized" . FirstLetterToUpperCase($attrName);
- $implementation{nameSpaceInternal}->add(<<END);
- if (!${attrName}.IsEmpty())
- event->${setter}(SerializedScriptValue::createAndSwallowExceptions(${attrName}, info.GetIsolate()));
-END
- }
- $implementation{nameSpaceInternal}->add(" }\n\n");
- }
-
- $implementation{nameSpaceInternal}->add(<<END);
- v8::Handle<v8::Object> wrapper = info.Holder();
- V8DOMWrapper::associateObjectWithWrapper<${v8ClassName}>(event.release(), &${v8ClassName}::wrapperTypeInfo, wrapper, info.GetIsolate(), WrapperConfiguration::Dependent);
- v8SetReturnValue(info, wrapper);
-}
-
-END
-
- my $code = "";
- $code .= <<END;
-bool initialize${implClassName}(${implClassName}Init& eventInit, const Dictionary& options, ExceptionState& exceptionState, const String& forEventName)
-{
- Dictionary::ConversionContext conversionContext(forEventName.isEmpty() ? String("${interfaceName}") : forEventName, "", exceptionState);
-END
-
- if ($interface->parent) {
- my $interfaceBase = $interface->parent;
- $code .= <<END;
- if (!initialize${interfaceBase}(eventInit, options, exceptionState, forEventName.isEmpty() ? String("${interfaceName}") : forEventName))
- return false;
-
-END
- }
-
- foreach my $attribute (@{$interface->attributes}) {
- if ($attribute->extendedAttributes->{"InitializedByEventConstructor"}) {
- if ($attribute->type ne "any") {
- my $attributeName = $attribute->name;
- my $attributeImplName = GetImplName($attribute);
-
- my $isNullable = $attribute->isNullable ? "true" : "false";
- my $dictionaryGetter = "options.convert(conversionContext.setConversionType(\"" . $attribute->type . "\", $isNullable), \"$attributeName\", eventInit.$attributeImplName)";
- my $deprecation = $attribute->extendedAttributes->{"DeprecateAs"};
- if ($deprecation) {
- $code .= " if ($dictionaryGetter) {\n";
- $code .= " if (options.hasProperty(\"$attributeName\"))\n";
- $code .= " " . GenerateDeprecationNotification($deprecation);
- $code .= " } else {\n";
- $code .= " return false;\n";
- $code .= " }\n";
- } else {
- $code .= " if (!$dictionaryGetter)\n";
- $code .= " return false;\n";
- }
- }
- }
- }
-
- $code .= <<END;
- return true;
-}
-
-END
- $implementation{nameSpaceWebCore}->add($code);
-}
-
-sub GenerateNamedConstructor
-{
- my $function = shift;
- my $interface = shift;
-
- my $interfaceName = $interface->name;
- my $implClassName = GetImplName($interface);
- my $v8ClassName = GetV8ClassName($interface);
- my $constructorRaisesException = $interface->extendedAttributes->{"RaisesException"} && $interface->extendedAttributes->{"RaisesException"} eq "Constructor";
- my $raisesExceptions = $function->extendedAttributes->{"RaisesException"} || $constructorRaisesException;
-
- my $maybeObserveFeature = GenerateFeatureObservation($function->extendedAttributes->{"MeasureAs"});
- my $maybeDeprecateFeature = GenerateDeprecationNotification($function->extendedAttributes->{"DeprecateAs"});
-
- my @beforeArgumentList;
- my @afterArgumentList;
-
- my $toActiveDOMObject = "0";
- if (InheritsExtendedAttribute($interface, "ActiveDOMObject")) {
- $toActiveDOMObject = "${v8ClassName}::toActiveDOMObject";
- }
-
- my $toEventTarget = "0";
- if (InheritsInterface($interface, "EventTarget")) {
- $toEventTarget = "${v8ClassName}::toEventTarget";
- }
-
- $implementation{nameSpaceWebCore}->add(<<END);
-const WrapperTypeInfo ${v8ClassName}Constructor::wrapperTypeInfo = { gin::kEmbedderBlink, ${v8ClassName}Constructor::domTemplate, ${v8ClassName}::derefObject, $toActiveDOMObject, $toEventTarget, 0, ${v8ClassName}::installPerContextEnabledMethods, 0, WrapperTypeObjectPrototype };
-
-END
-
- my $code = "";
- $code .= <<END;
-static void ${v8ClassName}ConstructorCallback(const v8::FunctionCallbackInfo<v8::Value>& info)
-{
-END
- $code .= $maybeObserveFeature if $maybeObserveFeature;
- $code .= $maybeDeprecateFeature if $maybeDeprecateFeature;
- $code .= GenerateConstructorHeader($function->extendedAttributes->{"NamedConstructor"});
- $code .= <<END;
- Document* document = currentDocument();
- ASSERT(document);
-
- // Make sure the document is added to the DOM Node map. Otherwise, the ${implClassName} instance
- // may end up being the only node in the map and get garbage-collected prematurely.
- toV8(document, info.Holder(), info.GetIsolate());
-
-END
-
- if ($raisesExceptions) {
- $code .= " ExceptionState exceptionState(ExceptionState::ConstructionContext, \"${interfaceName}\", info.Holder(), info.GetIsolate());\n";
- }
-
- my $hasExceptionState = $raisesExceptions;
- $code .= GenerateArgumentsCountCheck($function, $interface, $hasExceptionState);
-
- my ($parameterCheckString, $paramIndex, %replacements) = GenerateParametersCheck($function, $interface);
- $code .= $parameterCheckString;
-
- push(@beforeArgumentList, "*document");
-
- if ($constructorRaisesException) {
- push(@afterArgumentList, "exceptionState");
- }
-
- my @argumentList;
- my $index = 0;
- foreach my $parameter (@{$function->parameters}) {
- last if $index eq $paramIndex;
- if ($replacements{$parameter->name}) {
- push(@argumentList, $replacements{$parameter->name});
- } else {
- push(@argumentList, $parameter->name);
- }
- $index++;
- }
-
- my $argumentString = join(", ", @beforeArgumentList, @argumentList, @afterArgumentList);
- $code .= " RefPtr<${implClassName}> impl = ${implClassName}::createForJSConstructor(${argumentString});\n";
- $code .= " v8::Handle<v8::Object> wrapper = info.Holder();\n";
-
- if ($constructorRaisesException) {
- $code .= " if (exceptionState.throwIfNeeded())\n";
- $code .= " return;\n";
- }
-
- $code .= <<END;
-
- V8DOMWrapper::associateObjectWithWrapper<${v8ClassName}>(impl.release(), &${v8ClassName}Constructor::wrapperTypeInfo, wrapper, info.GetIsolate(), WrapperConfiguration::Dependent);
- v8SetReturnValue(info, wrapper);
-}
-
-END
- $implementation{nameSpaceWebCore}->add($code);
-
- $code = <<END;
-v8::Handle<v8::FunctionTemplate> ${v8ClassName}Constructor::domTemplate(v8::Isolate* isolate, WrapperWorldType currentWorldType)
-{
- // This is only for getting a unique pointer which we can pass to privateTemplate.
- static int privateTemplateUniqueKey;
- V8PerIsolateData* data = V8PerIsolateData::from(isolate);
- v8::Local<v8::FunctionTemplate> result = data->privateTemplateIfExists(currentWorldType, &privateTemplateUniqueKey);
- if (!result.IsEmpty())
- return result;
-
- TRACE_EVENT_SCOPED_SAMPLING_STATE("Blink", "BuildDOMTemplate");
- v8::EscapableHandleScope scope(isolate);
- result = v8::FunctionTemplate::New(isolate, ${v8ClassName}ConstructorCallback);
-
- v8::Local<v8::ObjectTemplate> instanceTemplate = result->InstanceTemplate();
- instanceTemplate->SetInternalFieldCount(${v8ClassName}::internalFieldCount);
- result->SetClassName(v8::String::NewFromUtf8(isolate, "${implClassName}", v8::String::kInternalizedString));
- result->Inherit(${v8ClassName}::domTemplate(isolate, currentWorldType));
- data->setPrivateTemplate(currentWorldType, &privateTemplateUniqueKey, result);
-
- return scope.Escape(result);
-}
-
-END
- $implementation{nameSpaceWebCore}->add($code);
-}
-
-sub GenerateConstructorHeader
-{
- my $constructorName = shift;
-
- AddToImplIncludes("bindings/v8/V8ObjectConstructor.h");
- my $content = <<END;
- if (!info.IsConstructCall()) {
- throwTypeError(ExceptionMessages::failedToConstruct("$constructorName", "Please use the 'new' operator, this DOM object constructor cannot be called as a function."), info.GetIsolate());
- return;
- }
-
- if (ConstructorMode::current() == ConstructorMode::WrapExistingObject) {
- v8SetReturnValue(info, info.Holder());
- return;
- }
-
-END
- return $content;
-}
-
-sub GenerateAttributeConfigurationArray
-{
- my $interface = shift;
- my $attributes = shift;
- my $exposeJSAccessors = shift;
-
- my $code = "";
- foreach my $attribute (@$attributes) {
- my $conditionalString = GenerateConditionalString($attribute);
- my $subCode = "";
- $subCode .= "#if ${conditionalString}\n" if $conditionalString;
- $subCode .= GenerateAttributeConfiguration($interface, $attribute, ",", "", $exposeJSAccessors);
- $subCode .= "#endif // ${conditionalString}\n" if $conditionalString;
- $code .= $subCode;
- }
- return $code;
-}
-
-sub GenerateAttributeConfigurationParameters
-{
- my $interface = shift;
- my $attribute = shift;
- my $attrName = $attribute->name;
- my $attrExt = $attribute->extendedAttributes;
- my $implClassName = GetImplName($interface);
-
- my @accessControlList;
- if (my $doNotCheckSecurity = $attrExt->{"DoNotCheckSecurity"}) {
- if ($doNotCheckSecurity eq "Getter") {
- push(@accessControlList, "v8::ALL_CAN_READ");
- } elsif ($doNotCheckSecurity eq "Setter") {
- push(@accessControlList, "v8::ALL_CAN_WRITE");
- } else {
- push(@accessControlList, "v8::ALL_CAN_READ");
- if (!IsReadonly($attribute)) {
- push(@accessControlList, "v8::ALL_CAN_WRITE");
- }
- }
- }
- if ($attrExt->{"Unforgeable"}) {
- push(@accessControlList, "v8::PROHIBITS_OVERWRITING");
- }
- @accessControlList = ("v8::DEFAULT") unless @accessControlList;
- my $accessControl = "static_cast<v8::AccessControl>(" . join(" | ", @accessControlList) . ")";
-
- my $customAccessor = HasCustomGetter($attrExt) || HasCustomSetter($attribute) || "";
- if ($customAccessor eq "VALUE_IS_MISSING") {
- # use the naming convension, interface + (capitalize) attr name
- $customAccessor = $implClassName . "::" . $attrName;
- }
-
- my $getter;
- my $setter;
- my $getterForMainWorld;
- my $setterForMainWorld;
-
- my $isConstructor = ($attribute->type =~ /Constructor$/);
-
- # Check attributes.
- # As per Web IDL specification, constructor properties on the ECMAScript global object should be
- # configurable and should not be enumerable.
- my @propAttributeList;
- if ($attrExt->{"NotEnumerable"} || $isConstructor) {
- push(@propAttributeList, "v8::DontEnum");
- }
- if ($attrExt->{"Unforgeable"} && !$isConstructor) {
- push(@propAttributeList, "v8::DontDelete");
- }
- @propAttributeList = ("v8::None") unless @propAttributeList;
- my $propAttribute = join(" | ", @propAttributeList);
-
- my $onProto = "0 /* on instance */";
- my $data = "0"; # no data
-
- # Constructor
- if ($isConstructor) {
- my $constructorType = $attribute->type;
- $constructorType =~ s/Constructor$//;
-
- # For NamedConstructors we do not generate a header file. The code for the NamedConstructor
- # gets generated when we generate the code for its interface.
- if ($constructorType !~ /Constructor$/) {
- AddToImplIncludes("V8${constructorType}.h");
- }
- $data = "const_cast<WrapperTypeInfo*>(&V8${constructorType}::wrapperTypeInfo)";
- $getter = "${implClassName}V8Internal::${implClassName}ConstructorGetter";
- $setter = "${implClassName}V8Internal::${implClassName}ReplaceableAttributeSetterCallback";
- $getterForMainWorld = "0";
- $setterForMainWorld = "0";
- } else {
- # Default Getter and Setter
- $getter = "${implClassName}V8Internal::${attrName}AttributeGetterCallback";
- $setter = "${implClassName}V8Internal::${attrName}AttributeSetterCallback";
- $getterForMainWorld = "${getter}ForMainWorld";
- $setterForMainWorld = "${setter}ForMainWorld";
-
- if (!HasCustomSetter($attribute) && !$attrExt->{"PutForwards"} && $attrExt->{"Replaceable"}) {
- $setter = "${implClassName}V8Internal::${implClassName}ReplaceableAttributeSetterCallback";
- $setterForMainWorld = "0";
- }
- }
-
- # Read only attributes
- if (IsReadonly($attribute)) {
- $setter = "0";
- $setterForMainWorld = "0";
- }
-
- # An accessor can be installed on the prototype
- if ($attrExt->{"OnPrototype"}) {
- $onProto = "1 /* on prototype */";
- }
-
- if (!$attrExt->{"PerWorldBindings"}) {
- $getterForMainWorld = "0";
- $setterForMainWorld = "0";
- }
-
- return ($attrName, $getter, $setter, $getterForMainWorld, $setterForMainWorld, $data, $accessControl, "static_cast<v8::PropertyAttribute>($propAttribute)", $onProto);
-}
-
-sub GenerateAttributeConfiguration
-{
- my $interface = shift;
- my $attribute = shift;
- my $delimiter = shift;
- my $indent = shift;
- my $exposeJSAccessors = shift;
-
- my $code = "";
-
- my ($attrName, $getter, $setter, $getterForMainWorld, $setterForMainWorld, $data, $accessControl, $propAttribute, $onProto) = GenerateAttributeConfigurationParameters($interface, $attribute, $exposeJSAccessors);
- if ($exposeJSAccessors) {
- $code .= $indent . " {\"$attrName\", $getter, $setter, $getterForMainWorld, $setterForMainWorld, $data, $accessControl, $propAttribute}" . $delimiter . "\n";
- } else {
- $code .= $indent . " {\"$attrName\", $getter, $setter, $getterForMainWorld, $setterForMainWorld, $data, $accessControl, $propAttribute, $onProto}" . $delimiter . "\n";
- }
- return $code;
-}
-
-sub GenerateStaticAttribute
-{
- my $interface = shift;
- my $attribute = shift;
- my $attrExt = $attribute->extendedAttributes;
- my $code = "";
-
- my ($attrName, $getter, $setter, $getterForMainWorld, $setterForMainWorld, $data, $accessControl, $propAttribute, $onProto) = GenerateAttributeConfigurationParameters($interface, $attribute);
-
- die "Static attributes do not support optimized getters or setters for the main world" if $getterForMainWorld || $setterForMainWorld;
-
- my $conditionalString = GenerateConditionalString($attribute);
-
- $code .= "#if ${conditionalString}\n" if $conditionalString;
- $code .= " functionTemplate->SetNativeDataProperty(v8::String::NewFromUtf8(isolate, \"$attrName\", v8::String::kInternalizedString), $getter, $setter, v8::External::New(isolate, $data), $propAttribute, v8::Handle<v8::AccessorSignature>(), $accessControl);\n";
- $code .= "#endif // ${conditionalString}\n" if $conditionalString;
-
- return $code;
-}
-
-sub IsStandardFunction
-{
- my $interface = shift;
- my $function = shift;
-
- my $interfaceName = $interface->name;
- my $attrExt = $function->extendedAttributes;
- return 0 if $attrExt->{"Unforgeable"};
- return 0 if $function->isStatic;
- return 0 if $attrExt->{"RuntimeEnabled"};
- return 0 if $attrExt->{"PerContextEnabled"};
- return 0 if RequiresCustomSignature($function);
- return 0 if $attrExt->{"DoNotCheckSignature"};
- return 0 if ($attrExt->{"DoNotCheckSecurity"} && ($interface->extendedAttributes->{"CheckSecurity"} || $interfaceName eq "Window"));
- return 0 if $attrExt->{"NotEnumerable"};
- return 0 if $attrExt->{"ReadOnly"};
- return 1;
-}
-
-sub GenerateNonStandardFunction
-{
- my $interface = shift;
- my $function = shift;
- my $code = "";
-
- my $implClassName = GetImplName($interface);
- my $attrExt = $function->extendedAttributes;
- my $name = $function->name;
-
- my $property_attributes = "v8::DontDelete";
- if ($attrExt->{"NotEnumerable"}) {
- $property_attributes .= " | v8::DontEnum";
- }
- if ($attrExt->{"ReadOnly"}) {
- $property_attributes .= " | v8::ReadOnly";
- }
-
- my $commentInfo = "Function '$name' (Extended Attributes: '" . join(' ', keys(%{$attrExt})) . "')";
-
- my $template = "prototypeTemplate";
- if ($attrExt->{"Unforgeable"}) {
- $template = "instanceTemplate";
- }
- if ($function->isStatic) {
- $template = "functionTemplate";
- }
-
- my $conditional4 = ""; # 4 space indent context
- my $conditional8 = ""; # 8 space indent context
- if ($attrExt->{"RuntimeEnabled"}) {
- # Only call Set()/SetAccessor() if this method should be enabled
- my $runtimeEnabledFunction = GetRuntimeEnabledFunctionName($function);
- $conditional4 = "if (${runtimeEnabledFunction}())\n ";
- }
- if ($attrExt->{"PerContextEnabled"}) {
- # Only call Set()/SetAccessor() if this method should be enabled
- my $contextEnabledFunction = GetContextEnabledFunctionName($function);
- $conditional4 = "if (${contextEnabledFunction}(impl->document()))\n ";
- }
- $conditional8 = $conditional4 . " " if $conditional4 ne "";
-
- if ($interface->extendedAttributes->{"CheckSecurity"} && $attrExt->{"DoNotCheckSecurity"}) {
- my $setter = $attrExt->{"ReadOnly"} ? "0" : "${implClassName}V8Internal::${implClassName}OriginSafeMethodSetterCallback";
- # Functions that are marked DoNotCheckSecurity are always readable but if they are changed
- # and then accessed on a different domain we do not return the underlying value but instead
- # return a new copy of the original function. This is achieved by storing the changed value
- # as hidden property.
- if ($function->extendedAttributes->{"PerWorldBindings"}) {
- $code .= <<END;
- if (currentWorldType == MainWorld) {
- ${conditional8}$template->SetAccessor(v8::String::NewFromUtf8(isolate, "$name", v8::String::kInternalizedString), ${implClassName}V8Internal::${name}OriginSafeMethodGetterCallbackForMainWorld, ${setter}, v8Undefined(), v8::ALL_CAN_READ, static_cast<v8::PropertyAttribute>($property_attributes));
- } else {
- ${conditional8}$template->SetAccessor(v8::String::NewFromUtf8(isolate, "$name", v8::String::kInternalizedString), ${implClassName}V8Internal::${name}OriginSafeMethodGetterCallback, ${setter}, v8Undefined(), v8::ALL_CAN_READ, static_cast<v8::PropertyAttribute>($property_attributes));
- }
-END
- } else {
- $code .= " ${conditional4}$template->SetAccessor(v8::String::NewFromUtf8(isolate, \"$name\", v8::String::kInternalizedString), ${implClassName}V8Internal::${name}OriginSafeMethodGetterCallback, ${setter}, v8Undefined(), v8::ALL_CAN_READ, static_cast<v8::PropertyAttribute>($property_attributes));\n";
- }
-
- return $code;
- }
-
- my $signature = "defaultSignature";
- if ($attrExt->{"DoNotCheckSignature"} || $function->isStatic) {
- $signature = "v8::Local<v8::Signature>()";
- }
-
- my $conditionalString = GenerateConditionalString($function);
- $code .= "#if ${conditionalString}\n" if $conditionalString;
- if (RequiresCustomSignature($function)) {
- $signature = "${name}Signature";
- $code .= "\n // Custom Signature '$name'\n" . CreateCustomSignature($function);
- }
-
- if ($property_attributes eq "v8::DontDelete") {
- $property_attributes = "";
- } else {
- $property_attributes = ", static_cast<v8::PropertyAttribute>($property_attributes)";
- }
-
- if ($template eq "prototypeTemplate" && $conditional4 eq "" && $signature eq "defaultSignature" && $property_attributes eq "") {
- die "This shouldn't happen: Class '$implClassName' $commentInfo\n";
- }
-
- my $functionLength = GetFunctionLength($function);
-
- if ($function->extendedAttributes->{"PerWorldBindings"}) {
- $code .= " if (currentWorldType == MainWorld) {\n";
- $code .= " ${conditional8}$template->Set(v8::String::NewFromUtf8(isolate, \"$name\", v8::String::kInternalizedString), v8::FunctionTemplate::New(isolate, ${implClassName}V8Internal::${name}MethodCallbackForMainWorld, v8Undefined(), ${signature}, $functionLength)$property_attributes);\n";
- $code .= " } else {\n";
- $code .= " ${conditional8}$template->Set(v8::String::NewFromUtf8(isolate, \"$name\", v8::String::kInternalizedString), v8::FunctionTemplate::New(isolate, ${implClassName}V8Internal::${name}MethodCallback, v8Undefined(), ${signature}, $functionLength)$property_attributes);\n";
- $code .= " }\n";
- } else {
- $code .= " ${conditional4}$template->Set(v8::String::NewFromUtf8(isolate, \"$name\", v8::String::kInternalizedString), v8::FunctionTemplate::New(isolate, ${implClassName}V8Internal::${name}MethodCallback, v8Undefined(), ${signature}, $functionLength)$property_attributes);\n";
- }
- $code .= "#endif // ${conditionalString}\n" if $conditionalString;
- return $code;
-}
-
-sub GenerateIsNullExpression
-{
- my $type = shift;
- my $variableName = shift;
- if (IsUnionType($type)) {
- my $types = $type->unionMemberTypes;
- my @expression = ();
- for my $i (0 .. scalar(@$types)-1) {
- my $unionMemberType = $types->[$i];
- my $unionMemberVariable = $variableName . $i;
- my $isNull = GenerateIsNullExpression($unionMemberType, $unionMemberVariable);
- push @expression, $isNull;
- }
- return join " && ", @expression;
- }
- if (IsRefPtrType($type)) {
- return "!${variableName}";
- } elsif ($type eq "DOMString") {
- return "${variableName}.isNull()";
- } elsif ($type eq "Promise") {
- return "${variableName}.isNull()";
- } else {
- return "";
- }
-}
-
-sub GenerateIfElseStatement
-{
- my $type = shift;
- my $outputVariableName = shift;
- my $conditions = shift;
- my $statements = shift;
-
- my $code = "";
- if (@$conditions == 1) {
- $code .= " ${type} ${outputVariableName} = " . $statements->[0] . "\n";
- } else {
- $code .= " ${type} ${outputVariableName};\n";
- for my $i (0 .. @$conditions - 1) {
- my $token = "else if";
- $token = "if" if $i == 0;
- $token = "else" if $i == @$conditions - 1;
- $code .= " ${token}";
- $code .= " (" . $conditions->[$i] . ")" if $conditions->[$i];
- $code .= "\n";
- $code .= " ${outputVariableName} = " . $statements->[$i] . "\n";
- }
- }
- return $code;
-}
-
-sub GenerateImplementationIndexedPropertyAccessors
-{
- my $interface = shift;
- my $interfaceName = $interface->name;
- my $implClassName = GetImplName($interface);
- my $v8ClassName = GetV8ClassName($interface);
-
- my $indexedGetterFunction = GetIndexedGetterFunction($interface);
- if ($indexedGetterFunction) {
- my $hasCustomIndexedGetter = $indexedGetterFunction->extendedAttributes->{"Custom"};
- if (!$hasCustomIndexedGetter) {
- GenerateImplementationIndexedPropertyGetter($interface, $indexedGetterFunction);
- }
- GenerateImplementationIndexedPropertyGetterCallback($interface, $hasCustomIndexedGetter);
- }
-
- my $indexedSetterFunction = GetIndexedSetterFunction($interface);
- if ($indexedSetterFunction) {
- my $hasCustomIndexedSetter = $indexedSetterFunction->extendedAttributes->{"Custom"};
- if (!$hasCustomIndexedSetter) {
- GenerateImplementationIndexedPropertySetter($interface, $indexedSetterFunction);
- }
- GenerateImplementationIndexedPropertySetterCallback($interface, $hasCustomIndexedSetter);
- }
-
- my $indexedDeleterFunction = GetIndexedDeleterFunction($interface);
- if ($indexedDeleterFunction) {
- my $hasCustomIndexedDeleter = $indexedDeleterFunction->extendedAttributes->{"Custom"};
- if (!$hasCustomIndexedDeleter) {
- GenerateImplementationIndexedPropertyDeleter($interface, $indexedDeleterFunction);
- }
- GenerateImplementationIndexedPropertyDeleterCallback($interface, $hasCustomIndexedDeleter);
- }
-
- my $indexedEnumeratorFunction = $indexedGetterFunction;
- $indexedEnumeratorFunction = 0 if $indexedGetterFunction && $indexedGetterFunction->extendedAttributes->{"NotEnumerable"};
-
- my $indexedQueryFunction = 0;
- # If there is an enumerator, there MUST be a query method to properly communicate property attributes.
- my $hasQuery = $indexedQueryFunction || $indexedEnumeratorFunction;
-
- my $setOn = "Instance";
-
- # V8 has access-check callback API (see ObjectTemplate::SetAccessCheckCallbacks) and it's used on Window
- # instead of deleters or enumerators. In addition, the getter should be set on prototype template, to
- # get implementation straight out of the Window prototype regardless of what prototype is actually set
- # on the object.
- if ($interfaceName eq "Window") {
- $setOn = "Prototype";
- }
-
- my $code = "";
- if ($indexedGetterFunction || $indexedSetterFunction || $indexedDeleterFunction || $indexedEnumeratorFunction || $hasQuery) {
- $code .= " functionTemplate->${setOn}Template()->SetIndexedPropertyHandler(${implClassName}V8Internal::indexedPropertyGetterCallback";
- $code .= $indexedSetterFunction ? ", ${implClassName}V8Internal::indexedPropertySetterCallback" : ", 0";
- $code .= ", 0"; # IndexedPropertyQuery -- not being used at the moment.
- $code .= $indexedDeleterFunction ? ", ${implClassName}V8Internal::indexedPropertyDeleterCallback" : ", 0";
- $code .= $indexedEnumeratorFunction ? ", indexedPropertyEnumerator<${implClassName}>" : ", 0";
- $code .= ");\n";
- }
-
- return $code;
-}
-
-sub GenerateImplementationIndexedPropertyGetter
-{
- my $interface = shift;
- my $indexedGetterFunction = shift;
- my $implClassName = GetImplName($interface);
- my $v8ClassName = GetV8ClassName($interface);
- my $methodName = GetImplName($indexedGetterFunction);
-
- my $returnType = $indexedGetterFunction->type;
- my $nativeType = GetNativeType($returnType);
- my $nativeValue = "element";
- $nativeValue .= ".release()" if (IsRefPtrType($returnType));
- my $isNull = GenerateIsNullExpression($returnType, "element");
- my $returnJSValueCode = NativeToJSValue($indexedGetterFunction->type, $indexedGetterFunction->extendedAttributes, $nativeValue, " ", "", "info.GetIsolate()", "info", "collection", "", "return");
- my $raisesExceptions = $indexedGetterFunction->extendedAttributes->{"RaisesException"};
- my $methodCallCode = GenerateMethodCall($returnType, "element", "collection->${methodName}", "index", $raisesExceptions);
- my $getterCode = "static void indexedPropertyGetter(uint32_t index, const v8::PropertyCallbackInfo<v8::Value>& info)\n";
- $getterCode .= "{\n";
- $getterCode .= " ASSERT(V8DOMWrapper::maybeDOMWrapper(info.Holder()));\n";
- $getterCode .= " ${implClassName}* collection = ${v8ClassName}::toNative(info.Holder());\n";
- if ($raisesExceptions) {
- $getterCode .= " ExceptionState exceptionState(info.Holder(), info.GetIsolate());\n";
- }
- $getterCode .= $methodCallCode . "\n";
- if ($raisesExceptions) {
- $getterCode .= " if (exceptionState.throwIfNeeded())\n";
- $getterCode .= " return;\n";
- }
- if (IsUnionType($returnType)) {
- $getterCode .= "${returnJSValueCode}\n";
- $getterCode .= " return;\n";
- } else {
- $getterCode .= " if (${isNull})\n";
- $getterCode .= " return;\n";
- $getterCode .= $returnJSValueCode . "\n";
- }
- $getterCode .= "}\n\n";
- $implementation{nameSpaceInternal}->add($getterCode);
-}
-
-sub GenerateImplementationIndexedPropertyGetterCallback
-{
- my $interface = shift;
- my $hasCustom = shift;
- my $implClassName = GetImplName($interface);
- my $v8ClassName = GetV8ClassName($interface);
-
- my $code = "static void indexedPropertyGetterCallback(uint32_t index, const v8::PropertyCallbackInfo<v8::Value>& info)\n";
- $code .= "{\n";
- $code .= " TRACE_EVENT_SET_SAMPLING_STATE(\"Blink\", \"DOMIndexedProperty\");\n";
- if ($hasCustom) {
- $code .= " ${v8ClassName}::indexedPropertyGetterCustom(index, info);\n";
- } else {
- $code .= " ${implClassName}V8Internal::indexedPropertyGetter(index, info);\n";
- }
- $code .= " TRACE_EVENT_SET_SAMPLING_STATE(\"V8\", \"Execution\");\n";
- $code .= "}\n\n";
- $implementation{nameSpaceInternal}->add($code);
-}
-
-sub GenerateImplementationIndexedPropertySetterCallback
-{
- my $interface = shift;
- my $hasCustom = shift;
- my $implClassName = GetImplName($interface);
- my $v8ClassName = GetV8ClassName($interface);
-
- my $code = "static void indexedPropertySetterCallback(uint32_t index, v8::Local<v8::Value> jsValue, const v8::PropertyCallbackInfo<v8::Value>& info)\n";
- $code .= "{\n";
- $code .= " TRACE_EVENT_SET_SAMPLING_STATE(\"Blink\", \"DOMIndexedProperty\");\n";
- if ($hasCustom) {
- $code .= " ${v8ClassName}::indexedPropertySetterCustom(index, jsValue, info);\n";
- } else {
- $code .= " ${implClassName}V8Internal::indexedPropertySetter(index, jsValue, info);\n";
- }
- $code .= " TRACE_EVENT_SET_SAMPLING_STATE(\"V8\", \"Execution\");\n";
- $code .= "}\n\n";
- $implementation{nameSpaceInternal}->add($code);
-}
-
-sub GenerateImplementationIndexedPropertyDeleterCallback
-{
- my $interface = shift;
- my $hasCustom = shift;
- my $implClassName = GetImplName($interface);
- my $v8ClassName = GetV8ClassName($interface);
-
- my $code = "static void indexedPropertyDeleterCallback(uint32_t index, const v8::PropertyCallbackInfo<v8::Boolean>& info)\n";
- $code .= "{\n";
- $code .= " TRACE_EVENT_SET_SAMPLING_STATE(\"Blink\", \"DOMIndexedProperty\");\n";
- if ($hasCustom) {
- $code .= " ${v8ClassName}::indexedPropertyDeleterCustom(index, info);\n";
- } else {
- $code .= " ${implClassName}V8Internal::indexedPropertyDeleter(index, info);\n";
- }
- $code .= " TRACE_EVENT_SET_SAMPLING_STATE(\"V8\", \"Execution\");\n";
- $code .= "}\n\n";
- $implementation{nameSpaceInternal}->add($code);
-}
-
-sub GenerateImplementationIndexedPropertySetter
-{
- my $interface = shift;
- my $indexedSetterFunction = shift;
- my $implClassName = GetImplName($interface);
- my $v8ClassName = GetV8ClassName($interface);
- my $methodName = GetImplName($indexedSetterFunction);
-
- my $type = $indexedSetterFunction->parameters->[1]->type;
- my $raisesExceptions = $indexedSetterFunction->extendedAttributes->{"RaisesException"};
- my $treatNullAs = $indexedSetterFunction->parameters->[1]->extendedAttributes->{"TreatNullAs"};
- my $treatUndefinedAs = $indexedSetterFunction->parameters->[1]->extendedAttributes->{"TreatUndefinedAs"};
- my $asSetterValue = 0;
-
- my $code = "static void indexedPropertySetter(uint32_t index, v8::Local<v8::Value> jsValue, const v8::PropertyCallbackInfo<v8::Value>& info)\n";
- $code .= "{\n";
- $code .= " ${implClassName}* collection = ${v8ClassName}::toNative(info.Holder());\n";
- $code .= JSValueToNativeStatement($indexedSetterFunction->parameters->[1]->type, $indexedSetterFunction->extendedAttributes, $asSetterValue, "jsValue", "propertyValue", " ", "info.GetIsolate()");
-
- my $extraArguments = "";
- if ($raisesExceptions) {
- $code .= " ExceptionState exceptionState(info.Holder(), info.GetIsolate());\n";
- $extraArguments = ", exceptionState";
- }
- my @conditions = ();
- my @statements = ();
- if ($treatNullAs && $treatNullAs ne "NullString") {
- push @conditions, "jsValue->IsNull()";
- push @statements, "collection->${treatNullAs}(index$extraArguments);";
- }
- if ($treatUndefinedAs && $treatUndefinedAs ne "NullString") {
- push @conditions, "jsValue->IsUndefined()";
- push @statements, "collection->${treatUndefinedAs}(index$extraArguments);";
- }
- push @conditions, "";
- push @statements, "collection->${methodName}(index, propertyValue$extraArguments);";
- $code .= GenerateIfElseStatement("bool", "result", \@conditions, \@statements);
-
- if ($raisesExceptions) {
- $code .= " if (exceptionState.throwIfNeeded())\n";
- $code .= " return;\n";
- }
- $code .= " if (!result)\n";
- $code .= " return;\n";
- $code .= " v8SetReturnValue(info, jsValue);\n";
- $code .= "}\n\n";
- $implementation{nameSpaceInternal}->add($code);
-}
-
-sub GenerateImplementationNamedPropertyAccessors
-{
- my $interface = shift;
-
- my $interfaceName = $interface->name;
- my $implClassName = GetImplName($interface);
- my $v8ClassName = GetV8ClassName($interface);
-
- my $namedGetterFunction = GetNamedGetterFunction($interface);
- if ($namedGetterFunction) {
- my $hasCustomNamedGetter = $namedGetterFunction->extendedAttributes->{"Custom"};
- if (!$hasCustomNamedGetter) {
- GenerateImplementationNamedPropertyGetter($interface, $namedGetterFunction);
- }
- GenerateImplementationNamedPropertyGetterCallback($interface, $hasCustomNamedGetter);
- }
-
- my $namedSetterFunction = GetNamedSetterFunction($interface);
- if ($namedSetterFunction) {
- my $hasCustomNamedSetter = $namedSetterFunction->extendedAttributes->{"Custom"};
- if (!$hasCustomNamedSetter) {
- GenerateImplementationNamedPropertySetter($interface, $namedSetterFunction);
- }
- GenerateImplementationNamedPropertySetterCallback($interface, $hasCustomNamedSetter);
- }
-
- my $namedDeleterFunction = GetNamedDeleterFunction($interface);
- if ($namedDeleterFunction) {
- my $hasCustomNamedDeleter = $namedDeleterFunction->extendedAttributes->{"Custom"};
- if (!$hasCustomNamedDeleter) {
- GenerateImplementationNamedPropertyDeleter($interface, $namedDeleterFunction);
- }
- GenerateImplementationNamedPropertyDeleterCallback($interface, $hasCustomNamedDeleter);
- }
-
- my $namedEnumeratorFunction = $namedGetterFunction && !$namedGetterFunction->extendedAttributes->{"NotEnumerable"};
- if ($namedEnumeratorFunction) {
- my $hasCustomNamedEnumerator = $namedGetterFunction->extendedAttributes->{"CustomEnumerateProperty"};
- if (!$hasCustomNamedEnumerator) {
- GenerateImplementationNamedPropertyEnumerator($interface);
- GenerateImplementationNamedPropertyQuery($interface);
- }
- GenerateImplementationNamedPropertyEnumeratorCallback($interface, $hasCustomNamedEnumerator);
- GenerateImplementationNamedPropertyQueryCallback($interface, $hasCustomNamedEnumerator);
- }
-
- my $subCode = "";
- if ($namedGetterFunction || $namedSetterFunction || $namedDeleterFunction || $namedEnumeratorFunction) {
- my $setOn = "Instance";
-
- # V8 has access-check callback API (see ObjectTemplate::SetAccessCheckCallbacks) and it's used on Window
- # instead of deleters or enumerators. In addition, the getter should be set on prototype template, to
- # get implementation straight out of the Window prototype regardless of what prototype is actually set
- # on the object.
- if ($interfaceName eq "Window") {
- $setOn = "Prototype";
- }
-
- $subCode .= " functionTemplate->${setOn}Template()->SetNamedPropertyHandler(";
- $subCode .= $namedGetterFunction ? "${implClassName}V8Internal::namedPropertyGetterCallback, " : "0, ";
- $subCode .= $namedSetterFunction ? "${implClassName}V8Internal::namedPropertySetterCallback, " : "0, ";
- $subCode .= $namedEnumeratorFunction ? "${implClassName}V8Internal::namedPropertyQueryCallback, " : "0, ";
- $subCode .= $namedDeleterFunction ? "${implClassName}V8Internal::namedPropertyDeleterCallback, " : "0, ";
- $subCode .= $namedEnumeratorFunction ? "${implClassName}V8Internal::namedPropertyEnumeratorCallback" : "0";
- $subCode .= ");\n";
- }
-
- return $subCode;
-}
-
-sub GenerateImplementationNamedPropertyGetterCallback
-{
- my $interface = shift;
- my $hasCustom = shift;
- my $implClassName = GetImplName($interface);
- my $v8ClassName = GetV8ClassName($interface);
-
- my $code = "static void namedPropertyGetterCallback(v8::Local<v8::String> name, const v8::PropertyCallbackInfo<v8::Value>& info)\n";
- $code .= "{\n";
- $code .= " TRACE_EVENT_SET_SAMPLING_STATE(\"Blink\", \"DOMNamedProperty\");\n";
- if ($hasCustom) {
- $code .= " ${v8ClassName}::namedPropertyGetterCustom(name, info);\n";
- } else {
- $code .= " ${implClassName}V8Internal::namedPropertyGetter(name, info);\n";
- }
- $code .= " TRACE_EVENT_SET_SAMPLING_STATE(\"V8\", \"Execution\");\n";
- $code .= "}\n\n";
- $implementation{nameSpaceInternal}->add($code);
-}
-
-sub GenerateImplementationNamedPropertySetterCallback
-{
- my $interface = shift;
- my $hasCustom = shift;
- my $implClassName = GetImplName($interface);
- my $v8ClassName = GetV8ClassName($interface);
-
- my $code = "static void namedPropertySetterCallback(v8::Local<v8::String> name, v8::Local<v8::Value> jsValue, const v8::PropertyCallbackInfo<v8::Value>& info)\n";
- $code .= "{\n";
- $code .= " TRACE_EVENT_SET_SAMPLING_STATE(\"Blink\", \"DOMNamedProperty\");\n";
- if ($hasCustom) {
- $code .= " ${v8ClassName}::namedPropertySetterCustom(name, jsValue, info);\n";
- } else {
- $code .= " ${implClassName}V8Internal::namedPropertySetter(name, jsValue, info);\n";
- }
- $code .= " TRACE_EVENT_SET_SAMPLING_STATE(\"V8\", \"Execution\");\n";
- $code .= "}\n\n";
- $implementation{nameSpaceInternal}->add($code);
-}
-
-sub GenerateImplementationNamedPropertyDeleterCallback
-{
- my $interface = shift;
- my $hasCustom = shift;
- my $implClassName = GetImplName($interface);
- my $v8ClassName = GetV8ClassName($interface);
-
- my $code = "static void namedPropertyDeleterCallback(v8::Local<v8::String> name, const v8::PropertyCallbackInfo<v8::Boolean>& info)\n";
- $code .= "{\n";
- $code .= " TRACE_EVENT_SET_SAMPLING_STATE(\"Blink\", \"DOMNamedProperty\");\n";
- if ($hasCustom) {
- $code .= " ${v8ClassName}::namedPropertyDeleterCustom(name, info);\n";
- } else {
- $code .= " ${implClassName}V8Internal::namedPropertyDeleter(name, info);\n";
- }
- $code .= " TRACE_EVENT_SET_SAMPLING_STATE(\"V8\", \"Execution\");\n";
- $code .= "}\n\n";
- $implementation{nameSpaceInternal}->add($code);
-}
-
-sub GenerateImplementationNamedPropertyEnumeratorCallback
-{
- my $interface = shift;
- my $hasCustom = shift;
- my $implClassName = GetImplName($interface);
- my $v8ClassName = GetV8ClassName($interface);
-
- my $code = "static void namedPropertyEnumeratorCallback(const v8::PropertyCallbackInfo<v8::Array>& info)\n";
- $code .= "{\n";
- $code .= " TRACE_EVENT_SET_SAMPLING_STATE(\"Blink\", \"DOMNamedProperty\");\n";
- if ($hasCustom) {
- $code .= " ${v8ClassName}::namedPropertyEnumeratorCustom(info);\n";
- } else {
- $code .= " ${implClassName}V8Internal::namedPropertyEnumerator(info);\n";
- }
- $code .= " TRACE_EVENT_SET_SAMPLING_STATE(\"V8\", \"Execution\");\n";
- $code .= "}\n\n";
- $implementation{nameSpaceInternal}->add($code);
-}
-
-sub GenerateImplementationNamedPropertyQueryCallback
-{
- my $interface = shift;
- my $hasCustom = shift;
- my $implClassName = GetImplName($interface);
- my $v8ClassName = GetV8ClassName($interface);
-
- my $code = "static void namedPropertyQueryCallback(v8::Local<v8::String> name, const v8::PropertyCallbackInfo<v8::Integer>& info)\n";
- $code .= "{\n";
- $code .= " TRACE_EVENT_SET_SAMPLING_STATE(\"Blink\", \"DOMNamedProperty\");\n";
- if ($hasCustom) {
- $code .= " ${v8ClassName}::namedPropertyQueryCustom(name, info);\n";
- } else {
- $code .= " ${implClassName}V8Internal::namedPropertyQuery(name, info);\n";
- }
- $code .= " TRACE_EVENT_SET_SAMPLING_STATE(\"V8\", \"Execution\");\n";
- $code .= "}\n\n";
- $implementation{nameSpaceInternal}->add($code);
-}
-
-sub GenerateMethodCall
-{
- my $returnType = shift; # string or UnionType
- my $returnName = shift;
- my $functionExpression = shift;
- my $firstArgument = shift;
- my $raisesExceptions = shift;
-
- my @arguments = ();
- push @arguments, $firstArgument;
- if ($raisesExceptions) {
- push @arguments, "exceptionState";
- }
-
- if (IsUnionType($returnType)) {
- my $code = "";
- my @extraArguments = ();
- for my $i (0..scalar(@{$returnType->unionMemberTypes})-1) {
- my $unionMemberType = $returnType->unionMemberTypes->[$i];
- my $nativeType = GetNativeType($unionMemberType);
- my $unionMemberVariable = $returnName . $i;
- my $unionMemberEnabledVariable = $returnName . $i . "Enabled";
- $code .= " bool ${unionMemberEnabledVariable} = false;\n";
- $code .= " ${nativeType} ${unionMemberVariable};\n";
- push @extraArguments, $unionMemberEnabledVariable;
- push @extraArguments, $unionMemberVariable;
- }
- push @arguments, @extraArguments;
- $code .= " ${functionExpression}(" . (join ", ", @arguments) . ");";
- return $code;
- } else {
- my $nativeType = GetNativeType($returnType);
- return " ${nativeType} element = ${functionExpression}(" . (join ", ", @arguments) . ");"
- }
-}
-
-sub GenerateImplementationNamedPropertyGetter
-{
- my $interface = shift;
- my $namedGetterFunction = shift;
- my $implClassName = GetImplName($interface);
- my $v8ClassName = GetV8ClassName($interface);
- my $methodName = GetImplName($namedGetterFunction);
-
- my $returnType = $namedGetterFunction->type;
- my $isNull = GenerateIsNullExpression($returnType, "element");
- my $nativeValue = "element";
- $nativeValue .= ".release()" if (IsRefPtrType($returnType));
- my $returnJSValueCode = NativeToJSValue($namedGetterFunction->type, $namedGetterFunction->extendedAttributes, $nativeValue, " ", "", "info.GetIsolate()", "info", "collection", "", "return");
- my $raisesExceptions = $namedGetterFunction->extendedAttributes->{"RaisesException"};
- my $methodCallCode = GenerateMethodCall($returnType, "element", "collection->${methodName}", "propertyName", $raisesExceptions);
-
- my $code = "static void namedPropertyGetter(v8::Local<v8::String> name, const v8::PropertyCallbackInfo<v8::Value>& info)\n";
- $code .= "{\n";
- if (!$namedGetterFunction->extendedAttributes->{"OverrideBuiltins"}) {
- $code .= " if (!info.Holder()->GetRealNamedPropertyInPrototypeChain(name).IsEmpty())\n";
- $code .= " return;\n";
- $code .= " if (info.Holder()->HasRealNamedCallbackProperty(name))\n";
- $code .= " return;\n";
- $code .= " if (info.Holder()->HasRealNamedProperty(name))\n";
- $code .= " return;\n";
- }
- $code .= "\n";
- $code .= " ASSERT(V8DOMWrapper::maybeDOMWrapper(info.Holder()));\n";
- $code .= " ${implClassName}* collection = ${v8ClassName}::toNative(info.Holder());\n";
- $code .= " AtomicString propertyName = toCoreAtomicString(name);\n";
- if ($raisesExceptions) {
- $code .= " ExceptionState exceptionState(info.Holder(), info.GetIsolate());\n";
- }
- $code .= $methodCallCode . "\n";
- if ($raisesExceptions) {
- $code .= " if (exceptionState.throwIfNeeded())\n";
- $code .= " return;\n";
- }
- if (IsUnionType($returnType)) {
- $code .= "${returnJSValueCode}\n";
- $code .= " return;\n";
- } else {
- $code .= " if (${isNull})\n";
- $code .= " return;\n";
- $code .= $returnJSValueCode . "\n";
- }
- $code .= "}\n\n";
- $implementation{nameSpaceInternal}->add($code);
-}
-
-sub GenerateImplementationNamedPropertySetter
-{
- my $interface = shift;
- my $namedSetterFunction = shift;
- my $implClassName = GetImplName($interface);
- my $v8ClassName = GetV8ClassName($interface);
- my $methodName = GetImplName($namedSetterFunction);
-
- my $raisesExceptions = $namedSetterFunction->extendedAttributes->{"RaisesException"};
- my $treatNullAs = $namedSetterFunction->parameters->[1]->extendedAttributes->{"TreatNullAs"};
- my $treatUndefinedAs = $namedSetterFunction->parameters->[1]->extendedAttributes->{"TreatUndefinedAs"};
- my $asSetterValue = 0;
-
- my $code = "static void namedPropertySetter(v8::Local<v8::String> name, v8::Local<v8::Value> jsValue, const v8::PropertyCallbackInfo<v8::Value>& info)\n";
- $code .= "{\n";
- if (!$namedSetterFunction->extendedAttributes->{"OverrideBuiltins"}) {
- $code .= " if (!info.Holder()->GetRealNamedPropertyInPrototypeChain(name).IsEmpty())\n";
- $code .= " return;\n";
- $code .= " if (info.Holder()->HasRealNamedCallbackProperty(name))\n";
- $code .= " return;\n";
- $code .= " if (info.Holder()->HasRealNamedProperty(name))\n";
- $code .= " return;\n";
- }
- $code .= " ${implClassName}* collection = ${v8ClassName}::toNative(info.Holder());\n";
- $code .= JSValueToNativeStatement($namedSetterFunction->parameters->[0]->type, $namedSetterFunction->extendedAttributes, $asSetterValue, "name", "propertyName", " ", "info.GetIsolate()");
- $code .= JSValueToNativeStatement($namedSetterFunction->parameters->[1]->type, $namedSetterFunction->extendedAttributes, $asSetterValue, "jsValue", "propertyValue", " ", "info.GetIsolate()");
- my $extraArguments = "";
- if ($raisesExceptions) {
- $code .= " ExceptionState exceptionState(info.Holder(), info.GetIsolate());\n";
- $extraArguments = ", exceptionState";
- }
-
- my @conditions = ();
- my @statements = ();
- if ($treatNullAs && $treatNullAs ne "NullString") {
- push @conditions, "jsValue->IsNull()";
- push @statements, "collection->${treatNullAs}(propertyName$extraArguments);";
- }
- if ($treatUndefinedAs && $treatUndefinedAs ne "NullString") {
- push @conditions, "jsValue->IsUndefined()";
- push @statements, "collection->${treatUndefinedAs}(propertyName$extraArguments);";
- }
- push @conditions, "";
- push @statements, "collection->${methodName}(propertyName, propertyValue$extraArguments);";
- $code .= GenerateIfElseStatement("bool", "result", \@conditions, \@statements);
-
- $code .= " if (!result)\n";
- $code .= " return;\n";
- if ($raisesExceptions) {
- $code .= " if (exceptionState.throwIfNeeded())\n";
- $code .= " return;\n";
- }
- $code .= " v8SetReturnValue(info, jsValue);\n";
- $code .= "}\n\n";
- $implementation{nameSpaceInternal}->add($code);
-}
-
-sub GenerateImplementationIndexedPropertyDeleter
-{
- my $interface = shift;
- my $indexedDeleterFunction = shift;
- my $implClassName = GetImplName($interface);
- my $v8ClassName = GetV8ClassName($interface);
- my $methodName = GetImplName($indexedDeleterFunction);
-
- my $raisesExceptions = $indexedDeleterFunction->extendedAttributes->{"RaisesException"};
-
- my $code = "static void indexedPropertyDeleter(unsigned index, const v8::PropertyCallbackInfo<v8::Boolean>& info)\n";
- $code .= "{\n";
- $code .= " ${implClassName}* collection = ${v8ClassName}::toNative(info.Holder());\n";
- my $extraArguments = "";
- if ($raisesExceptions) {
- $code .= " ExceptionState exceptionState(info.Holder(), info.GetIsolate());\n";
- $extraArguments = ", exceptionState";
- }
- $code .= " bool result = collection->${methodName}(index$extraArguments);\n";
- if ($raisesExceptions) {
- $code .= " if (exceptionState.throwIfNeeded())\n";
- $code .= " return;\n";
- }
- $code .= " return v8SetReturnValueBool(info, result);\n";
- $code .= "}\n\n";
- $implementation{nameSpaceInternal}->add($code);
-}
-
-sub GenerateImplementationNamedPropertyDeleter
-{
- my $interface = shift;
- my $namedDeleterFunction = shift;
- my $implClassName = GetImplName($interface);
- my $v8ClassName = GetV8ClassName($interface);
- my $methodName = GetImplName($namedDeleterFunction);
-
- my $raisesExceptions = $namedDeleterFunction->extendedAttributes->{"RaisesException"};
-
- my $code = "static void namedPropertyDeleter(v8::Local<v8::String> name, const v8::PropertyCallbackInfo<v8::Boolean>& info)\n";
- $code .= "{\n";
- $code .= " ${implClassName}* collection = ${v8ClassName}::toNative(info.Holder());\n";
- $code .= " AtomicString propertyName = toCoreAtomicString(name);\n";
- my $extraArguments = "";
- if ($raisesExceptions) {
- $code .= " ExceptionState exceptionState(info.Holder(), info.GetIsolate());\n";
- $extraArguments = ", exceptionState";
- }
- $code .= " bool result = collection->${methodName}(propertyName$extraArguments);\n";
- if ($raisesExceptions) {
- $code .= " if (exceptionState.throwIfNeeded())\n";
- $code .= " return;\n";
- }
- $code .= " return v8SetReturnValueBool(info, result);\n";
- $code .= "}\n\n";
- $implementation{nameSpaceInternal}->add($code);
-}
-
-sub GenerateImplementationNamedPropertyEnumerator
-{
- my $interface = shift;
- my $implClassName = GetImplName($interface);
- my $v8ClassName = GetV8ClassName($interface);
-
- $implementation{nameSpaceInternal}->add(<<END);
-static void namedPropertyEnumerator(const v8::PropertyCallbackInfo<v8::Array>& info)
-{
- ExceptionState exceptionState(info.Holder(), info.GetIsolate());
- ${implClassName}* collection = ${v8ClassName}::toNative(info.Holder());
- Vector<String> names;
- collection->namedPropertyEnumerator(names, exceptionState);
- if (exceptionState.throwIfNeeded())
- return;
- v8::Handle<v8::Array> v8names = v8::Array::New(info.GetIsolate(), names.size());
- for (size_t i = 0; i < names.size(); ++i)
- v8names->Set(v8::Integer::New(info.GetIsolate(), i), v8String(info.GetIsolate(), names[i]));
- v8SetReturnValue(info, v8names);
-}
-
-END
-}
-
-sub GenerateImplementationNamedPropertyQuery
-{
- my $interface = shift;
- my $implClassName = GetImplName($interface);
- my $v8ClassName = GetV8ClassName($interface);
-
- $implementation{nameSpaceInternal}->add(<<END);
-static void namedPropertyQuery(v8::Local<v8::String> name, const v8::PropertyCallbackInfo<v8::Integer>& info)
-{
- ${implClassName}* collection = ${v8ClassName}::toNative(info.Holder());
- AtomicString propertyName = toCoreAtomicString(name);
- ExceptionState exceptionState(info.Holder(), info.GetIsolate());
- bool result = collection->namedPropertyQuery(propertyName, exceptionState);
- if (exceptionState.throwIfNeeded())
- return;
- if (!result)
- return;
- v8SetReturnValueInt(info, v8::None);
-}
-
-END
-}
-
-sub GenerateImplementationLegacyCallAsFunction
-{
- my $interface = shift;
- my $code = "";
-
- my $v8ClassName = GetV8ClassName($interface);
-
- if (ExtendedAttributeContains($interface->extendedAttributes->{"Custom"}, "LegacyCallAsFunction")) {
- $code .= " functionTemplate->InstanceTemplate()->SetCallAsFunctionHandler(${v8ClassName}::legacyCallCustom);\n";
- }
- return $code;
-}
-
-sub GenerateImplementationMarkAsUndetectable
-{
- my $interface = shift;
- my $code = "";
-
- # Needed for legacy support of document.all
- if ($interface->name eq "HTMLAllCollection")
- {
- $code .= " functionTemplate->InstanceTemplate()->MarkAsUndetectable();\n";
- }
- return $code;
-}
-
-sub GenerateImplementation
-{
- my $object = shift;
- my $interface = shift;
- my $interfaceName = $interface->name;
- my $implClassName = GetImplName($interface);
- my $v8ClassName = GetV8ClassName($interface);
- my $nativeType = GetNativeTypeForConversions($interface);
-
- AddToImplIncludes("RuntimeEnabledFeatures.h");
- AddToImplIncludes("bindings/v8/ExceptionState.h");
- AddToImplIncludes("core/dom/ContextFeatures.h");
- AddToImplIncludes("core/dom/Document.h");
- AddToImplIncludes("platform/TraceEvent.h");
-
- AddIncludesForType($interfaceName);
- if ($interface->extendedAttributes->{"CheckSecurity"}) {
- AddToImplIncludes("bindings/v8/BindingSecurity.h");
- }
-
- my $toActiveDOMObject = InheritsExtendedAttribute($interface, "ActiveDOMObject") ? "${v8ClassName}::toActiveDOMObject" : "0";
- my $toEventTarget = InheritsInterface($interface, "EventTarget") ? "${v8ClassName}::toEventTarget" : "0";
- my $visitDOMWrapper = NeedsVisitDOMWrapper($interface) ? "${v8ClassName}::visitDOMWrapper" : "0";
-
- # Find the super descriptor.
- my $parentClass = "";
- my $parentClassTemplate = "";
- if ($interface->parent) {
- my $parent = $interface->parent;
- $parentClass = "V8" . $parent;
- $parentClassTemplate = $parentClass . "::domTemplate(isolate, currentWorldType)";
- }
-
- my $parentClassInfo = $parentClass ? "&${parentClass}::wrapperTypeInfo" : "0";
- my $WrapperTypePrototype = $interface->isException ? "WrapperTypeErrorPrototype" : "WrapperTypeObjectPrototype";
-
- if (!IsSVGTypeNeedingTearOff($interfaceName)) {
- my $code = <<END;
-static void initializeScriptWrappableForInterface(${implClassName}* object)
-{
- if (ScriptWrappable::wrapperCanBeStoredInObject(object))
- ScriptWrappable::setTypeInfoInObject(object, &${v8ClassName}::wrapperTypeInfo);
- else
- ASSERT_NOT_REACHED();
-}
-
-} // namespace WebCore
-
-// In ScriptWrappable::init, the use of a local function declaration has an issue on Windows:
-// the local declaration does not pick up the surrounding namespace. Therefore, we provide this function
-// in the global namespace.
-// (More info on the MSVC bug here: http://connect.microsoft.com/VisualStudio/feedback/details/664619/the-namespace-of-local-function-declarations-in-c)
-END
-
- if (GetNamespaceForInterface($interface) eq "WebCore") {
- $code .= "void webCoreInitializeScriptWrappableForInterface(WebCore::${implClassName}* object)\n";
- } else {
- $code .= "void webCoreInitializeScriptWrappableForInterface(${implClassName}* object)\n";
- }
-
- $code .= <<END;
-{
- WebCore::initializeScriptWrappableForInterface(object);
-}
-
-namespace WebCore {
-END
- $implementation{nameSpaceWebCore}->addHeader($code);
- }
-
- my $code = "const WrapperTypeInfo ${v8ClassName}::wrapperTypeInfo = { gin::kEmbedderBlink, ${v8ClassName}::domTemplate, ${v8ClassName}::derefObject, $toActiveDOMObject, $toEventTarget, ";
- $code .= "$visitDOMWrapper, ${v8ClassName}::installPerContextEnabledMethods, $parentClassInfo, $WrapperTypePrototype };\n";
- $implementation{nameSpaceWebCore}->addHeader($code);
-
- $implementation{nameSpaceInternal}->add("template <typename T> void V8_USE(T) { }\n\n");
-
- my $hasConstructors = 0;
- my $hasReplaceable = 0;
-
- # Generate property accessors for attributes.
- for (my $index = 0; $index < @{$interface->attributes}; $index++) {
- my $attribute = @{$interface->attributes}[$index];
- my $attrType = $attribute->type;
- my $attrExt = $attribute->extendedAttributes;
-
- # Generate special code for the constructor attributes.
- if ($attrType =~ /Constructor$/) {
- if (!HasCustomGetter($attrExt)) {
- $hasConstructors = 1;
- }
- next;
- }
-
- AddIncludesForType($attrType);
-
- if ($attrType eq "EventHandler" && $interfaceName eq "Window") {
- $attrExt->{"OnPrototype"} = 1;
- }
-
- if ($attrType eq "SerializedScriptValue") {
- AddToImplIncludes("bindings/v8/SerializedScriptValue.h");
- }
-
- my $isReplaceable = 0;
- if (!HasCustomSetter($attribute) && !$attrExt->{"PutForwards"} && $attrExt->{"Replaceable"}) {
- $isReplaceable = 1;
- $hasReplaceable = 1;
- }
-
- my $exposeJSAccessors = $attrExt->{"ExposeJSAccessors"};
- my @worldSuffixes = ("");
- if ($attrExt->{"PerWorldBindings"}) {
- push(@worldSuffixes, "ForMainWorld");
- }
- foreach my $worldSuffix (@worldSuffixes) {
- GenerateNormalAttributeGetter($attribute, $interface, $worldSuffix, $exposeJSAccessors);
- GenerateNormalAttributeGetterCallback($attribute, $interface, $worldSuffix, $exposeJSAccessors);
- if (!$isReplaceable && !IsReadonly($attribute)) {
- GenerateNormalAttributeSetter($attribute, $interface, $worldSuffix, $exposeJSAccessors);
- GenerateNormalAttributeSetterCallback($attribute, $interface, $worldSuffix, $exposeJSAccessors);
- }
- }
- }
-
- if ($hasConstructors) {
- GenerateConstructorGetter($interface);
- }
-
- if ($hasConstructors || $hasReplaceable) {
- GenerateReplaceableAttributeSetter($interface);
- GenerateReplaceableAttributeSetterCallback($interface);
- }
-
- if (NeedsVisitDOMWrapper($interface)) {
- GenerateVisitDOMWrapper($interface);
- }
-
- if ($interface->extendedAttributes->{"CheckSecurity"} && $interface->name ne "Window") {
- GenerateSecurityCheckFunctions($interface);
- }
-
- my @perContextEnabledFunctions;
- my @normalFunctions;
- my $needsDomainSafeFunctionSetter = 0;
- # Generate methods for functions.
- foreach my $function (@{$interface->functions}) {
- next if $function->name eq "";
- my @worldSuffixes = ("");
- if ($function->extendedAttributes->{"PerWorldBindings"}) {
- push(@worldSuffixes, "ForMainWorld");
- }
- foreach my $worldSuffix (@worldSuffixes) {
- GenerateFunction($function, $interface, $worldSuffix);
- if ($function->{overloadIndex} == @{$function->{overloads}}) {
- if ($function->{overloadIndex} > 1) {
- GenerateOverloadedFunction($function, $interface, $worldSuffix);
- }
- GenerateFunctionCallback($function, $interface, $worldSuffix);
- }
-
- # If the function does not need domain security check, we need to
- # generate an access getter that returns different function objects
- # for different calling context.
- if ($interface->extendedAttributes->{"CheckSecurity"} && $function->extendedAttributes->{"DoNotCheckSecurity"} && (!HasCustomMethod($function->extendedAttributes) || $function->{overloadIndex} == 1)) {
- GenerateDomainSafeFunctionGetter($function, $interface, $worldSuffix);
- if (!$function->extendedAttributes->{"ReadOnly"}) {
- $needsDomainSafeFunctionSetter = 1;
- }
- }
- }
-
- # Separate out functions that are enabled per context so we can process them specially.
- if ($function->extendedAttributes->{"PerContextEnabled"}) {
- push(@perContextEnabledFunctions, $function);
- } else {
- push(@normalFunctions, $function);
- }
- }
-
- if ($needsDomainSafeFunctionSetter) {
- GenerateDomainSafeFunctionSetter($interface);
- }
-
- # Attributes
- my $attributes = $interface->attributes;
-
- # For the Window interface we partition the attributes into the
- # ones that disallows shadowing and the rest.
- my @disallowsShadowing;
- # Also separate out attributes that are enabled at runtime so we can process them specially.
- my @runtimeEnabledAttributes;
- my @perContextEnabledAttributes;
- my @normalAttributes;
- my @normalAccessors;
- my @staticAttributes;
- foreach my $attribute (@$attributes) {
-
- if ($attribute->isStatic) {
- push(@staticAttributes, $attribute);
- } elsif ($interfaceName eq "Window" && $attribute->extendedAttributes->{"Unforgeable"}) {
- push(@disallowsShadowing, $attribute);
- } elsif ($attribute->extendedAttributes->{"PerContextEnabled"}) {
- push(@perContextEnabledAttributes, $attribute);
- } elsif ($attribute->extendedAttributes->{"RuntimeEnabled"}) {
- push(@runtimeEnabledAttributes, $attribute);
- } elsif ($attribute->extendedAttributes->{"ExposeJSAccessors"}) {
- push(@normalAccessors, $attribute);
- } else {
- push(@normalAttributes, $attribute);
- }
- }
- AddToImplIncludes("bindings/v8/V8DOMConfiguration.h");
- # Put the attributes that disallow shadowing on the shadow object.
- if (@disallowsShadowing) {
- my $code = "";
- $code .= "static const V8DOMConfiguration::AttributeConfiguration shadowAttributes[] = {\n";
- $code .= GenerateAttributeConfigurationArray($interface, \@disallowsShadowing);
- $code .= "};\n\n";
- $implementation{nameSpaceWebCore}->add($code);
- }
-
- my $hasAttributes = 0;
- if (@normalAttributes) {
- $hasAttributes = 1;
- my $code = "";
- $code .= "static const V8DOMConfiguration::AttributeConfiguration ${v8ClassName}Attributes[] = {\n";
- $code .= GenerateAttributeConfigurationArray($interface, \@normalAttributes);
- $code .= "};\n\n";
- $implementation{nameSpaceWebCore}->add($code);
- }
-
- my $hasAccessors = 0;
- if (@normalAccessors) {
- $hasAccessors = 1;
- my $code = "";
- $code .= "static const V8DOMConfiguration::AccessorConfiguration ${v8ClassName}Accessors[] = {\n";
- $code .= GenerateAttributeConfigurationArray($interface, \@normalAccessors, "accessor");
- $code .= "};\n\n";
- $implementation{nameSpaceWebCore}->add($code);
- }
-
- # Setup table of standard callback functions
- my $hasFunctions = 0;
- $code = "";
- foreach my $function (@normalFunctions) {
- # Only one table entry is needed for overloaded functions:
- next if $function->{overloadIndex} > 1;
- # Don't put any nonstandard functions into this table:
- next if !IsStandardFunction($interface, $function);
- next if $function->name eq "";
- if (!$hasFunctions) {
- $hasFunctions = 1;
- $code .= "static const V8DOMConfiguration::MethodConfiguration ${v8ClassName}Methods[] = {\n";
- }
- my $name = $function->name;
- my $methodForMainWorld = "0";
- if ($function->extendedAttributes->{"PerWorldBindings"}) {
- $methodForMainWorld = "${implClassName}V8Internal::${name}MethodCallbackForMainWorld";
- }
- my $functionLength = GetFunctionLength($function);
- my $conditionalString = GenerateConditionalString($function);
- $code .= "#if ${conditionalString}\n" if $conditionalString;
- $code .= <<END;
- {"$name", ${implClassName}V8Internal::${name}MethodCallback, ${methodForMainWorld}, ${functionLength}},
-END
- $code .= "#endif // ${conditionalString}\n" if $conditionalString;
- }
- $code .= "};\n\n" if $hasFunctions;
- $implementation{nameSpaceWebCore}->add($code);
-
- my $hasConstants = 0;
- if (@{$interface->constants}) {
- $hasConstants = 1;
- }
-
- if (!HasCustomConstructor($interface)) {
- if ($interface->extendedAttributes->{"NamedConstructor"}) {
- GenerateNamedConstructor(@{$interface->constructors}[0], $interface);
- } elsif ($interface->extendedAttributes->{"Constructor"}) {
- GenerateConstructor($interface);
- } elsif ($interface->extendedAttributes->{"EventConstructor"}) {
- GenerateEventConstructor($interface);
- }
- }
- if (IsConstructable($interface)) {
- GenerateConstructorCallback($interface);
- }
-
- my $accessCheck = "";
- if ($interface->extendedAttributes->{"CheckSecurity"} && $interfaceName ne "Window") {
- $accessCheck = "instanceTemplate->SetAccessCheckCallbacks(${implClassName}V8Internal::namedSecurityCheck, ${implClassName}V8Internal::indexedSecurityCheck, v8::External::New(isolate, const_cast<WrapperTypeInfo*>(&${v8ClassName}::wrapperTypeInfo)));";
- }
-
- # For the Window interface, generate the shadow object template
- # configuration method.
- if ($interfaceName eq "Window") {
- $implementation{nameSpaceWebCore}->add(<<END);
-static void ConfigureShadowObjectTemplate(v8::Handle<v8::ObjectTemplate> templ, v8::Isolate* isolate, WrapperWorldType currentWorldType)
-{
- V8DOMConfiguration::installAttributes(templ, v8::Handle<v8::ObjectTemplate>(), shadowAttributes, WTF_ARRAY_LENGTH(shadowAttributes), isolate, currentWorldType);
-
- // Install a security handler with V8.
- templ->SetAccessCheckCallbacks(V8Window::namedSecurityCheckCustom, V8Window::indexedSecurityCheckCustom, v8::External::New(isolate, const_cast<WrapperTypeInfo*>(&V8Window::wrapperTypeInfo)));
- templ->SetInternalFieldCount(V8Window::internalFieldCount);
-}
-END
- }
-
- if (!$parentClassTemplate) {
- $parentClassTemplate = "v8::Local<v8::FunctionTemplate>()";
- }
-
- # Generate the template configuration method
- $code = <<END;
-static v8::Handle<v8::FunctionTemplate> Configure${v8ClassName}Template(v8::Handle<v8::FunctionTemplate> functionTemplate, v8::Isolate* isolate, WrapperWorldType currentWorldType)
-{
- functionTemplate->ReadOnlyPrototype();
-
- v8::Local<v8::Signature> defaultSignature;
-END
-
- # Define constants, attributes, accessors and operations.
- my $runtimeEnabledIndent = "";
- if ($interface->extendedAttributes->{"RuntimeEnabled"}) {
- my $runtimeEnabledFunction = GetRuntimeEnabledFunctionName($interface);
- $runtimeEnabledIndent = " ";
- $code .= <<END;
- if (!${runtimeEnabledFunction}())
- defaultSignature = V8DOMConfiguration::installDOMClassTemplate(functionTemplate, \"\", $parentClassTemplate, ${v8ClassName}::internalFieldCount, 0, 0, 0, 0, 0, 0, isolate, currentWorldType);
- else
-END
- }
- $code .= $runtimeEnabledIndent . " defaultSignature = V8DOMConfiguration::installDOMClassTemplate(functionTemplate, \"${interfaceName}\", $parentClassTemplate, ${v8ClassName}::internalFieldCount,\n";
- $code .= $runtimeEnabledIndent . " " . ($hasAttributes ? "${v8ClassName}Attributes, WTF_ARRAY_LENGTH(${v8ClassName}Attributes),\n" : "0, 0,\n");
- $code .= $runtimeEnabledIndent . " " . ($hasAccessors ? "${v8ClassName}Accessors, WTF_ARRAY_LENGTH(${v8ClassName}Accessors),\n" : "0, 0,\n");
- $code .= $runtimeEnabledIndent . " " . ($hasFunctions ? "${v8ClassName}Methods, WTF_ARRAY_LENGTH(${v8ClassName}Methods),\n" : "0, 0,\n");
- $code .= $runtimeEnabledIndent . " isolate, currentWorldType);\n";
-
- if (IsConstructable($interface)) {
- $code .= " functionTemplate->SetCallHandler(${v8ClassName}::constructorCallback);\n";
- my $interfaceLength = GetInterfaceLength($interface);
- $code .= " functionTemplate->SetLength(${interfaceLength});\n";
- }
-
- $code .= <<END;
- v8::Local<v8::ObjectTemplate> ALLOW_UNUSED instanceTemplate = functionTemplate->InstanceTemplate();
- v8::Local<v8::ObjectTemplate> ALLOW_UNUSED prototypeTemplate = functionTemplate->PrototypeTemplate();
-END
-
- if ($accessCheck) {
- $code .= " $accessCheck\n";
- }
-
- # Define runtime enabled attributes.
- foreach my $runtimeEnabledAttribute (@runtimeEnabledAttributes) {
- my $runtimeEnabledFunction = GetRuntimeEnabledFunctionName($runtimeEnabledAttribute);
- my $conditionalString = GenerateConditionalString($runtimeEnabledAttribute);
- $code .= "#if ${conditionalString}\n" if $conditionalString;
- $code .= " if (${runtimeEnabledFunction}()) {\n";
- $code .= " static const V8DOMConfiguration::AttributeConfiguration attributeConfiguration =\\\n";
- $code .= GenerateAttributeConfiguration($interface, $runtimeEnabledAttribute, ";", " ");
- $code .= <<END;
- V8DOMConfiguration::installAttribute(instanceTemplate, prototypeTemplate, attributeConfiguration, isolate, currentWorldType);
- }
-END
- $code .= "#endif // ${conditionalString}\n" if $conditionalString;
- }
-
- my @runtimeEnabledConstants;
- if ($hasConstants) {
- # Define constants.
- $code .= " static const V8DOMConfiguration::ConstantConfiguration ${v8ClassName}Constants[] = {\n";
- foreach my $constant (@{$interface->constants}) {
- my $name = $constant->name;
- my $value = $constant->value;
- my $attrExt = $constant->extendedAttributes;
- my $implementedBy = $attrExt->{"ImplementedBy"};
- if ($implementedBy) {
- my $implementedByImplName = GetImplNameFromImplementedBy($implementedBy);
- AddToImplIncludes(HeaderFilesForInterface($implementedBy, $implementedByImplName));
- }
- if ($attrExt->{"RuntimeEnabled"}) {
- push(@runtimeEnabledConstants, $constant);
- } else {
- $code .= <<END;
- {"${name}", $value},
-END
- }
- }
- $code .= " };\n";
- $code .= <<END;
- V8DOMConfiguration::installConstants(functionTemplate, prototypeTemplate, ${v8ClassName}Constants, WTF_ARRAY_LENGTH(${v8ClassName}Constants), isolate);
-END
- # Define runtime enabled constants.
- foreach my $runtimeEnabledConstant (@runtimeEnabledConstants) {
- my $runtimeEnabledFunction = GetRuntimeEnabledFunctionName($runtimeEnabledConstant);
- my $name = $runtimeEnabledConstant->name;
- my $value = $runtimeEnabledConstant->value;
- $code .= " if (${runtimeEnabledFunction}()) {\n";
- $code .= <<END;
- static const V8DOMConfiguration::ConstantConfiguration constantConfiguration = {"${name}", static_cast<signed int>(${value})};
- V8DOMConfiguration::installConstants(functionTemplate, prototypeTemplate, &constantConfiguration, 1, isolate);
-END
- $code .= " }\n";
- }
- $code .= join "", GenerateCompileTimeCheckForEnumsIfNeeded($interface);
- }
-
- $code .= GenerateImplementationIndexedPropertyAccessors($interface);
- $code .= GenerateImplementationNamedPropertyAccessors($interface);
- $code .= GenerateImplementationLegacyCallAsFunction($interface);
- $code .= GenerateImplementationMarkAsUndetectable($interface);
-
- # Define operations.
- my $total_functions = 0;
- foreach my $function (@normalFunctions) {
- # Only one accessor is needed for overloaded operations.
- next if $function->{overloadIndex} > 1;
- next if $function->name eq "";
-
- $total_functions++;
- next if IsStandardFunction($interface, $function);
- $code .= GenerateNonStandardFunction($interface, $function);
- }
-
- # Define static attributes.
- foreach my $attribute (@staticAttributes) {
- $code .= GenerateStaticAttribute($interface, $attribute);
- }
-
- # Special cases
- if ($interfaceName eq "Window") {
- $code .= <<END;
-
- prototypeTemplate->SetInternalFieldCount(V8Window::internalFieldCount);
- functionTemplate->SetHiddenPrototype(true);
- instanceTemplate->SetInternalFieldCount(V8Window::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.
- instanceTemplate->SetAccessCheckCallbacks(V8Window::namedSecurityCheckCustom, V8Window::indexedSecurityCheckCustom, v8::External::New(isolate, const_cast<WrapperTypeInfo*>(&V8Window::wrapperTypeInfo)), false);
-END
- }
- if ($interfaceName eq "HTMLDocument" or $interfaceName eq "DedicatedWorkerGlobalScope" or $interfaceName eq "SharedWorkerGlobalScope" or $interfaceName eq "ServiceWorkerGlobalScope") {
- $code .= <<END;
- functionTemplate->SetHiddenPrototype(true);
-END
- }
-
- $code .= <<END;
-
- // Custom toString template
- functionTemplate->Set(v8::String::NewFromUtf8(isolate, "toString", v8::String::kInternalizedString), V8PerIsolateData::current()->toStringTemplate());
- return functionTemplate;
-}
-
-END
- $implementation{nameSpaceWebCore}->add($code);
-
- $implementation{nameSpaceWebCore}->add(<<END);
-v8::Handle<v8::FunctionTemplate> ${v8ClassName}::domTemplate(v8::Isolate* isolate, WrapperWorldType currentWorldType)
-{
- V8PerIsolateData* data = V8PerIsolateData::from(isolate);
- V8PerIsolateData::TemplateMap::iterator result = data->templateMap(currentWorldType).find(&wrapperTypeInfo);
- if (result != data->templateMap(currentWorldType).end())
- return result->value.newLocal(isolate);
-
- TRACE_EVENT_SCOPED_SAMPLING_STATE("Blink", "BuildDOMTemplate");
- v8::EscapableHandleScope handleScope(isolate);
- v8::Local<v8::FunctionTemplate> templ =
- Configure${v8ClassName}Template(data->rawDOMTemplate(&wrapperTypeInfo, currentWorldType), isolate, currentWorldType);
- data->templateMap(currentWorldType).add(&wrapperTypeInfo, UnsafePersistent<v8::FunctionTemplate>(isolate, templ));
- return handleScope.Escape(templ);
-}
-
-END
- $implementation{nameSpaceWebCore}->add(<<END);
-bool ${v8ClassName}::hasInstance(v8::Handle<v8::Value> jsValue, v8::Isolate* isolate, WrapperWorldType currentWorldType)
-{
- return V8PerIsolateData::from(isolate)->hasInstance(&wrapperTypeInfo, jsValue, currentWorldType);
-}
-
-END
- $implementation{nameSpaceWebCore}->add(<<END);
-bool ${v8ClassName}::hasInstanceInAnyWorld(v8::Handle<v8::Value> jsValue, v8::Isolate* isolate)
-{
- return V8PerIsolateData::from(isolate)->hasInstance(&wrapperTypeInfo, jsValue, MainWorld)
- || V8PerIsolateData::from(isolate)->hasInstance(&wrapperTypeInfo, jsValue, IsolatedWorld)
- || V8PerIsolateData::from(isolate)->hasInstance(&wrapperTypeInfo, jsValue, WorkerWorld);
-}
-
-END
-
- if (@perContextEnabledAttributes) {
- my $code = "";
- $code .= <<END;
-void ${v8ClassName}::installPerContextEnabledProperties(v8::Handle<v8::Object> instanceTemplate, ${nativeType}* impl, v8::Isolate* isolate)
-{
- v8::Local<v8::Object> prototypeTemplate = v8::Local<v8::Object>::Cast(instanceTemplate->GetPrototype());
-END
-
- # Define per-context enabled attributes.
- foreach my $perContextEnabledAttribute (@perContextEnabledAttributes) {
- my $contextEnabledFunction = GetContextEnabledFunctionName($perContextEnabledAttribute);
- $code .= " if (${contextEnabledFunction}(impl->document())) {\n";
-
- $code .= " static const V8DOMConfiguration::AttributeConfiguration attributeConfiguration =\\\n";
- $code .= GenerateAttributeConfiguration($interface, $perContextEnabledAttribute, ";", " ");
- $code .= <<END;
- V8DOMConfiguration::installAttribute(instanceTemplate, prototypeTemplate, attributeConfiguration, isolate);
-END
- $code .= " }\n";
- }
- $code .= <<END;
-}
-
-END
- $implementation{nameSpaceWebCore}->add($code);
- }
-
- if (@perContextEnabledFunctions) {
- my $code = "";
- $code .= <<END;
-void ${v8ClassName}::installPerContextEnabledMethods(v8::Handle<v8::Object> prototypeTemplate, v8::Isolate* isolate)
-{
-END
- # Define per-context enabled operations.
- $code .= <<END;
- v8::Local<v8::Signature> defaultSignature = v8::Signature::New(isolate, domTemplate(isolate, worldType(isolate)));
-
- ExecutionContext* context = toExecutionContext(prototypeTemplate->CreationContext());
-END
-
- foreach my $perContextEnabledFunction (@perContextEnabledFunctions) {
- my $contextEnabledFunction = GetContextEnabledFunctionName($perContextEnabledFunction);
- my $functionLength = GetFunctionLength($perContextEnabledFunction);
- my $conditionalString = GenerateConditionalString($perContextEnabledFunction);
- $code .= "\n#if ${conditionalString}\n" if $conditionalString;
- $code .= " if (context && context->isDocument() && ${contextEnabledFunction}(toDocument(context)))\n";
- my $name = $perContextEnabledFunction->name;
- $code .= <<END;
- prototypeTemplate->Set(v8::String::NewFromUtf8(isolate, "${name}", v8::String::kInternalizedString), v8::FunctionTemplate::New(isolate, ${implClassName}V8Internal::${name}MethodCallback, v8Undefined(), defaultSignature, $functionLength)->GetFunction());
-END
- $code .= "#endif // ${conditionalString}\n" if $conditionalString;
- }
-
- $code .= <<END;
-}
-
-END
- $implementation{nameSpaceWebCore}->add($code);
- }
-
- if (InheritsExtendedAttribute($interface, "ActiveDOMObject")) {
- $implementation{nameSpaceWebCore}->add(<<END);
-ActiveDOMObject* ${v8ClassName}::toActiveDOMObject(v8::Handle<v8::Object> wrapper)
-{
- return toNative(wrapper);
-}
-
-END
- }
-
- if (InheritsInterface($interface, "EventTarget")) {
- $implementation{nameSpaceWebCore}->add(<<END);
-EventTarget* ${v8ClassName}::toEventTarget(v8::Handle<v8::Object> object)
-{
- return toNative(object);
-}
-
-END
- }
-
- if ($interfaceName eq "Window") {
- $implementation{nameSpaceWebCore}->add(<<END);
-v8::Handle<v8::ObjectTemplate> V8Window::GetShadowObjectTemplate(v8::Isolate* isolate, WrapperWorldType currentWorldType)
-{
- if (currentWorldType == MainWorld) {
- DEFINE_STATIC_LOCAL(v8::Persistent<v8::ObjectTemplate>, V8WindowShadowObjectCacheForMainWorld, ());
- if (V8WindowShadowObjectCacheForMainWorld.IsEmpty()) {
- TRACE_EVENT_SCOPED_SAMPLING_STATE("Blink", "BuildDOMTemplate");
- v8::Handle<v8::ObjectTemplate> templ = v8::ObjectTemplate::New(isolate);
- ConfigureShadowObjectTemplate(templ, isolate, currentWorldType);
- V8WindowShadowObjectCacheForMainWorld.Reset(isolate, templ);
- return templ;
- }
- return v8::Local<v8::ObjectTemplate>::New(isolate, V8WindowShadowObjectCacheForMainWorld);
- } else {
- DEFINE_STATIC_LOCAL(v8::Persistent<v8::ObjectTemplate>, V8WindowShadowObjectCacheForNonMainWorld, ());
- if (V8WindowShadowObjectCacheForNonMainWorld.IsEmpty()) {
- TRACE_EVENT_SCOPED_SAMPLING_STATE("Blink", "BuildDOMTemplate");
- v8::Handle<v8::ObjectTemplate> templ = v8::ObjectTemplate::New(isolate);
- ConfigureShadowObjectTemplate(templ, isolate, currentWorldType);
- V8WindowShadowObjectCacheForNonMainWorld.Reset(isolate, templ);
- return templ;
- }
- return v8::Local<v8::ObjectTemplate>::New(isolate, V8WindowShadowObjectCacheForNonMainWorld);
- }
-}
-
-END
- }
-
- GenerateSpecialWrap($interface, $v8ClassName, $nativeType);
- GenerateToV8Converters($interface, $v8ClassName, $nativeType);
-
- $implementation{nameSpaceWebCore}->add(<<END);
-void ${v8ClassName}::derefObject(void* object)
-{
- fromInternalPointer(object)->deref();
-}
-
-template<>
-v8::Handle<v8::Value> toV8NoInline(${nativeType}* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
-{
- return toV8(impl, creationContext, isolate);
-}
-
-END
-}
-
-sub GenerateHeaderContentHeader
-{
- my $interface = shift;
- my $v8ClassName = GetV8ClassName($interface);
- my $conditionalString = GenerateConditionalString($interface);
-
- my @headerContentHeader = split("\r", $licenseHeader);
-
- push(@headerContentHeader, "#ifndef ${v8ClassName}" . "_h\n");
- push(@headerContentHeader, "#define ${v8ClassName}" . "_h\n\n");
- push(@headerContentHeader, "#if ${conditionalString}\n") if $conditionalString;
- return join "", @headerContentHeader;
-}
-
-sub GenerateCallbackHeader
-{
- my $object = shift;
- my $interface = shift;
-
- my $interfaceName = $interface->name;
- my $implClassName = GetImplName($interface);
- my $v8ClassName = GetV8ClassName($interface);
-
- my @includes = ();
- push(@includes, "bindings/v8/ActiveDOMCallback.h");
- push(@includes, "bindings/v8/DOMWrapperWorld.h");
- push(@includes, "bindings/v8/ScopedPersistent.h");
- push(@includes, HeaderFilesForInterface($interfaceName, $implClassName));
- for my $include (sort @includes) {
- $header{includes}->add("#include \"$include\"\n");
- }
- $header{nameSpaceWebCore}->addHeader("\nclass ExecutionContext;\n");
- $header{class}->addHeader("class $v8ClassName : public $implClassName, public ActiveDOMCallback {");
- $header{class}->addFooter("};\n");
-
- $header{classPublic}->add(<<END);
- static PassOwnPtr<${v8ClassName}> create(v8::Handle<v8::Function> callback, ExecutionContext* context)
- {
- ASSERT(context);
- return adoptPtr(new ${v8ClassName}(callback, context));
- }
-
- virtual ~${v8ClassName}();
-
-END
-
- # Functions
- my $numFunctions = @{$interface->functions};
- if ($numFunctions > 0) {
- foreach my $function (@{$interface->functions}) {
- my $code = " virtual " . GetNativeTypeForCallbacks($function->type) . " " . $function->name . "(";
-
- my @args = ();
- if (ExtendedAttributeContains($function->extendedAttributes->{"CallWith"}, "ThisValue")) {
- push(@args, GetNativeType("any") . " thisValue");
- }
- my @params = @{$function->parameters};
- foreach my $param (@params) {
- push(@args, GetNativeTypeForCallbacks($param->type) . " " . $param->name);
- }
- $code .= join(", ", @args);
- $code .= ");\n";
- $header{classPublic}->add($code);
- }
- }
-
- $header{classPrivate}->add(<<END);
- ${v8ClassName}(v8::Handle<v8::Function>, ExecutionContext*);
-
- ScopedPersistent<v8::Function> m_callback;
- RefPtr<DOMWrapperWorld> m_world;
-END
-}
-
-sub GenerateCallbackImplementation
-{
- my $object = shift;
- my $interface = shift;
- my $v8ClassName = GetV8ClassName($interface);
-
- AddToImplIncludes("core/dom/ExecutionContext.h");
- AddToImplIncludes("bindings/v8/V8Binding.h");
- AddToImplIncludes("bindings/v8/V8Callback.h");
- AddToImplIncludes("wtf/Assertions.h");
-
- $implementation{nameSpaceWebCore}->add(<<END);
-${v8ClassName}::${v8ClassName}(v8::Handle<v8::Function> callback, ExecutionContext* context)
- : ActiveDOMCallback(context)
- , m_callback(toIsolate(context), callback)
- , m_world(DOMWrapperWorld::current())
-{
-}
-
-END
-
- $implementation{nameSpaceWebCore}->add(<<END);
-${v8ClassName}::~${v8ClassName}()
-{
-}
-
-END
-
- # Functions
- my $numFunctions = @{$interface->functions};
- if ($numFunctions > 0) {
- foreach my $function (@{$interface->functions}) {
- my $code = "";
- my @params = @{$function->parameters};
- next if $function->extendedAttributes->{"Custom"};
-
- AddIncludesForType($function->type);
- die "We only support callbacks that return boolean or void values.\n" unless ($function->type eq "boolean" || $function->type eq "void");
- my $defaultReturn = $function->type eq "boolean" ? " true" : "";
- $code .= GetNativeTypeForCallbacks($function->type) . " ${v8ClassName}::" . $function->name . "(";
- my $callWithThisValue = ExtendedAttributeContains($function->extendedAttributes->{"CallWith"}, "ThisValue");
-
- my @args = ();
- if ($callWithThisValue) {
- push(@args, GetNativeTypeForCallbacks("any") . " thisValue");
- }
- foreach my $param (@params) {
- my $paramName = $param->name;
- my $type = $param->type;
- my $arrayOrSequenceType = GetArrayOrSequenceType($type);
-
- if ($arrayOrSequenceType) {
- if (IsRefPtrType($arrayOrSequenceType)) {
- AddIncludesForType($arrayOrSequenceType);
- }
- } else {
- AddIncludesForType($type);
- }
-
- push(@args, GetNativeTypeForCallbacks($type) . " " . $paramName);
- }
- $code .= join(", ", @args);
-
- $code .= ")\n";
- $code .= "{\n";
- $code .= " if (!canInvokeCallback())\n";
- $code .= " return${defaultReturn};\n\n";
- $code .= " v8::Isolate* isolate = v8::Isolate::GetCurrent();\n";
- $code .= " v8::HandleScope handleScope(isolate);\n\n";
- $code .= " v8::Handle<v8::Context> v8Context = toV8Context(executionContext(), m_world.get());\n";
- $code .= " if (v8Context.IsEmpty())\n";
- $code .= " return${defaultReturn};\n\n";
- $code .= " v8::Context::Scope scope(v8Context);\n";
-
- my $thisObjectHandle = "";
- if ($callWithThisValue) {
- $code .= " v8::Handle<v8::Value> thisHandle = thisValue.v8Value();\n";
- $code .= " if (thisHandle.IsEmpty()) {\n";
- $code .= " if (!isScriptControllerTerminating())\n";
- $code .= " CRASH();\n";
- $code .= " return${defaultReturn};\n";
- $code .= " }\n";
- $code .= " ASSERT(thisHandle->IsObject());\n";
- $thisObjectHandle = "v8::Handle<v8::Object>::Cast(thisHandle), ";
- }
- @args = ();
- foreach my $param (@params) {
- my $paramName = $param->name;
- $code .= NativeToJSValue($param->type, $param->extendedAttributes, $paramName, " ", "v8::Handle<v8::Value> ${paramName}Handle =", "isolate", "") . "\n";
- $code .= " if (${paramName}Handle.IsEmpty()) {\n";
- $code .= " if (!isScriptControllerTerminating())\n";
- $code .= " CRASH();\n";
- $code .= " return${defaultReturn};\n";
- $code .= " }\n";
- push(@args, "${paramName}Handle");
- }
-
- if (scalar(@args) > 0) {
- $code .= " v8::Handle<v8::Value> argv[] = { ";
- $code .= join(", ", @args);
- $code .= " };\n\n";
- } else {
- $code .= " v8::Handle<v8::Value> *argv = 0;\n\n";
- }
- $code .= " ";
- if ($function->type eq "boolean") {
- $code .= "return ";
- }
- $code .= "invokeCallback(m_callback.newLocal(isolate), ${thisObjectHandle}" . scalar(@args) . ", argv, executionContext(), isolate);\n";
- $code .= "}\n\n";
- $implementation{nameSpaceWebCore}->add($code);
- }
- }
-}
-
-sub GenerateSpecialWrap
-{
- my $interface = shift;
- my $v8ClassName = shift;
- my $nativeType = shift;
-
- my $specialWrap = $interface->extendedAttributes->{"SpecialWrapFor"};
- my $isDocument = InheritsInterface($interface, "Document");
- if (!$specialWrap && !$isDocument) {
- return;
- }
-
- my $code = "";
- $code .= <<END;
-v8::Handle<v8::Object> wrap(${nativeType}* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
-{
- ASSERT(impl);
-END
- if ($specialWrap) {
- foreach my $type (split(/\s*\|\s*/, $specialWrap)) {
- AddToImplIncludes("V8${type}.h");
- $code .= <<END;
- if (impl->is${type}())
- return wrap(to${type}(impl), creationContext, isolate);
-END
- }
- }
- $code .= <<END;
- v8::Handle<v8::Object> wrapper = ${v8ClassName}::createWrapper(impl, creationContext, isolate);
-END
- if ($isDocument) {
- AddToImplIncludes("bindings/v8/ScriptController.h");
- AddToImplIncludes("bindings/v8/V8WindowShell.h");
- $code .= <<END;
- if (wrapper.IsEmpty())
- return wrapper;
- if (!isolatedWorldForEnteredContext(isolate)) {
- if (Frame* frame = impl->frame())
- frame->script().windowShell(mainThreadNormalWorld())->updateDocumentWrapper(wrapper);
- }
-END
- }
- $code .= <<END;
- return wrapper;
-}
-
-END
- $implementation{nameSpaceWebCore}->add($code);
-}
-
-sub GenerateToV8Converters
-{
- my $interface = shift;
- my $v8ClassName = shift;
- my $nativeType = shift;
- my $interfaceName = $interface->name;
-
- if (ExtendedAttributeContains($interface->extendedAttributes->{"Custom"}, "ToV8")) {
- return;
- }
-
- my $createWrapperArgumentType = GetPassRefPtrType($nativeType);
-
- # FIXME: Do we really need to treat /SVG/ as dependent DOM objects?
- my $wrapperConfiguration = "WrapperConfiguration::Independent";
- if (InheritsExtendedAttribute($interface, "ActiveDOMObject")
- || InheritsExtendedAttribute($interface, "DependentLifetime")
- || NeedsVisitDOMWrapper($interface)
- || $v8ClassName =~ /SVG/) {
- $wrapperConfiguration = "WrapperConfiguration::Dependent";
- }
-
- my $code = "";
- $code .= <<END;
-v8::Handle<v8::Object> ${v8ClassName}::createWrapper(${createWrapperArgumentType} impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
-{
- ASSERT(impl);
- ASSERT(!DOMDataStore::containsWrapper<${v8ClassName}>(impl.get(), isolate));
- if (ScriptWrappable::wrapperCanBeStoredInObject(impl.get())) {
- const WrapperTypeInfo* actualInfo = ScriptWrappable::getTypeInfoFromObject(impl.get());
- // Might be a XXXConstructor::wrapperTypeInfo instead of an XXX::wrapperTypeInfo. These will both have
- // the same object de-ref functions, though, so use that as the basis of the check.
- RELEASE_ASSERT_WITH_SECURITY_IMPLICATION(actualInfo->derefObjectFunction == wrapperTypeInfo.derefObjectFunction);
- }
-
-END
-
- if (InheritsInterface($interface, "Document")) {
- AddToImplIncludes("bindings/v8/ScriptController.h");
- AddToImplIncludes("core/frame/Frame.h");
- $code .= <<END;
- if (Frame* frame = impl->frame()) {
- if (frame->script().initializeMainWorld()) {
- // initializeMainWorld may have created a wrapper for the object, retry from the start.
- v8::Handle<v8::Object> wrapper = DOMDataStore::getWrapper<${v8ClassName}>(impl.get(), isolate);
- if (!wrapper.IsEmpty())
- return wrapper;
- }
- }
-END
- }
-
- $code .= <<END;
- v8::Handle<v8::Object> wrapper = V8DOMWrapper::createWrapper(creationContext, &wrapperTypeInfo, toInternalPointer(impl.get()), isolate);
- if (UNLIKELY(wrapper.IsEmpty()))
- return wrapper;
-
-END
- if (IsTypedArrayType($interface->name)) {
- AddToImplIncludes("bindings/v8/custom/V8ArrayBufferCustom.h");
- $code .= <<END;
- impl->buffer()->setDeallocationObserver(V8ArrayBufferDeallocationObserver::instanceTemplate());
-END
- }
-
- if (InheritsInterface($interface, "AudioBuffer")) {
- AddToImplIncludes("modules/webaudio/AudioBuffer.h");
- $code .= <<END;
- for (unsigned i = 0, n = impl->numberOfChannels(); i < n; i++) {
- Float32Array* channelData = impl->getChannelData(i);
- channelData->buffer()->setDeallocationObserver(V8ArrayBufferDeallocationObserver::instanceTemplate());
- }
-END
- }
-
-
- $code .= <<END;
- installPerContextEnabledProperties(wrapper, impl.get(), isolate);
- V8DOMWrapper::associateObjectWithWrapper<$v8ClassName>(impl, &wrapperTypeInfo, wrapper, isolate, $wrapperConfiguration);
- return wrapper;
-}
-
-END
- $implementation{nameSpaceWebCore}->add($code);
-}
-
-sub GenerateSecurityCheckFunctions
-{
- my $interface = shift;
- my $implClassName = GetImplName($interface);
- my $v8ClassName = GetV8ClassName($interface);
-
- AddToImplIncludes("bindings/v8/BindingSecurity.h");
- $implementation{nameSpaceInternal}->add(<<END);
-bool indexedSecurityCheck(v8::Local<v8::Object> host, uint32_t index, v8::AccessType type, v8::Local<v8::Value>)
-{
- $implClassName* imp = ${v8ClassName}::toNative(host);
- return BindingSecurity::shouldAllowAccessToFrame(imp->frame(), DoNotReportSecurityError);
-}
-
-END
- $implementation{nameSpaceInternal}->add(<<END);
-bool namedSecurityCheck(v8::Local<v8::Object> host, v8::Local<v8::Value> key, v8::AccessType type, v8::Local<v8::Value>)
-{
- $implClassName* imp = ${v8ClassName}::toNative(host);
- return BindingSecurity::shouldAllowAccessToFrame(imp->frame(), DoNotReportSecurityError);
-}
-
-END
-}
-
-sub GetNativeTypeForConversions
-{
- my $interface = shift;
- my $implClassName = GetImplName($interface);
- $implClassName = GetSVGTypeNeedingTearOff($interface->name) if IsSVGTypeNeedingTearOff($interface->name);
- return $implClassName;
-}
-
-sub GetNamespaceForInterface
-{
- my $interface = shift;
- return "WTF" if IsTypedArrayType($interface->name);
- return "WebCore";
-}
-
-sub GenerateFunctionCallString
-{
- my $function = shift;
- my $numberOfParameters = shift;
- my $indent = shift;
- my $interface = shift;
- my $forMainWorldSuffix = shift;
- my %replacements = @_;
-
- my $interfaceName = $interface->name;
- my $implClassName = GetImplName($interface);
- my $name = GetImplName($function);
- my $returnType = $function->type;
- my $nativeReturnType = GetNativeType($returnType, {}, "");
- my $code = "";
-
- my $isSVGTearOffType = (IsSVGTypeNeedingTearOff($returnType) and not $interfaceName =~ /List$/);
- $nativeReturnType = GetSVGWrappedTypeNeedingTearOff($returnType) if $isSVGTearOffType;
-
- my $index = 0;
- my $humanFriendlyIndex = $index + 1;
-
- my @arguments;
- my $functionName;
- my $implementedBy = $function->extendedAttributes->{"ImplementedBy"};
- if ($implementedBy) {
- my $implementedByImplName = GetImplNameFromImplementedBy($implementedBy);
- AddToImplIncludes(HeaderFilesForInterface($implementedBy, $implementedByImplName));
- unshift(@arguments, "imp") if !$function->isStatic;
- $functionName = "${implementedByImplName}::${name}";
- } elsif ($function->isStatic) {
- $functionName = "${implClassName}::${name}";
- } else {
- $functionName = "imp->${name}";
- }
-
- my $callWith = $function->extendedAttributes->{"CallWith"};
- my ($callWithArgs, $subCode) = GenerateCallWith($callWith, $indent, 1, $function);
- $code .= $subCode;
- unshift(@arguments, @$callWithArgs);
- $index += @$callWithArgs;
- $humanFriendlyIndex = $index + 1;
-
- $numberOfParameters += @$callWithArgs;
-
- foreach my $parameter (@{$function->parameters}) {
- if ($index eq $numberOfParameters) {
- last;
- }
- my $paramName = $parameter->name;
- my $paramType = $parameter->type;
-
- if ($replacements{$paramName}) {
- push @arguments, $replacements{$paramName};
- } elsif (IsSVGTypeNeedingTearOff($parameter->type) and not $interfaceName =~ /List$/) {
- push @arguments, "$paramName->propertyReference()";
- $code .= <<END;
- if (!$paramName) {
- throwTypeError(ExceptionMessages::failedToExecute(\"$name\", \"$interfaceName\", \"parameter $humanFriendlyIndex is not of type '${ \$parameter->type }'.\"), info.GetIsolate());
- return;
- }
-END
- } elsif ($parameter->type eq "SVGMatrix" and $interfaceName eq "SVGTransformList") {
- push @arguments, "$paramName.get()";
- } elsif (IsNullableParameter($parameter)) {
- push @arguments, "${paramName}IsNull ? 0 : &$paramName";
- } elsif (IsCallbackInterface($paramType) or $paramType eq "NodeFilter" or $paramType eq "XPathNSResolver") {
- push @arguments, "$paramName.release()";
- } else {
- push @arguments, $paramName;
- }
- $index++;
- $humanFriendlyIndex = $index + 1;
- }
-
- if ($function->extendedAttributes->{"RaisesException"}) {
- push @arguments, "exceptionState";
- }
-
- my $functionString = "$functionName(" . join(", ", @arguments) . ")";
-
- my $return = "result";
- my $returnIsRef = IsRefPtrType($returnType);
-
- if ($returnType eq "void") {
- $code .= $indent . "$functionString;\n";
- } elsif (ExtendedAttributeContains($callWith, "ScriptState") or $function->extendedAttributes->{"RaisesException"}) {
- $code .= $indent . $nativeReturnType . " result = $functionString;\n";
- } else {
- # Can inline the function call into the return statement to avoid overhead of using a Ref<> temporary
- $return = $functionString;
- $returnIsRef = 0;
-
- if ($interfaceName eq "SVGTransformList" and IsRefPtrType($returnType)) {
- $return = "WTF::getPtr(" . $return . ")";
- }
- }
-
- if ($function->extendedAttributes->{"RaisesException"}) {
- $code .= $indent . "if (exceptionState.throwIfNeeded())\n";
- $code .= $indent . " return;\n";
- }
-
- if (ExtendedAttributeContains($callWith, "ScriptState")) {
- $code .= $indent . "if (state.hadException()) {\n";
- $code .= $indent . " v8::Local<v8::Value> exception = state.exception();\n";
- $code .= $indent . " state.clearException();\n";
- $code .= $indent . " throwError(exception, info.GetIsolate());\n";
- $code .= $indent . " return;\n";
- $code .= $indent . "}\n";
- }
-
- if ($isSVGTearOffType) {
- AddToImplIncludes("V8$returnType.h");
- AddToImplIncludes("core/svg/properties/SVGPropertyTearOff.h");
- my $svgNativeType = GetSVGTypeNeedingTearOff($returnType);
- # FIXME: Update for all ScriptWrappables.
- if (IsDOMNodeType($interfaceName)) {
- if ($forMainWorldSuffix eq "ForMainWorld") {
- $code .= $indent . "v8SetReturnValueForMainWorld(info, WTF::getPtr(${svgNativeType}::create($return)));\n";
- } else {
- $code .= $indent . "v8SetReturnValueFast(info, WTF::getPtr(${svgNativeType}::create($return)), imp);\n";
- }
- } else {
- $code .= $indent . "v8SetReturnValue${forMainWorldSuffix}(info, WTF::getPtr(${svgNativeType}::create($return)));\n";
- }
- return $code;
- }
-
- # If the implementing class is a POD type, commit changes
- if (IsSVGTypeNeedingTearOff($interfaceName) and not $interfaceName =~ /List$/) {
- $code .= $indent . "wrapper->commitChange();\n";
- }
-
- $return .= ".release()" if ($returnIsRef);
-
- my $nativeValue;
- # FIXME: Update for all ScriptWrappables.
- if (IsDOMNodeType($interfaceName)) {
- $nativeValue = NativeToJSValue($function->type, $function->extendedAttributes, $return, $indent, "", "info.GetIsolate()", "info", "imp", $forMainWorldSuffix, "return");
- } else {
- $nativeValue = NativeToJSValue($function->type, $function->extendedAttributes, $return, $indent, "", "info.GetIsolate()", "info", 0, $forMainWorldSuffix, "return");
- }
-
- $code .= $nativeValue . "\n" if $nativeValue; # Skip blank line for void return type
-
- return $code;
-}
-
-sub GetNativeType
-{
- my $type = shift;
- my $extendedAttributes = shift;
- my $isParameter = shift;
-
- my $svgNativeType = GetSVGTypeNeedingTearOff($type);
- if ($svgNativeType) {
- if ($svgNativeType =~ /List$/) {
- return "${svgNativeType}*";
- } else {
- return "RefPtr<${svgNativeType} >";
- }
- }
-
- return "float" if $type eq "float";
- return "double" if $type eq "double";
- return "int" if $type eq "long" or $type eq "int" or $type eq "short" or $type eq "byte";
- if ($type eq "unsigned long" or $type eq "unsigned int" or $type eq "unsigned short" or $type eq "octet") {
- return "unsigned";
- }
- return "long long" if $type eq "long long";
- return "unsigned long long" if $type eq "unsigned long long";
- return "bool" if $type eq "boolean";
-
- if (($type eq "DOMString" || IsEnumType($type)) and $isParameter) {
- my $mode = GetV8StringResourceMode($extendedAttributes);
- # FIXME: Add the case for 'elsif ($attributeOrParameter->extendedAttributes->{"TreatUndefinedAs"} and $attributeOrParameter->extendedAttributes->{"TreatUndefinedAs"} eq "NullString"))'.
- return "V8StringResource<$mode>";
- }
-
- return "String" if $type eq "DOMString" or IsEnumType($type);
-
- return "ScriptPromise" if $type eq "Promise";
-
- return "Range::CompareHow" if $type eq "CompareHow";
- return "DOMTimeStamp" if $type eq "DOMTimeStamp";
- return "double" if $type eq "Date";
- return "ScriptValue" if $type eq "any" or IsCallbackFunctionType($type);
- return "Dictionary" if $type eq "Dictionary";
-
- die "UnionType is not supported" if IsUnionType($type);
-
- if (IsTypedArrayType($type)) {
- return $isParameter ? "${type}*" : "RefPtr<${type}>";
- }
-
- # We need to check [ImplementedAs] extended attribute for wrapper types.
- return "RefPtr<$type>" if $type eq "XPathNSResolver"; # FIXME: can this be put in nonWrapperTypes instead?
- if (IsWrapperType($type)) {
- my $interface = ParseInterface($type);
- my $implClassName = GetImplName($interface);
- return $isParameter ? "${implClassName}*" : "RefPtr<${implClassName}>";
- }
- return "RefPtr<$type>" if IsRefPtrType($type) and (not $isParameter or $nonWrapperTypes{$type});
-
- my $arrayOrSequenceType = GetArrayOrSequenceType($type);
-
- if ($arrayOrSequenceType) {
- my $nativeType = GetNativeType($arrayOrSequenceType);
- $nativeType .= " " if ($nativeType =~ />$/);
- return "Vector<${nativeType}>";
- }
-
- # Default, assume native type is a pointer with same type name as idl type
- return "${type}*";
-}
-
-sub GetNativeTypeForCallbacks
-{
- my $type = shift;
- return "const String&" if $type eq "DOMString";
- return "PassRefPtr<SerializedScriptValue>" if $type eq "SerializedScriptValue";
- return "void" if $type eq "void";
-
- # Callbacks use raw pointers, so pass isParameter = 1
- my $nativeType = GetNativeType($type, {}, "parameter");
- return "const $nativeType&" if $nativeType =~ /^Vector/;
- return $nativeType;
-}
-
-sub JSValueToNativeStatement
-{
- my $type = shift;
- my $extendedAttributes = shift;
- my $argIndexOrZero = shift;
- my $jsValue = shift;
- my $variableName = shift;
- my $indent = shift;
- my $getIsolate = shift;
-
- my $nativeType = GetNativeType($type, $extendedAttributes, "parameter");
- my $native_value = JSValueToNative($type, $extendedAttributes, $argIndexOrZero, $jsValue, $getIsolate);
- my $code = "";
- if ($type eq "DOMString" || IsEnumType($type)) {
- die "Wrong native type passed: $nativeType" unless $nativeType =~ /^V8StringResource/;
- if ($type eq "DOMString" or IsEnumType($type)) {
- $code .= $indent . "V8TRYCATCH_FOR_V8STRINGRESOURCE_VOID($nativeType, $variableName, $native_value);\n"
- } else {
- $code .= $indent . "$nativeType $variableName($native_value, true);\n";
- }
- } elsif ($extendedAttributes->{"EnforceRange"}) {
- $code .= $indent . "V8TRYCATCH_WITH_TYPECHECK_VOID($nativeType, $variableName, $native_value, $getIsolate);\n";
- } else {
- $code .= $indent . "V8TRYCATCH_VOID($nativeType, $variableName, $native_value);\n";
- }
- return $code;
-}
-
-
-sub JSValueToNative
-{
- my $type = shift;
- my $extendedAttributes = shift;
- # Argument position (1-indexed) or 0 if for a setter's value.
- my $argIndexOrZero = shift;
- my $value = shift;
- my $getIsolate = shift;
-
- my $intConversion = $extendedAttributes->{"EnforceRange"} ? "EnforceRange" : "NormalConversion";
-
- return "$value->BooleanValue()" if $type eq "boolean";
- return "static_cast<$type>($value->NumberValue())" if $type eq "float" or $type eq "double";
-
- if ($intConversion ne "NormalConversion") {
- return "toInt8($value, $intConversion, ok)" if $type eq "byte";
- return "toUInt8($value, $intConversion, ok)" if $type eq "octet";
- return "toInt16($value, $intConversion, ok)" if $type eq "short";
- return "toUInt16($value, $intConversion, ok)" if $type eq "unsigned short";
- return "toInt32($value, $intConversion, ok)" if $type eq "long";
- return "toUInt32($value, $intConversion, ok)" if $type eq "unsigned long";
- return "toInt64($value, $intConversion, ok)" if $type eq "long long";
- return "toUInt64($value, $intConversion, ok)" if $type eq "unsigned long long";
- } else {
- return "toInt8($value)" if $type eq "byte";
- return "toUInt8($value)" if $type eq "octet";
- return "toInt16($value)" if $type eq "short";
- return "toUInt16($value)" if $type eq "unsigned short";
- return "toInt32($value)" if $type eq "long";
- return "toUInt32($value)" if $type eq "unsigned long";
- return "toInt64($value)" if $type eq "long long";
- return "toUInt64($value)" if $type eq "unsigned long long";
- }
- return "static_cast<Range::CompareHow>($value->Int32Value())" if $type eq "CompareHow";
- return "toWebCoreDate($value)" if $type eq "Date";
-
- if ($type eq "DOMString" or IsEnumType($type)) {
- return $value;
- }
-
- if ($type eq "SerializedScriptValue") {
- AddToImplIncludes("bindings/v8/SerializedScriptValue.h");
- return "SerializedScriptValue::create($value, $getIsolate)";
- }
-
- if ($type eq "Dictionary") {
- AddToImplIncludes("bindings/v8/Dictionary.h");
- return "Dictionary($value, $getIsolate)";
- }
-
- if ($type eq "any" || IsCallbackFunctionType($type)) {
- AddToImplIncludes("bindings/v8/ScriptValue.h");
- return "ScriptValue($value, $getIsolate)";
- }
-
- if ($type eq "Promise") {
- AddToImplIncludes("bindings/v8/ScriptPromise.h");
- return "ScriptPromise($value)";
- }
-
- if ($type eq "NodeFilter") {
- return "toNodeFilter($value, $getIsolate)";
- }
-
- if ($type eq "MediaQueryListListener") {
- AddToImplIncludes("core/css/MediaQueryListListener.h");
- return "MediaQueryListListener::create(ScriptValue(" . $value . ", $getIsolate))";
- }
-
- if ($type eq "EventTarget") {
- return "V8DOMWrapper::isDOMWrapper($value) ? toWrapperTypeInfo(v8::Handle<v8::Object>::Cast($value))->toEventTarget(v8::Handle<v8::Object>::Cast($value)) : 0";
- }
-
- if (IsTypedArrayType($type)) {
- AddIncludesForType($type);
- return "$value->Is${type}() ? V8${type}::toNative(v8::Handle<v8::${type}>::Cast($value)) : 0"
- }
-
- if ($type eq "XPathNSResolver") {
- return "toXPathNSResolver($value, $getIsolate)";
- }
-
- my $arrayOrSequenceType = GetArrayOrSequenceType($type);
-
- if ($arrayOrSequenceType) {
- if (IsRefPtrType($arrayOrSequenceType)) {
- AddToImplIncludes("V8${arrayOrSequenceType}.h");
- return "(toRefPtrNativeArray<${arrayOrSequenceType}, V8${arrayOrSequenceType}>($value, $argIndexOrZero, $getIsolate))";
- }
- return "toNativeArray<" . GetNativeType($arrayOrSequenceType) . ">($value, $argIndexOrZero, $getIsolate)";
- }
-
- AddIncludesForType($type);
-
- AddToImplIncludes("V8${type}.h");
- return "V8${type}::hasInstance($value, $getIsolate, worldType($getIsolate)) ? V8${type}::toNative(v8::Handle<v8::Object>::Cast($value)) : 0";
-}
-
-sub CreateCustomSignature
-{
- my $function = shift;
- my $count = @{$function->parameters};
- my $name = $function->name;
- my $code = " 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; }
- else { $code .= ", "; }
- if (IsWrapperType($parameter->type) && not IsTypedArrayType($parameter->type)) {
- if ($parameter->type eq "XPathNSResolver") {
- # Special case for XPathNSResolver. All other browsers accepts a callable,
- # so, even though it's against IDL, accept objects here.
- $code .= "v8::Handle<v8::FunctionTemplate>()";
- } else {
- my $type = $parameter->type;
- my $arrayOrSequenceType = GetArrayOrSequenceType($type);
-
- if ($arrayOrSequenceType) {
- if (IsRefPtrType($arrayOrSequenceType)) {
- AddIncludesForType($arrayOrSequenceType);
- } else {
- $code .= "v8::Handle<v8::FunctionTemplate>()";
- next;
- }
- } else {
- AddIncludesForType($type);
- }
- $code .= "V8PerIsolateData::from(isolate)->rawDOMTemplate(&V8${type}::wrapperTypeInfo, currentWorldType)";
- }
- } else {
- $code .= "v8::Handle<v8::FunctionTemplate>()";
- }
- }
- $code .= " };\n";
- $code .= " v8::Handle<v8::Signature> ${name}Signature = v8::Signature::New(isolate, functionTemplate, ${name}Argc, ${name}Argv);\n";
- return $code;
-}
-
-
-sub RequiresCustomSignature
-{
- my $function = shift;
- # No signature needed for Custom function
- if (HasCustomMethod($function->extendedAttributes)) {
- return 0;
- }
- # No signature needed for overloaded function
- if (@{$function->{overloads}} > 1) {
- return 0;
- }
- if ($function->isStatic) {
- return 0;
- }
- # Type checking is performed in the generated code
- if ($function->extendedAttributes->{"StrictTypeChecking"}) {
- return 0;
- }
- foreach my $parameter (@{$function->parameters}) {
- if (($parameter->isOptional && !$parameter->extendedAttributes->{"Default"}) || IsCallbackInterface($parameter->type)) {
- return 0;
- }
- }
-
- foreach my $parameter (@{$function->parameters}) {
- if (IsWrapperType($parameter->type)) {
- return 1;
- }
- }
- return 0;
-}
-
-sub IsUnionType
-{
- my $type = shift; # string or UnionType
- if(ref($type) eq "UnionType") {
- die "Currently only 2 values of non-union type is supported as union type.\n" unless @{$type->unionMemberTypes} == 2;
- return 1;
- }
- return 0;
-}
-
-sub IsWrapperType
-{
- my $type = shift;
- return 0 if GetArrayType($type);
- return 0 if GetSequenceType($type);
- return 0 if IsCallbackFunctionType($type);
- return 0 if IsEnumType($type);
- return 0 if IsPrimitiveType($type);
- return 0 if $type eq "Promise";
- return !$nonWrapperTypes{$type};
-}
-
-sub IsCallbackInterface
-{
- my $type = shift;
- return 0 unless IsWrapperType($type);
- return 0 if IsTypedArrayType($type);
-
- my $idlFile = IDLFileForInterface($type)
- or die("Could NOT find IDL file for interface \"$type\"!\n");
-
- open FILE, "<", $idlFile;
- my @lines = <FILE>;
- close FILE;
-
- my $fileContents = join('', @lines);
- return ($fileContents =~ /callback\s+interface\s+(\w+)/gs);
-}
-
-sub GetNativeTypeOfTypedArray
-{
- my $interface = shift;
- my $interfaceName = $interface->name;
- die "TypedArray of unknown type is found" unless $typedArrayHash{$interface->name};
- return @{$typedArrayHash{$interface->name}};
-}
-
-sub IsDOMNodeType
-{
- my $type = shift;
-
- return 1 if $type eq 'Attr';
- return 1 if $type eq 'CDATASection';
- return 1 if $type eq 'CharacterData';
- return 1 if $type eq 'Comment';
- return 1 if $type eq 'Document';
- return 1 if $type eq 'DocumentFragment';
- return 1 if $type eq 'DocumentType';
- return 1 if $type eq 'Element';
- return 1 if $type eq 'Entity';
- return 1 if $type eq 'HTMLDocument';
- return 1 if $type eq 'Node';
- return 1 if $type eq 'Notation';
- return 1 if $type eq 'ProcessingInstruction';
- return 1 if $type eq 'ShadowRoot';
- return 1 if $type eq 'SVGDocument';
- return 1 if $type eq 'Text';
-
- return 1 if $type =~ /^HTML.*Element$/;
- return 1 if $type =~ /^SVG.*Element$/;
-
- return 1 if $type eq 'TestNode';
-
- return 0;
-}
-
-
-sub NativeToJSValue
-{
- my $type = shift;
- my $extendedAttributes = shift;
- my $nativeValue = shift;
- my $indent = shift; # added before every line
- my $receiver = shift; # "return" or "<variableName> ="
- my $getIsolate = shift;
- die "An Isolate is mandatory for native value => JS value conversion." unless $getIsolate;
- my $getCallbackInfo = shift || "";
- my $creationContext = $getCallbackInfo ? "${getCallbackInfo}.Holder()" : "v8::Handle<v8::Object>()";
- my $getScriptWrappable = shift || "";
- my $forMainWorldSuffix = shift || "";
- my $returnValueArg = shift || 0;
- my $isReturnValue = $returnValueArg eq "return";
-
- if (IsUnionType($type)) {
- my $types = $type->unionMemberTypes;
- my @codes = ();
- for my $i (0 .. scalar(@$types)-1) {
- my $unionMemberType = $types->[$i];
- my $unionMemberNumber = $i + 1;
- my $unionMemberVariable = $nativeValue . $i;
- my $unionMemberEnabledVariable = $nativeValue . $i . "Enabled";
- my $unionMemberNativeValue = $unionMemberVariable;
- $unionMemberNativeValue .= ".release()" if (IsRefPtrType($unionMemberType));
- my $returnJSValueCode = NativeToJSValue($unionMemberType, $extendedAttributes, $unionMemberNativeValue, $indent . " ", $receiver, $getIsolate, $getCallbackInfo, $getScriptWrappable, $forMainWorldSuffix, $returnValueArg);
- my $code = "";
- if ($isReturnValue) {
- $code .= "${indent}if (${unionMemberEnabledVariable}) {\n";
- $code .= "${returnJSValueCode}\n";
- $code .= "${indent} return;\n";
- $code .= "${indent}}\n";
- } else {
- $code .= "${indent}if (${unionMemberEnabledVariable})\n";
- $code .= "${returnJSValueCode}";
- }
- push @codes, $code;
- }
- return join "\n", @codes;
- }
-
- if ($type eq "boolean") {
- return "${indent}v8SetReturnValueBool(${getCallbackInfo}, ${nativeValue});" if $isReturnValue;
- return "$indent$receiver v8Boolean($nativeValue, $getIsolate);";
- }
-
- if ($type eq "void") { # equivalent to v8Undefined()
- return "" if $isReturnValue;
- return "$indent$receiver v8Undefined();"
- }
-
- # HTML5 says that unsigned reflected attributes should be in the range
- # [0, 2^31). When a value isn't in this range, a default value (or 0)
- # should be returned instead.
- if ($extendedAttributes->{"Reflect"} and ($type eq "unsigned long" or $type eq "unsigned short")) {
- $nativeValue =~ s/getUnsignedIntegralAttribute/getIntegralAttribute/g;
- return "${indent}v8SetReturnValueUnsigned(${getCallbackInfo}, std::max(0, ${nativeValue}));" if $isReturnValue;
- return "$indent$receiver v8::Integer::NewFromUnsigned($getIsolate, std::max(0, " . $nativeValue . "));";
- }
-
- my $nativeType = GetNativeType($type);
- if ($nativeType eq "int") {
- return "${indent}v8SetReturnValueInt(${getCallbackInfo}, ${nativeValue});" if $isReturnValue;
- return "$indent$receiver v8::Integer::New($getIsolate, $nativeValue);";
- }
-
- if ($nativeType eq "unsigned") {
- return "${indent}v8SetReturnValueUnsigned(${getCallbackInfo}, ${nativeValue});" if $isReturnValue;
- return "$indent$receiver v8::Integer::NewFromUnsigned($getIsolate, $nativeValue);";
- }
-
- if ($type eq "Date") {
- return "${indent}v8SetReturnValue(${getCallbackInfo}, v8DateOrNull($nativeValue, $getIsolate));" if $isReturnValue;
- return "$indent$receiver v8DateOrNull($nativeValue, $getIsolate);"
- }
-
- # long long and unsigned long long are not representable in ECMAScript.
- if ($type eq "long long" or $type eq "unsigned long long" or $type eq "DOMTimeStamp") {
- return "${indent}v8SetReturnValue(${getCallbackInfo}, static_cast<double>($nativeValue));" if $isReturnValue;
- return "$indent$receiver v8::Number::New($getIsolate, static_cast<double>($nativeValue));";
- }
-
- my $conv = $extendedAttributes->{"TreatReturnedNullStringAs"};
- if (($type eq "DOMString" || IsEnumType($type)) && $isReturnValue) {
- my $functionSuffix = "";
- if (defined $conv) {
- if ($conv eq "Null") {
- $functionSuffix = "OrNull";
- } elsif ($conv eq "Undefined") {
- $functionSuffix = "OrUndefined";
- } else {
- die "Unknown value for TreatReturnedNullStringAs extended attribute";
- }
- }
- return "${indent}v8SetReturnValueString${functionSuffix}(${getCallbackInfo}, $nativeValue, $getIsolate);";
- }
-
- if ($type eq "DOMString" or IsEnumType($type)) {
- my $returnValue = "";
- if (defined $conv) {
- if ($conv eq "Null") {
- $returnValue = "v8StringOrNull($nativeValue, $getIsolate)";
- } elsif ($conv eq "Undefined") {
- $returnValue = "v8StringOrUndefined($nativeValue, $getIsolate)";
- } else {
- die "Unknown value for TreatReturnedNullStringAs extended attribute";
- }
- } else {
- $returnValue = "v8String($getIsolate, $nativeValue)";
- }
- return "$indent$receiver $returnValue;";
- }
-
- if (IsPrimitiveType($type)) {
- die "unexpected type $type" if not ($type eq "float" or $type eq "double");
- return "${indent}v8SetReturnValue(${getCallbackInfo}, ${nativeValue});" if $isReturnValue;
- return "$indent$receiver v8::Number::New($getIsolate, $nativeValue);";
- }
-
- if ($nativeType eq "ScriptValue" or $nativeType eq "ScriptPromise") {
- return "${indent}v8SetReturnValue(${getCallbackInfo}, ${nativeValue}.v8Value());" if $isReturnValue;
- return "$indent$receiver $nativeValue.v8Value();";
- }
-
- my $arrayOrSequenceType = GetArrayOrSequenceType($type);
-
- if ($arrayOrSequenceType) {
- if (IsRefPtrType($arrayOrSequenceType)) {
- AddIncludesForType($arrayOrSequenceType);
- }
- return "${indent}v8SetReturnValue(${getCallbackInfo}, v8Array($nativeValue, $getIsolate));" if $isReturnValue;
- return "$indent$receiver v8Array($nativeValue, $getIsolate);";
- }
-
- AddIncludesForType($type);
-
- if ($type eq "SerializedScriptValue") {
- my $returnValue = "$nativeValue ? $nativeValue->deserialize() : v8::Handle<v8::Value>(v8::Null($getIsolate))";
- return "${indent}v8SetReturnValue(${getCallbackInfo}, $returnValue);" if $isReturnValue;
- return "$indent$receiver $returnValue;";
- }
-
- AddToImplIncludes("wtf/RefPtr.h");
- AddToImplIncludes("wtf/GetPtr.h");
-
- if ($getScriptWrappable) {
- # FIXME: Use safe handles
- if ($isReturnValue) {
- if ($forMainWorldSuffix eq "ForMainWorld") {
- return "${indent}v8SetReturnValueForMainWorld(${getCallbackInfo}, $nativeValue);";
- }
- return "${indent}v8SetReturnValueFast(${getCallbackInfo}, $nativeValue, $getScriptWrappable);";
- }
- }
- # FIXME: Use safe handles
- return "${indent}v8SetReturnValue(${getCallbackInfo}, $nativeValue);" if $isReturnValue;
- return "$indent$receiver toV8($nativeValue, $creationContext, $getIsolate);";
-}
-
-sub WriteData
-{
- my $object = shift;
- my $interface = shift;
- my $outputDirectory = shift;
-
- my $name = $interface->name;
- my $headerFileName = "$outputDirectory/V8$name.h";
- my $implFileName = "$outputDirectory/V8$name.cpp";
-
- my @includes = ();
- foreach my $include (keys %implIncludes) {
- push @includes, "\"$include\"";
- }
-
- #FIXME: do not treat main header special
- my $mainInclude = "\"V8$name.h\"";
- foreach my $include (sort @includes) {
- $implementation{includes}->add("#include $include\n") unless $include eq $mainInclude;
- }
- $implementation{includes}->add("\n") unless $interface->isCallback;
- WriteFileIfChanged($implFileName, $implementation{root}->toString());
-
- %implIncludes = ();
-
- WriteFileIfChanged($headerFileName, $header{root}->toString());
-}
-
-sub ConvertToV8StringResource
-{
- my $attributeOrParameter = shift;
- my $nativeType = shift;
- my $variableName = shift;
- my $value = shift;
-
- die "Wrong native type passed: $nativeType" unless $nativeType =~ /^V8StringResource/;
- if ($attributeOrParameter->type eq "DOMString" or IsEnumType($attributeOrParameter->type)) {
- return "V8TRYCATCH_FOR_V8STRINGRESOURCE_VOID($nativeType, $variableName, $value);"
- } else {
- return "$nativeType $variableName($value, true);";
- }
-}
-
-# Returns the RuntimeEnabledFeatures function name that is hooked up to check if a method/attribute is enabled.
-sub GetRuntimeEnabledFunctionName
-{
- my $signature = shift;
-
- # Given [RuntimeEnabled=FeatureName],
- # return RuntimeEnabledFeatures::{featureName}Enabled;
- my $featureName = ToMethodName($signature->extendedAttributes->{"RuntimeEnabled"});
- return "RuntimeEnabledFeatures::${featureName}Enabled";
-}
-
-sub GetContextEnabledFunctionName
-{
- my $signature = shift;
-
- # Given [PerContextEnabled=FeatureName],
- # return ContextFeatures::{featureName}Enabled
- my $featureName = ToMethodName($signature->extendedAttributes->{"PerContextEnabled"});
- return "ContextFeatures::${featureName}Enabled";
-}
-
-sub GetPassRefPtrType
-{
- my $v8ClassName = shift;
-
- my $angleBracketSpace = $v8ClassName =~ />$/ ? " " : "";
- return "PassRefPtr<${v8ClassName}${angleBracketSpace}>";
-}
-
-sub WriteFileIfChanged
-{
- my $fileName = shift;
- my $contents = shift;
-
- if (-f $fileName && $writeFileOnlyIfChanged) {
- open FH, "<", $fileName or die "Couldn't open $fileName: $!\n";
- my @lines = <FH>;
- my $oldContents = join "", @lines;
- close FH;
- return if $contents eq $oldContents;
- }
- open FH, ">", $fileName or die "Couldn't open $fileName: $!\n";
- print FH $contents;
- close FH;
-}
-
-sub ForAllParents
-{
- my $interface = shift;
- my $beforeRecursion = shift;
- my $afterRecursion = shift;
-
- my $recurse;
- $recurse = sub {
- my $currentInterface = shift;
-
- if ($currentInterface->parent) {
- my $parentInterface = ParseInterface($currentInterface->parent);
- if ($beforeRecursion) {
- &$beforeRecursion($parentInterface) eq 'prune' and return;
- }
- &$recurse($parentInterface);
- &$afterRecursion($parentInterface) if $afterRecursion;
- }
- };
-
- &$recurse($interface);
-}
-
-sub IsPrimitiveType
-{
- my $type = shift;
-
- return 1 if $primitiveTypeHash{$type};
- return 0;
-}
-
-sub IsIntegerType
-{
- my $type = shift;
-
- return 1 if $integerTypeHash{$type};
- return 0;
-}
-
-sub IsCallbackFunctionType
-{
- my $type = shift;
-
- return 1 if $callbackFunctionTypeHash{$type};
- return 0;
-}
-
-sub IsEnumType
-{
- my $type = shift;
-
- return 1 if $enumTypeHash{$type};
- return 0;
-}
-
-sub ValidEnumValues
-{
- my $type = shift;
-
- return @{$enumTypeHash{$type}};
-}
-
-sub IsSVGTypeNeedingTearOff
-{
- my $type = shift;
-
- return 1 if $svgTypeNeedingTearOff{$type};
- return 0;
-}
-
-sub IsSVGTypeWithWritablePropertiesNeedingTearOff
-{
- my $type = shift;
-
- return 1 if $svgTypeWithWritablePropertiesNeedingTearOff{$type};
- return 0;
-}
-
-sub IsTypedArrayType
-{
- my $type = shift;
- return 1 if $typedArrayHash{$type};
- return 0;
-}
-
-sub IsRefPtrType
-{
- my $type = shift;
-
- return 0 if $type eq "any";
- return 0 if IsPrimitiveType($type);
- return 0 if GetArrayType($type);
- return 0 if GetSequenceType($type);
- return 0 if $type eq "Promise";
- return 0 if IsCallbackFunctionType($type);
- return 0 if IsEnumType($type);
- return 0 if IsUnionType($type);
- return 0 if $type eq "Dictionary";
-
- return 1;
-}
-
-sub IsNullableParameter
-{
- my $parameter = shift;
-
- return $parameter->isNullable && !IsRefPtrType($parameter->type) && $parameter->type ne "Dictionary";
-}
-
-sub GetSVGTypeNeedingTearOff
-{
- my $type = shift;
-
- return $svgTypeNeedingTearOff{$type} if exists $svgTypeNeedingTearOff{$type};
- return undef;
-}
-
-sub GetSVGWrappedTypeNeedingTearOff
-{
- my $type = shift;
-
- my $svgTypeNeedingTearOff = GetSVGTypeNeedingTearOff($type);
- return $svgTypeNeedingTearOff if not $svgTypeNeedingTearOff;
-
- if ($svgTypeNeedingTearOff =~ /SVGPropertyTearOff/) {
- $svgTypeNeedingTearOff =~ s/SVGPropertyTearOff<//;
- } elsif ($svgTypeNeedingTearOff =~ /SVGListPropertyTearOff/) {
- $svgTypeNeedingTearOff =~ s/SVGListPropertyTearOff<//;
- } elsif ($svgTypeNeedingTearOff =~ /SVGStaticListPropertyTearOff/) {
- $svgTypeNeedingTearOff =~ s/SVGStaticListPropertyTearOff<//;
- } elsif ($svgTypeNeedingTearOff =~ /SVGTransformListPropertyTearOff/) {
- $svgTypeNeedingTearOff =~ s/SVGTransformListPropertyTearOff<//;
- } elsif ($svgTypeNeedingTearOff =~ /SVGMatrixTearOff/) {
- $svgTypeNeedingTearOff = 'SVGMatrix';
- }
-
- $svgTypeNeedingTearOff =~ s/>//;
- return $svgTypeNeedingTearOff;
-}
-
-sub IsSVGAnimatedType
-{
- my $type = shift;
-
- return $type =~ /^SVGAnimated/;
-}
-
-sub SVGTypeNeedsToHoldContextElement
-{
- my $type = shift;
-
- return IsSVGTypeNeedingTearOff($type) || IsSVGAnimatedType($type);
-}
-
-sub GetSequenceType
-{
- my $type = shift;
-
- return $1 if $type =~ /^sequence<([\w\d_\s]+)>.*/;
- return "";
-}
-
-sub GetArrayType
-{
- my $type = shift;
-
- return $1 if $type =~ /^([\w\d_\s]+)\[\]/;
- return "";
-}
-
-sub GetArrayOrSequenceType
-{
- my $type = shift;
-
- return GetArrayType($type) || GetSequenceType($type);
-}
-
-sub AssertNotSequenceType
-{
- my $type = shift;
- die "Sequences must not be used as the type of an attribute, constant or exception field." if GetSequenceType($type);
-}
-
-sub FirstLetterToUpperCase
-{
- my $param = shift;
- my $ret = ucfirst($param);
- # Capitalize initial acronym, e.g., xml -> setXML
- $ret =~ s/Xml/XML/ if $ret =~ /^Xml/;
- $ret =~ s/Css/CSS/ if $ret =~ /^Css/;
- $ret =~ s/Html/HTML/ if $ret =~ /^Html/;
- $ret =~ s/Ime/IME/ if $ret =~ /^Ime/;
- $ret =~ s/Svg/SVG/ if $ret =~ /^Svg/;
- return $ret;
-}
-
-# URL becomes url, but SetURL becomes setURL.
-sub ToMethodName
-{
- my $param = shift;
- my $ret = lcfirst($param);
- $ret =~ s/hTML/html/ if $ret =~ /^hTML/;
- $ret =~ s/iME/ime/ if $ret =~ /^iME/;
- $ret =~ s/uRL/url/ if $ret =~ /^uRL/;
- $ret =~ s/jS/js/ if $ret =~ /^jS/;
- $ret =~ s/xML/xml/ if $ret =~ /^xML/;
- $ret =~ s/xSLT/xslt/ if $ret =~ /^xSLT/;
- $ret =~ s/cSS/css/ if $ret =~ /^cSS/;
-
- # For HTML5 FileSystem API Flags attributes.
- # (create is widely used to instantiate an object and must be avoided.)
- $ret =~ s/^create/isCreate/ if $ret =~ /^create$/;
- $ret =~ s/^exclusive/isExclusive/ if $ret =~ /^exclusive$/;
-
- return $ret;
-}
-
-sub NamespaceForAttributeName
-{
- my ($interfaceName, $attributeName) = @_;
- return "SVGNames" if $interfaceName =~ /^SVG/ && !$svgAttributesInHTMLHash{$attributeName};
- return "HTMLNames";
-}
-
-# Identifies overloaded functions and for each function adds an array with
-# links to its respective overloads (including itself).
-sub LinkOverloadedFunctions
-{
- my $interface = shift;
-
- my %nameToFunctionsMap = ();
- foreach my $function (@{$interface->functions}) {
- my $name = $function->name;
- $nameToFunctionsMap{$name} = [] if !exists $nameToFunctionsMap{$name} or !$name; # Nameless functions cannot be overloaded
- push(@{$nameToFunctionsMap{$name}}, $function);
- $function->{overloads} = $nameToFunctionsMap{$name};
- $function->{overloadIndex} = @{$nameToFunctionsMap{$name}};
- }
-}
-
-sub AttributeNameForGetterAndSetter
-{
- my $attribute = shift;
-
- my $attributeName = GetImplName($attribute);
- if ($attribute->extendedAttributes->{"ImplementedAs"}) {
- $attributeName = $attribute->extendedAttributes->{"ImplementedAs"};
- }
- my $attributeType = $attribute->type;
-
- return $attributeName;
-}
-
-sub ContentAttributeName
-{
- my ($interfaceName, $attribute) = @_;
-
- my $contentAttributeName = $attribute->extendedAttributes->{"Reflect"};
- return undef if !$contentAttributeName;
-
- $contentAttributeName = lc AttributeNameForGetterAndSetter($attribute) if $contentAttributeName eq "VALUE_IS_MISSING";
-
- my $namespace = NamespaceForAttributeName($interfaceName, $contentAttributeName);
-
- AddToImplIncludes("${namespace}.h");
- # Attr (not Attribute) used in core content attributes
- return "${namespace}::${contentAttributeName}Attr";
-}
-
-sub GetterExpression
-{
- my ($interfaceName, $attribute) = @_;
-
- my $contentAttributeName = ContentAttributeName($interfaceName, $attribute);
-
- if (!$contentAttributeName) {
- return (ToMethodName(AttributeNameForGetterAndSetter($attribute)));
- }
-
- my $functionName;
- if ($attribute->extendedAttributes->{"URL"}) {
- $functionName = "getURLAttribute";
- } elsif ($attribute->type eq "boolean") {
- $functionName = "fastHasAttribute";
- } elsif ($attribute->type eq "long") {
- $functionName = "getIntegralAttribute";
- } elsif ($attribute->type eq "unsigned long") {
- $functionName = "getUnsignedIntegralAttribute";
- } else {
- if ($contentAttributeName eq "HTMLNames::idAttr") {
- $functionName = "getIdAttribute";
- $contentAttributeName = "";
- } elsif ($contentAttributeName eq "HTMLNames::nameAttr") {
- $functionName = "getNameAttribute";
- $contentAttributeName = "";
- } elsif ($contentAttributeName eq "HTMLNames::classAttr") {
- $functionName = "getClassAttribute";
- $contentAttributeName = "";
- } else {
- # We cannot use fast attributes for animated SVG types.
- $functionName = IsSVGAnimatedType($attribute->type) ? "getAttribute" : "fastGetAttribute";
- }
- }
-
- return ($functionName, $contentAttributeName);
-}
-
-sub SetterExpression
-{
- my ($interfaceName, $attribute) = @_;
-
- my $contentAttributeName = ContentAttributeName($interfaceName, $attribute);
-
- if (!$contentAttributeName) {
- return ("set" . FirstLetterToUpperCase(AttributeNameForGetterAndSetter($attribute)));
- }
-
- my $functionName;
- if ($attribute->type eq "boolean") {
- $functionName = "setBooleanAttribute";
- } elsif ($attribute->type eq "long") {
- $functionName = "setIntegralAttribute";
- } elsif ($attribute->type eq "unsigned long") {
- $functionName = "setUnsignedIntegralAttribute";
- } else {
- $functionName = "setAttribute";
- }
-
- return ($functionName, $contentAttributeName);
-}
-
-sub GenerateConditionalString
-{
- my $node = shift;
-
- my $conditional = $node->extendedAttributes->{"Conditional"};
- if ($conditional) {
- return GenerateConditionalStringFromAttributeValue($conditional);
- } else {
- return "";
- }
-}
-
-sub GenerateConditionalStringFromAttributeValue
-{
- my $conditional = shift;
-
- my $operator = ($conditional =~ /&/ ? '&' : ($conditional =~ /\|/ ? '|' : ''));
- if ($operator) {
- # Avoid duplicated conditions.
- my %conditions;
- map { $conditions{$_} = 1 } split('\\' . $operator, $conditional);
- return "ENABLE(" . join(") $operator$operator ENABLE(", sort keys %conditions) . ")";
- } else {
- return "ENABLE(" . $conditional . ")";
- }
-}
-
-sub GenerateCompileTimeCheckForEnumsIfNeeded
-{
- my $interface = shift;
- my $implClassName = GetImplName($interface);
- my @checks = ();
- # If necessary, check that all constants are available as enums with the same value.
- if (!$interface->extendedAttributes->{"DoNotCheckConstants"} && @{$interface->constants}) {
- foreach my $constant (@{$interface->constants}) {
- my $reflect = $constant->extendedAttributes->{"Reflect"};
- my $name = $reflect ? $reflect : $constant->name;
- my $value = $constant->value;
-
- if ($constant->extendedAttributes->{"ImplementedBy"}) {
- my $implementedByImplName = GetImplNameFromImplementedBy($constant->extendedAttributes->{"ImplementedBy"});
- push(@checks, " COMPILE_ASSERT($value == " . $implementedByImplName . "::$name, TheValueOf${implClassName}_${name}DoesntMatchWithImplementation);\n");
- } else {
- push(@checks, " COMPILE_ASSERT($value == ${implClassName}::$name, TheValueOf${implClassName}_${name}DoesntMatchWithImplementation);\n");
- }
- }
- }
- return @checks;
-}
-
-sub ExtendedAttributeContains
-{
- my $extendedAttributeValue = shift;
- return 0 unless $extendedAttributeValue;
- my $keyword = shift;
-
- my @extendedAttributeValues = split /\s*(\&|\|)\s*/, $extendedAttributeValue;
- return grep { $_ eq $keyword } @extendedAttributeValues;
-}
-
-sub InheritsInterface
-{
- my $interface = shift;
- my $interfaceName = shift;
- my $found = 0;
-
- return 1 if $interfaceName eq $interface->name;
- ForAllParents($interface, sub {
- my $currentInterface = shift;
- if ($currentInterface->name eq $interfaceName) {
- $found = 1;
- }
- return 1 if $found;
- }, 0);
-
- return $found;
-}
-
-sub InheritsExtendedAttribute
-{
- my $interface = shift;
- my $extendedAttribute = shift;
- my $found = 0;
-
- return 1 if $interface->extendedAttributes->{$extendedAttribute};
- ForAllParents($interface, sub {
- my $currentInterface = shift;
- if ($currentInterface->extendedAttributes->{$extendedAttribute}) {
- $found = 1;
- }
- return 1 if $found;
- }, 0);
-
- return $found;
-}
-
-sub NeedsSpecialWrap
-{
- my $interface = shift;
-
- return 1 if ExtendedAttributeContains($interface->extendedAttributes->{"Custom"}, "ToV8");
- return 1 if ExtendedAttributeContains($interface->extendedAttributes->{"Custom"}, "Wrap");
- return 1 if $interface->extendedAttributes->{"SpecialWrapFor"};
- return 1 if InheritsInterface($interface, "Document");
-
- return 0;
-}
-
-1;
diff --git a/chromium/third_party/WebKit/Source/bindings/scripts/code_generator_v8.py b/chromium/third_party/WebKit/Source/bindings/scripts/code_generator_v8.py
new file mode 100644
index 00000000000..778a87ec79b
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/bindings/scripts/code_generator_v8.py
@@ -0,0 +1,222 @@
+# Copyright (C) 2013 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.
+
+"""Generate Blink V8 bindings (.h and .cpp files).
+
+If run itself, caches Jinja templates (and creates dummy file for build,
+since cache filenames are unpredictable and opaque).
+
+This module is *not* concurrency-safe without care: bytecode caching creates
+a race condition on cache *write* (crashes if one process tries to read a
+partially-written cache). However, if you pre-cache the templates (by running
+the module itself), then you can parallelize compiling individual files, since
+cache *reading* is safe.
+
+Input: An object of class IdlDefinitions, containing an IDL interface X
+Output: V8X.h and V8X.cpp
+
+Design doc: http://www.chromium.org/developers/design-documents/idl-compiler
+"""
+
+import os
+import posixpath
+import re
+import sys
+
+# Path handling for libraries and templates
+# Paths have to be normalized because Jinja uses the exact template path to
+# determine the hash used in the cache filename, and we need a pre-caching step
+# to be concurrency-safe. Use absolute path because __file__ is absolute if
+# module is imported, and relative if executed directly.
+# If paths differ between pre-caching and individual file compilation, the cache
+# is regenerated, which causes a race condition and breaks concurrent build,
+# since some compile processes will try to read the partially written cache.
+module_path, module_filename = os.path.split(os.path.realpath(__file__))
+third_party_dir = os.path.normpath(os.path.join(
+ module_path, os.pardir, os.pardir, os.pardir, os.pardir))
+templates_dir = os.path.normpath(os.path.join(
+ module_path, os.pardir, 'templates'))
+# Make sure extension is .py, not .pyc or .pyo, so doesn't depend on caching
+module_pyname = os.path.splitext(module_filename)[0] + '.py'
+
+# jinja2 is in chromium's third_party directory.
+# Insert at 1 so at front to override system libraries, and
+# after path[0] == invoking script dir
+sys.path.insert(1, third_party_dir)
+import jinja2
+
+import idl_types
+from idl_types import IdlType
+import v8_callback_interface
+from v8_globals import includes, interfaces
+import v8_interface
+import v8_types
+from v8_utilities import capitalize, cpp_name, conditional_string, v8_class_name
+
+
+class CodeGeneratorV8(object):
+ def __init__(self, interfaces_info, cache_dir):
+ interfaces_info = interfaces_info or {}
+ self.interfaces_info = interfaces_info
+ self.jinja_env = initialize_jinja_env(cache_dir)
+
+ # Set global type info
+ idl_types.set_ancestors(dict(
+ (interface_name, interface_info['ancestors'])
+ for interface_name, interface_info in interfaces_info.iteritems()
+ if interface_info['ancestors']))
+ IdlType.set_callback_interfaces(set(
+ interface_name
+ for interface_name, interface_info in interfaces_info.iteritems()
+ if interface_info['is_callback_interface']))
+ IdlType.set_implemented_as_interfaces(dict(
+ (interface_name, interface_info['implemented_as'])
+ for interface_name, interface_info in interfaces_info.iteritems()
+ if interface_info['implemented_as']))
+ IdlType.set_garbage_collected_types(set(
+ interface_name
+ for interface_name, interface_info in interfaces_info.iteritems()
+ if 'GarbageCollected' in interface_info['inherited_extended_attributes']))
+ IdlType.set_will_be_garbage_collected_types(set(
+ interface_name
+ for interface_name, interface_info in interfaces_info.iteritems()
+ if 'WillBeGarbageCollected' in interface_info['inherited_extended_attributes']))
+ v8_types.set_component_dirs(dict(
+ (interface_name, interface_info['component_dir'])
+ for interface_name, interface_info in interfaces_info.iteritems()))
+
+ def generate_code(self, definitions, interface_name):
+ """Returns .h/.cpp code as (header_text, cpp_text)."""
+ try:
+ interface = definitions.interfaces[interface_name]
+ except KeyError:
+ raise Exception('%s not in IDL definitions' % interface_name)
+
+ # Store other interfaces for introspection
+ interfaces.update(definitions.interfaces)
+
+ # Set local type info
+ IdlType.set_callback_functions(definitions.callback_functions.keys())
+ IdlType.set_enums((enum.name, enum.values)
+ for enum in definitions.enumerations.values())
+
+ # Select appropriate Jinja template and contents function
+ if interface.is_callback:
+ header_template_filename = 'callback_interface.h'
+ cpp_template_filename = 'callback_interface.cpp'
+ generate_contents = v8_callback_interface.generate_callback_interface
+ else:
+ header_template_filename = 'interface.h'
+ cpp_template_filename = 'interface.cpp'
+ generate_contents = v8_interface.generate_interface
+ header_template = self.jinja_env.get_template(header_template_filename)
+ cpp_template = self.jinja_env.get_template(cpp_template_filename)
+
+ # Generate contents (input parameters for Jinja)
+ template_contents = generate_contents(interface)
+ template_contents['code_generator'] = module_pyname
+
+ # Add includes for interface itself and any dependencies
+ interface_info = self.interfaces_info[interface_name]
+ template_contents['header_includes'].add(interface_info['include_path'])
+ template_contents['header_includes'] = sorted(template_contents['header_includes'])
+ includes.update(interface_info.get('dependencies_include_paths', []))
+ template_contents['cpp_includes'] = sorted(includes)
+
+ # Render Jinja templates
+ header_text = header_template.render(template_contents)
+ cpp_text = cpp_template.render(template_contents)
+ return header_text, cpp_text
+
+
+def initialize_jinja_env(cache_dir):
+ jinja_env = jinja2.Environment(
+ loader=jinja2.FileSystemLoader(templates_dir),
+ # Bytecode cache is not concurrency-safe unless pre-cached:
+ # if pre-cached this is read-only, but writing creates a race condition.
+ bytecode_cache=jinja2.FileSystemBytecodeCache(cache_dir),
+ keep_trailing_newline=True, # newline-terminate generated files
+ lstrip_blocks=True, # so can indent control flow tags
+ trim_blocks=True)
+ jinja_env.filters.update({
+ 'blink_capitalize': capitalize,
+ 'conditional': conditional_if_endif,
+ 'runtime_enabled': runtime_enabled_if,
+ })
+ return jinja_env
+
+
+# [Conditional]
+def conditional_if_endif(code, conditional_string):
+ # Jinja2 filter to generate if/endif directive blocks
+ if not conditional_string:
+ return code
+ return ('#if %s\n' % conditional_string +
+ code +
+ '#endif // %s\n' % conditional_string)
+
+
+# [RuntimeEnabled]
+def runtime_enabled_if(code, runtime_enabled_function_name):
+ if not runtime_enabled_function_name:
+ return code
+ # Indent if statement to level of original code
+ indent = re.match(' *', code).group(0)
+ return ('%sif (%s()) {\n' % (indent, runtime_enabled_function_name) +
+ ' %s\n' % '\n '.join(code.splitlines()) +
+ '%s}\n' % indent)
+
+
+################################################################################
+
+def main(argv):
+ # If file itself executed, cache templates
+ try:
+ cache_dir = argv[1]
+ dummy_filename = argv[2]
+ except IndexError as err:
+ print 'Usage: %s CACHE_DIR DUMMY_FILENAME' % argv[0]
+ return 1
+
+ # Cache templates
+ jinja_env = initialize_jinja_env(cache_dir)
+ template_filenames = [filename for filename in os.listdir(templates_dir)
+ # Skip .svn, directories, etc.
+ if filename.endswith(('.cpp', '.h'))]
+ for template_filename in template_filenames:
+ jinja_env.get_template(template_filename)
+
+ # Create a dummy file as output for the build system,
+ # since filenames of individual cache files are unpredictable and opaque
+ # (they are hashes of the template path, which varies based on environment)
+ with open(dummy_filename, 'w') as dummy_file:
+ pass # |open| creates or touches the file
+
+
+if __name__ == '__main__':
+ sys.exit(main(sys.argv))
diff --git a/chromium/third_party/WebKit/Source/bindings/scripts/compute_dependencies.py b/chromium/third_party/WebKit/Source/bindings/scripts/compute_dependencies.py
deleted file mode 100755
index b358ae60e01..00000000000
--- a/chromium/third_party/WebKit/Source/bindings/scripts/compute_dependencies.py
+++ /dev/null
@@ -1,404 +0,0 @@
-#!/usr/bin/python
-#
-# Copyright (C) 2013 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.
-
-import optparse
-import os
-import posixpath
-import re
-import string
-
-
-class IdlBadFilenameError(Exception):
- """Raised if an IDL filename disagrees with the interface name in the file."""
- pass
-
-
-class IdlInterfaceFileNotFoundError(Exception):
- """Raised if the IDL file implementing an interface cannot be found."""
- pass
-
-
-def parse_options():
- parser = optparse.OptionParser()
- parser.add_option('--event-names-file', help='output file')
- parser.add_option('--main-idl-files-list', help='file listing main (compiled to Blink) IDL files')
- parser.add_option('--support-idl-files-list', help='file listing support IDL files (not compiled to Blink, e.g. testing)')
- parser.add_option('--interface-dependencies-file', help='output file')
- parser.add_option('--bindings-derived-sources-file', help='output file')
- parser.add_option('--window-constructors-file', help='output file')
- parser.add_option('--workerglobalscope-constructors-file', help='output file')
- parser.add_option('--sharedworkerglobalscope-constructors-file', help='output file')
- parser.add_option('--dedicatedworkerglobalscope-constructors-file', help='output file')
- parser.add_option('--serviceworkerglobalscope-constructors-file', help='output file')
- parser.add_option('--write-file-only-if-changed', type='int', help='if true, do not write an output file if it would be identical to the existing one, which avoids unnecessary rebuilds in ninja')
- options, args = parser.parse_args()
- if options.event_names_file is None:
- parser.error('Must specify an output file using --event-names-file.')
- if options.interface_dependencies_file is None:
- parser.error('Must specify an output file using --interface-dependencies-file.')
- if options.bindings_derived_sources_file is None:
- parser.error('Must specify an output file using --bindings-derived-sources-file.')
- if options.window_constructors_file is None:
- parser.error('Must specify an output file using --window-constructors-file.')
- if options.workerglobalscope_constructors_file is None:
- parser.error('Must specify an output file using --workerglobalscope-constructors-file.')
- if options.sharedworkerglobalscope_constructors_file is None:
- parser.error('Must specify an output file using --sharedworkerglobalscope-constructors-file.')
- if options.dedicatedworkerglobalscope_constructors_file is None:
- parser.error('Must specify an output file using --dedicatedworkerglobalscope-constructors-file.')
- if options.serviceworkerglobalscope_constructors_file is None:
- parser.error('Must specify an output file using --serviceworkerglobalscope-constructors-file.')
- if options.main_idl_files_list is None:
- parser.error('Must specify a file listing main IDL files using --main-idl-files-list.')
- if options.support_idl_files_list is None:
- parser.error('Must specify a file listing support IDL files using --support-idl-files-list.')
- if options.write_file_only_if_changed is None:
- parser.error('Must specify whether file is only written if changed using --write-file-only-if-changed.')
- options.write_file_only_if_changed = bool(options.write_file_only_if_changed)
- if args:
- parser.error('No arguments taken, but "%s" given.' % ' '.join(args))
- return options
-
-
-def get_file_contents(idl_filename):
- with open(idl_filename) as idl_file:
- lines = idl_file.readlines()
- return ''.join(lines)
-
-
-def write_file(new_lines, destination_filename, only_if_changed):
- if only_if_changed and os.path.isfile(destination_filename):
- with open(destination_filename) as destination_file:
- old_lines = destination_file.readlines()
- if old_lines == new_lines:
- return
- with open(destination_filename, 'w') as destination_file:
- destination_file.write(''.join(new_lines))
-
-
-def get_partial_interface_name_from_idl(file_contents):
- match = re.search(r'partial\s+interface\s+(\w+)', file_contents)
- return match and match.group(1)
-
-
-# identifier-A implements identifier-B;
-# http://www.w3.org/TR/WebIDL/#idl-implements-statements
-def get_implemented_interfaces_from_idl(file_contents, interface_name):
- def get_implemented(left_identifier, right_identifier):
- # identifier-A must be the current interface
- if left_identifier != interface_name:
- raise IdlBadFilenameError("Identifier on the left of the 'implements' statement should be %s in %s.idl, but found %s" % (interface_name, interface_name, left_identifier))
- return right_identifier
-
- implements_re = r'^\s*(\w+)\s+implements\s+(\w+)\s*;'
- implements_matches = re.finditer(implements_re, file_contents, re.MULTILINE)
- implements_pairs = [(match.group(1), match.group(2))
- for match in implements_matches]
- return [get_implemented(left, right) for left, right in implements_pairs]
-
-
-def is_callback_interface_from_idl(file_contents):
- match = re.search(r'callback\s+interface\s+\w+', file_contents)
- return bool(match)
-
-
-def get_parent_interface(file_contents):
- match = re.search(r'interface\s+\w+\s*:\s*(\w+)\s*', file_contents)
- return match and match.group(1)
-
-
-def get_interface_extended_attributes_from_idl(file_contents):
- match = re.search(r'\[(.*)\]\s+(callback\s+)?(interface|exception)\s+(\w+)',
- file_contents, flags=re.DOTALL)
- if not match:
- return {}
- # Strip comments
- # re.compile needed b/c Python 2.6 doesn't support flags in re.sub
- single_line_comment_re = re.compile(r'//.*$', flags=re.MULTILINE)
- block_comment_re = re.compile(r'/\*.*?\*/', flags=re.MULTILINE | re.DOTALL)
- extended_attributes_string = re.sub(single_line_comment_re, '', match.group(1))
- extended_attributes_string = re.sub(block_comment_re, '', extended_attributes_string)
- extended_attributes = {}
- # FIXME: this splitting is WRONG: it fails on ExtendedAttributeArgList like
- # 'NamedConstructor=Foo(a, b)'
- parts = [extended_attribute.strip()
- for extended_attribute in extended_attributes_string.split(',')
- # Discard empty parts, which may exist due to trailing comma
- if extended_attribute.strip()]
- for part in parts:
- name, _, value = map(string.strip, part.partition('='))
- extended_attributes[name] = value
- return extended_attributes
-
-
-def generate_constructor_attribute_list(interface_name, extended_attributes):
- extended_attributes_list = [
- name + '=' + extended_attributes[name]
- for name in 'Conditional', 'PerContextEnabled', 'RuntimeEnabled'
- if name in extended_attributes]
- if extended_attributes_list:
- extended_string = '[%s] ' % ', '.join(extended_attributes_list)
- else:
- extended_string = ''
-
- attribute_string = 'attribute {interface_name}Constructor {interface_name}'.format(interface_name=interface_name)
- attributes_list = [extended_string + attribute_string]
-
- # In addition to the regular property, for every [NamedConstructor]
- # extended attribute on an interface, a corresponding property MUST exist
- # on the ECMAScript global object.
- if 'NamedConstructor' in extended_attributes:
- named_constructor = extended_attributes['NamedConstructor']
- # Extract function name, namely everything before opening '('
- constructor_name = re.sub(r'\(.*', '', named_constructor)
- # Note the reduplicated 'ConstructorConstructor'
- attribute_string = 'attribute %sConstructorConstructor %s' % (interface_name, constructor_name)
- attributes_list.append(extended_string + attribute_string)
-
- return attributes_list
-
-
-def generate_event_names_file(destination_filename, event_names, only_if_changed):
- def extended_attribute_string(name):
- value = extended_attributes[name]
- if name == 'RuntimeEnabled':
- value += 'Enabled'
- return name + '=' + value
-
- source_dir, _ = os.path.split(os.getcwd())
- lines = []
- lines.append('namespace="Event"\n')
- lines.append('\n')
- for filename, extended_attributes in sorted(event_names.iteritems()):
- refined_filename, _ = os.path.splitext(os.path.relpath(filename, source_dir))
- refined_filename = refined_filename.replace(os.sep, posixpath.sep)
- extended_attributes_list = [
- extended_attribute_string(name)
- for name in 'Conditional', 'ImplementedAs', 'RuntimeEnabled'
- if name in extended_attributes]
- lines.append('%s %s\n' % (refined_filename, ', '.join(extended_attributes_list)))
- write_file(lines, destination_filename, only_if_changed)
-
-
-def generate_global_constructors_partial_interface(interface_name, destination_filename, constructor_attributes_list, only_if_changed):
- lines = (['partial interface %s {\n' % interface_name] +
- [' %s;\n' % constructor_attribute
- for constructor_attribute in sorted(constructor_attributes_list)] +
- ['};\n'])
- write_file(lines, destination_filename, only_if_changed)
-
-
-def generate_dependencies(idl_file_name, interfaces, dependencies, partial_interface_files, implements_interfaces, implemented_somewhere):
- interface_name, _ = os.path.splitext(os.path.basename(idl_file_name))
- full_path = os.path.realpath(idl_file_name)
- idl_file_contents = get_file_contents(full_path)
-
- # Handle partial interfaces
- partial_interface_name = get_partial_interface_name_from_idl(idl_file_contents)
- if partial_interface_name:
- partial_interface_files[partial_interface_name].append(full_path)
- return partial_interface_name
-
- interfaces.add(interface_name)
- # Non-partial interfaces default to having bindings generated
- dependencies[full_path] = []
-
- # Parse 'identifier-A implements identifier-B;' statements
- implemented_interfaces = get_implemented_interfaces_from_idl(idl_file_contents, interface_name)
- implements_interfaces[interface_name] = implemented_interfaces
- implemented_somewhere |= set(implemented_interfaces)
-
- return partial_interface_name
-
-
-def remove_interfaces_implemented_somewhere(dependencies, interface_name_to_idl_file, implemented_somewhere):
- # Interfaces that are implemented by another interface do not have
- # their own bindings generated, as this would be redundant with the
- # actual implementation.
- for implemented_interface in implemented_somewhere:
- full_path = interface_name_to_idl_file[implemented_interface]
- del dependencies[full_path]
-
-
-def record_global_constructors_and_extended_attribute(idl_file_name, global_constructors, interface_extended_attribute, parent_interface):
- interface_name, _ = os.path.splitext(os.path.basename(idl_file_name))
- full_path = os.path.realpath(idl_file_name)
- idl_file_contents = get_file_contents(full_path)
- extended_attributes = get_interface_extended_attributes_from_idl(idl_file_contents)
-
- # Record global constructors
- if not is_callback_interface_from_idl(idl_file_contents) and 'NoInterfaceObject' not in extended_attributes:
- global_contexts = extended_attributes.get('GlobalContext', 'Window').split('&')
- new_constructor_list = generate_constructor_attribute_list(interface_name, extended_attributes)
- for global_object in global_contexts:
- global_constructors[global_object].extend(new_constructor_list)
-
- # Record parents and extended attributes for generating event names
- if interface_name == 'Event':
- interface_extended_attribute[interface_name] = extended_attributes
- parent = get_parent_interface(idl_file_contents)
- if parent:
- parent_interface[interface_name] = parent
- interface_extended_attribute[interface_name] = extended_attributes
-
-
-def parse_idl_files(main_idl_files, support_idl_files, global_constructors_filenames):
- """Return dependencies between IDL files, constructors on global objects, and events.
-
- Returns:
- interfaces:
- set of all interfaces
- bindings_derived_sources:
- list of main IDL file names (except support IDL file names)
- dependencies:
- dict of main IDL filename (for a given interface) -> list of partial IDL filenames (for that interface)
- The keys (main IDL files) are the files for which bindings are
- generated. This does not include IDL files for interfaces
- implemented by another interface.
- global_constructors:
- dict of global objects -> list of constructors on that object
- event_names:
- dict of interfaces that inherit from Event -> list of extended attributes for the interface
- """
- interfaces = set()
- dependencies = {}
- partial_interface_files = {}
- implements_interfaces = {}
- implemented_somewhere = set()
-
- global_constructors = {}
- for global_object in global_constructors_filenames.keys():
- global_constructors[global_object] = []
-
- # Parents and extended attributes (of interfaces with parents) are
- # used in generating event names
- parent_interface = {}
- interface_extended_attribute = {}
-
- interface_name_to_idl_file = {}
- for idl_file_name in main_idl_files + support_idl_files:
- full_path = os.path.realpath(idl_file_name)
- interface_name, _ = os.path.splitext(os.path.basename(idl_file_name))
- interface_name_to_idl_file[interface_name] = full_path
- partial_interface_files[interface_name] = []
-
- # Generate dependencies, global_constructors and interface_extended_attributes for main IDL files
- for idl_file_name in main_idl_files:
- if not generate_dependencies(idl_file_name, interfaces, dependencies, partial_interface_files, implements_interfaces, implemented_somewhere):
- record_global_constructors_and_extended_attribute(idl_file_name, global_constructors, interface_extended_attribute, parent_interface)
-
- bindings_derived_sources = dependencies.copy()
- remove_interfaces_implemented_somewhere(bindings_derived_sources, interface_name_to_idl_file, implemented_somewhere)
-
- # Add constructors on global objects to partial interfaces
- for global_object, filename in global_constructors_filenames.iteritems():
- if global_object in interfaces:
- partial_interface_files[global_object].append(filename)
-
- # Add support IDL files to the dependencies for supporting partial interface
- for idl_file_name in support_idl_files:
- generate_dependencies(idl_file_name, interfaces, dependencies, partial_interface_files, implements_interfaces, implemented_somewhere)
- remove_interfaces_implemented_somewhere(dependencies, interface_name_to_idl_file, implemented_somewhere)
-
- # An IDL file's dependencies are partial interface files that extend it,
- # and files for other interfaces that this interfaces implements.
- for idl_file_path in dependencies.iterkeys():
- interface_name, _ = os.path.splitext(os.path.basename(idl_file_path))
- implemented_interfaces = implements_interfaces[interface_name]
- try:
- interface_paths = map(lambda x: interface_name_to_idl_file[x], implemented_interfaces)
- except KeyError as key_name:
- raise IdlInterfaceFileNotFoundError('Could not find the IDL file where the following implemented interface is defined: %s' % key_name)
- dependencies[idl_file_path] = sorted(partial_interface_files[interface_name] + interface_paths)
-
- # Generate event names for all interfaces that inherit from Event,
- # including Event itself.
- event_names = {}
- if 'Event' in interfaces:
- event_names[interface_name_to_idl_file['Event']] = interface_extended_attribute['Event']
- for interface, parent in parent_interface.iteritems():
- while parent in parent_interface:
- parent = parent_interface[parent]
- if parent == 'Event':
- event_names[interface_name_to_idl_file[interface]] = interface_extended_attribute[interface]
-
- return interfaces, dependencies, bindings_derived_sources, global_constructors, event_names
-
-
-def write_dependency_file(filename, dependencies, only_if_changed):
- """Write the interface dependencies file.
-
- The format is as follows:
-
- Document.idl P.idl
- Event.idl
- Window.idl Q.idl R.idl S.idl
- ...
-
- The above indicates that:
- Document.idl depends on P.idl,
- Event.idl depends on no other IDL files, and
- Window.idl depends on Q.idl, R.idl, and S.idl.
-
- An IDL that is a dependency of another IDL (e.g. P.idl) does not have its
- own line in the dependency file.
- """
- lines = ['%s %s\n' % (idl_file, ' '.join(sorted(dependency_files)))
- for idl_file, dependency_files in sorted(dependencies.iteritems())]
- write_file(lines, filename, only_if_changed)
-
-
-def main():
- options = parse_options()
- with open(options.main_idl_files_list) as idl_files_list:
- main_idl_files = [string.rstrip(line, '\n') for line in idl_files_list]
- with open(options.support_idl_files_list) as idl_files_list:
- support_idl_files = [string.rstrip(line, '\n') for line in idl_files_list]
- only_if_changed = options.write_file_only_if_changed
- global_constructors_filenames = {
- 'Window': options.window_constructors_file,
- 'WorkerGlobalScope': options.workerglobalscope_constructors_file,
- 'SharedWorkerGlobalScope': options.sharedworkerglobalscope_constructors_file,
- 'DedicatedWorkerGlobalScope': options.dedicatedworkerglobalscope_constructors_file,
- 'ServiceWorkerGlobalScope': options.serviceworkerglobalscope_constructors_file,
- }
-
- interfaces, dependencies, bindings_derived_sources, global_constructors, event_names = parse_idl_files(main_idl_files, support_idl_files, global_constructors_filenames)
-
- write_dependency_file(options.interface_dependencies_file, dependencies, only_if_changed)
- write_dependency_file(options.bindings_derived_sources_file, bindings_derived_sources, only_if_changed)
- for interface_name, filename in global_constructors_filenames.iteritems():
- if interface_name in interfaces:
- generate_global_constructors_partial_interface(interface_name, filename, global_constructors[interface_name], only_if_changed)
- generate_event_names_file(options.event_names_file, event_names, only_if_changed)
-
-
-if __name__ == '__main__':
- main()
diff --git a/chromium/third_party/WebKit/Source/bindings/scripts/compute_global_objects.py b/chromium/third_party/WebKit/Source/bindings/scripts/compute_global_objects.py
new file mode 100755
index 00000000000..93d2eed5db3
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/bindings/scripts/compute_global_objects.py
@@ -0,0 +1,113 @@
+#!/usr/bin/python
+#
+# Copyright 2014 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""Compute global objects.
+
+Global objects are defined by interfaces with [Global] or [PrimaryGlobal] on
+their definition: http://heycam.github.io/webidl/#Global
+
+Design document: http://www.chromium.org/developers/design-documents/idl-build
+"""
+
+import optparse
+import os
+import cPickle as pickle
+import sys
+
+from utilities import get_file_contents, idl_filename_to_interface_name, get_interface_extended_attributes_from_idl, read_file_to_list, read_pickle_files, write_pickle_file
+
+GLOBAL_EXTENDED_ATTRIBUTES = frozenset([
+ 'Global',
+ 'PrimaryGlobal',
+])
+
+
+def parse_options():
+ usage = 'Usage: %prog [options] [GlobalObjectsComponent.pickle]... [GlobalObjects.pickle]'
+ parser = optparse.OptionParser(usage=usage)
+ parser.add_option('--idl-files-list', help='file listing IDL files')
+ parser.add_option('--write-file-only-if-changed', type='int', help='if true, do not write an output file if it would be identical to the existing one, which avoids unnecessary rebuilds in ninja')
+
+ options, args = parser.parse_args()
+
+ if options.idl_files_list is None:
+ parser.error('Must specify a file listing IDL files using --idl-files-list.')
+ if options.write_file_only_if_changed is None:
+ parser.error('Must specify whether output files are only written if changed using --write-file-only-if-changed.')
+ options.write_file_only_if_changed = bool(options.write_file_only_if_changed)
+ if not args:
+ parser.error('Must specify an output pickle filename as argument, '
+ 'optionally preceeded by input pickle filenames.')
+
+ return options, args
+
+
+def dict_union(dicts):
+ return dict((k, v) for d in dicts for k, v in d.iteritems())
+
+
+def idl_file_to_global_names(idl_filename):
+ """Returns global names, if any, for an IDL file.
+
+ If the [Global] or [PrimaryGlobal] extended attribute is declared with an
+ identifier list argument, then those identifiers are the interface's global
+ names; otherwise, the interface has a single global name, which is the
+ interface's identifier (http://heycam.github.io/webidl/#Global).
+ """
+ interface_name = idl_filename_to_interface_name(idl_filename)
+ full_path = os.path.realpath(idl_filename)
+ idl_file_contents = get_file_contents(full_path)
+ extended_attributes = get_interface_extended_attributes_from_idl(idl_file_contents)
+
+ global_keys = GLOBAL_EXTENDED_ATTRIBUTES.intersection(
+ extended_attributes.iterkeys())
+ if not global_keys:
+ return
+ if len(global_keys) > 1:
+ raise ValueError('The [Global] and [PrimaryGlobal] extended attributes '
+ 'MUST NOT be declared on the same interface.')
+ global_key = next(iter(global_keys))
+
+ global_value = extended_attributes[global_key]
+ if global_value:
+ # FIXME: In spec names are comma-separated, which makes parsing very
+ # difficult (https://www.w3.org/Bugs/Public/show_bug.cgi?id=24959).
+ return global_value.split('&')
+ return [interface_name]
+
+
+def idl_files_to_interface_name_global_names(idl_files):
+ """Yields pairs (interface_name, global_names) found in IDL files."""
+ for idl_filename in idl_files:
+ interface_name = idl_filename_to_interface_name(idl_filename)
+ global_names = idl_file_to_global_names(idl_filename)
+ if global_names:
+ yield interface_name, global_names
+
+
+################################################################################
+
+def main():
+ options, args = parse_options()
+ # args = Input1, Input2, ..., Output
+ output_global_objects_filename = args.pop()
+ interface_name_global_names = dict_union(
+ existing_interface_name_global_names
+ for existing_interface_name_global_names in read_pickle_files(args))
+
+ # Input IDL files are passed in a file, due to OS command line length
+ # limits. This is generated at GYP time, which is ok b/c files are static.
+ idl_files = read_file_to_list(options.idl_files_list)
+ interface_name_global_names.update(
+ idl_files_to_interface_name_global_names(idl_files))
+
+ write_pickle_file(output_global_objects_filename,
+ interface_name_global_names,
+ options.write_file_only_if_changed)
+
+
+if __name__ == '__main__':
+ sys.exit(main())
diff --git a/chromium/third_party/WebKit/Source/bindings/scripts/compute_interfaces_info_individual.py b/chromium/third_party/WebKit/Source/bindings/scripts/compute_interfaces_info_individual.py
new file mode 100755
index 00000000000..c3671d9ebdf
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/bindings/scripts/compute_interfaces_info_individual.py
@@ -0,0 +1,192 @@
+#!/usr/bin/python
+#
+# Copyright (C) 2013 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.
+
+"""Compute global interface information for individual IDL files.
+
+Auxiliary module for compute_interfaces_info_overall, which consolidates
+this individual information, computing info that spans multiple files
+(dependencies and ancestry).
+
+This distinction is so that individual interface info can be computed
+separately for each component (avoiding duplicated reading of individual
+files), then consolidated using *only* the info visible to a given component.
+
+Design doc: http://www.chromium.org/developers/design-documents/idl-build
+"""
+
+from collections import defaultdict
+import optparse
+import os
+import posixpath
+import sys
+
+from utilities import get_file_contents, read_file_to_list, idl_filename_to_interface_name, write_pickle_file, get_interface_extended_attributes_from_idl, is_callback_interface_from_idl, get_partial_interface_name_from_idl, get_implements_from_idl, get_parent_interface, get_put_forward_interfaces_from_idl
+
+module_path = os.path.dirname(__file__)
+source_path = os.path.normpath(os.path.join(module_path, os.pardir, os.pardir))
+
+# Global variables (filled in and exported)
+interfaces_info = {}
+partial_interface_files = defaultdict(lambda: {
+ 'full_paths': [],
+ 'include_paths': [],
+})
+
+
+def parse_options():
+ usage = 'Usage: %prog [options] [generated1.idl]...'
+ parser = optparse.OptionParser(usage=usage)
+ parser.add_option('--component-dir', help='component directory')
+ parser.add_option('--idl-files-list', help='file listing IDL files')
+ parser.add_option('--interfaces-info-file', help='output pickle file')
+ parser.add_option('--write-file-only-if-changed', type='int', help='if true, do not write an output file if it would be identical to the existing one, which avoids unnecessary rebuilds in ninja')
+
+ options, args = parser.parse_args()
+ if options.component_dir is None:
+ parser.error('Must specify a component directory using --component-dir.')
+ if options.interfaces_info_file is None:
+ parser.error('Must specify an output file using --interfaces-info-file.')
+ if options.idl_files_list is None:
+ parser.error('Must specify a file listing IDL files using --idl-files-list.')
+ if options.write_file_only_if_changed is None:
+ parser.error('Must specify whether file is only written if changed using --write-file-only-if-changed.')
+ options.write_file_only_if_changed = bool(options.write_file_only_if_changed)
+ return options, args
+
+
+################################################################################
+# Computations
+################################################################################
+
+def include_path(idl_filename, implemented_as=None):
+ """Returns relative path to header file in POSIX format; used in includes.
+
+ POSIX format is used for consistency of output, so reference tests are
+ platform-independent.
+ """
+ relative_path_local = os.path.relpath(idl_filename, source_path)
+ relative_dir_local = os.path.dirname(relative_path_local)
+ relative_dir_posix = relative_dir_local.replace(os.path.sep, posixpath.sep)
+
+ # IDL file basename is used even if only a partial interface file
+ idl_file_basename, _ = os.path.splitext(os.path.basename(idl_filename))
+ cpp_class_name = implemented_as or idl_file_basename
+
+ return posixpath.join(relative_dir_posix, cpp_class_name + '.h')
+
+
+def add_paths_to_partials_dict(partial_interface_name, full_path, this_include_path=None):
+ paths_dict = partial_interface_files[partial_interface_name]
+ paths_dict['full_paths'].append(full_path)
+ if this_include_path:
+ paths_dict['include_paths'].append(this_include_path)
+
+
+def compute_info_individual(idl_filename, component_dir):
+ full_path = os.path.realpath(idl_filename)
+ idl_file_contents = get_file_contents(full_path)
+
+ extended_attributes = get_interface_extended_attributes_from_idl(idl_file_contents)
+ implemented_as = extended_attributes.get('ImplementedAs')
+ this_include_path = include_path(idl_filename, implemented_as)
+
+ # Handle partial interfaces
+ partial_interface_name = get_partial_interface_name_from_idl(idl_file_contents)
+ if partial_interface_name:
+ add_paths_to_partials_dict(partial_interface_name, full_path, this_include_path)
+ return
+
+ # If not a partial interface, the basename is the interface name
+ interface_name = idl_filename_to_interface_name(idl_filename)
+
+ # 'implements' statements can be included in either the file for the
+ # implement*ing* interface (lhs of 'implements') or implement*ed* interface
+ # (rhs of 'implements'). Store both for now, then merge to implement*ing*
+ # interface later.
+ left_interfaces, right_interfaces = get_implements_from_idl(idl_file_contents, interface_name)
+
+ interfaces_info[interface_name] = {
+ 'component_dir': component_dir,
+ 'extended_attributes': extended_attributes,
+ 'full_path': full_path,
+ 'implemented_as': implemented_as,
+ 'implemented_by_interfaces': left_interfaces, # private, merged to next
+ 'implements_interfaces': right_interfaces,
+ 'include_path': this_include_path,
+ # FIXME: temporary private field, while removing old treatement of
+ # 'implements': http://crbug.com/360435
+ 'is_legacy_treat_as_partial_interface': 'LegacyTreatAsPartialInterface' in extended_attributes,
+ 'is_callback_interface': is_callback_interface_from_idl(idl_file_contents),
+ 'parent': get_parent_interface(idl_file_contents),
+ # Interfaces that are referenced (used as types) and that we introspect
+ # during code generation (beyond interface-level data ([ImplementedAs],
+ # is_callback_interface, ancestors, and inherited extended attributes):
+ # deep dependencies.
+ # These cause rebuilds of referrers, due to the dependency, so these
+ # should be minimized; currently only targets of [PutForwards].
+ 'referenced_interfaces': get_put_forward_interfaces_from_idl(idl_file_contents),
+ }
+
+
+def info_individual():
+ """Returns info packaged as a dict."""
+ return {
+ 'interfaces_info': interfaces_info,
+ # Can't pickle defaultdict, convert to dict
+ 'partial_interface_files': dict(partial_interface_files),
+ }
+
+
+################################################################################
+
+def main():
+ options, args = parse_options()
+
+ # Static IDL files are passed in a file (generated at GYP time), due to OS
+ # command line length limits
+ idl_files = read_file_to_list(options.idl_files_list)
+ # Generated IDL files are passed at the command line, since these are in the
+ # build directory, which is determined at build time, not GYP time, so these
+ # cannot be included in the file listing static files
+ idl_files.extend(args)
+
+ # Compute information for individual files
+ # Information is stored in global variables interfaces_info and
+ # partial_interface_files.
+ for idl_filename in idl_files:
+ compute_info_individual(idl_filename, options.component_dir)
+
+ write_pickle_file(options.interfaces_info_file,
+ info_individual(),
+ options.write_file_only_if_changed)
+
+
+if __name__ == '__main__':
+ sys.exit(main())
diff --git a/chromium/third_party/WebKit/Source/bindings/scripts/compute_interfaces_info_overall.py b/chromium/third_party/WebKit/Source/bindings/scripts/compute_interfaces_info_overall.py
new file mode 100755
index 00000000000..658ccfade6f
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/bindings/scripts/compute_interfaces_info_overall.py
@@ -0,0 +1,264 @@
+#!/usr/bin/python
+#
+# Copyright (C) 2013 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.
+
+"""Compute global interface information, including public information, dependencies, and inheritance.
+
+Computed data is stored in a global variable, |interfaces_info|, and written as
+output (concretely, exported as a pickle). This is then used by the IDL compiler
+itself, so it does not need to compute global information itself, and so that
+inter-IDL dependencies are clear, since they are all computed here.
+
+The |interfaces_info| pickle is a *global* dependency: any changes cause a full
+rebuild. This is to avoid having to compute which public data is visible by
+which IDL files on a file-by-file basis, which is very complex for little
+benefit.
+|interfaces_info| should thus only contain data about an interface that
+contains paths or is needed by *other* interfaces, e.g., path data (to abstract
+the compiler from OS-specific file paths) or public data (to avoid having to
+read other interfaces unnecessarily).
+It should *not* contain full information about an interface (e.g., all
+extended attributes), as this would cause unnecessary rebuilds.
+
+|interfaces_info| is a dict, keyed by |interface_name|.
+
+Current keys are:
+* dependencies:
+ 'implements_interfaces': targets of 'implements' statements
+ 'referenced_interfaces': reference interfaces that are introspected
+ (currently just targets of [PutForwards])
+
+* inheritance:
+ 'ancestors': all ancestor interfaces
+ 'inherited_extended_attributes': inherited extended attributes
+ (all controlling memory management)
+
+* public:
+ 'is_callback_interface': bool, callback interface or not
+ 'implemented_as': value of [ImplementedAs=...] on interface (C++ class name)
+
+* paths:
+ 'full_path': path to the IDL file, so can lookup an IDL by interface name
+ 'include_path': path for use in C++ #include directives
+ 'dependencies_full_paths': paths to dependencies (for merging into main)
+ 'dependencies_include_paths': paths for use in C++ #include directives
+
+Note that all of these are stable information, unlikely to change without
+moving or deleting files (hence requiring a full rebuild anyway) or significant
+code changes (for inherited extended attributes).
+
+Design doc: http://www.chromium.org/developers/design-documents/idl-build
+"""
+
+from collections import defaultdict
+import cPickle as pickle
+import optparse
+import sys
+
+from utilities import read_pickle_files, write_pickle_file
+
+INHERITED_EXTENDED_ATTRIBUTES = set([
+ 'ActiveDOMObject',
+ 'DependentLifetime',
+ 'GarbageCollected',
+ 'WillBeGarbageCollected',
+])
+
+# Main variable (filled in and exported)
+interfaces_info = {}
+
+# Auxiliary variables (not visible to future build steps)
+partial_interface_files = defaultdict(lambda: {
+ 'full_paths': [],
+ 'include_paths': [],
+})
+parent_interfaces = {}
+inherited_extended_attributes_by_interface = {} # interface name -> extended attributes
+
+
+class IdlInterfaceFileNotFoundError(Exception):
+ """Raised if the IDL file implementing an interface cannot be found."""
+ pass
+
+
+def parse_options():
+ usage = 'Usage: %prog [InfoIndividual.pickle]... [Info.pickle]'
+ parser = optparse.OptionParser(usage=usage)
+ parser.add_option('--write-file-only-if-changed', type='int', help='if true, do not write an output file if it would be identical to the existing one, which avoids unnecessary rebuilds in ninja')
+
+ options, args = parser.parse_args()
+ if options.write_file_only_if_changed is None:
+ parser.error('Must specify whether file is only written if changed using --write-file-only-if-changed.')
+ options.write_file_only_if_changed = bool(options.write_file_only_if_changed)
+ return options, args
+
+
+def dict_of_dicts_of_lists_update_or_append(existing, other):
+ """Updates an existing dict of dicts of lists, or appends to lists if key already present.
+
+ Needed for merging partial_interface_files across components.
+ """
+ for key, value in other.iteritems():
+ if key not in existing:
+ existing[key] = value
+ continue
+ existing_value = existing[key]
+ for inner_key, inner_value in value.iteritems():
+ existing_value[inner_key].extend(inner_value)
+
+
+################################################################################
+# Computations
+################################################################################
+
+def compute_inheritance_info(interface_name):
+ """Compute inheritance information, namely ancestors and inherited extended attributes."""
+ def generate_ancestors(interface_name):
+ while interface_name in parent_interfaces:
+ interface_name = parent_interfaces[interface_name]
+ yield interface_name
+
+ ancestors = list(generate_ancestors(interface_name))
+ inherited_extended_attributes = inherited_extended_attributes_by_interface[interface_name]
+ for ancestor in ancestors:
+ # Ancestors may not be present, notably if an ancestor is a generated
+ # IDL file and we are running this script from run-bindings-tests,
+ # where we don't generate these files.
+ ancestor_extended_attributes = inherited_extended_attributes_by_interface.get(ancestor, {})
+ inherited_extended_attributes.update(ancestor_extended_attributes)
+
+ interfaces_info[interface_name].update({
+ 'ancestors': ancestors,
+ 'inherited_extended_attributes': inherited_extended_attributes,
+ })
+
+
+def compute_interfaces_info_overall(info_individuals):
+ """Compute information about IDL files.
+
+ Information is stored in global interfaces_info.
+ """
+ for info in info_individuals:
+ # No overlap between interface names, so ok to use dict.update
+ interfaces_info.update(info['interfaces_info'])
+ # Interfaces in one component may have partial interfaces in
+ # another component. This is ok (not a layering violation), since
+ # partial interfaces are used to *extend* interfaces.
+ # We thus need to update or append if already present
+ dict_of_dicts_of_lists_update_or_append(
+ partial_interface_files, info['partial_interface_files'])
+
+ # Record inheritance information individually
+ for interface_name, interface_info in interfaces_info.iteritems():
+ extended_attributes = interface_info['extended_attributes']
+ inherited_extended_attributes_by_interface[interface_name] = dict(
+ (key, value)
+ for key, value in extended_attributes.iteritems()
+ if key in INHERITED_EXTENDED_ATTRIBUTES)
+ parent = interface_info['parent']
+ if parent:
+ parent_interfaces[interface_name] = parent
+
+ # Once all individual files handled, can compute inheritance information
+ # and dependencies
+
+ # Compute inheritance info
+ for interface_name in interfaces_info:
+ compute_inheritance_info(interface_name)
+
+ # Compute dependencies
+ # Move implements info from implement*ed* interface (rhs of 'implements')
+ # to implement*ing* interface (lhs of 'implements').
+ # Note that moving an 'implements' statement between implementing and
+ # implemented files does not change the info (or hence cause a rebuild)!
+ for right_interface_name, interface_info in interfaces_info.iteritems():
+ for left_interface_name in interface_info['implemented_by_interfaces']:
+ interfaces_info[left_interface_name]['implements_interfaces'].append(right_interface_name)
+ del interface_info['implemented_by_interfaces']
+
+ # An IDL file's dependencies are partial interface files that extend it,
+ # and files for other interfaces that this interfaces implements.
+ for interface_name, interface_info in interfaces_info.iteritems():
+ partial_interface_paths = partial_interface_files[interface_name]
+ partial_interfaces_full_paths = partial_interface_paths['full_paths']
+ # Partial interface definitions each need an include, as they are
+ # implemented in separate classes from the main interface.
+ partial_interfaces_include_paths = partial_interface_paths['include_paths']
+
+ implemented_interfaces = interface_info['implements_interfaces']
+ try:
+ implemented_interfaces_info = [
+ interfaces_info[interface]
+ for interface in implemented_interfaces]
+ except KeyError as key_name:
+ raise IdlInterfaceFileNotFoundError('Could not find the IDL file where the following implemented interface is defined: %s' % key_name)
+ implemented_interfaces_full_paths = [
+ implemented_interface_info['full_path']
+ for implemented_interface_info in implemented_interfaces_info]
+ # Implemented interfaces don't need includes, as this is handled in
+ # the Blink implementation (they are implemented on |impl| itself,
+ # hence header is included in implementing class).
+ # However, they are needed for legacy implemented interfaces that
+ # are being treated as partial interfaces, until we remove these.
+ # http://crbug.com/360435
+ implemented_interfaces_include_paths = [
+ implemented_interface_info['include_path']
+ for implemented_interface_info in implemented_interfaces_info
+ if implemented_interface_info['is_legacy_treat_as_partial_interface']]
+
+ interface_info.update({
+ 'dependencies_full_paths': (partial_interfaces_full_paths +
+ implemented_interfaces_full_paths),
+ 'dependencies_include_paths': (partial_interfaces_include_paths +
+ implemented_interfaces_include_paths),
+ })
+
+ # Clean up temporary private information
+ for interface_info in interfaces_info.itervalues():
+ del interface_info['extended_attributes']
+ del interface_info['is_legacy_treat_as_partial_interface']
+ del interface_info['parent']
+
+
+################################################################################
+
+def main():
+ options, args = parse_options()
+ # args = Input1, Input2, ..., Output
+ interfaces_info_filename = args.pop()
+ info_individuals = read_pickle_files(args)
+
+ compute_interfaces_info_overall(info_individuals)
+ write_pickle_file(interfaces_info_filename,
+ interfaces_info,
+ options.write_file_only_if_changed)
+
+
+if __name__ == '__main__':
+ sys.exit(main())
diff --git a/chromium/third_party/WebKit/Source/bindings/scripts/generate_bindings.pl b/chromium/third_party/WebKit/Source/bindings/scripts/generate_bindings.pl
deleted file mode 100755
index 68f36800403..00000000000
--- a/chromium/third_party/WebKit/Source/bindings/scripts/generate_bindings.pl
+++ /dev/null
@@ -1,309 +0,0 @@
-#!/usr/bin/perl -w
-#
-# Copyright (C) 2005 Apple Computer, Inc.
-# Copyright (C) 2006 Anders Carlsson <andersca@mac.com>
-#
-# 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
-# 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.
-#
-
-use strict;
-
-use File::Path;
-use File::Basename;
-use Getopt::Long;
-use Text::ParseWords;
-use Cwd;
-
-use idl_parser;
-use code_generator_v8;
-use idl_serializer;
-
-my @idlDirectories;
-my $outputDirectory;
-my $preprocessor;
-my $verbose;
-my $interfaceDependenciesFile;
-my $additionalIdlFiles;
-my $idlAttributesFile;
-my $writeFileOnlyIfChanged;
-
-GetOptions('include=s@' => \@idlDirectories,
- 'outputDir=s' => \$outputDirectory,
- 'preprocessor=s' => \$preprocessor,
- 'verbose' => \$verbose,
- 'interfaceDependenciesFile=s' => \$interfaceDependenciesFile,
- 'additionalIdlFiles=s' => \$additionalIdlFiles,
- 'idlAttributesFile=s' => \$idlAttributesFile,
- 'write-file-only-if-changed=s' => \$writeFileOnlyIfChanged);
-
-my $targetIdlFile = $ARGV[0];
-
-die('Must specify input file.') unless defined($targetIdlFile);
-die('Must specify output directory.') unless defined($outputDirectory);
-
-$targetIdlFile = Cwd::realpath($targetIdlFile);
-if ($verbose) {
- print "$targetIdlFile\n";
-}
-my $targetInterfaceName = fileparse(basename($targetIdlFile), ".idl");
-
-my $idlFound = 0;
-my @dependencyIdlFiles;
-if ($interfaceDependenciesFile) {
- # The format of the interface dependencies file:
- #
- # Window.idl P.idl Q.idl R.idl
- # Document.idl S.idl
- # Event.idl
- # ...
- #
- # The above indicates that Window.idl depends on P.idl, Q.idl, and R.idl,
- # Document.idl depends on S.idl, and Event.idl depends on no IDLs.
- # A dependency IDL file (one that is depended on by another IDL, e.g. P.idl
- # in the above) does not have its own entry in the dependency file.
- open FH, "< $interfaceDependenciesFile" or die "Cannot open $interfaceDependenciesFile\n";
- while (my $line = <FH>) {
- my ($idlFile, @followingIdlFiles) = split(/\s+/, $line);
- if ($idlFile and basename($idlFile) eq basename($targetIdlFile)) {
- $idlFound = 1;
- # We sort the dependency IDL files so that the corresponding code is generated
- # in a consistent order. This is important for the bindings tests.
- @dependencyIdlFiles = sort @followingIdlFiles;
- }
- }
- close FH;
-
- # $additionalIdlFiles is for IDL files not listed in the interface
- # dependencies file, namely generated IDL files for interfaces
- # (not partial interfaces), so we need to generate .h and .cpp files.
- if (!$idlFound and $additionalIdlFiles) {
- my @idlFiles = shellwords($additionalIdlFiles);
- $idlFound = grep { $_ and basename($_) eq basename($targetIdlFile) } @idlFiles;
- }
-
- if (!$idlFound) {
- # IDL files for dependencies (partial interfaces and interfaces
- # implemented elsewhere). We generate empty .h and .cpp files just to
- # tell build scripts that outputs have been created.
- generateEmptyHeaderAndCpp($targetInterfaceName, $outputDirectory);
- exit 0;
- }
-}
-
-# Parse the target IDL file.
-my $targetParser = idl_parser->new(!$verbose);
-my $targetDocument = $targetParser->Parse($targetIdlFile, $preprocessor);
-
-if ($idlAttributesFile) {
- my $idlAttributes = loadIDLAttributes($idlAttributesFile);
- checkIDLAttributes($idlAttributes, $targetDocument, basename($targetIdlFile));
-}
-
-foreach my $idlFile (@dependencyIdlFiles) {
- next if $idlFile eq $targetIdlFile;
-
- my $interfaceName = fileparse(basename($idlFile), ".idl");
- my $parser = idl_parser->new(!$verbose);
- my $document = $parser->Parse($idlFile, $preprocessor);
-
- foreach my $interface (@{$document->interfaces}) {
- if (!$interface->isPartial || $interface->name eq $targetInterfaceName) {
- my $targetDataNode;
- foreach my $interface (@{$targetDocument->interfaces}) {
- if ($interface->name eq $targetInterfaceName) {
- $targetDataNode = $interface;
- last;
- }
- }
- die "Not found an interface ${targetInterfaceName} in ${targetInterfaceName}.idl." unless defined $targetDataNode;
-
- # Support for attributes of partial interfaces.
- foreach my $attribute (@{$interface->attributes}) {
- # Record that this attribute is implemented by $interfaceName.
- $attribute->extendedAttributes->{"ImplementedBy"} = $interfaceName unless $interface->extendedAttributes->{"LegacyImplementedInBaseClass"};
-
- # Add interface-wide extended attributes to each attribute.
- applyInterfaceExtendedAttributes($interface, $attribute->extendedAttributes);
-
- push(@{$targetDataNode->attributes}, $attribute);
- }
-
- # Support for methods of partial interfaces.
- foreach my $function (@{$interface->functions}) {
- # Record that this method is implemented by $interfaceName.
- $function->extendedAttributes->{"ImplementedBy"} = $interfaceName unless $interface->extendedAttributes->{"LegacyImplementedInBaseClass"};
-
- # Add interface-wide extended attributes to each method.
- applyInterfaceExtendedAttributes($interface, $function->extendedAttributes);
-
- push(@{$targetDataNode->functions}, $function);
- }
-
- # Support for constants of partial interfaces.
- foreach my $constant (@{$interface->constants}) {
- # Record that this constant is implemented by $interfaceName.
- $constant->extendedAttributes->{"ImplementedBy"} = $interfaceName unless $interface->extendedAttributes->{"LegacyImplementedInBaseClass"};
-
- # Add interface-wide extended attributes to each constant.
- applyInterfaceExtendedAttributes($interface, $constant->extendedAttributes);
-
- push(@{$targetDataNode->constants}, $constant);
- }
- } else {
- die "$idlFile is not a dependency of $targetIdlFile. There maybe a bug in the dependency computer (compute_dependencies.py).\n";
- }
- }
-}
-
-# Serialize to and from JSON to ensure Perl and Python parsers are equivalent,
-# as part of porting compiler to Python. See http://crbug.com/242795
-$targetDocument = deserializeJSON(serializeJSON($targetDocument));
-
-# Generate desired output for the target IDL file.
-my @interfaceIdlFiles = ($targetDocument->fileName(), @dependencyIdlFiles);
-my $codeGenerator = code_generator_v8->new($targetDocument, \@idlDirectories, $preprocessor, $verbose, \@interfaceIdlFiles, $writeFileOnlyIfChanged);
-my $interfaces = $targetDocument->interfaces;
-foreach my $interface (@$interfaces) {
- print "Generating bindings code for IDL interface \"" . $interface->name . "\"...\n" if $verbose;
- $codeGenerator->GenerateInterface($interface);
- $codeGenerator->WriteData($interface, $outputDirectory);
-}
-
-sub generateEmptyHeaderAndCpp
-{
- my ($targetInterfaceName, $outputDirectory) = @_;
-
- my $headerName = "V8${targetInterfaceName}.h";
- my $cppName = "V8${targetInterfaceName}.cpp";
- my $contents = "/*
- This file is generated just to tell build scripts that $headerName and
- $cppName are created for ${targetInterfaceName}.idl, and thus
- prevent the build scripts from trying to generate $headerName and
- $cppName at every build. This file must not be tried to compile.
-*/
-";
- open FH, "> ${outputDirectory}/${headerName}" or die "Cannot open $headerName\n";
- print FH $contents;
- close FH;
-
- open FH, "> ${outputDirectory}/${cppName}" or die "Cannot open $cppName\n";
- print FH $contents;
- close FH;
-}
-
-sub loadIDLAttributes
-{
- my $idlAttributesFile = shift;
-
- my %idlAttributes;
- open FH, "<", $idlAttributesFile or die "Couldn't open $idlAttributesFile: $!";
- while (my $line = <FH>) {
- chomp $line;
- next if $line =~ /^\s*#/;
- next if $line =~ /^\s*$/;
-
- if ($line =~ /^\s*([^=\s]*)\s*=?\s*(.*)/) {
- my $name = $1;
- $idlAttributes{$name} = {};
- if ($2) {
- foreach my $rightValue (split /\|/, $2) {
- $rightValue =~ s/^\s*|\s*$//g;
- $rightValue = "VALUE_IS_MISSING" unless $rightValue;
- $idlAttributes{$name}{$rightValue} = 1;
- }
- } else {
- $idlAttributes{$name}{"VALUE_IS_MISSING"} = 1;
- }
- } else {
- die "The format of " . basename($idlAttributesFile) . " is wrong: line $.\n";
- }
- }
- close FH;
-
- return \%idlAttributes;
-}
-
-sub checkIDLAttributes
-{
- my $idlAttributes = shift;
- my $document = shift;
- my $idlFile = shift;
-
- foreach my $interface (@{$document->interfaces}) {
- checkIfIDLAttributesExists($idlAttributes, $interface->extendedAttributes, $idlFile);
-
- foreach my $attribute (@{$interface->attributes}) {
- checkIfIDLAttributesExists($idlAttributes, $attribute->extendedAttributes, $idlFile);
- }
-
- foreach my $function (@{$interface->functions}) {
- checkIfIDLAttributesExists($idlAttributes, $function->extendedAttributes, $idlFile);
- foreach my $parameter (@{$function->parameters}) {
- checkIfIDLAttributesExists($idlAttributes, $parameter->extendedAttributes, $idlFile);
- }
- }
- }
-}
-
-sub applyInterfaceExtendedAttributes
-{
- my $interface = shift;
- my $extendedAttributes = shift;
-
- foreach my $extendedAttributeName (keys %{$interface->extendedAttributes}) {
- next if $extendedAttributeName eq "ImplementedAs";
- $extendedAttributes->{$extendedAttributeName} = $interface->extendedAttributes->{$extendedAttributeName};
- }
-}
-
-sub checkIfIDLAttributesExists
-{
- my $idlAttributes = shift;
- my $extendedAttributes = shift;
- my $idlFile = shift;
-
- my $error;
- OUTER: for my $name (keys %$extendedAttributes) {
- if (!exists $idlAttributes->{$name}) {
- $error = "Invalid IDL attribute [$name] found in $idlFile.";
- last;
- }
- # Check no argument first, since "*" means "some argument (not missing)".
- if ($extendedAttributes->{$name} eq "VALUE_IS_MISSING" and not exists $idlAttributes->{$name}{"VALUE_IS_MISSING"}) {
- $error = "Missing required argument for IDL attribute [$name] in file $idlFile.";
- last;
- }
- if (exists $idlAttributes->{$name}{"*"}) {
- next;
- }
- for my $rightValue (split /\s*[|&]\s*/, $extendedAttributes->{$name}) {
- if (!(exists $idlAttributes->{$name}{$rightValue})) {
- $error = "Invalid IDL attribute value [$name=" . $extendedAttributes->{$name} . "] found in $idlFile.";
- last OUTER;
- }
- }
- }
- if ($error) {
- die "IDL ATTRIBUTE CHECKER ERROR: $error
-If you want to add a new IDL extended attribute, please add it to:
- bindings/IDLExtendedAttributes.txt
-and add an explanation to the Blink IDL documentation at:
- http://www.chromium.org/blink/webidl/blink-idl-extended-attributes
-";
- }
-}
diff --git a/chromium/third_party/WebKit/Source/bindings/scripts/generate_event_interfaces.py b/chromium/third_party/WebKit/Source/bindings/scripts/generate_event_interfaces.py
new file mode 100755
index 00000000000..b222cb4a64b
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/bindings/scripts/generate_event_interfaces.py
@@ -0,0 +1,122 @@
+#!/usr/bin/python
+#
+# Copyright (C) 2013 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.
+
+"""Generate event interfaces .in file (EventInterfaces.in).
+
+The event interfaces .in file contains a list of all Event interfaces, i.e.,
+all interfaces that inherit from Event, including Event itself,
+together with certain extended attributes.
+
+Paths are in POSIX format, and relative to Source/.
+
+This list is used in core/ to generate EventFactory and EventNames.
+The .in format is documented in build/scripts/in_file.py.
+"""
+
+from optparse import OptionParser
+import os
+import posixpath
+import sys
+
+from utilities import get_file_contents, read_file_to_list, write_file, get_interface_extended_attributes_from_idl
+
+EXPORTED_EXTENDED_ATTRIBUTES = (
+ 'Conditional',
+ 'ImplementedAs',
+ 'RuntimeEnabled',
+)
+module_path = os.path.dirname(os.path.realpath(__file__))
+source_dir = os.path.normpath(os.path.join(module_path, os.pardir, os.pardir))
+
+
+def parse_options():
+ parser = OptionParser()
+ parser.add_option('--event-idl-files-list', help='file listing event IDL files')
+ parser.add_option('--event-interfaces-file', help='output file')
+ parser.add_option('--write-file-only-if-changed', type='int', help='if true, do not write an output file if it would be identical to the existing one, which avoids unnecessary rebuilds in ninja')
+ parser.add_option('--suffix', help='specify a suffix to the namespace, i.e., "Modules". Default is None.')
+
+ options, args = parser.parse_args()
+ if options.event_idl_files_list is None:
+ parser.error('Must specify a file listing event IDL files using --event-idl-files-list.')
+ if options.event_interfaces_file is None:
+ parser.error('Must specify an output file using --event-interfaces-file.')
+ if options.write_file_only_if_changed is None:
+ parser.error('Must specify whether file is only written if changed using --write-file-only-if-changed.')
+ options.write_file_only_if_changed = bool(options.write_file_only_if_changed)
+ if args:
+ parser.error('No arguments allowed, but %d given.' % len(args))
+ return options
+
+
+def write_event_interfaces_file(event_idl_files, destination_filename, only_if_changed, suffix):
+ def extended_attribute_string(name, value):
+ if name == 'RuntimeEnabled':
+ value += 'Enabled'
+ return name + '=' + value
+
+ def interface_line(full_path):
+ relative_path_local, _ = os.path.splitext(os.path.relpath(full_path, source_dir))
+ relative_path_posix = relative_path_local.replace(os.sep, posixpath.sep)
+
+ idl_file_contents = get_file_contents(full_path)
+ extended_attributes = get_interface_extended_attributes_from_idl(idl_file_contents)
+ extended_attributes_list = [
+ extended_attribute_string(name, extended_attributes[name])
+ for name in EXPORTED_EXTENDED_ATTRIBUTES
+ if name in extended_attributes]
+
+ return '%s %s\n' % (relative_path_posix,
+ ', '.join(extended_attributes_list))
+
+ lines = ['namespace="Event"\n']
+ if suffix:
+ lines.append('suffix="' + suffix + '"\n')
+ lines.append('\n')
+ interface_lines = [interface_line(event_idl_file)
+ for event_idl_file in event_idl_files]
+ interface_lines.sort()
+ lines.extend(interface_lines)
+ write_file(''.join(lines), destination_filename, only_if_changed)
+
+
+################################################################################
+
+def main():
+ options = parse_options()
+ event_idl_files = read_file_to_list(options.event_idl_files_list)
+ write_event_interfaces_file(event_idl_files,
+ options.event_interfaces_file,
+ options.write_file_only_if_changed,
+ options.suffix)
+
+
+if __name__ == '__main__':
+ sys.exit(main())
diff --git a/chromium/third_party/WebKit/Source/bindings/scripts/generate_global_constructors.py b/chromium/third_party/WebKit/Source/bindings/scripts/generate_global_constructors.py
new file mode 100755
index 00000000000..81838fe1865
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/bindings/scripts/generate_global_constructors.py
@@ -0,0 +1,184 @@
+#!/usr/bin/python
+#
+# Copyright 2014 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""Generates interface properties on global objects.
+
+Concretely these are implemented as "constructor attributes", meaning
+"attributes whose name ends with Constructor" (special-cased by code generator),
+hence "global constructors" for short.
+
+For reference on global objects, see:
+http://heycam.github.io/webidl/#Global
+http://heycam.github.io/webidl/#Exposed
+
+Design document: http://www.chromium.org/developers/design-documents/idl-build
+"""
+
+import itertools
+import optparse
+import os
+import cPickle as pickle
+import re
+import sys
+
+from collections import defaultdict
+from utilities import get_file_contents, idl_filename_to_interface_name, read_file_to_list, write_file, get_interface_extended_attributes_from_idl, is_callback_interface_from_idl
+
+interface_name_to_global_names = {}
+global_name_to_constructors = defaultdict(list)
+
+
+HEADER_FORMAT = """// Stub header file for {{idl_basename}}
+// Required because the IDL compiler assumes that a corresponding header file
+// exists for each IDL file.
+"""
+
+def parse_options():
+ parser = optparse.OptionParser()
+ parser.add_option('--idl-files-list', help='file listing IDL files')
+ parser.add_option('--global-objects-file', help='pickle file of global objects')
+ parser.add_option('--write-file-only-if-changed', type='int', help='if true, do not write an output file if it would be identical to the existing one, which avoids unnecessary rebuilds in ninja')
+
+ options, args = parser.parse_args()
+
+ if options.idl_files_list is None:
+ parser.error('Must specify a file listing IDL files using --idl-files-list.')
+ if options.global_objects_file is None:
+ parser.error('Must specify a pickle file of global objects using --global-objects-file.')
+ if options.write_file_only_if_changed is None:
+ parser.error('Must specify whether output files are only written if changed using --write-file-only-if-changed.')
+ options.write_file_only_if_changed = bool(options.write_file_only_if_changed)
+
+ return options, args
+
+
+def flatten_list(iterable):
+ return list(itertools.chain.from_iterable(iterable))
+
+
+def interface_name_to_constructors(interface_name):
+ """Returns constructors for an interface."""
+ global_names = interface_name_to_global_names[interface_name]
+ return flatten_list(global_name_to_constructors[global_name]
+ for global_name in global_names)
+
+
+def record_global_constructors(idl_filename):
+ interface_name = idl_filename_to_interface_name(idl_filename)
+ full_path = os.path.realpath(idl_filename)
+ idl_file_contents = get_file_contents(full_path)
+ extended_attributes = get_interface_extended_attributes_from_idl(idl_file_contents)
+
+ # An interface property is produced for every non-callback interface
+ # that does not have [NoInterfaceObject].
+ # Callback interfaces with constants also have interface properties,
+ # but there are none of these in Blink.
+ # http://heycam.github.io/webidl/#es-interfaces
+ if (is_callback_interface_from_idl(idl_file_contents) or
+ 'NoInterfaceObject' in extended_attributes):
+ return
+
+ # The [Exposed] extended attribute MUST take an identifier list. Each
+ # identifier in the list MUST be a global name. An interface or interface
+ # member the extended attribute applies to will be exposed only on objects
+ # associated with ECMAScript global environments whose global object
+ # implements an interface that has a matching global name.
+ # FIXME: In spec names are comma-separated, but that makes parsing very
+ # difficult (https://www.w3.org/Bugs/Public/show_bug.cgi?id=24959).
+ exposed_global_names = extended_attributes.get('Exposed', 'Window').split('&')
+ new_constructors_list = generate_global_constructors_list(interface_name, extended_attributes)
+ for exposed_global_name in exposed_global_names:
+ global_name_to_constructors[exposed_global_name].extend(new_constructors_list)
+
+
+def generate_global_constructors_list(interface_name, extended_attributes):
+ extended_attributes_list = [
+ name + '=' + extended_attributes[name]
+ for name in 'Conditional', 'PerContextEnabled', 'RuntimeEnabled'
+ if name in extended_attributes]
+ if extended_attributes_list:
+ extended_string = '[%s] ' % ', '.join(extended_attributes_list)
+ else:
+ extended_string = ''
+
+ attribute_string = 'attribute {interface_name}Constructor {interface_name}'.format(interface_name=interface_name)
+ attributes_list = [extended_string + attribute_string]
+
+ # In addition to the usual interface property, for every [NamedConstructor]
+ # extended attribute on an interface, a corresponding property MUST exist
+ # on the ECMAScript global object.
+ # http://heycam.github.io/webidl/#NamedConstructor
+ if 'NamedConstructor' in extended_attributes:
+ named_constructor = extended_attributes['NamedConstructor']
+ # Extract function name, namely everything before opening '('
+ constructor_name = re.sub(r'\(.*', '', named_constructor)
+ # Note the reduplicated 'ConstructorConstructor'
+ # FIXME: rename to NamedConstructor
+ attribute_string = 'attribute %sConstructorConstructor %s' % (interface_name, constructor_name)
+ attributes_list.append(extended_string + attribute_string)
+
+ return attributes_list
+
+
+def write_global_constructors_partial_interface(interface_name, idl_filename, constructor_attributes_list, only_if_changed):
+ # FIXME: replace this with a simple Jinja template
+ lines = (['partial interface %s {\n' % interface_name] +
+ [' %s;\n' % constructor_attribute
+ # FIXME: sort by interface name (not first by extended attributes)
+ for constructor_attribute in sorted(constructor_attributes_list)] +
+ ['};\n'])
+ write_file(''.join(lines), idl_filename, only_if_changed)
+ header_filename = os.path.splitext(idl_filename)[0] + '.h'
+ idl_basename = os.path.basename(idl_filename)
+ write_file(HEADER_FORMAT.format(idl_basename=idl_basename),
+ header_filename, only_if_changed)
+
+
+################################################################################
+
+def main():
+ options, args = parse_options()
+
+ # Input IDL files are passed in a file, due to OS command line length
+ # limits. This is generated at GYP time, which is ok b/c files are static.
+ idl_files = read_file_to_list(options.idl_files_list)
+
+ # Output IDL files (to generate) are passed at the command line, since
+ # these are in the build directory, which is determined at build time, not
+ # GYP time.
+ # These are passed as pairs of GlobalObjectName, GlobalObject.idl
+ interface_name_idl_filename = [(args[i], args[i + 1])
+ for i in range(0, len(args), 2)]
+
+ with open(options.global_objects_file) as global_objects_file:
+ interface_name_to_global_names.update(pickle.load(global_objects_file))
+
+ for idl_filename in idl_files:
+ record_global_constructors(idl_filename)
+
+ # Check for [Exposed] / [Global] mismatch.
+ known_global_names = frozenset(itertools.chain.from_iterable(interface_name_to_global_names.values()))
+ exposed_global_names = frozenset(global_name_to_constructors)
+ if not exposed_global_names.issubset(known_global_names):
+ unknown_global_names = exposed_global_names.difference(known_global_names)
+ raise ValueError('The following global names were used in '
+ '[Exposed=xxx] but do not match any [Global] / '
+ '[PrimaryGlobal] interface: %s'
+ % list(unknown_global_names))
+
+ # Write partial interfaces containing constructor attributes for each
+ # global interface.
+ for interface_name, idl_filename in interface_name_idl_filename:
+ constructors = interface_name_to_constructors(interface_name)
+ write_global_constructors_partial_interface(
+ interface_name,
+ idl_filename,
+ constructors,
+ options.write_file_only_if_changed)
+
+
+if __name__ == '__main__':
+ sys.exit(main())
diff --git a/chromium/third_party/WebKit/Source/bindings/scripts/global_constructors.gypi b/chromium/third_party/WebKit/Source/bindings/scripts/global_constructors.gypi
new file mode 100644
index 00000000000..58073e70923
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/bindings/scripts/global_constructors.gypi
@@ -0,0 +1,73 @@
+# Copyright 2014 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+#
+# This file is meant to be included into a target to provide an action
+# to compute global objects in a component.
+#
+# To use this, create a gyp target with the following form:
+# {
+# 'target_name': 'core_global_constructors_idls',
+# 'dependencies': [
+# 'component_global_objects',
+# ],
+# 'variables': {
+# 'idl_files': '<(list_of_idl_files)',
+# 'global_objects_file': '<(some_dir)/GlobalObjectsComponent.pickle',
+# 'global_names_idl_files': [
+# 'GlobalName',
+# '<(blink_core_output_dir)/GlobalScopeComponentConstructors.idl',
+# # ...
+# ],
+# 'outputs': [
+# '<@(component_global_constructors_generated_idl_files)',
+# '<@(component_global_constructors_generated_header_files)',
+# ],
+# },
+# 'includes': ['path/to/this/gypi/file'],
+# },
+#
+# Required variables:
+# idl_files - List of .idl files that will be searched in.
+# This should *only* contain main IDL files, excluding dependencies and
+# testing, which should not appear on global objects.
+# global_objects - Pickle file of global objects.
+# global_names_idl_files - pairs (GlobalName, Constructors.idl)
+# outputs - List of output files.
+# Passed as a variable here, included by the template in the action.
+#
+# Spec: http://heycam.github.io/webidl/#Global
+# http://heycam.github.io/webidl/#Exposed
+# Design document: http://www.chromium.org/developers/design-documents/idl-build
+
+{
+ 'type': 'none',
+ 'actions': [{
+ 'action_name': 'generate_<(_target_name)',
+ 'message': 'Generating IDL files for constructors on global objects for <(_target_name)',
+ 'variables': {
+ 'idl_files_list': '<|(<(_target_name)_idl_files_list.tmp <@(idl_files))',
+ },
+ 'includes': ['scripts.gypi'],
+ 'inputs': [
+ '<(bindings_scripts_dir)/generate_global_constructors.py',
+ '<(bindings_scripts_dir)/utilities.py',
+ '<(idl_files_list)',
+ '<@(idl_files)',
+ '<(global_objects_file)',
+ ],
+ 'outputs': ['<@(outputs)'],
+ 'action': [
+ 'python',
+ '<(bindings_scripts_dir)/generate_global_constructors.py',
+ '--idl-files-list',
+ '<(idl_files_list)',
+ '--global-objects-file',
+ '<(global_objects_file)',
+ '--write-file-only-if-changed',
+ '<(write_file_only_if_changed)',
+ '--',
+ '<@(global_names_idl_files)',
+ ],
+ }],
+}
diff --git a/chromium/third_party/WebKit/Source/bindings/scripts/global_objects.gypi b/chromium/third_party/WebKit/Source/bindings/scripts/global_objects.gypi
new file mode 100644
index 00000000000..fa812ee0a8b
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/bindings/scripts/global_objects.gypi
@@ -0,0 +1,64 @@
+# Copyright 2014 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+#
+# This file is meant to be included into a target to provide an action
+# to compute global objects in a component.
+#
+# To use this, create a gyp target with the following form:
+# {
+# 'target_name': 'component_global_objects',
+# 'variables': {
+# 'idl_files': '<(list_of_idl_files)',
+# 'input_files': ['<(some_dir)/GlobalObjectBaseComponent.pickle'],
+# 'output_file': '<(some_dir)/GlobalObjectsComponent.pickle',
+# },
+# 'includes': ['path/to/this/gypi/file'],
+# },
+#
+# Required variables:
+# idl_files - List of .idl files that will be searched in.
+# This should *only* contain main IDL files, excluding dependencies and
+# testing, which should not define global objects.
+# output_file - Pickle file of output.
+#
+# Optional variables:
+# input_files - List of input pickle files of global objects in base
+# components. In this case make sure to include a dependencies section
+# in the target to ensure this is generated.
+#
+# Spec: http://heycam.github.io/webidl/#Global
+# Design document: http://www.chromium.org/developers/design-documents/idl-build
+
+{
+ 'type': 'none',
+ 'actions': [{
+ 'action_name': 'compute_<(_target_name)',
+ 'message': 'Computing global objects for <(_target_name)',
+ 'variables': {
+ 'input_files%': [],
+ 'idl_files_list': '<|(<(_target_name)_idl_files_list.tmp <@(idl_files))',
+ },
+ 'includes': ['scripts.gypi'],
+ 'inputs': [
+ '<(bindings_scripts_dir)/compute_global_objects.py',
+ '<(bindings_scripts_dir)/utilities.py',
+ '<(idl_files_list)',
+ '<@(idl_files)',
+ ],
+ 'outputs': [
+ '<(output_file)',
+ ],
+ 'action': [
+ 'python',
+ '<(bindings_scripts_dir)/compute_global_objects.py',
+ '--idl-files-list',
+ '<(idl_files_list)',
+ '--write-file-only-if-changed',
+ '<(write_file_only_if_changed)',
+ '--',
+ '<@(input_files)',
+ '<(output_file)',
+ ],
+ }],
+}
diff --git a/chromium/third_party/WebKit/Source/bindings/scripts/idl_compiler.py b/chromium/third_party/WebKit/Source/bindings/scripts/idl_compiler.py
new file mode 100755
index 00000000000..6728aff45c1
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/bindings/scripts/idl_compiler.py
@@ -0,0 +1,143 @@
+#!/usr/bin/python
+# Copyright (C) 2013 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.
+
+"""Compile an .idl file to Blink V8 bindings (.h and .cpp files).
+
+Design doc: http://www.chromium.org/developers/design-documents/idl-compiler
+"""
+
+import abc
+from optparse import OptionParser
+import os
+import cPickle as pickle
+import sys
+
+from code_generator_v8 import CodeGeneratorV8
+from idl_reader import IdlReader
+from utilities import write_file
+
+
+def parse_options():
+ parser = OptionParser()
+ parser.add_option('--cache-directory',
+ help='cache directory, defaults to output directory')
+ parser.add_option('--output-directory')
+ parser.add_option('--interfaces-info-file')
+ parser.add_option('--write-file-only-if-changed', type='int')
+ # ensure output comes last, so command line easy to parse via regexes
+ parser.disable_interspersed_args()
+
+ options, args = parser.parse_args()
+ if options.output_directory is None:
+ parser.error('Must specify output directory using --output-directory.')
+ options.write_file_only_if_changed = bool(options.write_file_only_if_changed)
+ if len(args) != 1:
+ parser.error('Must specify exactly 1 input file as argument, but %d given.' % len(args))
+ idl_filename = os.path.realpath(args[0])
+ return options, idl_filename
+
+
+def idl_filename_to_interface_name(idl_filename):
+ basename = os.path.basename(idl_filename)
+ interface_name, _ = os.path.splitext(basename)
+ return interface_name
+
+
+class IdlCompiler(object):
+ """Abstract Base Class for IDL compilers.
+
+ In concrete classes:
+ * self.code_generator must be set, implementing generate_code()
+ (returning a list of output code), and
+ * compile_file() must be implemented (handling output filenames).
+ """
+ __metaclass__ = abc.ABCMeta
+
+ def __init__(self, output_directory, cache_directory='',
+ code_generator=None, interfaces_info=None,
+ interfaces_info_filename='', only_if_changed=False):
+ """
+ Args:
+ interfaces_info:
+ interfaces_info dict
+ (avoids auxiliary file in run-bindings-tests)
+ interfaces_info_file: filename of pickled interfaces_info
+ """
+ cache_directory = cache_directory or output_directory
+ self.cache_directory = cache_directory
+ self.code_generator = code_generator
+ if interfaces_info_filename:
+ with open(interfaces_info_filename) as interfaces_info_file:
+ interfaces_info = pickle.load(interfaces_info_file)
+ self.interfaces_info = interfaces_info
+ self.only_if_changed = only_if_changed
+ self.output_directory = output_directory
+ self.reader = IdlReader(interfaces_info, cache_directory)
+
+ def compile_and_write(self, idl_filename, output_filenames):
+ interface_name = idl_filename_to_interface_name(idl_filename)
+ definitions = self.reader.read_idl_definitions(idl_filename)
+ output_code_list = self.code_generator.generate_code(
+ definitions, interface_name)
+ for output_code, output_filename in zip(output_code_list,
+ output_filenames):
+ write_file(output_code, output_filename, self.only_if_changed)
+
+ @abc.abstractmethod
+ def compile_file(self, idl_filename):
+ pass
+
+
+class IdlCompilerV8(IdlCompiler):
+ def __init__(self, *args, **kwargs):
+ IdlCompiler.__init__(self, *args, **kwargs)
+ self.code_generator = CodeGeneratorV8(self.interfaces_info,
+ self.cache_directory)
+
+ def compile_file(self, idl_filename):
+ interface_name = idl_filename_to_interface_name(idl_filename)
+ header_filename = os.path.join(self.output_directory,
+ 'V8%s.h' % interface_name)
+ cpp_filename = os.path.join(self.output_directory,
+ 'V8%s.cpp' % interface_name)
+ self.compile_and_write(idl_filename, (header_filename, cpp_filename))
+
+
+def main():
+ options, idl_filename = parse_options()
+ idl_compiler = IdlCompilerV8(
+ options.output_directory,
+ cache_directory=options.cache_directory,
+ interfaces_info_filename=options.interfaces_info_file,
+ only_if_changed=options.write_file_only_if_changed)
+ idl_compiler.compile_file(idl_filename)
+
+
+if __name__ == '__main__':
+ sys.exit(main())
diff --git a/chromium/third_party/WebKit/Source/bindings/scripts/idl_definitions.py b/chromium/third_party/WebKit/Source/bindings/scripts/idl_definitions.py
new file mode 100644
index 00000000000..50664ba12ef
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/bindings/scripts/idl_definitions.py
@@ -0,0 +1,756 @@
+# Copyright (C) 2013 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.
+
+"""Blink IDL Intermediate Representation (IR) classes.
+
+Classes are primarily constructors, which build an IdlDefinitions object
+(and various contained objects) from an AST (produced by blink_idl_parser).
+
+This is in two steps:
+* Constructors walk the AST, creating objects.
+* Typedef resolution.
+
+Typedefs are all resolved here, and not stored in IR.
+
+Typedef resolution uses some auxiliary classes and OOP techniques to make this
+a generic call, via the resolve_typedefs() method.
+
+Class hierarchy (mostly containment, '<' for inheritance):
+
+IdlDefinitions
+ IdlCallbackFunction < TypedObject
+ IdlEnum :: FIXME: remove, just use a dict for enums
+ IdlInterface
+ IdlAttribute < TypedObject
+ IdlConstant < TypedObject
+ IdlOperation < TypedObject
+ IdlArgument < TypedObject
+ IdlException < IdlInterface
+ (same contents as IdlInterface)
+
+TypedObject :: mixin for typedef resolution
+
+Design doc: http://www.chromium.org/developers/design-documents/idl-compiler
+"""
+
+import abc
+
+from idl_types import IdlType, IdlUnionType
+
+SPECIAL_KEYWORD_LIST = ['GETTER', 'SETTER', 'DELETER']
+STANDARD_TYPEDEFS = {
+ # http://www.w3.org/TR/WebIDL/#common-DOMTimeStamp
+ 'DOMTimeStamp': 'unsigned long long',
+}
+
+
+################################################################################
+# TypedObject (mixin for typedef resolution)
+################################################################################
+
+class TypedObject(object):
+ """Object with a type, such as an Attribute or Operation (return value).
+
+ The type can be an actual type, or can be a typedef, which must be resolved
+ before passing data to the code generator.
+ """
+ __metaclass__ = abc.ABCMeta
+ idl_type = None
+
+ def resolve_typedefs(self, typedefs):
+ """Resolve typedefs to actual types in the object."""
+ # Constructors don't have their own return type, because it's the
+ # interface itself.
+ if not self.idl_type:
+ return
+ # Need to re-assign self.idl_type, not just mutate idl_type,
+ # since type(idl_type) may change.
+ self.idl_type = self.idl_type.resolve_typedefs(typedefs)
+
+
+################################################################################
+# Definitions (main container class)
+################################################################################
+
+class IdlDefinitions(object):
+ def __init__(self, node):
+ """Args: node: AST root node, class == 'File'"""
+ self.callback_functions = {}
+ self.dictionaries = {}
+ self.enumerations = {}
+ self.interfaces = {}
+
+ node_class = node.GetClass()
+ if node_class != 'File':
+ raise ValueError('Unrecognized node class: %s' % node_class)
+
+ typedefs = dict((typedef_name, IdlType(type_name))
+ for typedef_name, type_name in
+ STANDARD_TYPEDEFS.iteritems())
+
+ children = node.GetChildren()
+ for child in children:
+ child_class = child.GetClass()
+ if child_class == 'Interface':
+ interface = IdlInterface(child)
+ self.interfaces[interface.name] = interface
+ elif child_class == 'Exception':
+ exception = IdlException(child)
+ # For simplicity, treat exceptions as interfaces
+ self.interfaces[exception.name] = exception
+ elif child_class == 'Typedef':
+ type_name = child.GetName()
+ typedefs[type_name] = typedef_node_to_type(child)
+ elif child_class == 'Enum':
+ enumeration = IdlEnum(child)
+ self.enumerations[enumeration.name] = enumeration
+ elif child_class == 'Callback':
+ callback_function = IdlCallbackFunction(child)
+ self.callback_functions[callback_function.name] = callback_function
+ elif child_class == 'Implements':
+ # Implements is handled at the interface merging step
+ pass
+ elif child_class == 'Dictionary':
+ dictionary = IdlDictionary(child)
+ self.dictionaries[dictionary.name] = dictionary
+ else:
+ raise ValueError('Unrecognized node class: %s' % child_class)
+
+ # Typedefs are not stored in IR:
+ # Resolve typedefs with the actual types and then discard the Typedefs.
+ # http://www.w3.org/TR/WebIDL/#idl-typedefs
+ self.resolve_typedefs(typedefs)
+
+ def resolve_typedefs(self, typedefs):
+ for callback_function in self.callback_functions.itervalues():
+ callback_function.resolve_typedefs(typedefs)
+ for interface in self.interfaces.itervalues():
+ interface.resolve_typedefs(typedefs)
+
+ def update(self, other):
+ """Update with additional IdlDefinitions."""
+ for interface_name, new_interface in other.interfaces.iteritems():
+ if not new_interface.is_partial:
+ # Add as new interface
+ self.interfaces[interface_name] = new_interface
+ continue
+
+ # Merge partial to existing interface
+ try:
+ self.interfaces[interface_name].merge(new_interface)
+ except KeyError:
+ raise Exception('Tried to merge partial interface for {0}, '
+ 'but no existing interface by that name'
+ .format(interface_name))
+
+ # Merge callbacks and enumerations
+ self.enumerations.update(other.enumerations)
+ self.callback_functions.update(other.callback_functions)
+
+
+################################################################################
+# Callback Functions
+################################################################################
+
+class IdlCallbackFunction(TypedObject):
+ def __init__(self, node):
+ children = node.GetChildren()
+ num_children = len(children)
+ if num_children != 2:
+ raise ValueError('Expected 2 children, got %s' % num_children)
+ type_node, arguments_node = children
+ arguments_node_class = arguments_node.GetClass()
+ if arguments_node_class != 'Arguments':
+ raise ValueError('Expected Arguments node, got %s' % arguments_node_class)
+
+ self.name = node.GetName()
+ self.idl_type = type_node_to_type(type_node)
+ self.arguments = arguments_node_to_arguments(arguments_node)
+
+ def resolve_typedefs(self, typedefs):
+ TypedObject.resolve_typedefs(self, typedefs)
+ for argument in self.arguments:
+ argument.resolve_typedefs(typedefs)
+
+
+################################################################################
+# Dictionary
+################################################################################
+
+class IdlDictionary(object):
+ def __init__(self, node):
+ self.parent = None
+ self.name = node.GetName()
+ self.members = []
+ for child in node.GetChildren():
+ child_class = child.GetClass()
+ if child_class == 'Inherit':
+ self.parent = child.GetName()
+ elif child_class == 'Key':
+ self.members.append(IdlDictionaryMember(child))
+ else:
+ raise ValueError('Unrecognized node class: %s' % child_class)
+
+
+class IdlDictionaryMember(object):
+ def __init__(self, node):
+ self.default_value = None
+ self.extended_attributes = {}
+ self.idl_type = None
+ self.name = node.GetName()
+ for child in node.GetChildren():
+ child_class = child.GetClass()
+ if child_class == 'Type':
+ self.idl_type = type_node_to_type(child)
+ elif child_class == 'Default':
+ self.default_value = child.GetProperty('VALUE')
+ elif child_class == 'ExtAttributes':
+ self.extended_attributes = ext_attributes_node_to_extended_attributes(child)
+ else:
+ raise ValueError('Unrecognized node class: %s' % child_class)
+
+
+################################################################################
+# Enumerations
+################################################################################
+
+class IdlEnum(object):
+ # FIXME: remove, just treat enums as a dictionary
+ def __init__(self, node):
+ self.name = node.GetName()
+ self.values = []
+ for child in node.GetChildren():
+ self.values.append(child.GetName())
+
+
+################################################################################
+# Interfaces and Exceptions
+################################################################################
+
+class IdlInterface(object):
+ def __init__(self, node=None):
+ self.attributes = []
+ self.constants = []
+ self.constructors = []
+ self.custom_constructors = []
+ self.extended_attributes = {}
+ self.operations = []
+ self.parent = None
+ if not node: # Early exit for IdlException.__init__
+ return
+
+ self.is_callback = node.GetProperty('CALLBACK') or False
+ self.is_exception = False
+ # FIXME: uppercase 'Partial' => 'PARTIAL' in base IDL parser
+ self.is_partial = node.GetProperty('Partial') or False
+ self.name = node.GetName()
+
+ children = node.GetChildren()
+ for child in children:
+ child_class = child.GetClass()
+ if child_class == 'Attribute':
+ self.attributes.append(IdlAttribute(child))
+ elif child_class == 'Const':
+ self.constants.append(IdlConstant(child))
+ elif child_class == 'ExtAttributes':
+ extended_attributes = ext_attributes_node_to_extended_attributes(child)
+ self.constructors, self.custom_constructors = (
+ extended_attributes_to_constructors(extended_attributes))
+ clear_constructor_attributes(extended_attributes)
+ self.extended_attributes = extended_attributes
+ elif child_class == 'Operation':
+ self.operations.append(IdlOperation(child))
+ elif child_class == 'Inherit':
+ self.parent = child.GetName()
+ else:
+ raise ValueError('Unrecognized node class: %s' % child_class)
+
+ def resolve_typedefs(self, typedefs):
+ for attribute in self.attributes:
+ attribute.resolve_typedefs(typedefs)
+ for constant in self.constants:
+ constant.resolve_typedefs(typedefs)
+ for constructor in self.constructors:
+ constructor.resolve_typedefs(typedefs)
+ for custom_constructor in self.custom_constructors:
+ custom_constructor.resolve_typedefs(typedefs)
+ for operation in self.operations:
+ operation.resolve_typedefs(typedefs)
+
+ def merge(self, other):
+ """Merge in another interface's members (e.g., partial interface)"""
+ self.attributes.extend(other.attributes)
+ self.constants.extend(other.constants)
+ self.operations.extend(other.operations)
+
+
+class IdlException(IdlInterface):
+ # Properly exceptions and interfaces are distinct, and thus should inherit a
+ # common base class (say, "IdlExceptionOrInterface").
+ # However, there is only one exception (DOMException), and new exceptions
+ # are not expected. Thus it is easier to implement exceptions as a
+ # restricted subclass of interfaces.
+ # http://www.w3.org/TR/WebIDL/#idl-exceptions
+ def __init__(self, node):
+ # Exceptions are similar to Interfaces, but simpler
+ IdlInterface.__init__(self)
+ self.is_callback = False
+ self.is_exception = True
+ self.is_partial = False
+ self.name = node.GetName()
+
+ children = node.GetChildren()
+ for child in children:
+ child_class = child.GetClass()
+ if child_class == 'Attribute':
+ attribute = IdlAttribute(child)
+ self.attributes.append(attribute)
+ elif child_class == 'Const':
+ self.constants.append(IdlConstant(child))
+ elif child_class == 'ExtAttributes':
+ self.extended_attributes = ext_attributes_node_to_extended_attributes(child)
+ elif child_class == 'ExceptionOperation':
+ self.operations.append(IdlOperation.from_exception_operation_node(child))
+ else:
+ raise ValueError('Unrecognized node class: %s' % child_class)
+
+
+################################################################################
+# Attributes
+################################################################################
+
+class IdlAttribute(TypedObject):
+ def __init__(self, node):
+ self.is_read_only = node.GetProperty('READONLY') or False
+ self.is_static = node.GetProperty('STATIC') or False
+ self.name = node.GetName()
+ # Defaults, overridden below
+ self.idl_type = None
+ self.extended_attributes = {}
+
+ children = node.GetChildren()
+ for child in children:
+ child_class = child.GetClass()
+ if child_class == 'Type':
+ self.idl_type = type_node_to_type(child)
+ elif child_class == 'ExtAttributes':
+ self.extended_attributes = ext_attributes_node_to_extended_attributes(child)
+ else:
+ raise ValueError('Unrecognized node class: %s' % child_class)
+
+
+################################################################################
+# Constants
+################################################################################
+
+class IdlConstant(TypedObject):
+ def __init__(self, node):
+ children = node.GetChildren()
+ num_children = len(children)
+ if num_children < 2 or num_children > 3:
+ raise ValueError('Expected 2 or 3 children, got %s' % num_children)
+ type_node = children[0]
+ value_node = children[1]
+ value_node_class = value_node.GetClass()
+ if value_node_class != 'Value':
+ raise ValueError('Expected Value node, got %s' % value_node_class)
+
+ self.name = node.GetName()
+ # ConstType is more limited than Type, so subtree is smaller and
+ # we don't use the full type_node_to_type function.
+ self.idl_type = type_node_inner_to_type(type_node)
+ self.value = value_node.GetName()
+
+ if num_children == 3:
+ ext_attributes_node = children[2]
+ self.extended_attributes = ext_attributes_node_to_extended_attributes(ext_attributes_node)
+ else:
+ self.extended_attributes = {}
+
+
+################################################################################
+# Literals
+################################################################################
+
+class IdlLiteral(object):
+ def __init__(self, idl_type, value):
+ self.idl_type = idl_type
+ self.value = value
+ self.is_null = False
+
+ def __str__(self):
+ if self.idl_type == 'DOMString':
+ return 'String("%s")' % self.value
+ if self.idl_type == 'integer':
+ return '%d' % self.value
+ if self.idl_type == 'float':
+ return '%g' % self.value
+ if self.idl_type == 'boolean':
+ return 'true' if self.value else 'false'
+ raise ValueError('Unsupported literal type: %s' % self.idl_type)
+
+
+class IdlLiteralNull(IdlLiteral):
+ def __init__(self):
+ self.idl_type = 'NULL'
+ self.value = None
+ self.is_null = True
+
+ def __str__(self):
+ return 'nullptr'
+
+
+def default_node_to_idl_literal(node):
+ # FIXME: This code is unnecessarily complicated due to the rather
+ # inconsistent way the upstream IDL parser outputs default values.
+ # http://crbug.com/374178
+ idl_type = node.GetProperty('TYPE')
+ if idl_type == 'DOMString':
+ value = node.GetProperty('NAME')
+ if '"' in value or '\\' in value:
+ raise ValueError('Unsupported string value: %r' % value)
+ return IdlLiteral(idl_type, value)
+ if idl_type == 'integer':
+ return IdlLiteral(idl_type, int(node.GetProperty('NAME')))
+ if idl_type == 'float':
+ return IdlLiteral(idl_type, float(node.GetProperty('VALUE')))
+ if idl_type == 'boolean':
+ return IdlLiteral(idl_type, node.GetProperty('VALUE'))
+ if idl_type == 'NULL':
+ return IdlLiteralNull()
+ raise ValueError('Unrecognized default value type: %s' % idl_type)
+
+
+################################################################################
+# Operations
+################################################################################
+
+class IdlOperation(TypedObject):
+ def __init__(self, node=None):
+ self.arguments = []
+ self.extended_attributes = {}
+ self.specials = []
+ self.is_constructor = False
+
+ if not node:
+ self.is_static = False
+ return
+ self.name = node.GetName() # FIXME: should just be: or ''
+ # FIXME: AST should use None internally
+ if self.name == '_unnamed_':
+ self.name = ''
+
+ self.is_static = node.GetProperty('STATIC') or False
+ property_dictionary = node.GetProperties()
+ for special_keyword in SPECIAL_KEYWORD_LIST:
+ if special_keyword in property_dictionary:
+ self.specials.append(special_keyword.lower())
+
+ self.idl_type = None
+ children = node.GetChildren()
+ for child in children:
+ child_class = child.GetClass()
+ if child_class == 'Arguments':
+ self.arguments = arguments_node_to_arguments(child)
+ elif child_class == 'Type':
+ self.idl_type = type_node_to_type(child)
+ elif child_class == 'ExtAttributes':
+ self.extended_attributes = ext_attributes_node_to_extended_attributes(child)
+ else:
+ raise ValueError('Unrecognized node class: %s' % child_class)
+
+ @classmethod
+ def from_exception_operation_node(cls, node):
+ # Needed to handle one case in DOMException.idl:
+ # // Override in a Mozilla compatible format
+ # [NotEnumerable] DOMString toString();
+ # FIXME: can we remove this? replace with a stringifier?
+ operation = cls()
+ operation.name = node.GetName()
+ children = node.GetChildren()
+ if len(children) < 1 or len(children) > 2:
+ raise ValueError('ExceptionOperation node with %s children, expected 1 or 2' % len(children))
+
+ type_node = children[0]
+ operation.idl_type = type_node_to_type(type_node)
+
+ if len(children) > 1:
+ ext_attributes_node = children[1]
+ operation.extended_attributes = ext_attributes_node_to_extended_attributes(ext_attributes_node)
+
+ return operation
+
+ @classmethod
+ def constructor_from_arguments_node(cls, name, arguments_node):
+ constructor = cls()
+ constructor.name = name
+ constructor.arguments = arguments_node_to_arguments(arguments_node)
+ constructor.is_constructor = True
+ return constructor
+
+ def resolve_typedefs(self, typedefs):
+ TypedObject.resolve_typedefs(self, typedefs)
+ for argument in self.arguments:
+ argument.resolve_typedefs(typedefs)
+
+
+################################################################################
+# Arguments
+################################################################################
+
+class IdlArgument(TypedObject):
+ def __init__(self, node):
+ self.extended_attributes = {}
+ self.idl_type = None
+ self.is_optional = node.GetProperty('OPTIONAL') # syntax: (optional T)
+ self.is_variadic = False # syntax: (T...)
+ self.name = node.GetName()
+ self.default_value = None
+
+ children = node.GetChildren()
+ for child in children:
+ child_class = child.GetClass()
+ if child_class == 'Type':
+ self.idl_type = type_node_to_type(child)
+ elif child_class == 'ExtAttributes':
+ self.extended_attributes = ext_attributes_node_to_extended_attributes(child)
+ elif child_class == 'Argument':
+ child_name = child.GetName()
+ if child_name != '...':
+ raise ValueError('Unrecognized Argument node; expected "...", got "%s"' % child_name)
+ self.is_variadic = child.GetProperty('ELLIPSIS') or False
+ elif child_class == 'Default':
+ self.default_value = default_node_to_idl_literal(child)
+ else:
+ raise ValueError('Unrecognized node class: %s' % child_class)
+
+
+def arguments_node_to_arguments(node):
+ # [Constructor] and [CustomConstructor] without arguments (the bare form)
+ # have None instead of an arguments node, but have the same meaning as using
+ # an empty argument list, [Constructor()], so special-case this.
+ # http://www.w3.org/TR/WebIDL/#Constructor
+ if node is None:
+ return []
+ return [IdlArgument(argument_node)
+ for argument_node in node.GetChildren()]
+
+
+################################################################################
+# Extended attributes
+################################################################################
+
+def ext_attributes_node_to_extended_attributes(node):
+ """
+ Returns:
+ Dictionary of {ExtAttributeName: ExtAttributeValue}.
+ Value is usually a string, with three exceptions:
+ Constructors: value is a list of Arguments nodes, corresponding to
+ possible signatures of the constructor.
+ CustomConstructors: value is a list of Arguments nodes, corresponding to
+ possible signatures of the custom constructor.
+ NamedConstructor: value is a Call node, corresponding to the single
+ signature of the named constructor.
+ """
+ # Primarily just make a dictionary from the children.
+ # The only complexity is handling various types of constructors:
+ # Constructors and Custom Constructors can have duplicate entries due to
+ # overloading, and thus are stored in temporary lists.
+ # However, Named Constructors cannot be overloaded, and thus do not have
+ # a list.
+ # FIXME: move Constructor logic into separate function, instead of modifying
+ # extended attributes in-place.
+ constructors = []
+ custom_constructors = []
+ extended_attributes = {}
+
+ def child_node(extended_attribute_node):
+ children = extended_attribute_node.GetChildren()
+ if not children:
+ return None
+ if len(children) > 1:
+ raise ValueError('ExtAttributes node with %s children, expected at most 1' % len(children))
+ return children[0]
+
+ extended_attribute_node_list = node.GetChildren()
+ for extended_attribute_node in extended_attribute_node_list:
+ name = extended_attribute_node.GetName()
+ child = child_node(extended_attribute_node)
+ child_class = child and child.GetClass()
+ if name == 'Constructor':
+ if child_class and child_class != 'Arguments':
+ raise ValueError('Constructor only supports Arguments as child, but has child of class: %s' % child_class)
+ constructors.append(child)
+ elif name == 'CustomConstructor':
+ if child_class and child_class != 'Arguments':
+ raise ValueError('[CustomConstructor] only supports Arguments as child, but has child of class: %s' % child_class)
+ custom_constructors.append(child)
+ elif name == 'NamedConstructor':
+ if child_class and child_class != 'Call':
+ raise ValueError('[NamedConstructor] only supports Call as child, but has child of class: %s' % child_class)
+ extended_attributes[name] = child
+ elif name == 'SetWrapperReferenceTo':
+ if not child:
+ raise ValueError('[SetWrapperReferenceTo] requires a child, but has none.')
+ if child_class != 'Arguments':
+ raise ValueError('[SetWrapperReferenceTo] only supports Arguments as child, but has child of class: %s' % child_class)
+ extended_attributes[name] = arguments_node_to_arguments(child)
+ elif child:
+ raise ValueError('ExtAttributes node with unexpected children: %s' % name)
+ else:
+ value = extended_attribute_node.GetProperty('VALUE')
+ extended_attributes[name] = value
+
+ # Store constructors and custom constructors in special list attributes,
+ # which are deleted later. Note plural in key.
+ if constructors:
+ extended_attributes['Constructors'] = constructors
+ if custom_constructors:
+ extended_attributes['CustomConstructors'] = custom_constructors
+
+ return extended_attributes
+
+
+def extended_attributes_to_constructors(extended_attributes):
+ """Returns constructors and custom_constructors (lists of IdlOperations).
+
+ Auxiliary function for IdlInterface.__init__.
+ """
+
+ constructor_list = extended_attributes.get('Constructors', [])
+ constructors = [
+ IdlOperation.constructor_from_arguments_node('Constructor', arguments_node)
+ for arguments_node in constructor_list]
+
+ custom_constructor_list = extended_attributes.get('CustomConstructors', [])
+ custom_constructors = [
+ IdlOperation.constructor_from_arguments_node('CustomConstructor', arguments_node)
+ for arguments_node in custom_constructor_list]
+
+ if 'NamedConstructor' in extended_attributes:
+ # FIXME: support overloaded named constructors, and make homogeneous
+ name = 'NamedConstructor'
+ call_node = extended_attributes['NamedConstructor']
+ extended_attributes['NamedConstructor'] = call_node.GetName()
+ children = call_node.GetChildren()
+ if len(children) != 1:
+ raise ValueError('NamedConstructor node expects 1 child, got %s.' % len(children))
+ arguments_node = children[0]
+ named_constructor = IdlOperation.constructor_from_arguments_node('NamedConstructor', arguments_node)
+ # FIXME: should return named_constructor separately; appended for Perl
+ constructors.append(named_constructor)
+
+ return constructors, custom_constructors
+
+
+def clear_constructor_attributes(extended_attributes):
+ # Deletes Constructor*s* (plural), sets Constructor (singular)
+ if 'Constructors' in extended_attributes:
+ del extended_attributes['Constructors']
+ extended_attributes['Constructor'] = None
+ if 'CustomConstructors' in extended_attributes:
+ del extended_attributes['CustomConstructors']
+ extended_attributes['CustomConstructor'] = None
+
+
+################################################################################
+# Types
+################################################################################
+
+def type_node_to_type(node):
+ children = node.GetChildren()
+ if len(children) < 1 or len(children) > 2:
+ raise ValueError('Type node expects 1 or 2 children (type + optional array []), got %s (multi-dimensional arrays are not supported).' % len(children))
+
+ type_node_child = children[0]
+
+ if len(children) == 2:
+ array_node = children[1]
+ array_node_class = array_node.GetClass()
+ if array_node_class != 'Array':
+ raise ValueError('Expected Array node as TypeSuffix, got %s node.' % array_node_class)
+ # FIXME: use IdlArrayType instead of is_array, once have that
+ is_array = True
+ else:
+ is_array = False
+
+ is_nullable = node.GetProperty('NULLABLE') or False # syntax: T?
+
+ return type_node_inner_to_type(type_node_child, is_array=is_array, is_nullable=is_nullable)
+
+
+def type_node_inner_to_type(node, is_array=False, is_nullable=False):
+ # FIXME: remove is_array and is_nullable once have IdlArrayType and IdlNullableType
+ node_class = node.GetClass()
+ # Note Type*r*ef, not Typedef, meaning the type is an identifier, thus
+ # either a typedef shorthand (but not a Typedef declaration itself) or an
+ # interface type. We do not distinguish these, and just use the type name.
+ if node_class in ['PrimitiveType', 'Typeref']:
+ # unrestricted syntax: unrestricted double | unrestricted float
+ is_unrestricted = node.GetProperty('UNRESTRICTED') or False
+ return IdlType(node.GetName(), is_array=is_array, is_nullable=is_nullable, is_unrestricted=is_unrestricted)
+ elif node_class == 'Any':
+ return IdlType('any', is_array=is_array, is_nullable=is_nullable)
+ elif node_class == 'Sequence':
+ if is_array:
+ raise ValueError('Arrays of sequences are not supported')
+ return sequence_node_to_type(node, is_nullable=is_nullable)
+ elif node_class == 'UnionType':
+ if is_array:
+ raise ValueError('Arrays of unions are not supported')
+ return union_type_node_to_idl_union_type(node, is_nullable=is_nullable)
+ raise ValueError('Unrecognized node class: %s' % node_class)
+
+
+def sequence_node_to_type(node, is_nullable=False):
+ children = node.GetChildren()
+ if len(children) != 1:
+ raise ValueError('Sequence node expects exactly 1 child, got %s' % len(children))
+ sequence_child = children[0]
+ sequence_child_class = sequence_child.GetClass()
+ if sequence_child_class != 'Type':
+ raise ValueError('Unrecognized node class: %s' % sequence_child_class)
+ element_type = type_node_to_type(sequence_child).base_type
+ return IdlType(element_type, is_sequence=True, is_nullable=is_nullable)
+
+
+def typedef_node_to_type(node):
+ children = node.GetChildren()
+ if len(children) != 1:
+ raise ValueError('Typedef node with %s children, expected 1' % len(children))
+ child = children[0]
+ child_class = child.GetClass()
+ if child_class != 'Type':
+ raise ValueError('Unrecognized node class: %s' % child_class)
+ return type_node_to_type(child)
+
+
+def union_type_node_to_idl_union_type(node, is_nullable=False):
+ member_types = [type_node_to_type(member_type_node)
+ for member_type_node in node.GetChildren()]
+ return IdlUnionType(member_types, is_nullable=is_nullable)
diff --git a/chromium/third_party/WebKit/Source/bindings/scripts/idl_parser.pm b/chromium/third_party/WebKit/Source/bindings/scripts/idl_parser.pm
deleted file mode 100644
index a216c242c71..00000000000
--- a/chromium/third_party/WebKit/Source/bindings/scripts/idl_parser.pm
+++ /dev/null
@@ -1,2222 +0,0 @@
-#
-# KDOM IDL parser
-#
-# Copyright (C) 2005 Nikolas Zimmermann <wildfox@kde.org>
-#
-# 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.
-#
-
-package idl_parser;
-
-use strict;
-
-use preprocessor;
-use Class::Struct;
-
-use constant StringToken => 0;
-use constant IntegerToken => 1;
-use constant FloatToken => 2;
-use constant IdentifierToken => 3;
-use constant OtherToken => 4;
-use constant EmptyToken => 5;
-
-# Used to represent a parsed IDL document
-struct( idlDocument => {
- fileName => '$', # file name
- callbackFunctions => '@',
- enumerations => '@', # All parsed enumerations
- interfaces => '@', # All parsed interfaces
-});
-
-struct( callbackFunction => {
- name => '$',
- type => '$',
- parameters => '@',
-});
-
-# Used to represent 'interface' blocks
-struct( domInterface => {
- name => '$', # Class identifier
- parent => '$', # Parent class identifier
- constants => '@', # List of 'domConstant'
- functions => '@', # List of 'domFunction'
- attributes => '@', # List of 'domAttribute'
- extendedAttributes => '$', # Extended attributes
- constructors => '@', # Constructors, list of 'domFunction'
- customConstructors => '@', # Custom constructors, list of 'domFunction'
- isException => '$', # Used for exception interfaces
- isCallback => '$', # Used for callback interfaces
- isPartial => '$', # Used for partial interfaces
-});
-
-# Used to represent domInterface contents
-struct( domFunction => {
- isStatic => '$',
- name => '$',
- type => '$',
- extendedAttributes => '$', # Extended attributes
- specials => '@', # Specials
- parameters => '@', # List of 'domParameter'
- overloadedIndex => '$',
-});
-
-# Used to represent domInterface contents
-struct( domAttribute => {
- type => '$', # Attribute type (including namespace) (string or UnionType)
- name => '$',
- isNullable => '$', # Is variable type Nullable (T?)
- isStatic => '$',
- isReadOnly => '$',
- getterExceptions => '@', # Possibly raised exceptions.
- setterExceptions => '@', # Possibly raised exceptions.
- extendedAttributes => '$', # Extended attributes
-});
-
-# Used to represent a map of 'variable name' <-> 'variable type'
-struct( domParameter => {
- name => '$', # Variable name
- type => '$', # Variable type (string or UnionType)
- extendedAttributes => '$', # Extended attributes
- isOptional => '$', # Is variable optional (optional T)
- isNullable => '$', # Is variable type Nullable (T?)
- isVariadic => '$' # Is variable variadic (long... numbers)
-});
-
-# Used to represent string constants
-struct( domConstant => {
- name => '$', # DOM Constant identifier
- type => '$', # Type of data
- value => '$', # Constant value
- extendedAttributes => '$', # Extended attributes
-});
-
-# Used to represent 'enum' definitions
-struct( domEnum => {
- name => '$', # Enumeration identifier
- values => '@', # Enumeration values (list of unique strings)
-});
-
-struct( Token => {
- type => '$', # type of token
- value => '$' # value of token
-});
-
-struct( UnionType => {
- unionMemberTypes => '@', # (UnionType or string)[]
-});
-
-# Maps 'typedef name' -> 'type'
-my %typedefs = ();
-
-sub new {
- my $class = shift;
-
- my $emptyToken = Token->new();
- $emptyToken->type(EmptyToken);
- $emptyToken->value("empty");
-
- my $self = {
- DocumentContent => "",
- EmptyToken => $emptyToken,
- NextToken => $emptyToken,
- Token => $emptyToken,
- Line => "",
- LineNumber => 1
- };
- return bless $self, $class;
-}
-
-sub assertTokenValue
-{
- my $self = shift;
- my $token = shift;
- my $value = shift;
- my $line = shift;
- my $msg = "Next token should be " . $value . ", but " . $token->value() . " at " . $self->{Line};
- if (defined ($line)) {
- $msg .= " idl_parser.pm:" . $line;
- }
- die $msg unless $token->value() eq $value;
-}
-
-sub assertTokenType
-{
- my $self = shift;
- my $token = shift;
- my $type = shift;
- die "Next token's type should be " . $type . ", but " . $token->type() . " at " . $self->{Line} unless $token->type() eq $type;
-}
-
-sub assertUnexpectedToken
-{
- my $self = shift;
- my $token = shift;
- my $line = shift;
- my $msg = "Unexpected token " . $token . " at " . $self->{Line};
- if (defined ($line)) {
- $msg .= " idl_parser.pm:" . $line;
- }
- die $msg;
-}
-
-sub Parse
-{
- my $self = shift;
- my $fileName = shift;
- my $preprocessor = shift;
- my $defines = "";
-
- my @definitions = ();
-
- my @lines = applyPreprocessor($fileName, $defines, $preprocessor);
- $self->{Line} = $lines[0];
- $self->{DocumentContent} = join(' ', @lines);
-
- $self->getToken();
- eval {
- my $result = $self->parseDefinitions();
- push(@definitions, @{$result});
-
- my $next = $self->nextToken();
- $self->assertTokenType($next, EmptyToken);
- };
- die $@ . " in $fileName" if $@;
-
- my $document = idlDocument->new();
- $document->fileName($fileName);
- foreach my $definition (@definitions) {
- if (ref($definition) eq "domInterface") {
- push(@{$document->interfaces}, $definition);
- } elsif (ref($definition) eq "domEnum") {
- push(@{$document->enumerations}, $definition);
- } elsif (ref($definition) eq "callbackFunction") {
- push(@{$document->callbackFunctions}, $definition);
- } else {
- die "Unrecognized IDL definition kind: \"" . ref($definition) . "\"";
- }
- }
- # Sort so output independent of order in IDL file (e.g., for JSON output)
- @{$document->callbackFunctions} = sort {$a->name cmp $b->name} @{$document->callbackFunctions};
- @{$document->enumerations} = sort {$a->name cmp $b->name} @{$document->enumerations};
- @{$document->interfaces} = sort {$a->name cmp $b->name} @{$document->interfaces};
- return $document;
-}
-
-sub nextToken
-{
- my $self = shift;
- return $self->{NextToken};
-}
-
-sub getToken
-{
- my $self = shift;
- $self->{Token} = $self->{NextToken};
- $self->{NextToken} = $self->getTokenInternal();
- return $self->{Token};
-}
-
-my $whitespaceTokenPattern = '^[\t\n\r ]*[\n\r]';
-my $floatTokenPattern = '^(-?(([0-9]+\.[0-9]*|[0-9]*\.[0-9]+)([Ee][+-]?[0-9]+)?|[0-9]+[Ee][+-]?[0-9]+))';
-my $integerTokenPattern = '^(-?[1-9][0-9]*|-?0[Xx][0-9A-Fa-f]+|-?0[0-7]*)';
-my $stringTokenPattern = '^(\"[^\"]*\")';
-my $identifierTokenPattern = '^([A-Z_a-z][0-9A-Z_a-z]*)';
-my $otherTokenPattern = '^(::|\.\.\.|[^\t\n\r 0-9A-Z_a-z])';
-
-sub getTokenInternal
-{
- my $self = shift;
-
- if ($self->{DocumentContent} =~ /$whitespaceTokenPattern/) {
- $self->{DocumentContent} =~ s/($whitespaceTokenPattern)//;
- my $skipped = $1;
- $self->{LineNumber}++ while ($skipped =~ /\n/g);
- if ($self->{DocumentContent} =~ /^([^\n\r]+)/) {
- $self->{Line} = $self->{LineNumber} . ":" . $1;
- } else {
- $self->{Line} = "Unknown";
- }
- }
- $self->{DocumentContent} =~ s/^([\t\n\r ]+)//;
- if ($self->{DocumentContent} eq "") {
- return $self->{EmptyToken};
- }
-
- my $token = Token->new();
- if ($self->{DocumentContent} =~ /$floatTokenPattern/) {
- $token->type(FloatToken);
- $token->value($1);
- $self->{DocumentContent} =~ s/$floatTokenPattern//;
- return $token;
- }
- if ($self->{DocumentContent} =~ /$integerTokenPattern/) {
- $token->type(IntegerToken);
- $token->value($1);
- $self->{DocumentContent} =~ s/$integerTokenPattern//;
- return $token;
- }
- if ($self->{DocumentContent} =~ /$stringTokenPattern/) {
- $token->type(StringToken);
- $token->value($1);
- $self->{DocumentContent} =~ s/$stringTokenPattern//;
- return $token;
- }
- if ($self->{DocumentContent} =~ /$identifierTokenPattern/) {
- $token->type(IdentifierToken);
- (my $value = $1) =~ s/^_//; # strip leading underscore, used to strope reserved words
- $token->value($value);
- $self->{DocumentContent} =~ s/$identifierTokenPattern//;
- return $token;
- }
- if ($self->{DocumentContent} =~ /$otherTokenPattern/) {
- $token->type(OtherToken);
- $token->value($1);
- $self->{DocumentContent} =~ s/$otherTokenPattern//;
- return $token;
- }
- die "Failed in tokenizing at " . $self->{Line};
-}
-
-sub unquoteString
-{
- my $self = shift;
- my $quotedString = shift;
- if ($quotedString =~ /^"([^"]*)"$/) {
- return $1;
- }
- die "Failed to parse string (" . $quotedString . ") at " . $self->{Line};
-}
-
-sub typeHasNullableSuffix
-{
- my $type = shift;
- return $type =~ /\?$/;
-}
-
-sub typeRemoveNullableSuffix
-{
- my $type = shift;
- $type =~ s/\?$//g;
- return $type;
-}
-
-# Promise is not yet in the Web IDL spec but is going to be speced
-# as primitive types in the future.
-my $nextAttribute_1 = '^(attribute|inherit|readonly)$';
-my $nextPrimitiveType_1 = '^(int|long|short|unsigned)$';
-my $nextPrimitiveType_2 = '^(double|float|unrestricted)$';
-my $nextArgumentList_1 = '^(\(|::|ByteString|DOMString|Promise|Date|\[|any|boolean|byte|double|float|in|int|long|object|octet|optional|sequence|short|unrestricted|unsigned)$';
-my $nextNonAnyType_1 = '^(boolean|byte|double|float|int|long|octet|short|unrestricted|unsigned)$';
-my $nextInterfaceMember_1 = '^(\(|::|ByteString|DOMString|Promise|Date|any|attribute|boolean|byte|creator|deleter|double|float|getter|inherit|int|legacycaller|long|object|octet|readonly|sequence|serializer|setter|short|static|stringifier|unrestricted|unsigned|void)$';
-my $nextOptionalIteratorInterfaceOrObject_1 = '^(;|=)$';
-my $nextAttributeOrOperationOrIterator_1 = '^(static|stringifier)$';
-my $nextAttributeOrOperationOrIterator_2 = '^(\(|::|ByteString|DOMString|Promise|Date|any|boolean|byte|creator|deleter|double|float|getter|int|legacycaller|long|object|octet|sequence|setter|short|unrestricted|unsigned|void)$';
-my $nextUnrestrictedFloatType_1 = '^(double|float)$';
-my $nextExtendedAttributeRest3_1 = '^(\,|::|\])$';
-my $nextExceptionField_1 = '^(\(|::|ByteString|DOMString|Promise|Date|any|boolean|byte|double|float|int|long|object|octet|sequence|short|unrestricted|unsigned)$';
-my $nextType_1 = '^(::|ByteString|DOMString|Promise|Date|any|boolean|byte|double|float|int|long|object|octet|sequence|short|unrestricted|unsigned)$';
-my $nextSpecials_1 = '^(creator|deleter|getter|legacycaller|setter)$';
-my $nextDefinitions_1 = '^(::|callback|dictionary|enum|exception|interface|partial|typedef)$';
-my $nextExceptionMembers_1 = '^(\(|::|ByteString|DOMString|Promise|Date|\[|any|boolean|byte|const|double|float|int|long|object|octet|optional|sequence|short|unrestricted|unsigned)$';
-my $nextAttributeRest_1 = '^(attribute|readonly)$';
-my $nextInterfaceMembers_1 = '^(\(|::|ByteString|DOMString|Promise|Date|any|attribute|boolean|byte|const|creator|deleter|double|float|getter|inherit|int|legacycaller|long|object|octet|readonly|sequence|serializer|setter|short|static|stringifier|unrestricted|unsigned|void)$';
-my $nextSingleType_1 = '^(::|ByteString|DOMString|Promise|Date|boolean|byte|double|float|int|long|object|octet|sequence|short|unrestricted|unsigned)$';
-my $nextArgumentName_1 = '^(attribute|callback|const|creator|deleter|dictionary|enum|exception|getter|implements|inherit|interface|legacycaller|partial|serializer|setter|static|stringifier|typedef|unrestricted)$';
-my $nextConstValue_1 = '^(false|true)$';
-my $nextConstValue_2 = '^(-|Infinity|NaN)$';
-my $nextDefinition_1 = '^(callback|interface)$';
-my $nextAttributeOrOperationRest_1 = '^(\(|::|ByteString|DOMString|Promise|Date|any|boolean|byte|double|float|int|long|object|octet|sequence|short|unrestricted|unsigned|void)$';
-my $nextUnsignedIntegerType_1 = '^(int|long|short)$';
-my $nextDefaultValue_1 = '^(-|Infinity|NaN|false|null|true)$';
-
-
-sub parseDefinitions
-{
- my $self = shift;
- my @definitions = ();
-
- while (1) {
- my $extendedAttributeList = $self->parseExtendedAttributeListAllowEmpty();
- my $next = $self->nextToken();
- my $definition;
- if ($next->type() == IdentifierToken || $next->value() =~ /$nextDefinitions_1/) {
- $definition = $self->parseDefinition($extendedAttributeList);
- } else {
- last;
- }
- if (defined ($definition)) {
- push(@definitions, $definition);
- }
- }
- $self->applyTypedefs(\@definitions);
- return \@definitions;
-}
-
-sub applyTypedefs
-{
- my $self = shift;
- my $definitions = shift;
-
- if (!%typedefs) {
- return;
- }
- foreach my $definition (@$definitions) {
- if (ref($definition) eq "domInterface") {
- foreach my $constant (@{$definition->constants}) {
- $self->applyTypedefsForTypedObject($constant);
- }
- foreach my $attribute (@{$definition->attributes}) {
- $self->applyTypedefsForTypedObject($attribute);
- }
- foreach my $function (@{$definition->functions}, @{$definition->constructors}, @{$definition->customConstructors}) {
- $self->applyTypedefsForTypedObject($function);
- foreach my $parameter (@{$function->parameters}) {
- $self->applyTypedefsForTypedObject($parameter);
- }
- }
- }
- }
-}
-
-sub applyTypedefsForTypedObject
-{
- my $self = shift;
- my $typedObject = shift;
-
- if (!defined ($typedObject->type)) {
- return;
- }
-
- my $type = $typedObject->type;
- $type =~ s/[\?\[\]]+$//g;
- my $typeSuffix = $typedObject->type;
- $typeSuffix =~ s/^[^\?\[\]]+//g;
- if (exists $typedefs{$type}) {
- $typedObject->type($typedefs{$type} . $typeSuffix);
- }
-
- # Handle union types, sequences and etc.
- foreach my $name (%typedefs) {
- if (!exists $typedefs{$name}) {
- next;
- }
- my $regex = '\\b' . $name . '\\b';
- my $replacement = $typedefs{$name};
- my $type = $typedObject->type;
- $type =~ s/($regex)/$replacement/g;
- $typedObject->type($type);
- }
-}
-
-sub parseDefinition
-{
- my $self = shift;
- my $extendedAttributeList = shift;
-
- my $next = $self->nextToken();
- if ($next->value() =~ /$nextDefinition_1/) {
- return $self->parseCallbackOrInterface($extendedAttributeList);
- }
- if ($next->value() eq "partial") {
- return $self->parsePartial($extendedAttributeList);
- }
- if ($next->value() eq "dictionary") {
- return $self->parseDictionary($extendedAttributeList);
- }
- if ($next->value() eq "exception") {
- return $self->parseException($extendedAttributeList);
- }
- if ($next->value() eq "enum") {
- return $self->parseEnum($extendedAttributeList);
- }
- if ($next->value() eq "typedef") {
- return $self->parseTypedef($extendedAttributeList);
- }
- if ($next->type() == IdentifierToken || $next->value() eq "::") {
- return $self->parseImplementsStatement($extendedAttributeList);
- }
- $self->assertUnexpectedToken($next->value(), __LINE__);
-}
-
-sub parseCallbackOrInterface
-{
- my $self = shift;
- my $extendedAttributeList = shift;
-
- my $next = $self->nextToken();
- if ($next->value() eq "callback") {
- $self->assertTokenValue($self->getToken(), "callback", __LINE__);
- return $self->parseCallbackRestOrInterface($extendedAttributeList);
- }
- if ($next->value() eq "interface") {
- return $self->parseInterface($extendedAttributeList);
- }
- $self->assertUnexpectedToken($next->value(), __LINE__);
-}
-
-sub parseCallbackRestOrInterface
-{
- my $self = shift;
- my $extendedAttributeList = shift;
-
- my $next = $self->nextToken();
- if ($next->value() eq "interface") {
- my $interface = $self->parseInterface($extendedAttributeList);
- $interface->isCallback(1);
- return $interface;
- }
- if ($next->type() == IdentifierToken) {
- return $self->parseCallbackRest($extendedAttributeList);
- }
- $self->assertUnexpectedToken($next->value(), __LINE__);
-}
-
-sub parseInterface
-{
- my $self = shift;
- my $extendedAttributeList = shift;
-
- my $next = $self->nextToken();
- if ($next->value() eq "interface") {
- my $interface = domInterface->new();
- $self->assertTokenValue($self->getToken(), "interface", __LINE__);
- my $interfaceNameToken = $self->getToken();
- $self->assertTokenType($interfaceNameToken, IdentifierToken);
- $interface->name($interfaceNameToken->value());
- $interface->parent($self->parseInheritance());
- $self->assertTokenValue($self->getToken(), "{", __LINE__);
- my $interfaceMembers = $self->parseInterfaceMembers();
- $self->assertTokenValue($self->getToken(), "}", __LINE__);
- $self->assertTokenValue($self->getToken(), ";", __LINE__);
- applyMemberList($interface, $interfaceMembers);
- applyExtendedAttributeList($interface, $extendedAttributeList);
- return $interface;
- }
- $self->assertUnexpectedToken($next->value(), __LINE__);
-}
-
-sub parsePartial
-{
- my $self = shift;
- my $extendedAttributeList = shift;
-
- my $next = $self->nextToken();
- if ($next->value() eq "partial") {
- $self->assertTokenValue($self->getToken(), "partial", __LINE__);
- return $self->parsePartialDefinition($extendedAttributeList);
- }
- $self->assertUnexpectedToken($next->value(), __LINE__);
-}
-
-sub parsePartialDefinition
-{
- my $self = shift;
- my $extendedAttributeList = shift;
-
- my $next = $self->nextToken();
- if ($next->value() eq "interface") {
- my $interface = $self->parseInterface($extendedAttributeList);
- $interface->isPartial(1);
- return $interface;
- }
- if ($next->value() eq "dictionary") {
- return $self->parsePartialDictionary($extendedAttributeList);
- }
- $self->assertUnexpectedToken($next->value(), __LINE__);
-}
-
-sub parsePartialInterface
-{
- my $self = shift;
- my $extendedAttributeList = shift;
-
- my $next = $self->nextToken();
- if ($next->value() eq "interface") {
- $self->assertTokenValue($self->getToken(), "interface", __LINE__);
- $self->assertTokenType($self->getToken(), IdentifierToken);
- $self->assertTokenValue($self->getToken(), "{", __LINE__);
- $self->parseInterfaceMembers();
- $self->assertTokenValue($self->getToken(), "}", __LINE__);
- $self->assertTokenValue($self->getToken(), ";", __LINE__);
- return;
- }
- $self->assertUnexpectedToken($next->value(), __LINE__);
-}
-
-sub parseInterfaceMembers
-{
- my $self = shift;
- my @interfaceMembers = ();
-
- while (1) {
- my $extendedAttributeList = $self->parseExtendedAttributeListAllowEmpty();
- my $next = $self->nextToken();
- my $interfaceMember;
- if ($next->type() == IdentifierToken || $next->value() =~ /$nextInterfaceMembers_1/) {
- $interfaceMember = $self->parseInterfaceMember($extendedAttributeList);
- } else {
- last;
- }
- if (defined $interfaceMember) {
- push(@interfaceMembers, $interfaceMember);
- }
- }
- return \@interfaceMembers;
-}
-
-sub parseInterfaceMember
-{
- my $self = shift;
- my $extendedAttributeList = shift;
-
- my $next = $self->nextToken();
- if ($next->value() eq "const") {
- return $self->parseConst($extendedAttributeList);
- }
- if ($next->type() == IdentifierToken || $next->value() =~ /$nextInterfaceMember_1/) {
- return $self->parseAttributeOrOperationOrIterator($extendedAttributeList);
- }
- $self->assertUnexpectedToken($next->value(), __LINE__);
-}
-
-sub parseDictionary
-{
- my $self = shift;
- my $extendedAttributeList = shift;
-
- my $next = $self->nextToken();
- if ($next->value() eq "dictionary") {
- $self->assertTokenValue($self->getToken(), "dictionary", __LINE__);
- $self->assertTokenType($self->getToken(), IdentifierToken);
- $self->parseInheritance();
- $self->assertTokenValue($self->getToken(), "{", __LINE__);
- $self->parseDictionaryMembers();
- $self->assertTokenValue($self->getToken(), "}", __LINE__);
- $self->assertTokenValue($self->getToken(), ";", __LINE__);
- return;
- }
- $self->assertUnexpectedToken($next->value(), __LINE__);
-}
-
-sub parseDictionaryMembers
-{
- my $self = shift;
-
- while (1) {
- my $extendedAttributeList = $self->parseExtendedAttributeListAllowEmpty();
- my $next = $self->nextToken();
- if ($next->type() == IdentifierToken || $next->value() =~ /$nextExceptionField_1/) {
- $self->parseDictionaryMember($extendedAttributeList);
- } else {
- last;
- }
- }
-}
-
-sub parseDictionaryMember
-{
- my $self = shift;
- my $extendedAttributeList = shift;
-
- my $next = $self->nextToken();
- if ($next->type() == IdentifierToken || $next->value() =~ /$nextExceptionField_1/) {
- $self->parseType();
- $self->assertTokenType($self->getToken(), IdentifierToken);
- $self->parseDefault();
- $self->assertTokenValue($self->getToken(), ";", __LINE__);
- return;
- }
- $self->assertUnexpectedToken($next->value(), __LINE__);
-}
-
-sub parsePartialDictionary
-{
- my $self = shift;
- my $next = $self->nextToken();
- if ($next->value() eq "dictionary") {
- $self->assertTokenValue($self->getToken(), "dictionary", __LINE__);
- $self->assertTokenType($self->getToken(), IdentifierToken);
- $self->assertTokenValue($self->getToken(), "{", __LINE__);
- $self->parseDictionaryMembers();
- $self->assertTokenValue($self->getToken(), "}", __LINE__);
- $self->assertTokenValue($self->getToken(), ";", __LINE__);
- return;
- }
- $self->assertUnexpectedToken($next->value(), __LINE__);
-}
-
-sub parseDefault
-{
- my $self = shift;
- my $next = $self->nextToken();
- if ($next->value() eq "=") {
- $self->assertTokenValue($self->getToken(), "=", __LINE__);
- return $self->parseDefaultValue();
- }
-}
-
-sub parseDefaultValue
-{
- my $self = shift;
- my $next = $self->nextToken();
- if ($next->type() == FloatToken || $next->type() == IntegerToken || $next->value() =~ /$nextDefaultValue_1/) {
- return $self->parseConstValue();
- }
- if ($next->type() == StringToken) {
- return $self->getToken()->value();
- }
- $self->assertUnexpectedToken($next->value(), __LINE__);
-}
-
-sub parseException
-{
- my $self = shift;
- my $extendedAttributeList = shift;
-
- my $next = $self->nextToken();
- if ($next->value() eq "exception") {
- my $interface = domInterface->new();
- $self->assertTokenValue($self->getToken(), "exception", __LINE__);
- my $exceptionNameToken = $self->getToken();
- $self->assertTokenType($exceptionNameToken, IdentifierToken);
- $interface->name($exceptionNameToken->value());
- $interface->isException(1);
- $interface->parent($self->parseInheritance());
- $self->assertTokenValue($self->getToken(), "{", __LINE__);
- my $exceptionMembers = $self->parseExceptionMembers();
- $self->assertTokenValue($self->getToken(), "}", __LINE__);
- $self->assertTokenValue($self->getToken(), ";", __LINE__);
- applyMemberList($interface, $exceptionMembers);
- applyExtendedAttributeList($interface, $extendedAttributeList);
- return $interface;
- }
- $self->assertUnexpectedToken($next->value(), __LINE__);
-}
-
-sub parseExceptionMembers
-{
- my $self = shift;
- my @members = ();
-
- while (1) {
- my $next = $self->nextToken();
- if ($next->type() == IdentifierToken || $next->value() =~ /$nextExceptionMembers_1/) {
- my $extendedAttributeList = $self->parseExtendedAttributeListAllowEmpty();
- #my $member = $self->parseExceptionMember($extendedAttributeList);
- my $member = $self->parseInterfaceMember($extendedAttributeList);
- if (defined ($member)) {
- push(@members, $member);
- }
- } else {
- last;
- }
- }
- return \@members;
-}
-
-sub parseInheritance
-{
- my $self = shift;
- my $parent;
-
- my $next = $self->nextToken();
- if ($next->value() eq ":") {
- $self->assertTokenValue($self->getToken(), ":", __LINE__);
- $parent = $self->parseScopedName();
- }
- return $parent;
-}
-
-sub parseEnum
-{
- my $self = shift;
- my $extendedAttributeList = shift; # ignored: Extended attributes are not applicable to enumerations
-
- my $next = $self->nextToken();
- if ($next->value() eq "enum") {
- my $enum = domEnum->new();
- $self->assertTokenValue($self->getToken(), "enum", __LINE__);
- my $enumNameToken = $self->getToken();
- $self->assertTokenType($enumNameToken, IdentifierToken);
- $enum->name($enumNameToken->value());
- $self->assertTokenValue($self->getToken(), "{", __LINE__);
- push(@{$enum->values}, @{$self->parseEnumValueList()});
- $self->assertTokenValue($self->getToken(), "}", __LINE__);
- $self->assertTokenValue($self->getToken(), ";", __LINE__);
- return $enum;
- }
- $self->assertUnexpectedToken($next->value(), __LINE__);
-}
-
-sub parseEnumValueList
-{
- my $self = shift;
- my @values = ();
- my $next = $self->nextToken();
- if ($next->type() == StringToken) {
- my $enumValueToken = $self->getToken();
- $self->assertTokenType($enumValueToken, StringToken);
- my $enumValue = $self->unquoteString($enumValueToken->value());
- push(@values, $enumValue);
- push(@values, @{$self->parseEnumValues()});
- return \@values;
- }
- # value list must be non-empty
- $self->assertUnexpectedToken($next->value(), __LINE__);
-}
-
-sub parseEnumValues
-{
- my $self = shift;
- my @values = ();
- my $next = $self->nextToken();
- if ($next->value() eq ",") {
- $self->assertTokenValue($self->getToken(), ",", __LINE__);
- my $enumValueToken = $self->getToken();
- $self->assertTokenType($enumValueToken, StringToken);
- my $enumValue = $self->unquoteString($enumValueToken->value());
- push(@values, $enumValue);
- push(@values, @{$self->parseEnumValues()});
- return \@values;
- }
- return \@values; # empty list (end of enumeration-values)
-}
-
-sub parseCallbackRest
-{
- my $self = shift;
- my $extendedAttributeList = shift;
-
- my $next = $self->nextToken();
- if ($next->type() == IdentifierToken) {
- my $callback = callbackFunction->new();
- my $name = $self->getToken();
- $self->assertTokenType($name, IdentifierToken);
- $callback->name($name->value());
- $self->assertTokenValue($self->getToken(), "=", __LINE__);
- $callback->type($self->parseReturnType());
- $self->assertTokenValue($self->getToken(), "(", __LINE__);
- $callback->parameters($self->parseArgumentList());
- $self->assertTokenValue($self->getToken(), ")", __LINE__);
- $self->assertTokenValue($self->getToken(), ";", __LINE__);
- return $callback;
- }
- $self->assertUnexpectedToken($next->value(), __LINE__);
-}
-
-sub parseTypedef
-{
- my $self = shift;
- my $extendedAttributeList = shift;
- die "Extended attributes are not applicable to typedefs themselves: " . $self->{Line} if %{$extendedAttributeList};
-
- my $next = $self->nextToken();
- if ($next->value() eq "typedef") {
- $self->assertTokenValue($self->getToken(), "typedef", __LINE__);
- my $typedef = $self->parseType();
- my $nameToken = $self->getToken();
- $self->assertTokenType($nameToken, IdentifierToken);
- $self->assertTokenValue($self->getToken(), ";", __LINE__);
- my $name = $nameToken->value();
- die "typedef redefinition for " . $name . " at " . $self->{Line} if (exists $typedefs{$name} && $typedef ne $typedefs{$name});
- $typedefs{$name} = $typedef;
- return;
- }
- $self->assertUnexpectedToken($next->value(), __LINE__);
-}
-
-sub parseImplementsStatement
-{
- my $self = shift;
- my $extendedAttributeList = shift;
-
- my $next = $self->nextToken();
- if ($next->type() == IdentifierToken) {
- $self->parseScopedName();
- $self->assertTokenValue($self->getToken(), "implements", __LINE__);
- $self->parseScopedName();
- $self->assertTokenValue($self->getToken(), ";", __LINE__);
- return;
- }
- $self->assertUnexpectedToken($next->value(), __LINE__);
-}
-
-sub parseConst
-{
- my $self = shift;
- my $extendedAttributeList = shift;
-
- my $next = $self->nextToken();
- if ($next->value() eq "const") {
- my $newDataNode = domConstant->new();
- $self->assertTokenValue($self->getToken(), "const", __LINE__);
- $newDataNode->type($self->parseConstType());
- my $constNameToken = $self->getToken();
- $self->assertTokenType($constNameToken, IdentifierToken);
- $newDataNode->name($constNameToken->value());
- $self->assertTokenValue($self->getToken(), "=", __LINE__);
- $newDataNode->value($self->parseConstValue());
- $self->assertTokenValue($self->getToken(), ";", __LINE__);
- $newDataNode->extendedAttributes($extendedAttributeList);
- return $newDataNode;
- }
- $self->assertUnexpectedToken($next->value(), __LINE__);
-}
-
-sub parseConstValue
-{
- my $self = shift;
- my $next = $self->nextToken();
- if ($next->value() =~ /$nextConstValue_1/) {
- return $self->parseBooleanLiteral();
- }
- if ($next->value() eq "null") {
- $self->assertTokenValue($self->getToken(), "null", __LINE__);
- return "null";
- }
- if ($next->type() == FloatToken || $next->value() =~ /$nextConstValue_2/) {
- return $self->parseFloatLiteral();
- }
- # backward compatibility
- if ($next->type() == StringToken) {
- return $self->getToken()->value();
- }
- if ($next->type() == IntegerToken) {
- return $self->getToken()->value();
- }
- $self->assertUnexpectedToken($next->value(), __LINE__);
-}
-
-sub parseBooleanLiteral
-{
- my $self = shift;
- my $next = $self->nextToken();
- if ($next->value() eq "true") {
- $self->assertTokenValue($self->getToken(), "true", __LINE__);
- return "true";
- }
- if ($next->value() eq "false") {
- $self->assertTokenValue($self->getToken(), "false", __LINE__);
- return "false";
- }
- $self->assertUnexpectedToken($next->value(), __LINE__);
-}
-
-sub parseFloatLiteral
-{
- my $self = shift;
- my $next = $self->nextToken();
- if ($next->value() eq "-") {
- $self->assertTokenValue($self->getToken(), "-", __LINE__);
- $self->assertTokenValue($self->getToken(), "Infinity", __LINE__);
- return "-Infinity";
- }
- if ($next->value() eq "Infinity") {
- $self->assertTokenValue($self->getToken(), "Infinity", __LINE__);
- return "Infinity";
- }
- if ($next->value() eq "NaN") {
- $self->assertTokenValue($self->getToken(), "NaN", __LINE__);
- return "NaN";
- }
- if ($next->type() == FloatToken) {
- return $self->getToken()->value();
- }
- $self->assertUnexpectedToken($next->value(), __LINE__);
-}
-
-sub parseAttributeOrOperationOrIterator
-{
- my $self = shift;
- my $extendedAttributeList = shift;
-
- my $next = $self->nextToken();
- if ($next->value() eq "serializer") {
- return $self->parseSerializer($extendedAttributeList);
- }
- if ($next->value() =~ /$nextAttributeOrOperationOrIterator_1/) {
- my $qualifier = $self->parseQualifier();
- my $newDataNode = $self->parseAttributeOrOperationRest($extendedAttributeList);
- if (defined($newDataNode) && $qualifier eq "static") {
- $newDataNode->isStatic(1);
- }
- return $newDataNode;
- }
- if ($next->value() =~ /$nextAttribute_1/) {
- return $self->parseAttribute($extendedAttributeList);
- }
- if ($next->type() == IdentifierToken || $next->value() =~ /$nextAttributeOrOperationOrIterator_2/) {
- return $self->parseOperationOrIterator($extendedAttributeList);
- }
- $self->assertUnexpectedToken($next->value(), __LINE__);
-}
-
-sub parseSerializer
-{
- my $self = shift;
- my $extendedAttributeList = shift;
-
- my $next = $self->nextToken();
- if ($next->value() eq "serializer") {
- $self->assertTokenValue($self->getToken(), "serializer", __LINE__);
- return $self->parseSerializerRest($extendedAttributeList);
- }
- $self->assertUnexpectedToken($next->value(), __LINE__);
-}
-
-sub parseSerializerRest
-{
- my $self = shift;
- my $extendedAttributeList = shift;
-
- my $next = $self->nextToken();
- if ($next->value() eq "=") {
- $self->assertTokenValue($self->getToken(), "=", __LINE__);
- return $self->parseSerializationPattern($extendedAttributeList);
- }
- if ($next->type() == IdentifierToken || $next->value() eq "(") {
- return $self->parseOperationRest($extendedAttributeList);
- }
-}
-
-sub parseSerializationPattern
-{
- my $self = shift;
- my $extendedAttributeList = shift;
-
- my $next = $self->nextToken();
- if ($next->value() eq "{") {
- $self->assertTokenValue($self->getToken(), "{", __LINE__);
- $self->parseSerializationPatternMap();
- $self->assertTokenValue($self->getToken(), "}", __LINE__);
- return;
- }
- if ($next->value() eq "[") {
- $self->assertTokenValue($self->getToken(), "[", __LINE__);
- $self->parseSerializationPatternList();
- $self->assertTokenValue($self->getToken(), "]", __LINE__);
- return;
- }
- if ($next->type() == IdentifierToken) {
- $self->assertTokenType($self->getToken(), IdentifierToken);
- return;
- }
- $self->assertUnexpectedToken($next->value(), __LINE__);
-}
-
-sub parseSerializationPatternMap
-{
- my $self = shift;
- my $next = $self->nextToken();
- if ($next->value() eq "getter") {
- $self->assertTokenValue($self->getToken(), "getter", __LINE__);
- return;
- }
- if ($next->value() eq "inherit") {
- $self->assertTokenValue($self->getToken(), "inherit", __LINE__);
- $self->parseIdentifiers();
- return;
- }
- if ($next->type() == IdentifierToken) {
- $self->assertTokenType($self->getToken(), IdentifierToken);
- $self->parseIdentifiers();
- }
-}
-
-sub parseSerializationPatternList
-{
- my $self = shift;
- my $next = $self->nextToken();
- if ($next->value() eq "getter") {
- $self->assertTokenValue($self->getToken(), "getter", __LINE__);
- return;
- }
- if ($next->type() == IdentifierToken) {
- $self->assertTokenType($self->getToken(), IdentifierToken);
- $self->parseIdentifiers();
- }
-}
-
-sub parseIdentifiers
-{
- my $self = shift;
- my @idents = ();
-
- while (1) {
- my $next = $self->nextToken();
- if ($next->value() eq ",") {
- $self->assertTokenValue($self->getToken(), ",", __LINE__);
- my $token = $self->getToken();
- $self->assertTokenType($token, IdentifierToken);
- push(@idents, $token->value());
- } else {
- last;
- }
- }
- return \@idents;
-}
-
-sub parseQualifier
-{
- my $self = shift;
-
- my $next = $self->nextToken();
- if ($next->value() eq "static") {
- $self->assertTokenValue($self->getToken(), "static", __LINE__);
- return "static";
- }
- if ($next->value() eq "stringifier") {
- $self->assertTokenValue($self->getToken(), "stringifier", __LINE__);
- return "stringifier";
- }
- $self->assertUnexpectedToken($next->value(), __LINE__);
-}
-
-sub parseAttributeOrOperationRest
-{
- my $self = shift;
- my $extendedAttributeList = shift;
-
- my $next = $self->nextToken();
- if ($next->value() =~ /$nextAttributeRest_1/) {
- return $self->parseAttributeRest($extendedAttributeList);
- }
- if ($next->value() eq ";") {
- $self->assertTokenValue($self->getToken(), ";", __LINE__);
- return;
- }
- if ($next->type() == IdentifierToken || $next->value() =~ /$nextAttributeOrOperationRest_1/) {
- my $returnType = $self->parseReturnType();
- my $function = $self->parseOperationRest($extendedAttributeList);
- if (defined ($function)) {
- $function->type($returnType);
- }
- return $function;
- }
- $self->assertUnexpectedToken($next->value(), __LINE__);
-}
-
-sub parseAttribute
-{
- my $self = shift;
- my $extendedAttributeList = shift;
-
- my $next = $self->nextToken();
- if ($next->value() =~ /$nextAttribute_1/) {
- $self->parseInherit();
- return $self->parseAttributeRest($extendedAttributeList);
- }
- $self->assertUnexpectedToken($next->value(), __LINE__);
-}
-
-sub parseAttributeRest
-{
- my $self = shift;
- my $extendedAttributeList = shift;
-
- my $next = $self->nextToken();
- if ($next->value() =~ /$nextAttributeRest_1/) {
- my $newDataNode = domAttribute->new();
- if ($self->parseReadOnly()) {
- $newDataNode->isReadOnly(1);
- }
- $self->assertTokenValue($self->getToken(), "attribute", __LINE__);
- my $type = $self->parseType();
- $newDataNode->isNullable(typeHasNullableSuffix($type));
- # Remove all "?" in the type declaration, e.g. "double?" -> "double".
- $newDataNode->type(typeRemoveNullableSuffix($type));
- my $token = $self->getToken();
- $self->assertTokenType($token, IdentifierToken);
- $newDataNode->name($token->value());
- $self->assertTokenValue($self->getToken(), ";", __LINE__);
- # CustomConstructor may also be used on attributes.
- if (defined $extendedAttributeList->{"CustomConstructors"}) {
- delete $extendedAttributeList->{"CustomConstructors"};
- $extendedAttributeList->{"CustomConstructor"} = "VALUE_IS_MISSING";
- }
- $newDataNode->extendedAttributes($extendedAttributeList);
- return $newDataNode;
- }
- $self->assertUnexpectedToken($next->value(), __LINE__);
-}
-
-sub parseInherit
-{
- my $self = shift;
- my $next = $self->nextToken();
- if ($next->value() eq "inherit") {
- $self->assertTokenValue($self->getToken(), "inherit", __LINE__);
- return 1;
- }
- return 0;
-}
-
-sub parseReadOnly
-{
- my $self = shift;
- my $next = $self->nextToken();
- if ($next->value() eq "readonly") {
- $self->assertTokenValue($self->getToken(), "readonly", __LINE__);
- return 1;
- }
- return 0;
-}
-
-sub parseOperationOrIterator
-{
- my $self = shift;
- my $extendedAttributeList = shift;
-
- my $next = $self->nextToken();
- if ($next->value() =~ /$nextSpecials_1/) {
- return $self->parseSpecialOperation($extendedAttributeList);
- }
- if ($next->type() == IdentifierToken || $next->value() =~ /$nextAttributeOrOperationRest_1/) {
- my $returnType = $self->parseReturnType();
- my $interface = $self->parseOperationOrIteratorRest($extendedAttributeList);
- if (defined ($interface)) {
- $interface->type($returnType);
- }
- return $interface;
- }
- $self->assertUnexpectedToken($next->value(), __LINE__);
-}
-
-sub parseSpecialOperation
-{
- my $self = shift;
- my $extendedAttributeList = shift;
-
- my $next = $self->nextToken();
- if ($next->value() =~ /$nextSpecials_1/) {
- my @specials = ();
- push(@specials, @{$self->parseSpecials()});
- my $returnType = $self->parseReturnType();
- my $function = $self->parseOperationRest($extendedAttributeList);
- if (defined ($function)) {
- $function->type($returnType);
- $function->specials(\@specials);
- }
- return $function;
- }
- $self->assertUnexpectedToken($next->value(), __LINE__);
-}
-
-sub parseSpecials
-{
- my $self = shift;
- my @specials = ();
-
- while (1) {
- my $next = $self->nextToken();
- if ($next->value() =~ /$nextSpecials_1/) {
- push(@specials, $self->parseSpecial());
- } else {
- last;
- }
- }
- return \@specials;
-}
-
-sub parseSpecial
-{
- my $self = shift;
- my $next = $self->nextToken();
- if ($next->value() eq "getter") {
- $self->assertTokenValue($self->getToken(), "getter", __LINE__);
- return "getter";
- }
- if ($next->value() eq "setter") {
- $self->assertTokenValue($self->getToken(), "setter", __LINE__);
- return "setter";
- }
- if ($next->value() eq "creator") {
- $self->assertTokenValue($self->getToken(), "creator", __LINE__);
- return "creator";
- }
- if ($next->value() eq "deleter") {
- $self->assertTokenValue($self->getToken(), "deleter", __LINE__);
- return "deleter";
- }
- if ($next->value() eq "legacycaller") {
- $self->assertTokenValue($self->getToken(), "legacycaller", __LINE__);
- return "legacycaller";
- }
- $self->assertUnexpectedToken($next->value(), __LINE__);
-}
-
-sub parseOperationOrIteratorRest
-{
- my $self = shift;
- my $extendedAttributeList = shift;
-
- my $next = $self->nextToken();
- if ($next->value() eq "iterator") {
- return $self->parseIteratorRest($extendedAttributeList);
- }
- if ($next->type() == IdentifierToken || $next->value() eq "(") {
- return $self->parseOperationRest($extendedAttributeList);
- }
- $self->assertUnexpectedToken($next->value(), __LINE__);
-}
-
-sub parseIteratorRest
-{
- my $self = shift;
- my $extendedAttributeList = shift;
-
- my $next = $self->nextToken();
- if ($next->value() eq "iterator") {
- $self->assertTokenValue($self->getToken(), "iterator", __LINE__);
- $self->parseOptionalIteratorInterfaceOrObject($extendedAttributeList);
- $self->assertTokenValue($self->getToken(), ";", __LINE__);
- return;
- }
- $self->assertUnexpectedToken($next->value(), __LINE__);
-}
-
-sub parseOptionalIteratorInterfaceOrObject
-{
- my $self = shift;
- my $extendedAttributeList = shift;
-
- my $next = $self->nextToken();
- if ($next->value() =~ /$nextOptionalIteratorInterfaceOrObject_1/) {
- return $self->parseOptionalIteratorInterface($extendedAttributeList);
- }
- if ($next->value() eq "object") {
- $self->assertTokenValue($self->getToken(), "object", __LINE__);
- return;
- }
- $self->assertUnexpectedToken($next->value(), __LINE__);
-}
-
-sub parseOptionalIteratorInterface
-{
- my $self = shift;
- my $extendedAttributeList = shift;
-
- my $next = $self->nextToken();
- if ($next->value() eq "=") {
- $self->assertTokenValue($self->getToken(), "=", __LINE__);
- $self->assertTokenType($self->getToken(), IdentifierToken);
- }
-}
-
-sub parseOperationRest
-{
- my $self = shift;
- my $extendedAttributeList = shift;
-
- my $next = $self->nextToken();
- if ($next->type() == IdentifierToken || $next->value() eq "(") {
- my $newDataNode = domFunction->new();
- my $name = $self->parseOptionalIdentifier();
- $newDataNode->name($name);
- $self->assertTokenValue($self->getToken(), "(", __LINE__);
- push(@{$newDataNode->parameters}, @{$self->parseArgumentList()});
- $self->assertTokenValue($self->getToken(), ")", __LINE__);
- $self->assertTokenValue($self->getToken(), ";", __LINE__);
- $newDataNode->extendedAttributes($extendedAttributeList);
- return $newDataNode;
- }
- $self->assertUnexpectedToken($next->value(), __LINE__);
-}
-
-sub parseOptionalIdentifier
-{
- my $self = shift;
- my $next = $self->nextToken();
- if ($next->type() == IdentifierToken) {
- my $token = $self->getToken();
- return $token->value();
- }
- return "";
-}
-
-sub parseArgumentList
-{
- my $self = shift;
- my @arguments = ();
-
- my $next = $self->nextToken();
- if ($next->type() == IdentifierToken || $next->value() =~ /$nextArgumentList_1/) {
- push(@arguments, $self->parseArgument());
- push(@arguments, @{$self->parseArguments()});
- }
- return \@arguments;
-}
-
-sub parseArguments
-{
- my $self = shift;
- my @arguments = ();
-
- while (1) {
- my $next = $self->nextToken();
- if ($next->value() eq ",") {
- $self->assertTokenValue($self->getToken(), ",", __LINE__);
- push(@arguments, $self->parseArgument());
- } else {
- last;
- }
- }
- return \@arguments;
-}
-
-sub parseArgument
-{
- my $self = shift;
- my $next = $self->nextToken();
- if ($next->type() == IdentifierToken || $next->value() =~ /$nextArgumentList_1/) {
- my $extendedAttributeList = $self->parseExtendedAttributeListAllowEmpty();
- my $argument = $self->parseOptionalOrRequiredArgument($extendedAttributeList);
- return $argument;
- }
- $self->assertUnexpectedToken($next->value(), __LINE__);
-}
-
-sub parseOptionalOrRequiredArgument
-{
- my $self = shift;
- my $extendedAttributeList = shift;
-
- my $paramDataNode = domParameter->new();
- $paramDataNode->extendedAttributes($extendedAttributeList);
-
- my $next = $self->nextToken();
- if ($next->value() eq "optional") {
- $self->assertTokenValue($self->getToken(), "optional", __LINE__);
- my $type = $self->parseType();
- # domDataNode can only consider last "?".
- $paramDataNode->isNullable(typeHasNullableSuffix($type));
- # Remove all "?" if exists, e.g. "object?[]?" -> "object[]".
- $paramDataNode->type(typeRemoveNullableSuffix($type));
- $paramDataNode->isOptional(1);
- $paramDataNode->name($self->parseArgumentName());
- $self->parseDefault();
- return $paramDataNode;
- }
- if ($next->type() == IdentifierToken || $next->value() =~ /$nextExceptionField_1/) {
- my $type = $self->parseType();
- # domDataNode can only consider last "?".
- $paramDataNode->isNullable(typeHasNullableSuffix($type));
- # Remove all "?" if exists, e.g. "object?[]?" -> "object[]".
- $paramDataNode->type(typeRemoveNullableSuffix($type));
- $paramDataNode->isOptional(0);
- $paramDataNode->isVariadic($self->parseEllipsis());
- $paramDataNode->name($self->parseArgumentName());
- return $paramDataNode;
- }
- $self->assertUnexpectedToken($next->value(), __LINE__);
-}
-
-sub parseArgumentName
-{
- my $self = shift;
- my $next = $self->nextToken();
- if ($next->value() =~ /$nextArgumentName_1/) {
- return $self->parseArgumentNameKeyword();
- }
- if ($next->type() == IdentifierToken) {
- return $self->getToken()->value();
- }
- $self->assertUnexpectedToken($next->value(), __LINE__);
-}
-
-sub parseEllipsis
-{
- my $self = shift;
- my $next = $self->nextToken();
- if ($next->value() eq "...") {
- $self->assertTokenValue($self->getToken(), "...", __LINE__);
- return 1;
- }
- return 0;
-}
-
-sub parseExceptionMember
-{
- my $self = shift;
- my $extendedAttributeList = shift;
-
- my $next = $self->nextToken();
- if ($next->value() eq "const") {
- return $self->parseConst($extendedAttributeList);
- }
- if ($next->type() == IdentifierToken || $next->value() =~ /$nextExceptionField_1/) {
- return $self->parseExceptionField($extendedAttributeList);
- }
- $self->assertUnexpectedToken($next->value(), __LINE__);
-}
-
-sub parseExceptionField
-{
- my $self = shift;
- my $extendedAttributeList = shift;
-
- my $next = $self->nextToken();
- if ($next->type() == IdentifierToken || $next->value() =~ /$nextExceptionField_1/) {
- my $newDataNode = domAttribute->new();
- $newDataNode->type("attribute");
- $newDataNode->isReadOnly(1);
- $newDataNode->type($self->parseType());
- my $token = $self->getToken();
- $self->assertTokenType($token, IdentifierToken);
- $newDataNode->name($token->value());
- $self->assertTokenValue($self->getToken(), ";", __LINE__);
- $newDataNode->extendedAttributes($extendedAttributeList);
- return $newDataNode;
- }
- $self->assertUnexpectedToken($next->value(), __LINE__);
-}
-
-sub parseExtendedAttributeListAllowEmpty
-{
- my $self = shift;
- my $next = $self->nextToken();
- if ($next->value() eq "[") {
- return $self->parseExtendedAttributeList();
- }
- return {};
-}
-
-sub copyExtendedAttributes
-{
- my $extendedAttributeList = shift;
- my $attr = shift;
-
- for my $key (keys %{$attr}) {
- if ($key eq "Constructor") {
- push(@{$extendedAttributeList->{"Constructors"}}, $attr->{$key});
- } elsif ($key eq "Constructors") {
- my @constructors = @{$attr->{$key}};
- foreach my $constructor (@constructors) {
- push(@{$extendedAttributeList->{"Constructors"}}, $constructor);
- }
- } elsif ($key eq "CustomConstructor") {
- push(@{$extendedAttributeList->{"CustomConstructors"}}, $attr->{$key});
- } elsif ($key eq "CustomConstructors") {
- my @customConstructors = @{$attr->{$key}};
- foreach my $customConstructor (@customConstructors) {
- push(@{$extendedAttributeList->{"CustomConstructors"}}, $customConstructor);
- }
- } else {
- $extendedAttributeList->{$key} = $attr->{$key};
- }
- }
-}
-
-sub parseExtendedAttributeList
-{
- my $self = shift;
- my $next = $self->nextToken();
- if ($next->value() eq "[") {
- $self->assertTokenValue($self->getToken(), "[", __LINE__);
- my $extendedAttributeList = {};
- my $attr = $self->parseExtendedAttribute();
- copyExtendedAttributes($extendedAttributeList, $attr);
- $attr = $self->parseExtendedAttributes();
- copyExtendedAttributes($extendedAttributeList, $attr);
- $self->assertTokenValue($self->getToken(), "]", __LINE__);
- return $extendedAttributeList;
- }
- $self->assertUnexpectedToken($next->value(), __LINE__);
-}
-
-sub parseExtendedAttributes
-{
- my $self = shift;
- my $extendedAttributeList = {};
-
- while (1) {
- my $next = $self->nextToken();
- if ($next->value() eq ",") {
- $self->assertTokenValue($self->getToken(), ",", __LINE__);
- my $attr = $self->parseExtendedAttribute2();
- copyExtendedAttributes($extendedAttributeList, $attr);
- } else {
- last;
- }
- }
- return $extendedAttributeList;
-}
-
-sub parseExtendedAttribute
-{
- my $self = shift;
- my $next = $self->nextToken();
- if ($next->type() == IdentifierToken || $next->value() eq "::") {
- my $scopedName = $self->parseScopedName();
- return $self->parseExtendedAttributeRest($scopedName);
- }
- # backward compatibility. Spec doesn' allow "[]". But WebKit requires.
- if ($next->value() eq ']') {
- return {};
- }
- $self->assertUnexpectedToken($next->value(), __LINE__);
-}
-
-sub parseExtendedAttribute2
-{
- my $self = shift;
- my $next = $self->nextToken();
- if ($next->type() == IdentifierToken || $next->value() eq "::") {
- my $scopedName = $self->parseScopedName();
- return $self->parseExtendedAttributeRest($scopedName);
- }
- return {};
-}
-
-sub parseExtendedAttributeRest
-{
- my $self = shift;
- my $name = shift;
- my $attrs = {};
-
- my $next = $self->nextToken();
- if ($next->value() eq "(") {
- $self->assertTokenValue($self->getToken(), "(", __LINE__);
- $attrs->{$name} = $self->parseArgumentList();
- $self->assertTokenValue($self->getToken(), ")", __LINE__);
- return $attrs;
- }
- if ($next->value() eq "=") {
- $self->assertTokenValue($self->getToken(), "=", __LINE__);
- $attrs->{$name} = $self->parseExtendedAttributeRest2();
- return $attrs;
- }
-
- if ($name eq "Constructor" || $name eq "CustomConstructor") {
- $attrs->{$name} = [];
- } else {
- $attrs->{$name} = "VALUE_IS_MISSING";
- }
- return $attrs;
-}
-
-sub parseExtendedAttributeRest2
-{
- my $self = shift;
- my $next = $self->nextToken();
- if ($next->type() == IdentifierToken || $next->value() eq "::") {
- my $scopedName = $self->parseScopedName();
- return $self->parseExtendedAttributeRest3($scopedName);
- }
- if ($next->type() == IntegerToken) {
- my $token = $self->getToken();
- return $token->value();
- }
- $self->assertUnexpectedToken($next->value(), __LINE__);
-}
-
-sub parseExtendedAttributeRest3
-{
- my $self = shift;
- my $name = shift;
-
- my $next = $self->nextToken();
- if ($next->value() eq "&") {
- $self->assertTokenValue($self->getToken(), "&", __LINE__);
- my $rightValue = $self->parseScopedName();
- return $name . "&" . $rightValue;
- }
- if ($next->value() eq "|") {
- $self->assertTokenValue($self->getToken(), "|", __LINE__);
- my $rightValue = $self->parseScopedName();
- return $name . "|" . $rightValue;
- }
- if ($next->value() eq "(") {
- my $attr = {};
- $self->assertTokenValue($self->getToken(), "(", __LINE__);
- $attr->{$name} = $self->parseArgumentList();
- $self->assertTokenValue($self->getToken(), ")", __LINE__);
- return $attr;
- }
- if ($next->type() == IdentifierToken || $next->value() =~ /$nextExtendedAttributeRest3_1/) {
- my @names = ();
- push(@names, $name);
- push(@names, @{$self->parseScopedNameListNoComma()});
- return join(' ', @names);
- }
- $self->assertUnexpectedToken($next->value());
-}
-
-sub parseScopedNameListNoComma
-{
- my $self = shift;
- my @names = ();
-
- while (1) {
- my $next = $self->nextToken();
- if ($next->type() == IdentifierToken || $next->value() eq "::") {
- push(@names, $self->parseScopedName());
- } else {
- last;
- }
- }
- return \@names;
-}
-
-sub parseArgumentNameKeyword
-{
- my $self = shift;
- my $next = $self->nextToken();
- if ($next->value() eq "attribute") {
- return $self->getToken()->value();
- }
- if ($next->value() eq "callback") {
- return $self->getToken()->value();
- }
- if ($next->value() eq "const") {
- return $self->getToken()->value();
- }
- if ($next->value() eq "creator") {
- return $self->getToken()->value();
- }
- if ($next->value() eq "deleter") {
- return $self->getToken()->value();
- }
- if ($next->value() eq "dictionary") {
- return $self->getToken()->value();
- }
- if ($next->value() eq "enum") {
- return $self->getToken()->value();
- }
- if ($next->value() eq "exception") {
- return $self->getToken()->value();
- }
- if ($next->value() eq "getter") {
- return $self->getToken()->value();
- }
- if ($next->value() eq "implements") {
- return $self->getToken()->value();
- }
- if ($next->value() eq "inherit") {
- return $self->getToken()->value();
- }
- if ($next->value() eq "interface") {
- return $self->getToken()->value();
- }
- if ($next->value() eq "legacycaller") {
- return $self->getToken()->value();
- }
- if ($next->value() eq "partial") {
- return $self->getToken()->value();
- }
- if ($next->value() eq "serializer") {
- return $self->getToken()->value();
- }
- if ($next->value() eq "setter") {
- return $self->getToken()->value();
- }
- if ($next->value() eq "static") {
- return $self->getToken()->value();
- }
- if ($next->value() eq "stringifier") {
- return $self->getToken()->value();
- }
- if ($next->value() eq "typedef") {
- return $self->getToken()->value();
- }
- if ($next->value() eq "unrestricted") {
- return $self->getToken()->value();
- }
- $self->assertUnexpectedToken($next->value(), __LINE__);
-}
-
-sub parseType
-{
- my $self = shift;
- my $next = $self->nextToken();
- if ($next->value() eq "(") {
- my $unionType = $self->parseUnionType();
- my $suffix = $self->parseTypeSuffix();
- die "Suffix after UnionType is not supported." if $suffix ne "";
- return $unionType;
- }
- if ($next->type() == IdentifierToken || $next->value() =~ /$nextType_1/) {
- return $self->parseSingleType();
- }
- $self->assertUnexpectedToken($next->value(), __LINE__);
-}
-
-sub parseSingleType
-{
- my $self = shift;
- my $next = $self->nextToken();
- if ($next->value() eq "any") {
- $self->assertTokenValue($self->getToken(), "any", __LINE__);
- return "any" . $self->parseTypeSuffixStartingWithArray();
- }
- if ($next->type() == IdentifierToken || $next->value() =~ /$nextSingleType_1/) {
- return $self->parseNonAnyType();
- }
- $self->assertUnexpectedToken($next->value(), __LINE__);
-}
-
-sub parseUnionType
-{
- my $self = shift;
- my $next = $self->nextToken();
- if ($next->value() eq "(") {
- my $unionType = UnionType->new();
- $self->assertTokenValue($self->getToken(), "(", __LINE__);
- push @{$unionType->unionMemberTypes}, $self->parseUnionMemberType();
- $self->assertTokenValue($self->getToken(), "or", __LINE__);
- push @{$unionType->unionMemberTypes}, $self->parseUnionMemberType();
- push @{$unionType->unionMemberTypes}, $self->parseUnionMemberTypes();
- $self->assertTokenValue($self->getToken(), ")", __LINE__);
- return $unionType;
- }
- $self->assertUnexpectedToken($next->value(), __LINE__);
-}
-
-# Returns UnionType or string
-sub parseUnionMemberType
-{
- my $self = shift;
- my $next = $self->nextToken();
- if ($next->value() eq "(") {
- my $unionType = $self->parseUnionType();
- my $suffix = $self->parseTypeSuffix();
- die "Suffix after UnionType is not supported." if $suffix ne "";
- return $unionType;
- }
- if ($next->value() eq "any") {
- my $type = $self->assertTokenValue($self->getToken(), "any", __LINE__);
- $type .= $self->assertTokenValue($self->getToken(), "[", __LINE__);
- $type .= $self->assertTokenValue($self->getToken(), "]", __LINE__);
- $type .= $self->parseTypeSuffix();
- return $type;
- }
- if ($next->type() == IdentifierToken || $next->value() =~ /$nextSingleType_1/) {
- return $self->parseNonAnyType();
- }
- $self->assertUnexpectedToken($next->value(), __LINE__);
-}
-
-sub parseUnionMemberTypes
-{
- my $self = shift;
- my @types = ();
- my $next = $self->nextToken();
- if ($next->value() eq "or") {
- $self->assertTokenValue($self->getToken(), "or", __LINE__);
- push @types, $self->parseUnionMemberType();
- push @types, $self->parseUnionMemberTypes();
- }
- return @types;
-}
-
-sub parseNonAnyType
-{
- my $self = shift;
- my $next = $self->nextToken();
- if ($next->value() =~ /$nextNonAnyType_1/) {
- return $self->parsePrimitiveType() . $self->parseTypeSuffix();
- }
- if ($next->value() eq "ByteString") {
- $self->assertTokenValue($self->getToken(), "ByteString", __LINE__);
- return "ByteString" . $self->parseTypeSuffix();
- }
- if ($next->value() eq "DOMString") {
- $self->assertTokenValue($self->getToken(), "DOMString", __LINE__);
- return "DOMString" . $self->parseTypeSuffix();
- }
- if ($next->value() eq "Promise") {
- $self->assertTokenValue($self->getToken(), "Promise", __LINE__);
- return "Promise" . $self->parseTypeSuffix();
- }
- if ($next->value() eq "sequence") {
- $self->assertTokenValue($self->getToken(), "sequence", __LINE__);
- $self->assertTokenValue($self->getToken(), "<", __LINE__);
- my $type = $self->parseType();
- $self->assertTokenValue($self->getToken(), ">", __LINE__);
- return "sequence<" . $type . ">" . $self->parseNull();
- }
- if ($next->value() eq "object") {
- $self->assertTokenValue($self->getToken(), "object", __LINE__);
- return "object" . $self->parseTypeSuffix();
- }
- if ($next->value() eq "Date") {
- $self->assertTokenValue($self->getToken(), "Date", __LINE__);
- return "Date" . $self->parseTypeSuffix();
- }
- if ($next->type() == IdentifierToken || $next->value() eq "::") {
- my $name = $self->parseScopedName();
- return $name . $self->parseTypeSuffix();
- }
- $self->assertUnexpectedToken($next->value(), __LINE__);
-}
-
-sub parseConstType
-{
- my $self = shift;
- my $next = $self->nextToken();
- if ($next->value() =~ /$nextNonAnyType_1/) {
- return $self->parsePrimitiveType() . $self->parseNull();
- }
- if ($next->type() == IdentifierToken) {
- my $token = $self->getToken();
- return $token->value() . $self->parseNull();
- }
- $self->assertUnexpectedToken($next->value(), __LINE__);
-}
-
-sub parsePrimitiveType
-{
- my $self = shift;
- my $next = $self->nextToken();
- if ($next->value() =~ /$nextPrimitiveType_1/) {
- return $self->parseUnsignedIntegerType();
- }
- if ($next->value() =~ /$nextPrimitiveType_2/) {
- return $self->parseUnrestrictedFloatType();
- }
- if ($next->value() eq "boolean") {
- $self->assertTokenValue($self->getToken(), "boolean", __LINE__);
- return "boolean";
- }
- if ($next->value() eq "byte") {
- $self->assertTokenValue($self->getToken(), "byte", __LINE__);
- return "byte";
- }
- if ($next->value() eq "octet") {
- $self->assertTokenValue($self->getToken(), "octet", __LINE__);
- return "octet";
- }
- $self->assertUnexpectedToken($next->value(), __LINE__);
-}
-
-sub parseUnrestrictedFloatType
-{
- my $self = shift;
- my $next = $self->nextToken();
- if ($next->value() eq "unrestricted") {
- $self->assertTokenValue($self->getToken(), "unrestricted", __LINE__);
- return "unrestricted " . $self->parseFloatType();
- }
- if ($next->value() =~ /$nextUnrestrictedFloatType_1/) {
- return $self->parseFloatType();
- }
- $self->assertUnexpectedToken($next->value(), __LINE__);
-}
-
-sub parseFloatType
-{
- my $self = shift;
- my $next = $self->nextToken();
- if ($next->value() eq "float") {
- $self->assertTokenValue($self->getToken(), "float", __LINE__);
- return "float";
- }
- if ($next->value() eq "double") {
- $self->assertTokenValue($self->getToken(), "double", __LINE__);
- return "double";
- }
- $self->assertUnexpectedToken($next->value(), __LINE__);
-}
-
-sub parseUnsignedIntegerType
-{
- my $self = shift;
- my $next = $self->nextToken();
- if ($next->value() eq "unsigned") {
- $self->assertTokenValue($self->getToken(), "unsigned", __LINE__);
- return "unsigned " . $self->parseIntegerType();
- }
- if ($next->value() =~ /$nextUnsignedIntegerType_1/) {
- return $self->parseIntegerType();
- }
- $self->assertUnexpectedToken($next->value(), __LINE__);
-}
-
-sub parseIntegerType
-{
- my $self = shift;
- my $next = $self->nextToken();
- if ($next->value() eq "short") {
- $self->assertTokenValue($self->getToken(), "short", __LINE__);
- return "short";
- }
- if ($next->value() eq "int") {
- $self->assertTokenValue($self->getToken(), "int", __LINE__);
- return "int";
- }
- if ($next->value() eq "long") {
- $self->assertTokenValue($self->getToken(), "long", __LINE__);
- if ($self->parseOptionalLong()) {
- return "long long";
- }
- return "long";
- }
- $self->assertUnexpectedToken($next->value(), __LINE__);
-}
-
-sub parseOptionalLong
-{
- my $self = shift;
- my $next = $self->nextToken();
- if ($next->value() eq "long") {
- $self->assertTokenValue($self->getToken(), "long", __LINE__);
- return 1;
- }
- return 0;
-}
-
-sub parseTypeSuffix
-{
- my $self = shift;
- my $next = $self->nextToken();
- if ($next->value() eq "[") {
- $self->assertTokenValue($self->getToken(), "[", __LINE__);
- $self->assertTokenValue($self->getToken(), "]", __LINE__);
- return "[]" . $self->parseTypeSuffix();
- }
- if ($next->value() eq "?") {
- $self->assertTokenValue($self->getToken(), "?", __LINE__);
- return "?" . $self->parseTypeSuffixStartingWithArray();
- }
- return "";
-}
-
-sub parseTypeSuffixStartingWithArray
-{
- my $self = shift;
- my $next = $self->nextToken();
- if ($next->value() eq "[") {
- $self->assertTokenValue($self->getToken(), "[", __LINE__);
- $self->assertTokenValue($self->getToken(), "]", __LINE__);
- return "[]" . $self->parseTypeSuffix();
- }
- return "";
-}
-
-sub parseNull
-{
- my $self = shift;
- my $next = $self->nextToken();
- if ($next->value() eq "?") {
- $self->assertTokenValue($self->getToken(), "?", __LINE__);
- return "?";
- }
- return "";
-}
-
-sub parseReturnType
-{
- my $self = shift;
- my $next = $self->nextToken();
- if ($next->value() eq "void") {
- $self->assertTokenValue($self->getToken(), "void", __LINE__);
- return "void";
- }
- if ($next->type() == IdentifierToken || $next->value() =~ /$nextExceptionField_1/) {
- return $self->parseType();
- }
- $self->assertUnexpectedToken($next->value(), __LINE__);
-}
-
-sub parseExceptionList
-{
- my $self = shift;
- my $next = $self->nextToken();
- if ($next->value() eq "(") {
- my @exceptions = ();
- $self->assertTokenValue($self->getToken(), "(", __LINE__);
- push(@exceptions, @{$self->parseScopedNameList()});
- $self->assertTokenValue($self->getToken(), ")", __LINE__);
- return \@exceptions;
- }
- $self->assertUnexpectedToken($next->value(), __LINE__);
-}
-
-sub parseRaises
-{
- my $self = shift;
- my $next = $self->nextToken();
- if ($next->value() eq "raises") {
- $self->assertTokenValue($self->getToken(), "raises", __LINE__);
- return $self->parseExceptionList();
- }
- return [];
-}
-
-sub parseOptionalSemicolon
-{
- my $self = shift;
- my $next = $self->nextToken();
- if ($next->value() eq ";") {
- $self->assertTokenValue($self->getToken(), ";", __LINE__);
- }
-}
-
-sub parseScopedName
-{
- my $self = shift;
- my $next = $self->nextToken();
- if ($next->value() eq "::") {
- return $self->parseAbsoluteScopedName();
- }
- if ($next->type() == IdentifierToken) {
- return $self->parseRelativeScopedName();
- }
- $self->assertUnexpectedToken($next->value());
-}
-
-sub parseAbsoluteScopedName
-{
- my $self = shift;
- my $next = $self->nextToken();
- if ($next->value() eq "::") {
- $self->assertTokenValue($self->getToken(), "::");
- my $token = $self->getToken();
- $self->assertTokenType($token, IdentifierToken);
- return "::" . $token->value() . $self->parseScopedNameParts();
- }
- $self->assertUnexpectedToken($next->value());
-}
-
-sub parseRelativeScopedName
-{
- my $self = shift;
- my $next = $self->nextToken();
- if ($next->type() == IdentifierToken) {
- my $token = $self->getToken();
- return $token->value() . $self->parseScopedNameParts();
- }
- $self->assertUnexpectedToken($next->value());
-}
-
-sub parseScopedNameParts
-{
- my $self = shift;
- my @names = ();
-
- while (1) {
- my $next = $self->nextToken();
- if ($next->value() eq "::") {
- $self->assertTokenValue($self->getToken(), "::");
- push(@names, "::");
- my $token = $self->getToken();
- $self->assertTokenType($token, IdentifierToken);
- push(@names, $token->value());
- } else {
- last;
- }
- }
- return join("", @names);
-}
-
-sub parseScopedNameList
-{
- my $self = shift;
- my $next = $self->nextToken();
- if ($next->type() == IdentifierToken || $next->value() eq "::") {
- my @names = ();
- push(@names, $self->parseScopedName());
- push(@names, @{$self->parseScopedNames()});
- return \@names;
- }
- $self->assertUnexpectedToken($next->value(), __LINE__);
-}
-
-sub parseScopedNames
-{
- my $self = shift;
- my @names = ();
-
- while (1) {
- my $next = $self->nextToken();
- if ($next->value() eq ",") {
- $self->assertTokenValue($self->getToken(), ",");
- push(@names, $self->parseScopedName());
- } else {
- last;
- }
- }
- return \@names;
-}
-
-sub applyMemberList
-{
- my $interface = shift;
- my $members = shift;
-
- for my $item (@{$members}) {
- if (ref($item) eq "domAttribute") {
- push(@{$interface->attributes}, $item);
- next;
- }
- if (ref($item) eq "domConstant") {
- push(@{$interface->constants}, $item);
- next;
- }
- if (ref($item) eq "domFunction") {
- push(@{$interface->functions}, $item);
- next;
- }
- }
-}
-
-sub applyExtendedAttributeList
-{
- my $interface = shift;
- my $extendedAttributeList = shift;
-
- if (defined $extendedAttributeList->{"Constructors"}) {
- my @constructorParams = @{$extendedAttributeList->{"Constructors"}};
- my $index = (@constructorParams == 1) ? 0 : 1;
- foreach my $param (@constructorParams) {
- my $constructor = domFunction->new();
- $constructor->name("Constructor");
- $constructor->extendedAttributes($extendedAttributeList);
- $constructor->parameters($param);
- $constructor->overloadedIndex($index++);
- push(@{$interface->constructors}, $constructor);
- }
- delete $extendedAttributeList->{"Constructors"};
- $extendedAttributeList->{"Constructor"} = "VALUE_IS_MISSING";
- } elsif (defined $extendedAttributeList->{"NamedConstructor"}) {
- my $newDataNode = domFunction->new();
- $newDataNode->name("NamedConstructor");
- $newDataNode->extendedAttributes($extendedAttributeList);
- my %attributes = %{$extendedAttributeList->{"NamedConstructor"}};
- my @attributeKeys = keys (%attributes);
- my $constructorName = $attributeKeys[0];
- push(@{$newDataNode->parameters}, @{$attributes{$constructorName}});
- $extendedAttributeList->{"NamedConstructor"} = $constructorName;
- push(@{$interface->constructors}, $newDataNode);
- }
- if (defined $extendedAttributeList->{"CustomConstructors"}) {
- my @customConstructorParams = @{$extendedAttributeList->{"CustomConstructors"}};
- my $index = (@customConstructorParams == 1) ? 0 : 1;
- foreach my $param (@customConstructorParams) {
- my $customConstructor = domFunction->new();
- $customConstructor->name("CustomConstructor");
- $customConstructor->extendedAttributes($extendedAttributeList);
- $customConstructor->parameters($param);
- $customConstructor->overloadedIndex($index++);
- push(@{$interface->customConstructors}, $customConstructor);
- }
- delete $extendedAttributeList->{"CustomConstructors"};
- $extendedAttributeList->{"CustomConstructor"} = "VALUE_IS_MISSING";
- }
- $interface->extendedAttributes($extendedAttributeList);
-}
-
-1;
diff --git a/chromium/third_party/WebKit/Source/bindings/scripts/idl_reader.py b/chromium/third_party/WebKit/Source/bindings/scripts/idl_reader.py
new file mode 100644
index 00000000000..450c73d9f29
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/bindings/scripts/idl_reader.py
@@ -0,0 +1,109 @@
+# Copyright (C) 2013 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.
+
+"""Read an IDL file or complete IDL interface, producing an IdlDefinitions object.
+
+Design doc:
+http://www.chromium.org/developers/design-documents/idl-compiler#TOC-Front-end
+"""
+
+import os
+
+import blink_idl_parser
+from blink_idl_parser import BlinkIDLParser
+from idl_definitions import IdlDefinitions
+from idl_validator import EXTENDED_ATTRIBUTES_RELATIVE_PATH, IDLInvalidExtendedAttributeError, IDLExtendedAttributeValidator
+from interface_dependency_resolver import InterfaceDependencyResolver
+
+
+class IdlReader(object):
+ def __init__(self, interfaces_info=None, outputdir=''):
+ self.extended_attribute_validator = IDLExtendedAttributeValidator()
+
+ if interfaces_info:
+ self.interface_dependency_resolver = InterfaceDependencyResolver(interfaces_info, self)
+ else:
+ self.interface_dependency_resolver = None
+
+ self.parser = BlinkIDLParser(outputdir=outputdir)
+
+ def read_idl_definitions(self, idl_filename):
+ """Returns an IdlDefinitions object for an IDL file, including all dependencies."""
+ definitions = self.read_idl_file(idl_filename)
+ if not self.interface_dependency_resolver:
+ return definitions
+ self.interface_dependency_resolver.resolve_dependencies(definitions)
+ return definitions
+
+ def read_idl_file(self, idl_filename):
+ """Returns an IdlDefinitions object for an IDL file, without any dependencies.
+
+ The IdlDefinitions object is guaranteed to contain a single
+ IdlInterface; it may also contain other definitions, such as
+ callback functions and enumerations."""
+ ast = blink_idl_parser.parse_file(self.parser, idl_filename)
+ if not ast:
+ raise Exception('Failed to parse %s' % idl_filename)
+ definitions = IdlDefinitions(ast)
+
+ # Validate file contents with filename convention
+ # The Blink IDL filenaming convention is that the file
+ # <interface_name>.idl MUST contain exactly 1 interface (or exception),
+ # and the interface name must agree with the file's basename,
+ # unless it is a partial interface.
+ # (e.g., 'partial interface Foo' can be in FooBar.idl).
+ number_of_interfaces = len(definitions.interfaces)
+ if number_of_interfaces != 1:
+ raise Exception(
+ 'Expected exactly 1 interface in file {0}, but found {1}'
+ .format(idl_filename, number_of_interfaces))
+ interface = next(definitions.interfaces.itervalues())
+ idl_file_basename, _ = os.path.splitext(os.path.basename(idl_filename))
+ if not interface.is_partial and interface.name != idl_file_basename:
+ raise Exception(
+ 'Interface name "{0}" disagrees with IDL file basename "{1}".'
+ .format(interface.name, idl_file_basename))
+
+ # Validate extended attributes
+ if not self.extended_attribute_validator:
+ return definitions
+
+ try:
+ self.extended_attribute_validator.validate_extended_attributes(definitions)
+ except IDLInvalidExtendedAttributeError as error:
+ raise IDLInvalidExtendedAttributeError("""
+IDL ATTRIBUTE ERROR in file:
+%s:
+ %s
+If you want to add a new IDL extended attribute, please add it to:
+ %s
+and add an explanation to the Blink IDL documentation at:
+ http://www.chromium.org/blink/webidl/blink-idl-extended-attributes
+ """ % (idl_filename, str(error), EXTENDED_ATTRIBUTES_RELATIVE_PATH))
+
+ return definitions
diff --git a/chromium/third_party/WebKit/Source/bindings/scripts/idl_serializer.pm b/chromium/third_party/WebKit/Source/bindings/scripts/idl_serializer.pm
deleted file mode 100644
index 0a6fdae3124..00000000000
--- a/chromium/third_party/WebKit/Source/bindings/scripts/idl_serializer.pm
+++ /dev/null
@@ -1,126 +0,0 @@
-# Copyright (C) 2013 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.
-
-
-# Converts the intermediate representation of IDLs between Perl and JSON, for:
-# 1. Modularity between parser and code generator; and
-# 2. Piecemeal porting to Python, by letting us connect Perl and Python scripts.
-
-use strict;
-use warnings;
-
-use Class::Struct;
-use JSON -convert_blessed_universally; # IR contains objects (blessed references)
-
-sub serializeJSON
-{
- my $document = shift;
- my $json = JSON->new->utf8;
- # JSON.pm defaults to dying on objects (blessed references) and returning
- # keys in indeterminate order. We set options to change this:
- # allow_blessed: don't die when encounter a blessed reference
- # (but default to return null)
- # convert_blessed: convert blessed reference as if unblessed
- # (rather than returning null)
- # canonical: sort keys when writing JSON, so JSON always in same order,
- # so can compare output between runs or between Perl and Python
- $json = $json->allow_blessed->convert_blessed->canonical();
- return $json->encode($document);
-}
-
-sub deserializeJSON
-{
- my $jsonText = shift;
- my $json = JSON->new->utf8;
- my $jsonHash = $json->decode($jsonText);
- return jsonToPerl($jsonHash);
-}
-
-sub jsonToPerl
-{
- # JSON.pm serializes Perl objects as hashes (with keys CLASS::KEY),
- # so we need to rebuild objects when deserializing
- my $jsonData = shift;
-
- if (ref $jsonData eq "ARRAY") {
- return [map(jsonToPerl($_), @$jsonData)];
- }
-
- if (ref $jsonData eq "HASH") {
- my @keys = keys %$jsonData;
- return {} unless @keys;
-
- my $class = determineClassFromKeys(@keys);
- return jsonHashToPerlObject($jsonData, $class) if $class;
-
- # just a hash
- my $hashRef = {};
- foreach my $key (@keys) {
- $hashRef->{$key} = jsonToPerl($jsonData->{$key});
- }
- return $hashRef;
- }
-
- die "Unexpected reference type: " . ref $jsonData . "\n" if ref $jsonData;
-
- return $jsonData;
-}
-
-sub determineClassFromKeys
-{
- my @keys = shift;
-
- # Detect objects as hashes where all keys are of the form CLASS::KEY.
- my $firstKey = $keys[0];
- my $isObject = $firstKey =~ /::/;
-
- return unless $isObject;
-
- my $class = (split('::', $firstKey))[0];
- return $class;
-}
-
-sub jsonHashToPerlObject
-{
- # JSON.pm serializes hash objects of class CLASS as a hash with keys
- # CLASS::KEY1, CLASS::KEY2, etc.
- # When deserializing, need to rebuild objects by stripping prefix
- # and calling the constructor.
- my $jsonHash = shift;
- my $class = shift;
-
- my %keysValues = ();
- foreach my $classAndKey (keys %{$jsonHash}) {
- my $key = (split('::', $classAndKey))[1];
- $keysValues{$key} = jsonToPerl($jsonHash->{$classAndKey});
- }
- my $object = $class->new(%keysValues); # Build object
- return $object;
-}
-
-1;
diff --git a/chromium/third_party/WebKit/Source/bindings/scripts/idl_types.py b/chromium/third_party/WebKit/Source/bindings/scripts/idl_types.py
new file mode 100644
index 00000000000..e488e332648
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/bindings/scripts/idl_types.py
@@ -0,0 +1,321 @@
+# Copyright 2014 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+"""IDL type handling.
+
+Classes:
+IdlType
+IdlUnionType
+"""
+
+from collections import defaultdict
+
+
+################################################################################
+# IDL types
+################################################################################
+
+INTEGER_TYPES = frozenset([
+ # http://www.w3.org/TR/WebIDL/#dfn-integer-type
+ 'byte',
+ 'octet',
+ 'short',
+ 'unsigned short',
+ # int and unsigned are not IDL types
+ 'long',
+ 'unsigned long',
+ 'long long',
+ 'unsigned long long',
+])
+NUMERIC_TYPES = (INTEGER_TYPES | frozenset([
+ # http://www.w3.org/TR/WebIDL/#dfn-numeric-type
+ 'float',
+ 'unrestricted float',
+ 'double',
+ 'unrestricted double',
+]))
+# http://www.w3.org/TR/WebIDL/#dfn-primitive-type
+PRIMITIVE_TYPES = (frozenset(['boolean']) | NUMERIC_TYPES)
+BASIC_TYPES = (PRIMITIVE_TYPES | frozenset([
+ # Built-in, non-composite, non-object data types
+ # http://heycam.github.io/webidl/#idl-types
+ 'DOMString',
+ 'ByteString',
+ 'Date',
+ # http://heycam.github.io/webidl/#es-type-mapping
+ 'void',
+ # http://encoding.spec.whatwg.org/#type-scalarvaluestring
+ 'ScalarValueString',
+]))
+TYPE_NAMES = {
+ # http://heycam.github.io/webidl/#dfn-type-name
+ 'any': 'Any',
+ 'boolean': 'Boolean',
+ 'byte': 'Byte',
+ 'octet': 'Octet',
+ 'short': 'Short',
+ 'unsigned short': 'UnsignedShort',
+ 'long': 'Long',
+ 'unsigned long': 'UnsignedLong',
+ 'long long': 'LongLong',
+ 'unsigned long long': 'UnsignedLongLong',
+ 'float': 'Float',
+ 'unrestricted float': 'UnrestrictedFloat',
+ 'double': 'Double',
+ 'unrestricted double': 'UnrestrictedDouble',
+ 'DOMString': 'String',
+ 'ByteString': 'ByteString',
+ 'ScalarValueString': 'ScalarValueString',
+ 'object': 'Object',
+ 'Date': 'Date',
+}
+
+
+################################################################################
+# Inheritance
+################################################################################
+
+ancestors = defaultdict(list) # interface_name -> ancestors
+
+def inherits_interface(interface_name, ancestor_name):
+ return (interface_name == ancestor_name or
+ ancestor_name in ancestors[interface_name])
+
+
+def set_ancestors(new_ancestors):
+ ancestors.update(new_ancestors)
+
+
+################################################################################
+# IdlType
+################################################################################
+
+class IdlType(object):
+ # FIXME: incorporate Nullable, etc.
+ # FIXME: use nested types: IdlArrayType, IdlNullableType, IdlSequenceType
+ # to support types like short?[] vs. short[]?, instead of treating these
+ # as orthogonal properties (via flags).
+ callback_functions = set()
+ callback_interfaces = set()
+ enums = {} # name -> values
+
+ def __init__(self, base_type, is_array=False, is_sequence=False, is_nullable=False, is_unrestricted=False):
+ if is_array and is_sequence:
+ raise ValueError('Array of Sequences are not allowed.')
+ if is_unrestricted:
+ self.base_type = 'unrestricted %s' % base_type
+ else:
+ self.base_type = base_type
+ self.is_array = is_array
+ self.is_sequence = is_sequence
+ self.is_nullable = is_nullable
+
+ def __str__(self):
+ type_string = self.base_type
+ if self.is_array:
+ return type_string + '[]'
+ if self.is_sequence:
+ return 'sequence<%s>' % type_string
+ if self.is_nullable:
+ # FIXME: Dictionary::ConversionContext::setConversionType can't
+ # handle the '?' in nullable types (passes nullability separately).
+ # Update that function to handle nullability from the type name,
+ # simplifying its signature.
+ # return type_string + '?'
+ return type_string
+ return type_string
+
+ # FIXME: rename to native_array_element_type and move to v8_types.py
+ @property
+ def array_or_sequence_type(self):
+ return self.array_type or self.sequence_type
+
+ # FIXME: rename to array_element_type
+ @property
+ def array_type(self):
+ return self.is_array and IdlType(self.base_type)
+
+ # FIXME: rename to sequence_element_type
+ @property
+ def sequence_type(self):
+ return self.is_sequence and IdlType(self.base_type)
+
+ @property
+ def is_basic_type(self):
+ return self.base_type in BASIC_TYPES and not self.array_or_sequence_type
+
+ @property
+ def is_callback_function(self):
+ return self.base_type in IdlType.callback_functions
+
+ @property
+ def is_callback_interface(self):
+ return self.base_type in IdlType.callback_interfaces
+
+ @property
+ def is_composite_type(self):
+ return (self.name == 'Any' or
+ self.array_type or
+ self.sequence_type or
+ self.is_union_type)
+
+ @property
+ def is_enum(self):
+ # FIXME: add an IdlEnumType class and a resolve_enums step at end of
+ # IdlDefinitions constructor
+ return self.name in IdlType.enums
+
+ @property
+ def enum_values(self):
+ return IdlType.enums[self.name]
+
+ @property
+ def is_integer_type(self):
+ return self.base_type in INTEGER_TYPES and not self.array_or_sequence_type
+
+ @property
+ def is_numeric_type(self):
+ return self.base_type in NUMERIC_TYPES and not self.array_or_sequence_type
+
+ @property
+ def is_primitive_type(self):
+ return self.base_type in PRIMITIVE_TYPES and not self.array_or_sequence_type
+
+ @property
+ def is_interface_type(self):
+ # Anything that is not another type is an interface type.
+ # http://www.w3.org/TR/WebIDL/#idl-types
+ # http://www.w3.org/TR/WebIDL/#idl-interface
+ # In C++ these are RefPtr or PassRefPtr types.
+ return not(self.is_basic_type or
+ self.is_composite_type or
+ self.is_callback_function or
+ self.is_enum or
+ self.name == 'Object' or
+ self.name == 'Promise') # Promise will be basic in future
+
+ @property
+ def is_union_type(self):
+ return isinstance(self, IdlUnionType)
+
+ @property
+ def name(self):
+ """Return type name.
+
+ http://heycam.github.io/webidl/#dfn-type-name
+ """
+ base_type = self.base_type
+ base_type_name = TYPE_NAMES.get(base_type, base_type)
+ if self.is_array:
+ return base_type_name + 'Array'
+ if self.is_sequence:
+ return base_type_name + 'Sequence'
+ if self.is_nullable:
+ return base_type_name + 'OrNull'
+ return base_type_name
+
+ @classmethod
+ def set_callback_functions(cls, new_callback_functions):
+ cls.callback_functions.update(new_callback_functions)
+
+ @classmethod
+ def set_callback_interfaces(cls, new_callback_interfaces):
+ cls.callback_interfaces.update(new_callback_interfaces)
+
+ @classmethod
+ def set_enums(cls, new_enums):
+ cls.enums.update(new_enums)
+
+ def resolve_typedefs(self, typedefs):
+ if self.base_type not in typedefs:
+ return self
+ new_type = typedefs[self.base_type]
+ if type(new_type) != type(self):
+ # If type changes, need to return a different object,
+ # since can't change type(self)
+ return new_type
+ # If type doesn't change, just mutate self to avoid a new object
+ # FIXME: a bit ugly; use __init__ instead of setting flags
+ self.base_type = new_type.base_type
+ # handle array both in use and in typedef itself:
+ # typedef Type TypeDef;
+ # TypeDef[] ...
+ # and:
+ # typedef Type[] TypeArray
+ # TypeArray ...
+ self.is_array |= new_type.is_array
+ self.is_sequence |= new_type.is_sequence
+ return self
+
+
+################################################################################
+# IdlUnionType
+################################################################################
+
+class IdlUnionType(object):
+ # http://heycam.github.io/webidl/#idl-union
+ # FIXME: derive from IdlType, instead of stand-alone class, to reduce
+ # duplication.
+ def __init__(self, member_types, is_nullable=False):
+ self.member_types = member_types
+ self.is_nullable = is_nullable
+
+ @property
+ def array_or_sequence_type(self):
+ return False
+
+ @property
+ def array_type(self):
+ return False
+
+ @property
+ def is_array(self):
+ # We do not support arrays of union types
+ return False
+
+ @property
+ def base_type(self):
+ return None
+
+ @property
+ def is_basic_type(self):
+ return False
+
+ @property
+ def is_callback_function(self):
+ return False
+
+ @property
+ def is_enum(self):
+ return False
+
+ @property
+ def is_integer_type(self):
+ return False
+
+ @property
+ def is_numeric_type(self):
+ return False
+
+ @property
+ def is_primitivee_type(self):
+ return False
+
+ @property
+ def is_sequence(self):
+ # We do not support sequences of union types
+ return False
+
+ @property
+ def is_union_type(self):
+ return True
+
+ @property
+ def name(self):
+ return 'Or'.join(member_type.name for member_type in self.member_types)
+
+ def resolve_typedefs(self, typedefs):
+ self.member_types = [
+ typedefs.get(member_type, member_type)
+ for member_type in self.member_types]
+ return self
diff --git a/chromium/third_party/WebKit/Source/bindings/scripts/unstable/idl_validator.py b/chromium/third_party/WebKit/Source/bindings/scripts/idl_validator.py
index aa93242d46f..e527442cab7 100644
--- a/chromium/third_party/WebKit/Source/bindings/scripts/unstable/idl_validator.py
+++ b/chromium/third_party/WebKit/Source/bindings/scripts/idl_validator.py
@@ -26,19 +26,29 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-"""Validate extended attributes."""
+"""Validate extended attributes.
+Design doc: http://www.chromium.org/developers/design-documents/idl-compiler#TOC-Extended-attribute-validation
+"""
+
+import os.path
import re
+module_path = os.path.dirname(__file__)
+source_path = os.path.join(module_path, os.pardir, os.pardir)
+EXTENDED_ATTRIBUTES_RELATIVE_PATH = os.path.join('bindings',
+ 'IDLExtendedAttributes.txt')
+EXTENDED_ATTRIBUTES_FILENAME = os.path.join(source_path,
+ EXTENDED_ATTRIBUTES_RELATIVE_PATH)
class IDLInvalidExtendedAttributeError(Exception):
pass
class IDLExtendedAttributeValidator(object):
- def __init__(self, extended_attributes_filename):
- self.valid_extended_attributes = read_extended_attributes_file(extended_attributes_filename)
+ def __init__(self):
+ self.valid_extended_attributes = read_extended_attributes_file()
def validate_extended_attributes(self, definitions):
# FIXME: this should be done when parsing the file, rather than after.
@@ -56,13 +66,13 @@ class IDLExtendedAttributeValidator(object):
self.validate_name_values_string(name, values_string)
def validate_name_values_string(self, name, values_string):
- if name == 'ImplementedBy': # attribute added when merging interfaces
- return
if name not in self.valid_extended_attributes:
- raise IDLInvalidExtendedAttributeError('Unknown extended attribute [%s]' % name)
+ raise IDLInvalidExtendedAttributeError(
+ 'Unknown extended attribute [%s]' % name)
valid_values = self.valid_extended_attributes[name]
if values_string is None and None not in valid_values:
- raise IDLInvalidExtendedAttributeError('Missing required argument for extended attribute [%s]' % name)
+ raise IDLInvalidExtendedAttributeError(
+ 'Missing required argument for extended attribute [%s]' % name)
if '*' in valid_values: # wildcard, any (non-empty) value ok
return
if values_string is None:
@@ -72,12 +82,14 @@ class IDLExtendedAttributeValidator(object):
invalid_values = values - valid_values
if invalid_values:
invalid_value = invalid_values.pop()
- raise IDLInvalidExtendedAttributeError('Invalid value "%s" found in extended attribute [%s=%s]' % (invalid_value, name, values_string))
+ raise IDLInvalidExtendedAttributeError(
+ 'Invalid value "%s" found in extended attribute [%s=%s]' %
+ (invalid_value, name, values_string))
-def read_extended_attributes_file(extended_attributes_filename):
+def read_extended_attributes_file():
def extended_attribute_name_values():
- with open(extended_attributes_filename) as extended_attributes_file:
+ with open(EXTENDED_ATTRIBUTES_FILENAME) as extended_attributes_file:
for line in extended_attributes_file:
line = line.strip()
if not line or line.startswith('#'):
diff --git a/chromium/third_party/WebKit/Source/bindings/scripts/interface_dependency_resolver.py b/chromium/third_party/WebKit/Source/bindings/scripts/interface_dependency_resolver.py
new file mode 100644
index 00000000000..c65d3f68734
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/bindings/scripts/interface_dependency_resolver.py
@@ -0,0 +1,179 @@
+# Copyright (C) 2013 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.
+
+"""Resolve interface dependencies, producing a merged IdlDefinitions object.
+
+This library computes interface dependencies (partial interfaces and
+implements), reads the dependency files, and merges them to the IdlDefinitions
+for the main IDL file, producing an IdlDefinitions object representing the
+entire interface.
+
+Design doc: http://www.chromium.org/developers/design-documents/idl-compiler#TOC-Dependency-resolution
+"""
+
+import os.path
+
+# The following extended attributes can be applied to a dependency interface,
+# and are then applied to the individual members when merging.
+# Note that this moves the extended attribute from the interface to the member,
+# which changes the semantics and yields different code than the same extended
+# attribute on the main interface.
+DEPENDENCY_EXTENDED_ATTRIBUTES = set([
+ 'Conditional',
+ 'PerContextEnabled',
+ 'RuntimeEnabled',
+])
+
+
+class InterfaceDependencyResolver(object):
+ def __init__(self, interfaces_info, reader):
+ """Initialize dependency resolver.
+
+ Args:
+ interfaces_info:
+ dict of interfaces information, from compute_dependencies.py
+ reader:
+ IdlReader, used for reading dependency files
+ """
+ self.interfaces_info = interfaces_info
+ self.reader = reader
+
+ def resolve_dependencies(self, definitions):
+ """Resolve dependencies, merging them into IDL definitions of main file.
+
+ Dependencies consist of 'partial interface' for the same interface as
+ in the main file, and other interfaces that this interface 'implements'.
+ These are merged into the main IdlInterface, as the main IdlInterface
+ implements all these members.
+
+ Referenced interfaces are added to IdlDefinitions, but not merged into
+ the main IdlInterface, as these are only referenced (their members are
+ introspected, but not implemented in this interface).
+
+ Inherited extended attributes are also added to the main IdlInterface.
+
+ Modifies definitions in place by adding parsed dependencies.
+
+ Args:
+ definitions: IdlDefinitions object, modified in place
+ """
+ target_interface = next(definitions.interfaces.itervalues())
+ interface_name = target_interface.name
+ interface_info = self.interfaces_info[interface_name]
+
+ if 'inherited_extended_attributes' in interface_info:
+ target_interface.extended_attributes.update(
+ interface_info['inherited_extended_attributes'])
+
+ merge_interface_dependencies(definitions,
+ target_interface,
+ interface_info['dependencies_full_paths'],
+ self.reader)
+
+ for referenced_interface_name in interface_info['referenced_interfaces']:
+ referenced_definitions = self.reader.read_idl_definitions(
+ self.interfaces_info[referenced_interface_name]['full_path'])
+ definitions.update(referenced_definitions)
+
+
+def merge_interface_dependencies(definitions, target_interface, dependency_idl_filenames, reader):
+ """Merge dependencies ('partial interface' and 'implements') in dependency_idl_filenames into target_interface.
+
+ No return: modifies target_interface in place.
+ """
+ # Sort so order consistent, so can compare output from run to run.
+ for dependency_idl_filename in sorted(dependency_idl_filenames):
+ dependency_definitions = reader.read_idl_file(dependency_idl_filename)
+ dependency_interface = next(dependency_definitions.interfaces.itervalues())
+ dependency_interface_basename, _ = os.path.splitext(os.path.basename(dependency_idl_filename))
+
+ transfer_extended_attributes(dependency_interface,
+ dependency_interface_basename)
+ definitions.update(dependency_definitions) # merges partial interfaces
+ if not dependency_interface.is_partial:
+ # Implemented interfaces (non-partial dependencies) are also merged
+ # into the target interface, so Code Generator can just iterate
+ # over one list (and not need to handle 'implements' itself).
+ target_interface.merge(dependency_interface)
+
+
+def transfer_extended_attributes(dependency_interface, dependency_interface_basename):
+ """Transfer extended attributes from dependency interface onto members.
+
+ Merging consists of storing certain interface-level data in extended
+ attributes of the *members* (because there is no separate dependency
+ interface post-merging).
+
+ The data storing consists of:
+ * applying certain extended attributes from the dependency interface
+ to its members
+ * storing the C++ class of the implementation in an internal
+ extended attribute of each member, [PartialInterfaceImplementedAs]
+
+ No return: modifies dependency_interface in place.
+ """
+ merged_extended_attributes = dict(
+ (key, value)
+ for key, value in dependency_interface.extended_attributes.iteritems()
+ if key in DEPENDENCY_EXTENDED_ATTRIBUTES)
+
+ # A partial interface's members are implemented as static member functions
+ # in a separate C++ class. This class name is stored in
+ # [PartialInterfaceImplementedAs] which defaults to the basename of
+ # dependency IDL file.
+ # This class name can be overridden by [ImplementedAs] on the partial
+ # interface definition.
+ #
+ # Note that implemented interfaces do *not* need [ImplementedAs], since
+ # they are implemented on the C++ object |impl| itself, just like members of
+ # the main interface definition, so the bindings do not need to know in
+ # which class implemented interfaces are implemented.
+ #
+ # Currently [LegacyTreatAsPartialInterface] can be used to have partial
+ # interface behavior on implemented interfaces, but this is being removed
+ # as legacy cruft:
+ # FIXME: Remove [LegacyTreatAsPartialInterface]
+ # http://crbug.com/360435
+ #
+ # Note that [ImplementedAs] is used with different meanings on interfaces
+ # and members:
+ # for Blink class name and function name (or constant name), respectively.
+ # Thus we do not want to copy this from the interface to the member, but
+ # instead extract it and handle it separately.
+ if (dependency_interface.is_partial or
+ 'LegacyTreatAsPartialInterface' in dependency_interface.extended_attributes):
+ merged_extended_attributes['PartialInterfaceImplementedAs'] = (
+ dependency_interface.extended_attributes.get(
+ 'ImplementedAs', dependency_interface_basename))
+
+ for attribute in dependency_interface.attributes:
+ attribute.extended_attributes.update(merged_extended_attributes)
+ for constant in dependency_interface.constants:
+ constant.extended_attributes.update(merged_extended_attributes)
+ for operation in dependency_interface.operations:
+ operation.extended_attributes.update(merged_extended_attributes)
diff --git a/chromium/third_party/WebKit/Source/bindings/scripts/interfaces_info_individual.gypi b/chromium/third_party/WebKit/Source/bindings/scripts/interfaces_info_individual.gypi
new file mode 100644
index 00000000000..32f72b5011e
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/bindings/scripts/interfaces_info_individual.gypi
@@ -0,0 +1,70 @@
+# Copyright 2014 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+#
+# This file is meant to be included into a target to provide an action
+# to compute information about individual interfaces defined in a component.
+#
+# To use this, create a gyp target with the following form:
+# {
+# 'target_name': 'interfaces_info_individual_component',
+# 'dependencies': [
+# 'generated_idls_target',
+# ],
+# 'variables': {
+# 'static_idl_files': '<(component_static_idl_files)',
+# 'generated_idl_files': '<(component_generated_idl_files)',
+# 'component_dir': 'component',
+# 'output_file':
+# '<(bindings_core_output_dir)/InterfacesInfoComponentIndividual.pickle',
+# },
+# 'includes': ['path/to/this/gypi/file'],
+# },
+#
+# Required variables:
+# static_idl_files - All static .idl files for the component, including
+# dependencies and testing.
+# generated_idl_files - All generated .idl files for the component.
+# (Must be separate from static because build dir not know at gyp time.)
+# component_dir - Relative directory for component, e.g., 'core'.
+# output_file - Pickle file containing output.
+#
+# Design document: http://www.chromium.org/developers/design-documents/idl-build
+
+{
+ 'type': 'none',
+ 'actions': [{
+ 'action_name': 'compute_<(_target_name)',
+ 'message': 'Computing global information about individual IDL files for <(_target_name)',
+ 'variables': {
+ 'static_idl_files_list':
+ '<|(<(_target_name)_static_idl_files_list.tmp <@(static_idl_files))',
+ },
+ 'inputs': [
+ '<(bindings_scripts_dir)/compute_interfaces_info_individual.py',
+ '<(bindings_scripts_dir)/utilities.py',
+ '<(static_idl_files_list)',
+ '<@(static_idl_files)',
+ '<@(generated_idl_files)',
+ ],
+ 'outputs': [
+ '<(output_file)',
+ ],
+
+ 'action': [
+ 'python',
+ '<(bindings_scripts_dir)/compute_interfaces_info_individual.py',
+ '--component-dir',
+ '<(component_dir)',
+ '--idl-files-list',
+ '<(static_idl_files_list)',
+ '--interfaces-info-file',
+ '<(output_file)',
+ '--write-file-only-if-changed',
+ '<(write_file_only_if_changed)',
+ '--',
+ # Generated files must be passed at command line
+ '<@(generated_idl_files)',
+ ],
+ }],
+}
diff --git a/chromium/third_party/WebKit/Source/bindings/scripts/interfaces_info_overall.gypi b/chromium/third_party/WebKit/Source/bindings/scripts/interfaces_info_overall.gypi
new file mode 100644
index 00000000000..024fb2a6511
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/bindings/scripts/interfaces_info_overall.gypi
@@ -0,0 +1,56 @@
+# Copyright 2014 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+#
+# This file is meant to be included into a target to provide an action
+# to compute overall information about interfaces defined in a component.
+#
+# To use this, create a gyp target with the following form:
+# {
+# 'target_name': 'interfaces_info_component',
+# 'dependencies': [
+# 'interfaces_info_individual_base_component',
+# 'interfaces_info_individual_component',
+# ],
+# 'variables': {
+# 'input_files': [
+# '<(bindings_base_component_output_dir)/InterfacesInfoBaseComponentIndividual.pickle',
+# '<(bindings_component_output_dir)/InterfacesInfoComponentIndividual.pickle',
+# ],
+# 'output_file':
+# '<(bindings_component_output_dir)/InterfacesInfoComponent.pickle',
+# },
+# 'includes': ['path/to/this/gypi/file'],
+# },
+#
+# Required variables:
+# input_files - Pickle files containing info about individual interfaces, both
+# current component and any base components.
+# output_file - Pickle file containing output (overall info).
+#
+# Design document: http://www.chromium.org/developers/design-documents/idl-build
+
+{
+ 'type': 'none',
+ 'actions': [{
+ 'action_name': 'compute_<(_target_name)',
+ 'message': 'Computing overall global information about IDL files for <(_target_name)',
+
+ 'inputs': [
+ '<(bindings_scripts_dir)/compute_interfaces_info_overall.py',
+ '<@(input_files)',
+ ],
+ 'outputs': [
+ '<(output_file)',
+ ],
+ 'action': [
+ 'python',
+ '<(bindings_scripts_dir)/compute_interfaces_info_overall.py',
+ '--write-file-only-if-changed',
+ '<(write_file_only_if_changed)',
+ '--',
+ '<@(input_files)',
+ '<(output_file)',
+ ],
+ }],
+}
diff --git a/chromium/third_party/WebKit/Source/bindings/scripts/scripts.gni b/chromium/third_party/WebKit/Source/bindings/scripts/scripts.gni
new file mode 100644
index 00000000000..f606a56439a
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/bindings/scripts/scripts.gni
@@ -0,0 +1,202 @@
+# Copyright 2014 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import("//third_party/WebKit/Source/bindings/core/v8/generated.gni")
+import("//third_party/WebKit/Source/bindings/modules/idl.gni")
+import("//third_party/WebKit/Source/bindings/modules/modules.gni")
+
+bindings_scripts_dir = get_path_info(".", "abspath")
+bindings_scripts_output_dir = "$root_gen_dir/blink/bindings/scripts"
+
+# Replacing <(DEPTH) with "/" makes paths like "<(DEPTH)/foo" absolute.
+_gypi = exec_script(
+ "//build/gypi_to_gn.py",
+ [ rebase_path("scripts.gypi"),
+ "--replace=<(DEPTH)=/" ],
+ "scope",
+ [ "scripts.gypi" ])
+
+jinja_module_files = get_path_info(_gypi.jinja_module_files, "abspath")
+idl_lexer_parser_files = get_path_info(_gypi.idl_lexer_parser_files, "abspath")
+idl_compiler_files = get_path_info(_gypi.idl_compiler_files, "abspath")
+
+# Calls the compute_interfaces_info_individual script.
+#
+# Parameters:
+# sources_static = list of IDL files to pass as inputs
+# sources_generated = list of generated IDL files to pass as inputs
+# component_dir = name if subdirectory (one word, no slashes) of component.
+# output_file = pickle file to write
+#
+# FIXME: Note the static/generated split is for consistency with GYP. This
+# split is not necessary in the GN build and could be combined into a single
+# "sources".
+template("compute_interfaces_info_individual") {
+ action(target_name) {
+ script = "$bindings_scripts_dir/compute_interfaces_info_individual.py"
+ if (defined(invoker.visibility)) {
+ visibility = invoker.visibility
+ }
+
+ # Save static list to temp file to avoid blowing out command-line length
+ # limit.
+ file_list = "$target_gen_dir/${target_name}_file_list.txt"
+ write_file(file_list, rebase_path(invoker.sources_static, root_build_dir))
+
+ source_prereqs = [
+ "$bindings_scripts_dir/utilities.py",
+ file_list,
+ ] + invoker.sources_static + invoker.sources_generated
+
+ outputs = [
+ invoker.output_file
+ ]
+
+ args = [
+ "--component-dir", invoker.component_dir,
+ "--idl-files-list", rebase_path(file_list, root_build_dir),
+ "--interfaces-info-file",
+ rebase_path(invoker.output_file, root_build_dir),
+ "--write-file-only-if-changed=1",
+ "--",
+ ] + rebase_path(invoker.sources_generated, root_build_dir)
+
+ deps = [
+ # FIXME: should be {modules|core}_generated_idls
+ # http://crbug.com/358074
+ "//third_party/WebKit/Source/bindings:generated_idls",
+ ]
+ }
+}
+
+# Calls generate_event_interfaces
+#
+# Parameters:
+# sources = A list of IDL files to process.
+# output_file = The .in file to write, relative to the blink_gen_dir.
+# suffix = (Optional) String to be passed to script via --suffix
+template("generate_event_interfaces") {
+ action(target_name) {
+ # Write the file list to a unique temp file to avoid blowing out the
+ # command line length limit.
+ idl_files_list = "$target_gen_dir/${target_name}_file_list.tmp"
+ write_file(idl_files_list,
+ rebase_path(invoker.sources, root_build_dir))
+
+ source_prereqs = [
+ "//third_party/WebKit/Source/bindings/scripts/utilities.py",
+ idl_files_list,
+ ] + invoker.sources
+
+ output_file = "$root_gen_dir/blink/" + invoker.output_file
+ outputs = [ output_file ]
+
+ script = "//third_party/WebKit/Source/bindings/scripts/generate_event_interfaces.py"
+ args = [
+ "--event-idl-files-list",
+ rebase_path(idl_files_list, root_build_dir),
+ "--event-interfaces-file",
+ rebase_path(output_file, root_build_dir),
+ "--write-file-only-if-changed=1", # Always true for Ninja.
+ ]
+
+ if (defined(invoker.suffix)) {
+ args += [ "--suffix", invoker.suffix ]
+ }
+ }
+}
+
+# Runs the idl_compiler script over a list of sources.
+#
+# Parameters:
+# sources = list of IDL files to compile
+# output_dir = string containing the directory to put the output files.
+template("idl_compiler") {
+ output_dir = invoker.output_dir
+
+ action_foreach(target_name) {
+ # TODO(brettw) GYP adds a "-S before the script name to skip "import site" to
+ # speed up startup. Figure out if we need this and do something similar (not
+ # really expressible in GN now).
+ script = "//third_party/WebKit/Source/bindings/scripts/idl_compiler.py"
+
+ source_prereqs =
+ idl_lexer_parser_files + # to be explicit (covered by parsetab)
+ idl_compiler_files
+ source_prereqs += [
+ "$bindings_scripts_output_dir/lextab.py",
+ "$bindings_scripts_output_dir/parsetab.pickle",
+ "$bindings_scripts_output_dir/cached_jinja_templates.stamp",
+ "$bindings_dir/IDLExtendedAttributes.txt",
+ # If the dependency structure or public interface info (e.g.,
+ # [ImplementedAs]) changes, we rebuild all files, since we're not
+ # computing dependencies file-by-file in the build.
+ # This data is generally stable.
+ "$bindings_modules_output_dir/InterfacesInfoModules.pickle",
+ ]
+ # Further, if any dependency (partial interface or implemented
+ # interface) changes, rebuild everything, since every IDL potentially
+ # depends on them, because we're not computing dependencies
+ # file-by-file.
+ # FIXME: This is too conservative, and causes excess rebuilds:
+ # compute this file-by-file. http://crbug.com/341748
+ # This should theoretically just be the IDL files passed in.
+ source_prereqs += all_dependency_idl_files
+
+ sources = invoker.sources
+ outputs = [
+ "$output_dir/V8{{source_name_part}}.cpp",
+ "$output_dir/V8{{source_name_part}}.h",
+ ]
+
+ args = [
+ "--cache-dir",
+ rebase_path(bindings_scripts_output_dir, root_build_dir),
+ "--output-dir",
+ rebase_path(output_dir, root_build_dir),
+ "--interfaces-info",
+ rebase_path("$bindings_modules_output_dir/InterfacesInfoModules.pickle",
+ root_build_dir),
+ "--write-file-only-if-changed=1", # Always true for Ninja.
+ "{{source}}",
+ ]
+
+ deps = [
+ # FIXME: should be interfaces_info_core (w/o modules)
+ # http://crbug.com/358074
+ "//third_party/WebKit/Source/bindings/modules:interfaces_info",
+
+ "//third_party/WebKit/Source/bindings/scripts:cached_lex_yacc_tables",
+ "//third_party/WebKit/Source/bindings/scripts:cached_jinja_templates",
+ "//third_party/WebKit/Source/core:generated_testing_idls",
+ ]
+ }
+}
+
+# Calls the aggregate_generated_bindings script.
+#
+# Parameters:
+# sources = a list of source IDL files.
+# component_dir = Name of directory for these files (one word, no slashes).
+# outputs = a list of files to write to.
+template("aggregate_generated_bindings") {
+ action(target_name) {
+ script = "//third_party/WebKit/Source/bindings/scripts/aggregate_generated_bindings.py"
+
+ # Write lists of main IDL files to a file, so that the command lines don't
+ # exceed OS length limits.
+ idl_files_list = "$target_gen_dir/${target_name}_file_list.tmp"
+ write_file(idl_files_list, rebase_path(invoker.sources, root_build_dir))
+
+ source_prereqs = [ idl_files_list ] + invoker.sources
+ outputs = invoker.outputs
+
+ args = [
+ invoker.component_dir,
+ rebase_path(idl_files_list, root_build_dir),
+ "--",
+ ]
+ args += rebase_path(invoker.outputs, root_build_dir)
+ }
+}
diff --git a/chromium/third_party/WebKit/Source/bindings/scripts/scripts.gyp b/chromium/third_party/WebKit/Source/bindings/scripts/scripts.gyp
new file mode 100644
index 00000000000..d8d86871713
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/bindings/scripts/scripts.gyp
@@ -0,0 +1,75 @@
+# Copyright 2014 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# Pre-caching steps used internally by the IDL compiler
+#
+# Design doc: http://www.chromium.org/developers/design-documents/idl-build
+
+{
+ 'includes': [
+ 'scripts.gypi',
+ '../bindings.gypi',
+ '../templates/templates.gypi',
+ ],
+
+ 'targets': [
+################################################################################
+ {
+ # A separate pre-caching step is *not required* to use lex/parse table
+ # caching in PLY, as the caches are concurrency-safe.
+ # However, pre-caching ensures that all compiler processes use the cached
+ # files (hence maximizing speed), instead of early processes building the
+ # tables themselves (as they've not yet been written when they start).
+ #
+ # GN version: //third_party/WebKit/Source/bindings/scripts:cached_lex_yacc_tables
+ 'target_name': 'cached_lex_yacc_tables',
+ 'type': 'none',
+ 'actions': [{
+ 'action_name': 'cache_lex_yacc_tables',
+ 'inputs': [
+ '<@(idl_lexer_parser_files)',
+ ],
+ 'outputs': [
+ '<(bindings_scripts_output_dir)/lextab.py',
+ '<(bindings_scripts_output_dir)/parsetab.pickle',
+ ],
+ 'action': [
+ 'python',
+ 'blink_idl_parser.py',
+ '<(bindings_scripts_output_dir)',
+ ],
+ 'message': 'Caching PLY lex & yacc lex/parse tables',
+ }],
+ },
+################################################################################
+ {
+ # A separate pre-caching step is *required* to use bytecode caching in
+ # Jinja (which improves speed significantly), as the bytecode cache is
+ # not concurrency-safe on write; details in code_generator_v8.py.
+ #
+ # GN version: //third_party/WebKit/Source/bindings/scripts:cached_jinja_templates
+ 'target_name': 'cached_jinja_templates',
+ 'type': 'none',
+ 'actions': [{
+ 'action_name': 'cache_jinja_templates',
+ 'inputs': [
+ '<@(jinja_module_files)',
+ 'code_generator_v8.py',
+ '<@(code_generator_template_files)',
+ ],
+ 'outputs': [
+ '<(bindings_scripts_output_dir)/cached_jinja_templates.stamp', # Dummy to track dependency
+ ],
+ 'action': [
+ 'python',
+ 'code_generator_v8.py',
+ '<(bindings_scripts_output_dir)',
+ '<(bindings_scripts_output_dir)/cached_jinja_templates.stamp',
+ ],
+ 'message': 'Caching bytecode of Jinja templates',
+ }],
+ },
+################################################################################
+ ], # targets
+}
diff --git a/chromium/third_party/WebKit/Source/bindings/scripts/scripts.gypi b/chromium/third_party/WebKit/Source/bindings/scripts/scripts.gypi
new file mode 100644
index 00000000000..9bf033d7eee
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/bindings/scripts/scripts.gypi
@@ -0,0 +1,59 @@
+# Copyright 2014 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+{
+ 'variables': {
+ 'bindings_scripts_dir': '.',
+ 'bindings_scripts_output_dir': '<(SHARED_INTERMEDIATE_DIR)/blink/bindings/scripts',
+ 'jinja_module_files': [
+ # jinja2/__init__.py contains version string, so sufficient for package
+ '<(DEPTH)/third_party/jinja2/__init__.py',
+ '<(DEPTH)/third_party/markupsafe/__init__.py', # jinja2 dep
+ ],
+ 'idl_lexer_parser_files': [
+ # PLY (Python Lex-Yacc)
+ '<(DEPTH)/third_party/ply/lex.py',
+ '<(DEPTH)/third_party/ply/yacc.py',
+ # Web IDL lexer/parser (base parser)
+ '<(DEPTH)/tools/idl_parser/idl_lexer.py',
+ '<(DEPTH)/tools/idl_parser/idl_node.py',
+ '<(DEPTH)/tools/idl_parser/idl_parser.py',
+ # Blink IDL lexer/parser/constructor
+ 'blink_idl_lexer.py',
+ 'blink_idl_parser.py',
+ ],
+ 'idl_compiler_files': [
+ 'idl_compiler.py',
+ # Blink IDL front end (ex-lexer/parser)
+ 'idl_definitions.py',
+ 'idl_reader.py',
+ 'idl_types.py',
+ 'idl_validator.py',
+ 'interface_dependency_resolver.py',
+ # V8 code generator
+ 'code_generator_v8.py',
+ 'v8_attributes.py',
+ 'v8_callback_interface.py',
+ 'v8_globals.py',
+ 'v8_interface.py',
+ 'v8_methods.py',
+ 'v8_types.py',
+ 'v8_utilities.py',
+ ],
+
+ 'conditions': [
+ # These scripts can skip writing generated files if they are identical
+ # to the already existing files, which avoids further build steps, like
+ # recompilation. However, a dependency (earlier build step) having a
+ # newer timestamp than an output (later build step) confuses some build
+ # systems, so only use this on ninja, which explicitly supports this use
+ # case (gyp turns all actions into ninja restat rules).
+ ['"<(GENERATOR)"=="ninja"', {
+ 'write_file_only_if_changed': '1',
+ }, {
+ 'write_file_only_if_changed': '0',
+ }],
+ ],
+ },
+}
diff --git a/chromium/third_party/WebKit/Source/bindings/scripts/unstable/code_generator_v8.py b/chromium/third_party/WebKit/Source/bindings/scripts/unstable/code_generator_v8.py
deleted file mode 100644
index 21e5ce2cce9..00000000000
--- a/chromium/third_party/WebKit/Source/bindings/scripts/unstable/code_generator_v8.py
+++ /dev/null
@@ -1,156 +0,0 @@
-# Copyright (C) 2013 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.
-
-"""Generate Blink V8 bindings (.h and .cpp files).
-
-FIXME: Not currently used in build.
-This is a rewrite of the Perl IDL compiler in Python, but is not complete.
-Once it is complete, we will switch all IDL files over to Python at once.
-Until then, please work on the Perl IDL compiler.
-For details, see bug http://crbug.com/239771
-
-Input: An object of class IdlDefinitions, containing an IDL interface X
-Output: V8X.h and V8X.cpp
-"""
-
-import os
-import posixpath
-import re
-import sys
-
-# jinja2 is in chromium's third_party directory.
-module_path, module_name = os.path.split(__file__)
-third_party = os.path.join(module_path, os.pardir, os.pardir, os.pardir, os.pardir, os.pardir)
-# Insert at front to override system libraries, and after path[0] == script dir
-sys.path.insert(1, third_party)
-import jinja2
-
-templates_dir = os.path.join(module_path, os.pardir, os.pardir, 'templates')
-
-import v8_callback_interface
-from v8_globals import includes
-import v8_interface
-import v8_types
-from v8_utilities import capitalize, cpp_name, conditional_string, v8_class_name
-
-
-class CodeGeneratorV8:
- def __init__(self, definitions, interface_name, output_directory, relative_dir_posix, idl_directories, verbose=False):
- self.idl_definitions = definitions
- self.interface_name = interface_name
- self.idl_directories = idl_directories
- self.output_directory = output_directory
- self.verbose = verbose
- # FIXME: remove definitions check when remove write_dummy_header_and_cpp
- if not definitions:
- return
- try:
- self.interface = definitions.interfaces[interface_name]
- except KeyError:
- raise Exception('%s not in IDL definitions' % interface_name)
- if self.interface.is_callback:
- header_template_filename = 'callback_interface.h'
- cpp_template_filename = 'callback_interface.cpp'
- self.generate_contents = v8_callback_interface.generate_callback_interface
- else:
- header_template_filename = 'interface.h'
- cpp_template_filename = 'interface.cpp'
- self.generate_contents = v8_interface.generate_interface
- jinja_env = jinja2.Environment(
- loader=jinja2.FileSystemLoader(templates_dir),
- keep_trailing_newline=True, # newline-terminate generated files
- lstrip_blocks=True, # so can indent control flow tags
- trim_blocks=True)
- jinja_env.filters.update({
- 'blink_capitalize': capitalize,
- 'conditional': conditional_if_endif,
- 'runtime_enabled': runtime_enabled_if,
- })
- self.header_template = jinja_env.get_template(header_template_filename)
- self.cpp_template = jinja_env.get_template(cpp_template_filename)
-
- class_name = cpp_name(self.interface)
- self.include_for_cpp_class = posixpath.join(relative_dir_posix, class_name + '.h')
- enumerations = definitions.enumerations
- if enumerations:
- v8_types.set_enum_types(enumerations)
-
- def write_dummy_header_and_cpp(self):
- # FIXME: fix GYP so these files aren't needed and remove this method
- target_interface_name = self.interface_name
- header_basename = 'V8%s.h' % target_interface_name
- cpp_basename = 'V8%s.cpp' % target_interface_name
- contents = """/*
- This file is generated just to tell build scripts that {header_basename} and
- {cpp_basename} are created for {target_interface_name}.idl, and thus
- prevent the build scripts from trying to generate {header_basename} and
- {cpp_basename} at every build. This file must not be tried to compile.
-*/
-""".format(**locals())
- self.write_file(header_basename, contents)
- self.write_file(cpp_basename, contents)
-
- def write_header_and_cpp(self):
- interface = self.interface
- template_contents = self.generate_contents(interface)
- template_contents['header_includes'].add(self.include_for_cpp_class)
- template_contents['header_includes'] = sorted(template_contents['header_includes'])
- template_contents['cpp_includes'] = sorted(includes)
-
- header_basename = v8_class_name(interface) + '.h'
- header_file_text = self.header_template.render(template_contents)
- self.write_file(header_basename, header_file_text)
-
- cpp_basename = v8_class_name(interface) + '.cpp'
- cpp_file_text = self.cpp_template.render(template_contents)
- self.write_file(cpp_basename, cpp_file_text)
-
- def write_file(self, basename, file_text):
- filename = os.path.join(self.output_directory, basename)
- with open(filename, 'w') as output_file:
- output_file.write(file_text)
-
-
-# [Conditional]
-def conditional_if_endif(code, conditional_string):
- # Jinja2 filter to generate if/endif directive blocks
- if not conditional_string:
- return code
- return ('#if %s\n' % conditional_string +
- code +
- '#endif // %s\n' % conditional_string)
-
-
-# [RuntimeEnabled]
-def runtime_enabled_if(code, runtime_enabled_function_name):
- if not runtime_enabled_function_name:
- return code
- # Indent if statement to level of original code
- indent = re.match(' *', code).group(0)
- return ('%sif (%s())\n' % (indent, runtime_enabled_function_name) +
- ' %s' % code)
diff --git a/chromium/third_party/WebKit/Source/bindings/scripts/unstable/idl_compiler.py b/chromium/third_party/WebKit/Source/bindings/scripts/unstable/idl_compiler.py
deleted file mode 100755
index b95a759f44b..00000000000
--- a/chromium/third_party/WebKit/Source/bindings/scripts/unstable/idl_compiler.py
+++ /dev/null
@@ -1,129 +0,0 @@
-#!/usr/bin/python
-# Copyright (C) 2013 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.
-
-"""Compile an .idl file to Blink V8 bindings (.h and .cpp files).
-
-FIXME: Not currently used in build.
-This is a rewrite of the Perl IDL compiler in Python, but is not complete.
-Once it is complete, we will switch all IDL files over to Python at once.
-Until then, please work on the Perl IDL compiler.
-For details, see bug http://crbug.com/239771
-"""
-
-import optparse
-import os
-import pickle
-import posixpath
-import shlex
-import sys
-
-import code_generator_v8
-import idl_reader
-
-module_path, _ = os.path.split(__file__)
-source_path = os.path.normpath(os.path.join(module_path, os.pardir, os.pardir, os.pardir))
-
-
-def parse_options():
- parser = optparse.OptionParser()
- parser.add_option('--additional-idl-files')
- # FIXME: The --dump-json-and-pickle option is only for debugging and will
- # be removed once we complete migrating all IDL files from the Perl flow to
- # the Python flow.
- parser.add_option('--dump-json-and-pickle', action='store_true', default=False)
- parser.add_option('--idl-attributes-file')
- parser.add_option('--include', dest='idl_directories', action='append')
- parser.add_option('--output-directory')
- parser.add_option('--interface-dependencies-file')
- parser.add_option('--verbose', action='store_true', default=False)
- parser.add_option('--write-file-only-if-changed', type='int')
- # ensure output comes last, so command line easy to parse via regexes
- parser.disable_interspersed_args()
-
- options, args = parser.parse_args()
- if options.output_directory is None:
- parser.error('Must specify output directory using --output-directory.')
- if options.additional_idl_files is None:
- options.additional_idl_files = []
- else:
- # additional_idl_files is passed as a string with varied (shell-style)
- # quoting, hence needs parsing.
- options.additional_idl_files = shlex.split(options.additional_idl_files)
- if len(args) != 1:
- parser.error('Must specify exactly 1 input file as argument, but %d given.' % len(args))
- options.idl_filename = os.path.realpath(args[0])
- return options
-
-
-def get_relative_dir_posix(filename):
- """Returns directory of a local file relative to Source, in POSIX format."""
- relative_path_local = os.path.relpath(filename, source_path)
- relative_dir_local = os.path.dirname(relative_path_local)
- return relative_dir_local.replace(os.path.sep, posixpath.sep)
-
-
-def write_json_and_pickle(definitions, interface_name, output_directory):
- json_string = definitions.to_json()
- json_basename = interface_name + '.json'
- json_filename = os.path.join(output_directory, json_basename)
- with open(json_filename, 'w') as json_file:
- json_file.write(json_string)
- pickle_basename = interface_name + '.pkl'
- pickle_filename = os.path.join(output_directory, pickle_basename)
- with open(pickle_filename, 'wb') as pickle_file:
- pickle.dump(definitions, pickle_file)
-
-
-def main():
- options = parse_options()
- idl_filename = options.idl_filename
- basename = os.path.basename(idl_filename)
- interface_name, _ = os.path.splitext(basename)
- output_directory = options.output_directory
- verbose = options.verbose
- if verbose:
- print idl_filename
- relative_dir_posix = get_relative_dir_posix(idl_filename)
-
- reader = idl_reader.IdlReader(options.interface_dependencies_file, options.additional_idl_files, options.idl_attributes_file, output_directory, verbose)
- definitions = reader.read_idl_definitions(idl_filename)
- code_generator = code_generator_v8.CodeGeneratorV8(definitions, interface_name, options.output_directory, relative_dir_posix, options.idl_directories, verbose)
- if not definitions:
- # We generate dummy .h and .cpp files just to tell build scripts
- # that outputs have been created.
- code_generator.write_dummy_header_and_cpp()
- return
- if options.dump_json_and_pickle:
- write_json_and_pickle(definitions, interface_name, output_directory)
- return
- code_generator.write_header_and_cpp()
-
-
-if __name__ == '__main__':
- sys.exit(main())
diff --git a/chromium/third_party/WebKit/Source/bindings/scripts/unstable/idl_definitions.py b/chromium/third_party/WebKit/Source/bindings/scripts/unstable/idl_definitions.py
deleted file mode 100644
index ef6ff79466c..00000000000
--- a/chromium/third_party/WebKit/Source/bindings/scripts/unstable/idl_definitions.py
+++ /dev/null
@@ -1,446 +0,0 @@
-# Copyright (C) 2013 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.
-
-"""Blink IDL Intermediate Representation (IR) classes.
-
-Also JSON export, using legacy Perl terms and format, to ensure that both
-parsers produce the same output.
-FIXME: remove BaseIdl, JSON export (json_serializable and to_json), and Perl
-compatibility functions and hacks once Perl compiler gone.
-"""
-
-# Disable attribute hiding check (else JSONEncoder default raises an error)
-# pylint: disable=E0202
-# pylint doesn't understand ABCs.
-# pylint: disable=W0232, E0203, W0201
-
-import abc
-import json
-import re
-
-
-# Base classes
-
-
-class BaseIdl:
- """Abstract base class, used for JSON serialization."""
- __metaclass__ = abc.ABCMeta
-
- @abc.abstractmethod
- def json_serializable(self):
- """Returns a JSON serializable form of the object.
-
- This should be a dictionary, with keys scoped names of the form
- Class::key, where the scope is the class name.
- This is so we produce identical output to the Perl code, which uses
- the Perl module JSON.pm, which uses this format.
- """
- pass
-
-
-class TypedObject:
- """Object with a type, such as an Attribute or Operation (return value).
-
- The type can be an actual type, or can be a typedef, which must be resolved
- before passing data to the code generator.
- """
- __metaclass__ = abc.ABCMeta
- idl_type = None
- extended_attributes = None
-
- def resolve_typedefs(self, typedefs):
- """Resolve typedefs to actual types in the object."""
- # Constructors don't have their own return type, because it's the
- # interface itself.
- if not self.idl_type:
- return
- # Convert string representation to and from an IdlType object
- # to handle parsing of composite types (arrays and sequences)
- idl_type_object = IdlType.from_string(self.idl_type)
- base_type = idl_type_object.base_type
- if base_type in typedefs:
- idl_type_object.base_type = typedefs[base_type]
- self.idl_type = str(idl_type_object)
-
-
-# IDL classes
-
-
-class IdlDefinitions(BaseIdl):
- def __init__(self, callback_functions=None, enumerations=None, exceptions=None, file_name=None, interfaces=None, typedefs=None):
- self.callback_functions = callback_functions or {}
- self.enumerations = enumerations or {}
- self.exceptions = exceptions or {}
- self.file_name = file_name or None
- self.interfaces = interfaces or {}
- # Typedefs are not exposed by bindings; resolve typedefs with the
- # actual types and then discard the Typedefs.
- # http://www.w3.org/TR/WebIDL/#idl-typedefs
- if typedefs:
- self.resolve_typedefs(typedefs)
-
- def resolve_typedefs(self, typedefs):
- for callback_function in self.callback_functions.itervalues():
- callback_function.resolve_typedefs(typedefs)
- for exception in self.exceptions.itervalues():
- exception.resolve_typedefs(typedefs)
- for interface in self.interfaces.itervalues():
- interface.resolve_typedefs(typedefs)
-
- def json_serializable(self):
- return {
- 'idlDocument::callbackFunctions': self.callback_functions.values(),
- 'idlDocument::enumerations': self.enumerations.values(),
- 'idlDocument::fileName': self.file_name,
- # Perl treats exceptions as a kind of interface
- 'idlDocument::interfaces': sorted(self.exceptions.values() + self.interfaces.values()),
- }
-
- def to_json(self, debug=False):
- """Returns a JSON string representing the Definitions.
-
- The JSON output should be identical with the output of the Perl parser,
- specifically the function serializeJSON in idl_serializer.pm,
- which takes a Perl object created by idl_parser.pm.
- """
- # Sort so order consistent, allowing comparison of output
- if debug:
- # indent turns on pretty-printing for legibility
- return json.dumps(self, cls=IdlEncoder, sort_keys=True, indent=4)
- # Use compact separators so output identical to Perl
- return json.dumps(self, cls=IdlEncoder, sort_keys=True, separators=(',', ':'))
-
-
-class IdlCallbackFunction(BaseIdl, TypedObject):
- def __init__(self, name=None, idl_type=None, arguments=None):
- self.idl_type = idl_type
- self.name = name
- self.arguments = arguments or []
-
- def resolve_typedefs(self, typedefs):
- TypedObject.resolve_typedefs(self, typedefs)
- for argument in self.arguments:
- argument.resolve_typedefs(typedefs)
- raise ValueError('Typedefs in callback functions are untested!')
-
- def json_serializable(self):
- return {
- 'callbackFunction::name': self.name,
- 'callbackFunction::type': self.idl_type,
- 'callbackFunction::parameters': self.arguments,
- }
-
-
-class IdlEnum(BaseIdl):
- def __init__(self, name=None, values=None):
- self.name = name
- self.values = values or []
-
- def json_serializable(self):
- return {
- 'domEnum::name': self.name,
- 'domEnum::values': self.values,
- }
-
-
-class IdlInterface(BaseIdl):
- def __init__(self, attributes=None, constants=None, constructors=None, custom_constructors=None, extended_attributes=None, operations=None, is_callback=False, is_partial=False, name=None, parent=None):
- self.attributes = attributes or []
- self.constants = constants or []
- self.constructors = constructors or []
- self.custom_constructors = custom_constructors or []
- self.extended_attributes = extended_attributes or {}
- self.operations = operations or []
- self.is_callback = is_callback
- self.is_partial = is_partial
- self.name = name
- self.parent = parent
-
- def resolve_typedefs(self, typedefs):
- for attribute in self.attributes:
- attribute.resolve_typedefs(typedefs)
- for constant in self.constants:
- constant.resolve_typedefs(typedefs)
- for constructor in self.constructors:
- constructor.resolve_typedefs(typedefs)
- for custom_constructor in self.custom_constructors:
- custom_constructor.resolve_typedefs(typedefs)
- for operation in self.operations:
- operation.resolve_typedefs(typedefs)
-
- def json_serializable(self):
- return {
- 'domInterface::attributes': self.attributes,
- 'domInterface::constants': self.constants,
- 'domInterface::constructors': self.constructors,
- 'domInterface::customConstructors': self.custom_constructors,
- 'domInterface::extendedAttributes': none_to_value_is_missing(self.extended_attributes),
- 'domInterface::functions': self.operations,
- 'domInterface::isException': None,
- 'domInterface::isCallback': boolean_to_perl(false_to_none(self.is_callback)),
- 'domInterface::isPartial': false_to_none(self.is_partial),
- 'domInterface::name': self.name,
- 'domInterface::parent': self.parent,
- }
-
-
-class IdlException(BaseIdl):
- def __init__(self, name=None, constants=None, operations=None, attributes=None, extended_attributes=None):
- self.attributes = attributes or []
- self.constants = constants or []
- self.extended_attributes = extended_attributes or {}
- self.operations = operations or []
- self.name = name
-
- def resolve_typedefs(self, typedefs):
- for constant in self.constants:
- constant.resolve_typedefs(typedefs)
- for attribute in self.attributes:
- attribute.resolve_typedefs(typedefs)
- for operations in self.operations:
- operations.resolve_typedefs(typedefs)
-
- def json_serializable(self):
- return {
- # Perl code treats Exceptions as a kind of Interface
- 'domInterface::name': self.name,
- 'domInterface::attributes': self.attributes,
- 'domInterface::constants': self.constants,
- 'domInterface::extendedAttributes': none_to_value_is_missing(self.extended_attributes),
- 'domInterface::functions': self.operations,
- # These values don't vary for exceptions
- 'domInterface::constructors': [],
- 'domInterface::customConstructors': [],
- 'domInterface::isException': 1,
- 'domInterface::isCallback': None,
- 'domInterface::isPartial': None,
- 'domInterface::parent': None,
- }
-
-
-class IdlAttribute(BaseIdl, TypedObject):
- def __init__(self, idl_type=None, extended_attributes=None, getter_exceptions=None, is_nullable=False, is_static=False, is_read_only=False, name=None, setter_exceptions=None):
- self.idl_type = idl_type
- self.extended_attributes = extended_attributes or {}
- self.getter_exceptions = getter_exceptions or []
- self.is_nullable = is_nullable
- self.is_static = is_static
- self.is_read_only = is_read_only
- self.name = name
- self.setter_exceptions = setter_exceptions or []
-
- def json_serializable(self):
- return {
- 'domAttribute::extendedAttributes': none_to_value_is_missing(self.extended_attributes),
- 'domAttribute::getterExceptions': self.getter_exceptions,
- 'domAttribute::isNullable': boolean_to_perl_quoted(false_to_none(self.is_nullable)),
- 'domAttribute::isReadOnly': boolean_to_perl(false_to_none(self.is_read_only)),
- 'domAttribute::isStatic': boolean_to_perl(false_to_none(self.is_static)),
- 'domAttribute::name': self.name,
- 'domAttribute::setterExceptions': self.setter_exceptions,
- 'domAttribute::type': self.idl_type,
- }
-
-
-class IdlConstant(BaseIdl, TypedObject):
- def __init__(self, name=None, idl_type=None, value=None, extended_attributes=None):
- self.idl_type = idl_type
- self.extended_attributes = extended_attributes or {}
- self.name = name
- self.value = value
-
- def json_serializable(self):
- return {
- 'domConstant::extendedAttributes': none_to_value_is_missing(self.extended_attributes),
- 'domConstant::name': self.name,
- 'domConstant::type': self.idl_type,
- 'domConstant::value': self.value,
- }
-
-
-class IdlOperation(BaseIdl, TypedObject):
- def __init__(self, is_static=False, name=None, idl_type=None, extended_attributes=None, specials=None, arguments=None, overloaded_index=None):
- self.is_static = is_static
- self.name = name or ''
- self.idl_type = idl_type
- self.extended_attributes = extended_attributes or {}
- self.specials = specials or []
- self.arguments = arguments or []
- # FIXME: remove overloaded_index (only here for Perl compatibility),
- # as overloading is handled in code generator (v8_interface.py).
- self.overloaded_index = overloaded_index
-
- def resolve_typedefs(self, typedefs):
- TypedObject.resolve_typedefs(self, typedefs)
- for argument in self.arguments:
- argument.resolve_typedefs(typedefs)
-
- def json_serializable(self):
- return {
- 'domFunction::extendedAttributes': none_to_value_is_missing(self.extended_attributes),
- 'domFunction::isStatic': boolean_to_perl(false_to_none(self.is_static)),
- 'domFunction::name': self.name,
- 'domFunction::overloadedIndex': self.overloaded_index,
- 'domFunction::parameters': self.arguments,
- 'domFunction::specials': self.specials,
- 'domFunction::type': self.idl_type,
- }
-
-
-class IdlArgument(BaseIdl, TypedObject):
- def __init__(self, name=None, idl_type=None, extended_attributes=None, is_optional=False, is_nullable=None, is_variadic=False):
- self.idl_type = idl_type
- self.extended_attributes = extended_attributes or {}
- # FIXME: boolean values are inconsistent.
- # The below hack is so that generated JSON is identical to
- # Perl-generated JSON, where the exact values depend on the code path.
- # False and None (Perl: 0 and undef) are semantically interchangeable,
- # but yield different JSON.
- # Once Perl removed, have all default to False.
- if is_optional is None:
- is_optional = False
- if is_variadic is None:
- is_variadic = False
- self.is_nullable = is_nullable # (T?)
- self.is_optional = is_optional # (optional T)
- self.is_variadic = is_variadic # (T...)
- self.name = name
-
- def json_serializable(self):
- return {
- 'domParameter::extendedAttributes': none_to_value_is_missing(self.extended_attributes),
- 'domParameter::isNullable': boolean_to_perl_quoted(self.is_nullable),
- 'domParameter::isOptional': boolean_to_perl(self.is_optional),
- 'domParameter::isVariadic': boolean_to_perl(self.is_variadic),
- 'domParameter::name': self.name,
- 'domParameter::type': self.idl_type,
- }
-
-# Type classes
-
-
-class IdlType:
- # FIXME: replace type strings with these objects,
- # so don't need to parse everywhere types are used.
- # Types are stored internally as strings, not objects,
- # e.g., as 'sequence<Foo>' or 'Foo[]',
- # hence need to parse the string whenever a type is used.
- # FIXME: incorporate Nullable, Variadic, etc.
- # FIXME: properly should nest types
- # Formally types are nested, e.g., short?[] vs. short[]?,
- # but in practice these complex types aren't used and can treat
- # as orthogonal properties.
- def __init__(self, base_type, is_array=False, is_sequence=False):
- if is_array and is_sequence:
- raise ValueError('Array of Sequences are not allowed.')
- self.base_type = base_type
- self.is_array = is_array
- self.is_sequence = is_sequence
-
- def __str__(self):
- type_string = self.base_type
- if self.is_array:
- return type_string + '[]'
- if self.is_sequence:
- return 'sequence<%s>' % type_string
- return type_string
-
- @classmethod
- def from_string(cls, type_string):
- sequence_re = r'^sequence<([^>]*)>$'
- if type_string.endswith('[]'):
- type_string = type_string[:-2]
- sequence_match = re.match(sequence_re, type_string)
- if sequence_match:
- raise ValueError('Array of Sequences are not allowed.')
- return cls(type_string, is_array=True)
- sequence_match = re.match(sequence_re, type_string)
- if sequence_match:
- base_type = sequence_match.group(1)
- return cls(base_type, is_sequence=True)
- return cls(type_string)
-
-
-class IdlUnionType(BaseIdl):
- def __init__(self, union_member_types=None):
- self.union_member_types = union_member_types or []
-
- def json_serializable(self):
- return {
- 'UnionType::unionMemberTypes': self.union_member_types,
- }
-
-
-# Perl JSON compatibility functions
-
-def none_to_value_is_missing(extended_attributes):
- # Perl IDL Parser uses 'VALUE_IS_MISSING' for null values in
- # extended attributes, so add this as a filter when exporting to JSON.
- new_extended_attributes = {}
- for key, value in extended_attributes.iteritems():
- if value is None:
- new_extended_attributes[key] = 'VALUE_IS_MISSING'
- else:
- new_extended_attributes[key] = value
- return new_extended_attributes
-
-
-def boolean_to_perl(value):
- # Perl stores booleans as 1, 0, or undefined (JSON null);
- # convert to this format.
- if value is None:
- return None
- return int(value)
-
-
-def boolean_to_perl_quoted(value):
- # Bug-for-bug compatibility with Perl.
- # The value of isNullable is quoted ('1', '0', or undefined), rather than
- # an integer, so add quotes.
- if value is None:
- return None
- return str(int(value))
-
-
-def false_to_none(value):
- # The Perl parser generally uses undefined (Python None) rather than False
- # for boolean flags, because the value is simply left undefined, rather than
- # explicitly set to False.
- if value is False:
- return None
- return value
-
-
-# JSON export
-
-
-class IdlEncoder(json.JSONEncoder):
- def default(self, obj):
- if isinstance(obj, BaseIdl):
- return obj.json_serializable()
- return json.JSONEncoder.default(self, obj)
diff --git a/chromium/third_party/WebKit/Source/bindings/scripts/unstable/idl_definitions_builder.py b/chromium/third_party/WebKit/Source/bindings/scripts/unstable/idl_definitions_builder.py
deleted file mode 100644
index 720c014de24..00000000000
--- a/chromium/third_party/WebKit/Source/bindings/scripts/unstable/idl_definitions_builder.py
+++ /dev/null
@@ -1,511 +0,0 @@
-# Copyright (C) 2013 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.
-
-"""Builds an IdlDefinitions object from an AST (produced by blink_idl_parser)."""
-
-import os
-
-from idl_definitions import IdlDefinitions, IdlInterface, IdlException, IdlOperation, IdlCallbackFunction, IdlArgument, IdlAttribute, IdlConstant, IdlEnum, IdlUnionType
-
-SPECIAL_KEYWORD_LIST = ['GETTER', 'SETTER', 'DELETER']
-STANDARD_TYPEDEFS = {
- # http://www.w3.org/TR/WebIDL/#common-DOMTimeStamp
- 'DOMTimeStamp': 'unsigned long long',
-}
-
-def build_idl_definitions_from_ast(node):
- if node is None:
- return None
- node_class = node.GetClass()
- if node_class != 'File':
- raise ValueError('Unrecognized node class: %s' % node_class)
- return file_node_to_idl_definitions(node)
-
-
-def file_node_to_idl_definitions(node):
- callback_functions = {}
- enumerations = {}
- exceptions = {}
- interfaces = {}
- typedefs = STANDARD_TYPEDEFS
-
- # FIXME: only needed for Perl, remove later
- file_name = os.path.abspath(node.GetName())
-
- children = node.GetChildren()
- for child in children:
- child_class = child.GetClass()
- if child_class == 'Interface':
- interface = interface_node_to_idl_interface(child)
- interfaces[interface.name] = interface
- elif child_class == 'Exception':
- exception = exception_node_to_idl_exception(child)
- exceptions[exception.name] = exception
- elif child_class == 'Typedef':
- type_name = child.GetName()
- typedefs[type_name] = typedef_node_to_type(child)
- elif child_class == 'Enum':
- enumeration = enum_node_to_idl_enum(child)
- enumerations[enumeration.name] = enumeration
- elif child_class == 'Callback':
- callback_function = callback_node_to_idl_callback_function(child)
- callback_functions[callback_function.name] = callback_function
- elif child_class == 'Implements':
- # Implements is handled at the interface merging step
- pass
- else:
- raise ValueError('Unrecognized node class: %s' % child_class)
-
- return IdlDefinitions(callback_functions=callback_functions, enumerations=enumerations, exceptions=exceptions, file_name=file_name, interfaces=interfaces, typedefs=typedefs)
-
-# Constructors for Interface definitions and interface members
-
-
-def interface_node_to_idl_interface(node):
- attributes = []
- constants = []
- constructors = None
- custom_constructors = None
- extended_attributes = None
- operations = []
- is_callback = node.GetProperty('CALLBACK') or False
- # FIXME: uppercase 'Partial' => 'PARTIAL' in base IDL parser
- is_partial = node.GetProperty('Partial') or False
- name = node.GetName()
- parent = None
-
- children = node.GetChildren()
- for child in children:
- child_class = child.GetClass()
- if child_class == 'Attribute':
- attributes.append(attribute_node_to_idl_attribute(child))
- elif child_class == 'Const':
- constants.append(constant_node_to_idl_constant(child))
- elif child_class == 'ExtAttributes':
- extended_attributes = ext_attributes_node_to_extended_attributes(child)
- constructors, custom_constructors = extended_attributes_to_constructors(extended_attributes)
- clear_constructor_attributes(extended_attributes)
- elif child_class == 'Operation':
- operations.append(operation_node_to_idl_operation(child))
- elif child_class == 'Inherit':
- parent = child.GetName()
- else:
- raise ValueError('Unrecognized node class: %s' % child_class)
-
- return IdlInterface(name=name, attributes=attributes, constants=constants, constructors=constructors, custom_constructors=custom_constructors, extended_attributes=extended_attributes, operations=operations, is_callback=is_callback, is_partial=is_partial, parent=parent)
-
-
-def attribute_node_to_idl_attribute(node):
- idl_type = None
- extended_attributes = {}
- is_nullable = False
- is_read_only = node.GetProperty('READONLY') or False
- is_static = node.GetProperty('STATIC') or False
- name = node.GetName()
-
- children = node.GetChildren()
- for child in children:
- child_class = child.GetClass()
- if child_class == 'Type':
- idl_type = type_node_to_type(child)
- is_nullable = child.GetProperty('NULLABLE') or False
- elif child_class == 'ExtAttributes':
- extended_attributes = ext_attributes_node_to_extended_attributes(child)
- else:
- raise ValueError('Unrecognized node class: %s' % child_class)
-
- return IdlAttribute(idl_type=idl_type, extended_attributes=extended_attributes, is_nullable=is_nullable, is_read_only=is_read_only, is_static=is_static, name=name)
-
-
-def constant_node_to_idl_constant(node):
- name = node.GetName()
-
- children = node.GetChildren()
- num_children = len(children)
- if num_children < 2 or num_children > 3:
- raise ValueError('Expected 2 or 3 children, got %s' % num_children)
-
- type_node = children[0]
- # ConstType is more limited than Type, so subtree is smaller and we don't
- # use the full type_node_to_type function.
- idl_type = type_node_inner_to_type(type_node)
-
- value_node = children[1]
- value_node_class = value_node.GetClass()
- if value_node_class != 'Value':
- raise ValueError('Expected Value node, got %s' % value_node_class)
- value = value_node.GetName()
-
- extended_attributes = None
- if num_children == 3:
- ext_attributes_node = children[2]
- extended_attributes = ext_attributes_node_to_extended_attributes(ext_attributes_node)
-
- return IdlConstant(idl_type=idl_type, extended_attributes=extended_attributes, name=name, value=value)
-
-
-def operation_node_to_idl_operation(node):
- name = node.GetName()
- # FIXME: AST should use None internally
- if name == '_unnamed_':
- name = None
-
- is_static = node.GetProperty('STATIC') or False
- specials = []
- property_dictionary = node.GetProperties()
- for special_keyword in SPECIAL_KEYWORD_LIST:
- if special_keyword in property_dictionary:
- specials.append(special_keyword.lower())
-
- extended_attributes = None
- arguments = []
- return_type = None
- children = node.GetChildren()
- for child in children:
- child_class = child.GetClass()
- if child_class == 'Arguments':
- arguments = arguments_node_to_arguments(child)
- elif child_class == 'Type':
- return_type = type_node_to_type(child)
- elif child_class == 'ExtAttributes':
- extended_attributes = ext_attributes_node_to_extended_attributes(child)
- else:
- raise ValueError('Unrecognized node class: %s' % child_class)
-
- return IdlOperation(name=name, idl_type=return_type, extended_attributes=extended_attributes, is_static=is_static, arguments=arguments, specials=specials)
-
-
-def arguments_node_to_arguments(node):
- # [Constructor] and [CustomConstructor] without arguments (the bare form)
- # have None instead of an arguments node, but have the same meaning as using
- # an empty argument list, [Constructor()], so special-case this.
- # http://www.w3.org/TR/WebIDL/#Constructor
- if node is None:
- return []
- arguments = []
- argument_node_list = node.GetChildren()
- for argument_node in argument_node_list:
- arguments.append(argument_node_to_idl_argument(argument_node))
- return arguments
-
-
-def argument_node_to_idl_argument(node):
- name = node.GetName()
-
- idl_type = None
- extended_attributes = {}
- # FIXME: Boolean values are inconsistent due to Perl compatibility.
- # Make all default to False once Perl removed.
- is_nullable = False
- is_optional = node.GetProperty('OPTIONAL')
- is_variadic = None
- children = node.GetChildren()
- for child in children:
- child_class = child.GetClass()
- if child_class == 'Type':
- idl_type = type_node_to_type(child)
- # FIXME: Doesn't handle nullable arrays (Foo[]?), and arrays of
- # nullable (Foo?[]) are treated as nullable arrays. No actual use.
- is_nullable = child.GetProperty('NULLABLE')
- elif child_class == 'ExtAttributes':
- extended_attributes = ext_attributes_node_to_extended_attributes(child)
- elif child_class == 'Argument':
- child_name = child.GetName()
- if child_name != '...':
- raise ValueError('Unrecognized Argument node; expected "...", got "%s"' % child_name)
- is_variadic = child.GetProperty('ELLIPSIS') or False
- else:
- raise ValueError('Unrecognized node class: %s' % child_class)
-
- return IdlArgument(name=name, idl_type=idl_type, extended_attributes=extended_attributes, is_nullable=is_nullable, is_optional=is_optional, is_variadic=is_variadic)
-
-# Constructors for for non-interface definitions
-
-
-def callback_node_to_idl_callback_function(node):
- name = node.GetName()
- children = node.GetChildren()
- num_children = len(children)
- if num_children != 2:
- raise ValueError('Expected 2 children, got %s' % num_children)
-
- type_node = children[0]
- idl_type = type_node_to_type(type_node)
-
- arguments_node = children[1]
- arguments_node_class = arguments_node.GetClass()
- if arguments_node_class != 'Arguments':
- raise ValueError('Expected Value node, got %s' % arguments_node_class)
- arguments = arguments_node_to_arguments(arguments_node)
-
- return IdlCallbackFunction(name=name, idl_type=idl_type, arguments=arguments)
-
-
-def enum_node_to_idl_enum(node):
- name = node.GetName()
- values = []
- for child in node.GetChildren():
- values.append(child.GetName())
- return IdlEnum(name=name, values=values)
-
-
-def exception_operation_node_to_idl_operation(node):
- # Needed to handle one case in DOMException.idl:
- # // Override in a Mozilla compatible format
- # [NotEnumerable] DOMString toString();
- # FIXME: can we remove this? replace with a stringifier?
- extended_attributes = {}
- name = node.GetName()
- children = node.GetChildren()
- if len(children) < 1 or len(children) > 2:
- raise ValueError('ExceptionOperation node with %s children, expected 1 or 2' % len(children))
-
- type_node = children[0]
- return_type = type_node_to_type(type_node)
-
- if len(children) > 1:
- ext_attributes_node = children[1]
- extended_attributes = ext_attributes_node_to_extended_attributes(ext_attributes_node)
-
- return IdlOperation(name=name, idl_type=return_type, extended_attributes=extended_attributes)
-
-
-def exception_node_to_idl_exception(node):
- # Exceptions are similar to Interfaces, but simpler
- attributes = []
- constants = []
- extended_attributes = None
- operations = []
- name = node.GetName()
-
- children = node.GetChildren()
- for child in children:
- child_class = child.GetClass()
- if child_class == 'Attribute':
- attribute = attribute_node_to_idl_attribute(child)
- attributes.append(attribute)
- elif child_class == 'Const':
- constants.append(constant_node_to_idl_constant(child))
- elif child_class == 'ExtAttributes':
- extended_attributes = ext_attributes_node_to_extended_attributes(child)
- elif child_class == 'ExceptionOperation':
- operations.append(exception_operation_node_to_idl_operation(child))
- else:
- raise ValueError('Unrecognized node class: %s' % child_class)
-
- return IdlException(name=name, attributes=attributes, constants=constants, extended_attributes=extended_attributes, operations=operations)
-
-
-def typedef_node_to_type(node):
- children = node.GetChildren()
- if len(children) != 1:
- raise ValueError('Typedef node with %s children, expected 1' % len(children))
- child = children[0]
- child_class = child.GetClass()
- if child_class != 'Type':
- raise ValueError('Unrecognized node class: %s' % child_class)
- return type_node_to_type(child)
-
-# Extended attributes
-
-
-def ext_attributes_node_to_extended_attributes(node):
- """
- Returns:
- Dictionary of {ExtAttributeName: ExtAttributeValue}.
- Value is usually a string, with three exceptions:
- Constructors: value is a list of Arguments nodes, corresponding to
- possibly signatures of the constructor.
- CustomConstructors: value is a list of Arguments nodes, corresponding to
- possibly signatures of the custom constructor.
- NamedConstructor: value is a Call node, corresponding to the single
- signature of the named constructor.
- """
- # Primarily just make a dictionary from the children.
- # The only complexity is handling various types of constructors:
- # Constructors and Custom Constructors can have duplicate entries due to
- # overloading, and thus are stored in temporary lists.
- # However, Named Constructors cannot be overloaded, and thus do not have
- # a list.
- # FIXME: move Constructor logic into separate function, instead of modifying
- # extended attributes in-place.
- constructors = []
- custom_constructors = []
- extended_attributes = {}
-
- attribute_list = node.GetChildren()
- for attribute in attribute_list:
- name = attribute.GetName()
- children = attribute.GetChildren()
- if name in ['Constructor', 'CustomConstructor', 'NamedConstructor']:
- child = None
- child_class = None
- if children:
- if len(children) > 1:
- raise ValueError('ExtAttributes node with %s children, expected at most 1' % len(children))
- child = children[0]
- child_class = child.GetClass()
- if name == 'Constructor':
- if child_class and child_class != 'Arguments':
- raise ValueError('Constructor only supports Arguments as child, but has child of class: %s' % child_class)
- constructors.append(child)
- elif name == 'CustomConstructor':
- if child_class and child_class != 'Arguments':
- raise ValueError('Custom Constructor only supports Arguments as child, but has child of class: %s' % child_class)
- custom_constructors.append(child)
- else: # name == 'NamedConstructor'
- if child_class and child_class != 'Call':
- raise ValueError('Named Constructor only supports Call as child, but has child of class: %s' % child_class)
- extended_attributes[name] = child
- elif children:
- raise ValueError('Non-constructor ExtAttributes node with children: %s' % name)
- else:
- value = attribute.GetProperty('VALUE')
- extended_attributes[name] = value
-
- # Store constructors and custom constructors in special list attributes,
- # which are deleted later. Note plural in key.
- if constructors:
- extended_attributes['Constructors'] = constructors
- if custom_constructors:
- extended_attributes['CustomConstructors'] = custom_constructors
-
- return extended_attributes
-
-
-def extended_attributes_to_constructors(extended_attributes):
- """Returns constructors and custom_constructors (lists of IdlOperations).
-
- Auxiliary function for interface_node_to_idl_interface.
- """
- constructors = []
- custom_constructors = []
- if 'Constructors' in extended_attributes:
- constructor_list = extended_attributes['Constructors']
- # If not overloaded, have index 0, otherwise index from 1
- overloaded_index = 0 if len(constructor_list) == 1 else 1
- for arguments_node in constructor_list:
- name = 'Constructor'
- arguments = arguments_node_to_arguments(arguments_node)
- constructor = IdlOperation(name=name, extended_attributes=extended_attributes, overloaded_index=overloaded_index, arguments=arguments)
- constructors.append(constructor)
- overloaded_index += 1
-
- if 'CustomConstructors' in extended_attributes:
- custom_constructor_list = extended_attributes['CustomConstructors']
- # If not overloaded, have index 0, otherwise index from 1
- overloaded_index = 0 if len(custom_constructor_list) == 1 else 1
- for arguments_node in custom_constructor_list:
- name = 'CustomConstructor'
- arguments = arguments_node_to_arguments(arguments_node)
- custom_constructor = IdlOperation(name=name, extended_attributes=extended_attributes, overloaded_index=overloaded_index, arguments=arguments)
- custom_constructors.append(custom_constructor)
- overloaded_index += 1
-
- if 'NamedConstructor' in extended_attributes:
- name = 'NamedConstructor'
- call_node = extended_attributes['NamedConstructor']
- extended_attributes['NamedConstructor'] = call_node.GetName()
- overloaded_index = None # named constructors are not overloaded
- children = call_node.GetChildren()
- if len(children) != 1:
- raise ValueError('NamedConstructor node expects 1 child, got %s.' % len(children))
- arguments_node = children[0]
- arguments = arguments_node_to_arguments(arguments_node)
- named_constructor = IdlOperation(name=name, extended_attributes=extended_attributes, overloaded_index=overloaded_index, arguments=arguments)
- # FIXME: should return named_constructor separately; appended for Perl
- constructors.append(named_constructor)
-
- return constructors, custom_constructors
-
-
-def clear_constructor_attributes(extended_attributes):
- # Deletes Constructor*s* (plural), sets Constructor (singular)
- if 'Constructors' in extended_attributes:
- del extended_attributes['Constructors']
- extended_attributes['Constructor'] = None
- if 'CustomConstructors' in extended_attributes:
- del extended_attributes['CustomConstructors']
- extended_attributes['CustomConstructor'] = None
-
-
-# Types
-
-
-def type_node_to_type(node):
- children = node.GetChildren()
- if len(children) < 1 or len(children) > 2:
- raise ValueError('Type node expects 1 or 2 children (type + optional array []), got %s (multi-dimensional arrays are not supported).' % len(children))
-
- type_node_child = children[0]
- idl_type = type_node_inner_to_type(type_node_child)
-
- if len(children) == 2:
- array_node = children[1]
- array_node_class = array_node.GetClass()
- if array_node_class != 'Array':
- raise ValueError('Expected Array node as TypeSuffix, got %s node.' % array_node_class)
- idl_type += '[]'
-
- return idl_type
-
-
-def type_node_inner_to_type(node):
- node_class = node.GetClass()
- # Note Type*r*ef, not Typedef, meaning the type is an identifier, thus
- # either a typedef shorthand (but not a Typedef declaration itself) or an
- # interface type. We do not distinguish these, and just use the type name.
- if node_class in ['PrimitiveType', 'Typeref']:
- return node.GetName()
- elif node_class == 'Any':
- return 'any'
- elif node_class == 'Sequence':
- return sequence_node_to_type(node)
- elif node_class == 'UnionType':
- return union_type_node_to_idl_union_type(node)
- raise ValueError('Unrecognized node class: %s' % node_class)
-
-
-def sequence_node_to_type(node):
- children = node.GetChildren()
- if len(children) != 1:
- raise ValueError('Sequence node expects exactly 1 child, got %s' % len(children))
- sequence_child = children[0]
- sequence_child_class = sequence_child.GetClass()
- if sequence_child_class != 'Type':
- raise ValueError('Unrecognized node class: %s' % sequence_child_class)
- sequence_type = type_node_to_type(sequence_child)
- return 'sequence<%s>' % sequence_type
-
-
-def union_type_node_to_idl_union_type(node):
- union_member_types = []
- for member_type_node in node.GetChildren():
- member_type = type_node_to_type(member_type_node)
- union_member_types.append(member_type)
- return IdlUnionType(union_member_types=union_member_types)
diff --git a/chromium/third_party/WebKit/Source/bindings/scripts/unstable/idl_reader.py b/chromium/third_party/WebKit/Source/bindings/scripts/unstable/idl_reader.py
deleted file mode 100644
index eece7425ae6..00000000000
--- a/chromium/third_party/WebKit/Source/bindings/scripts/unstable/idl_reader.py
+++ /dev/null
@@ -1,80 +0,0 @@
-# Copyright (C) 2013 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.
-
-"""Read an IDL file or complete IDL interface, producing an IdlDefinitions object."""
-
-import os.path
-
-import blink_idl_parser
-import idl_definitions_builder
-import idl_validator
-import interface_dependency_resolver
-
-
-class IdlReader:
- def __init__(self, interface_dependencies_filename=None, additional_idl_filenames=None, idl_attributes_filename=None, outputdir='', verbose=False):
- if idl_attributes_filename:
- self.extended_attribute_validator = idl_validator.IDLExtendedAttributeValidator(idl_attributes_filename)
- else:
- self.extended_attribute_validator = None
-
- if interface_dependencies_filename:
- self.interface_dependency_resolver = interface_dependency_resolver.InterfaceDependencyResolver(interface_dependencies_filename, additional_idl_filenames, self)
- else:
- self.interface_dependency_resolver = None
-
- self.parser = blink_idl_parser.BlinkIDLParser(outputdir=outputdir, verbose=verbose)
-
- def read_idl_definitions(self, idl_filename):
- """Returns an IdlDefinitions object for an IDL file, including all dependencies."""
- basename = os.path.basename(idl_filename)
- interface_name, _ = os.path.splitext(basename)
- definitions = self.read_idl_file(idl_filename)
- if self.interface_dependency_resolver:
- should_generate_bindings = self.interface_dependency_resolver.resolve_dependencies(definitions, interface_name)
- if not should_generate_bindings:
- return None
- return definitions
-
- def read_idl_file(self, idl_filename):
- """Returns an IdlDefinitions object for an IDL file, without any dependencies."""
- ast = blink_idl_parser.parse_file(self.parser, idl_filename)
- definitions = idl_definitions_builder.build_idl_definitions_from_ast(ast)
- if self.extended_attribute_validator:
- try:
- self.extended_attribute_validator.validate_extended_attributes(definitions)
- except idl_validator.IDLInvalidExtendedAttributeError as error:
- raise idl_validator.IDLInvalidExtendedAttributeError("""IDL ATTRIBUTE ERROR in file %s:
- %s
-If you want to add a new IDL extended attribute, please add it to
- bindings/IDLExtendedAttributes.txt
-and add an explanation to the Blink IDL documentation at:
- http://www.chromium.org/blink/webidl/blink-idl-extended-attributes
- """ % (idl_filename, str(error)))
-
- return definitions
diff --git a/chromium/third_party/WebKit/Source/bindings/scripts/unstable/interface_dependency_resolver.py b/chromium/third_party/WebKit/Source/bindings/scripts/unstable/interface_dependency_resolver.py
deleted file mode 100644
index 592be907051..00000000000
--- a/chromium/third_party/WebKit/Source/bindings/scripts/unstable/interface_dependency_resolver.py
+++ /dev/null
@@ -1,211 +0,0 @@
-# Copyright (C) 2013 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.
-
-"""Resolve interface dependencies, producing a merged IdlDefinitions object.
-
-This library computes interface dependencies (partial interfaces and
-implements), reads the dependency files, and merges them to the IdlDefinitions
-for the main IDL file, producing an IdlDefinitions object representing the
-entire interface.
-
-It also checks whether a file should have bindings generated, or whether
-instead it is just a dependency.
-"""
-
-import os.path
-
-
-class InterfaceNotFoundError(Exception):
- """Raised if (partial) interface not found in target IDL file."""
- pass
-
-
-class InvalidPartialInterfaceError(Exception):
- """Raised if a file listed as a partial interface is not in fact so."""
- pass
-
-
-class InterfaceDependencyResolver:
- def __init__(self, interface_dependencies_filename, additional_idl_filenames, reader):
- """Inits dependency resolver.
-
- Args:
- interface_dependencies_filename:
- filename of dependencies file (produced by
- compute_dependencies.py)
- additional_idl_filenames:
- list of additional files, not listed in
- interface_dependencies_file, for which bindings should
- nonetheless be generated
- reader:
- IdlReader, used for reading dependency files
- """
- self.interface_dependencies = read_interface_dependencies_file(interface_dependencies_filename)
- self.additional_interfaces = set()
- for filename in additional_idl_filenames:
- basename = os.path.basename(filename)
- interface_name, _ = os.path.splitext(basename)
- self.additional_interfaces.add(interface_name)
- self.reader = reader
-
- def resolve_dependencies(self, definitions, interface_name):
- """Resolves dependencies, merging them into IDL definitions of main file.
-
- Dependencies consist of 'partial interface' for the same interface as
- in the main file, and other interfaces that this interface 'implements'.
-
- Modifies definitions in place by adding parsed dependencies, and checks
- whether bindings should be generated, returning bool.
-
- Args:
- definitions: IdlDefinitions object, modified in place
- idl_filename: filename of main IDL file for the interface
- Returns:
- bool, whether bindings should be generated or not.
- """
- dependency_idl_filenames = self.compute_dependency_idl_files(interface_name)
- if dependency_idl_filenames is None:
- return False
- # The Blink IDL filenaming convention is that the file
- # <interface_name>.idl MUST contain the interface "interface_name" or
- # exception "interface_name", unless it is a dependency (e.g.,
- # 'partial interface Foo' can be in FooBar.idl).
- if interface_name in definitions.exceptions:
- # Exceptions do not have dependencies, so no merging necessary
- return definitions
- try:
- target_interface = definitions.interfaces[interface_name]
- except KeyError:
- raise InterfaceNotFoundError('Could not find interface or exception "{0}" in {0}.idl'.format(interface_name))
- merge_interface_dependencies(target_interface, dependency_idl_filenames, self.reader)
-
- return definitions
-
- def compute_dependency_idl_files(self, target_interface_name):
- """Returns list of IDL file dependencies for a given main IDL file.
-
- - Returns a list of IDL files on which a given IDL file depends,
- possibly empty.
- Dependencies consist of partial interface files and files for other
- interfaces that the given interface implements.
- - Returns an empty list also if the given IDL file is an additional IDL
- file.
- - Otherwise, return None. This happens when the given IDL file is a
- dependency, for which we don't want to generate bindings.
- """
- if target_interface_name in self.interface_dependencies:
- return self.interface_dependencies[target_interface_name]
-
- # additional_interfaces is a list of interfaces that should not be
- # included in DerivedSources*.cpp, and hence are not listed in the
- # interface dependencies file, but for which we should generate .cpp
- # and .h files.
- if target_interface_name in self.additional_interfaces:
- return []
-
- return None
-
-
-def read_interface_dependencies_file(interface_dependencies_filename):
- """Reads the interface dependencies file, returns a dict for resolving dependencies.
-
- The format of the interface dependencies file is:
-
- Document.idl P.idl
- Event.idl
- Window.idl Q.idl R.idl S.idl
- ...
-
- The above indicates that:
- Document.idl depends on P.idl,
- Event.idl depends on no other IDL files, and
- Window.idl depends on Q.idl, R.idl, and S.idl.
-
- The head entries (first IDL file on a line) are the files that should
- have bindings generated.
-
- An IDL file that is a dependency of another IDL file (e.g., P.idl in the
- above example) does not have its own line in the dependency file:
- dependencies do not have bindings generated, and do not have their
- own dependencies.
-
- Args:
- interface_dependencies_filename: filename of file in above format
- Returns:
- dict of interface_name -> dependency_filenames
- """
- interface_dependencies = {}
- with open(interface_dependencies_filename) as interface_dependencies_file:
- for line in interface_dependencies_file:
- idl_filename, _, dependency_filenames_string = line.partition(' ')
- idl_basename = os.path.basename(idl_filename)
- interface_name, _ = os.path.splitext(idl_basename)
- dependency_filenames = dependency_filenames_string.split()
- interface_dependencies[interface_name] = dependency_filenames
- return interface_dependencies
-
-
-def merge_interface_dependencies(target_interface, dependency_idl_filenames, reader):
- """Merge dependencies ('partial interface' and 'implements') in dependency_idl_filenames into target_interface.
-
- No return: modifies target_document in place.
- """
- # Sort so order consistent, so can compare output from run to run.
- for dependency_idl_filename in sorted(dependency_idl_filenames):
- dependency_interface_name, _ = os.path.splitext(os.path.basename(dependency_idl_filename))
- definitions = reader.read_idl_file(dependency_idl_filename)
-
- for dependency_interface in definitions.interfaces.itervalues():
- # Dependency files contain either partial interfaces for
- # the (single) target interface, in which case the interface names
- # must agree, or interfaces that are implemented by the target
- # interface, in which case the interface names differ.
- if dependency_interface.is_partial and dependency_interface.name != target_interface.name:
- raise InvalidPartialInterfaceError('%s is not a partial interface of %s. There maybe a bug in the the dependency generator (compute_depedencies.py).' % (dependency_idl_filename, target_interface.name))
- if 'ImplementedAs' in dependency_interface.extended_attributes:
- del dependency_interface.extended_attributes['ImplementedAs']
- merge_dependency_interface(target_interface, dependency_interface, dependency_interface_name)
-
-
-def merge_dependency_interface(target_interface, dependency_interface, dependency_interface_name):
- """Merge dependency_interface into target_interface.
-
- No return: modifies target_interface in place.
- """
- def merge_lists(source_list, target_list):
- for element in source_list:
- # FIXME: remove check for LegacyImplementedInBaseClass when this
- # attribute is removed
- if 'LegacyImplementedInBaseClass' not in dependency_interface.extended_attributes:
- element.extended_attributes['ImplementedBy'] = dependency_interface_name
- element.extended_attributes.update(dependency_interface.extended_attributes)
- target_list.append(element)
-
- merge_lists(dependency_interface.attributes, target_interface.attributes)
- merge_lists(dependency_interface.constants, target_interface.constants)
- merge_lists(dependency_interface.operations, target_interface.operations)
diff --git a/chromium/third_party/WebKit/Source/bindings/scripts/unstable/v8_attributes.py b/chromium/third_party/WebKit/Source/bindings/scripts/unstable/v8_attributes.py
deleted file mode 100644
index 56b14963983..00000000000
--- a/chromium/third_party/WebKit/Source/bindings/scripts/unstable/v8_attributes.py
+++ /dev/null
@@ -1,331 +0,0 @@
-# Copyright (C) 2013 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.
-
-"""Generate template values for attributes.
-
-FIXME: Not currently used in build.
-This is a rewrite of the Perl IDL compiler in Python, but is not complete.
-Once it is complete, we will switch all IDL files over to Python at once.
-Until then, please work on the Perl IDL compiler.
-For details, see bug http://crbug.com/239771
-"""
-
-from v8_globals import includes
-import v8_types
-import v8_utilities
-from v8_utilities import capitalize, cpp_name, has_extended_attribute, uncapitalize
-
-
-def generate_attribute(interface, attribute):
- idl_type = attribute.idl_type
- extended_attributes = attribute.extended_attributes
-
- v8_types.add_includes_for_type(idl_type)
-
- # [CheckSecurity]
- is_check_security_for_node = 'CheckSecurity' in extended_attributes
- if is_check_security_for_node:
- includes.add('bindings/v8/BindingSecurity.h')
- # [Custom]
- has_custom_getter = ('Custom' in extended_attributes and
- extended_attributes['Custom'] in [None, 'Getter'])
- has_custom_setter = (not attribute.is_read_only and
- 'Custom' in extended_attributes and
- extended_attributes['Custom'] in [None, 'Setter'])
- # [Reflect]
- is_reflect = 'Reflect' in extended_attributes
- if is_reflect:
- includes.add('core/dom/custom/CustomElementCallbackDispatcher.h')
-
- if (idl_type == 'EventHandler' and
- interface.name in ['Window', 'WorkerGlobalScope'] and
- attribute.name == 'onerror'):
- includes.add('bindings/v8/V8ErrorHandler.h')
-
- contents = {
- 'access_control_list': access_control_list(attribute),
- 'activity_logging_world_list_for_getter': v8_utilities.activity_logging_world_list(attribute, 'Getter'), # [ActivityLogging]
- 'activity_logging_world_list_for_setter': v8_utilities.activity_logging_world_list(attribute, 'Setter'), # [ActivityLogging]
- 'cached_attribute_validation_method': extended_attributes.get('CachedAttribute'),
- 'conditional_string': v8_utilities.conditional_string(attribute),
- 'constructor_type': v8_types.constructor_type(idl_type)
- if is_constructor_attribute(attribute) else None,
- 'cpp_name': cpp_name(attribute),
- 'cpp_type': v8_types.cpp_type(idl_type),
- 'deprecate_as': v8_utilities.deprecate_as(attribute), # [DeprecateAs]
- 'enum_validation_expression':
- v8_utilities.enum_validation_expression(idl_type),
- 'has_custom_getter': has_custom_getter,
- 'has_custom_setter': has_custom_setter,
- 'has_strict_type_checking': (
- 'StrictTypeChecking' in extended_attributes and
- v8_types.is_interface_type(idl_type)),
- 'idl_type': idl_type,
- 'is_call_with_execution_context': v8_utilities.has_extended_attribute_value(attribute, 'CallWith', 'ExecutionContext'),
- 'is_check_security_for_node': is_check_security_for_node,
- 'is_expose_js_accessors': 'ExposeJSAccessors' in extended_attributes,
- 'is_getter_raises_exception': ( # [RaisesException]
- 'RaisesException' in extended_attributes and
- extended_attributes['RaisesException'] in [None, 'Getter']),
- 'is_initialized_by_event_constructor':
- 'InitializedByEventConstructor' in extended_attributes,
- 'is_keep_alive_for_gc': is_keep_alive_for_gc(attribute),
- 'is_nullable': attribute.is_nullable,
- 'is_per_world_bindings': 'PerWorldBindings' in extended_attributes,
- 'is_read_only': attribute.is_read_only,
- 'is_reflect': is_reflect,
- 'is_replaceable': 'Replaceable' in attribute.extended_attributes,
- 'is_setter_raises_exception': (
- 'RaisesException' in extended_attributes and
- extended_attributes['RaisesException'] in [None, 'Setter']),
- 'is_static': attribute.is_static,
- 'is_unforgeable': 'Unforgeable' in extended_attributes,
- 'measure_as': v8_utilities.measure_as(attribute), # [MeasureAs]
- 'name': attribute.name,
- 'per_context_enabled_function': v8_utilities.per_context_enabled_function_name(attribute), # [PerContextEnabled]
- 'property_attributes': property_attributes(attribute),
- 'setter_callback': setter_callback_name(interface, attribute),
- 'v8_type': v8_types.v8_type(idl_type),
- 'runtime_enabled_function': v8_utilities.runtime_enabled_function_name(attribute), # [RuntimeEnabled]
- 'world_suffixes': ['', 'ForMainWorld']
- if 'PerWorldBindings' in extended_attributes
- else [''], # [PerWorldBindings]
- }
-
- if is_constructor_attribute(attribute):
- return contents
- if not has_custom_getter:
- generate_getter(interface, attribute, contents)
- if not(attribute.is_read_only or has_custom_setter):
- contents.update({
- 'cpp_setter': setter_expression(interface, attribute, contents),
- 'v8_value_to_local_cpp_value': v8_types.v8_value_to_local_cpp_value(
- idl_type, extended_attributes, 'jsValue', 'cppValue'),
- })
-
- return contents
-
-
-# Getter
-
-def generate_getter(interface, attribute, contents):
- idl_type = attribute.idl_type
- extended_attributes = attribute.extended_attributes
-
- cpp_value = getter_expression(interface, attribute, contents)
- # Normally we can inline the function call into the return statement to
- # avoid the overhead of using a Ref<> temporary, but for some cases
- # (nullable types, EventHandler, [CachedAttribute], or if there are
- # exceptions), we need to use a local variable.
- # FIXME: check if compilers are smart enough to inline this, and if so,
- # always use a local variable (for readability and CG simplicity).
- if (attribute.is_nullable or
- idl_type == 'EventHandler' or
- 'CachedAttribute' in extended_attributes or
- contents['is_getter_raises_exception']):
- contents['cpp_value_original'] = cpp_value
- cpp_value = 'jsValue'
-
- if contents['is_keep_alive_for_gc']:
- v8_set_return_value_statement = 'v8SetReturnValue(info, wrapper)'
- includes.add('bindings/v8/V8HiddenPropertyName.h')
- else:
- v8_set_return_value_statement = v8_types.v8_set_return_value(idl_type, cpp_value, extended_attributes=extended_attributes, script_wrappable='imp')
-
- contents.update({
- 'cpp_value': cpp_value,
- 'v8_set_return_value': v8_set_return_value_statement,
- })
-
-
-def getter_expression(interface, attribute, contents):
- arguments = []
- this_getter_base_name = getter_base_name(attribute, arguments)
- getter_name = v8_utilities.scoped_name(interface, attribute, this_getter_base_name)
-
- arguments.extend(v8_utilities.call_with_arguments(attribute))
- if attribute.is_nullable:
- arguments.append('isNull')
- if contents['is_getter_raises_exception']:
- arguments.append('exceptionState')
- if attribute.idl_type == 'EventHandler':
- arguments.append('isolatedWorldForIsolate(info.GetIsolate())')
- return '%s(%s)' % (getter_name, ', '.join(arguments))
-
-
-CONTENT_ATTRIBUTE_GETTER_NAMES = {
- 'boolean': 'fastHasAttribute',
- 'long': 'getIntegralAttribute',
- 'unsigned long': 'getUnsignedIntegralAttribute',
-}
-
-
-def getter_base_name(attribute, arguments):
- extended_attributes = attribute.extended_attributes
- if 'Reflect' not in extended_attributes:
- return uncapitalize(cpp_name(attribute))
-
- content_attribute_name = extended_attributes['Reflect'] or attribute.name.lower()
- if content_attribute_name in ['class', 'id', 'name']:
- # Special-case for performance optimization.
- return 'get%sAttribute' % content_attribute_name.capitalize()
-
- arguments.append(scoped_content_attribute_name(attribute))
-
- idl_type = attribute.idl_type
- if idl_type in CONTENT_ATTRIBUTE_GETTER_NAMES:
- return CONTENT_ATTRIBUTE_GETTER_NAMES[idl_type]
- if 'URL' in attribute.extended_attributes:
- return 'getURLAttribute'
- return 'fastGetAttribute'
-
-
-def is_keep_alive_for_gc(attribute):
- idl_type = attribute.idl_type
- extended_attributes = attribute.extended_attributes
- return (
- # For readonly attributes, for performance reasons we keep the attribute
- # wrapper alive while the owner wrapper is alive, because the attribute
- # never changes.
- (attribute.is_read_only and
- v8_types.is_wrapper_type(idl_type) and
- # There are some exceptions, however:
- not(
- # Node lifetime is managed by object grouping.
- v8_types.is_dom_node_type(idl_type) or
- # A self-reference is unnecessary.
- attribute.name == 'self' or
- # FIXME: Remove these hard-coded hacks.
- idl_type in ['EventHandler', 'Promise', 'Window'] or
- idl_type.startswith('HTML'))))
-
-
-# Setter
-
-def setter_expression(interface, attribute, contents):
- arguments = v8_utilities.call_with_arguments(attribute, attribute.extended_attributes.get('SetterCallWith'))
-
- this_setter_base_name = setter_base_name(attribute, arguments)
- setter_name = v8_utilities.scoped_name(interface, attribute, this_setter_base_name)
-
- idl_type = attribute.idl_type
- if idl_type == 'EventHandler':
- # FIXME: pass the isolate instead of the isolated world
- isolated_world = 'isolatedWorldForIsolate(info.GetIsolate())'
- arguments.extend(['V8EventListenerList::getEventListener(jsValue, true, ListenerFindOrCreate)', isolated_world])
- contents['event_handler_getter_expression'] = 'imp->%s(%s)' % (cpp_name(attribute), isolated_world)
- elif v8_types.is_interface_type(idl_type) and not v8_types.array_type(idl_type):
- # FIXME: should be able to eliminate WTF::getPtr in most or all cases
- arguments.append('WTF::getPtr(cppValue)')
- else:
- arguments.append('cppValue')
- if contents['is_setter_raises_exception']:
- arguments.append('exceptionState')
-
- return '%s(%s)' % (setter_name, ', '.join(arguments))
-
-
-CONTENT_ATTRIBUTE_SETTER_NAMES = {
- 'boolean': 'setBooleanAttribute',
- 'long': 'setIntegralAttribute',
- 'unsigned long': 'setUnsignedIntegralAttribute',
-}
-
-
-def setter_base_name(attribute, arguments):
- if 'Reflect' not in attribute.extended_attributes:
- return 'set%s' % capitalize(cpp_name(attribute))
- arguments.append(scoped_content_attribute_name(attribute))
-
- idl_type = attribute.idl_type
- if idl_type in CONTENT_ATTRIBUTE_SETTER_NAMES:
- return CONTENT_ATTRIBUTE_SETTER_NAMES[idl_type]
- return 'setAttribute'
-
-
-def scoped_content_attribute_name(attribute):
- content_attribute_name = attribute.extended_attributes['Reflect'] or attribute.name.lower()
- namespace = 'HTMLNames' # FIXME: can be SVG too
- includes.add('%s.h' % namespace)
- return '%s::%sAttr' % (namespace, content_attribute_name)
-
-
-def scoped_name(interface, attribute, base_name):
- if attribute.is_static:
- return '%s::%s' % (interface.name, base_name)
- return 'imp->%s' % base_name
-
-
-# Attribute configuration
-
-# [Replaceable]
-def setter_callback_name(interface, attribute):
- cpp_class_name = cpp_name(interface)
- if ('Replaceable' in attribute.extended_attributes or
- is_constructor_attribute(attribute)):
- # FIXME: rename to ForceSetAttributeOnThisCallback, since also used for Constructors
- return '{0}V8Internal::{0}ReplaceableAttributeSetterCallback'.format(cpp_class_name)
- # FIXME: support [PutForwards]
- if attribute.is_read_only:
- return '0'
- return '%sV8Internal::%sAttributeSetterCallback' % (cpp_class_name, attribute.name)
-
-
-# [DoNotCheckSecurity], [Unforgeable]
-def access_control_list(attribute):
- extended_attributes = attribute.extended_attributes
- access_control = []
- if 'DoNotCheckSecurity' in extended_attributes:
- do_not_check_security = extended_attributes['DoNotCheckSecurity']
- if do_not_check_security == 'Setter':
- access_control.append('v8::ALL_CAN_WRITE')
- else:
- access_control.append('v8::ALL_CAN_READ')
- if not attribute.is_read_only:
- access_control.append('v8::ALL_CAN_WRITE')
- if 'Unforgeable' in extended_attributes:
- access_control.append('v8::PROHIBITS_OVERWRITING')
- return access_control or ['v8::DEFAULT']
-
-
-# [NotEnumerable], [Unforgeable]
-def property_attributes(attribute):
- extended_attributes = attribute.extended_attributes
- property_attributes_list = []
- if ('NotEnumerable' in extended_attributes or
- is_constructor_attribute(attribute)):
- property_attributes_list.append('v8::DontEnum')
- if 'Unforgeable' in extended_attributes:
- property_attributes_list.append('v8::DontDelete')
- return property_attributes_list or ['v8::None']
-
-
-# Constructors
-
-def is_constructor_attribute(attribute):
- return attribute.idl_type.endswith('Constructor')
diff --git a/chromium/third_party/WebKit/Source/bindings/scripts/unstable/v8_interface.py b/chromium/third_party/WebKit/Source/bindings/scripts/unstable/v8_interface.py
deleted file mode 100644
index 5d8b312fa5b..00000000000
--- a/chromium/third_party/WebKit/Source/bindings/scripts/unstable/v8_interface.py
+++ /dev/null
@@ -1,406 +0,0 @@
-# Copyright (C) 2013 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.
-
-"""Generate template values for an interface.
-
-FIXME: Not currently used in build.
-This is a rewrite of the Perl IDL compiler in Python, but is not complete.
-Once it is complete, we will switch all IDL files over to Python at once.
-Until then, please work on the Perl IDL compiler.
-For details, see bug http://crbug.com/239771
-"""
-
-import v8_attributes
-from v8_globals import includes
-import v8_methods
-import v8_types
-import v8_utilities
-from v8_utilities import capitalize, conditional_string, cpp_name, has_extended_attribute, has_extended_attribute_value, runtime_enabled_function_name
-
-
-INTERFACE_H_INCLUDES = set([
- 'bindings/v8/V8Binding.h',
- 'bindings/v8/V8DOMWrapper.h',
- 'bindings/v8/WrapperTypeInfo.h',
-])
-INTERFACE_CPP_INCLUDES = set([
- 'RuntimeEnabledFeatures.h',
- 'bindings/v8/ExceptionState.h',
- 'bindings/v8/V8DOMConfiguration.h',
- 'core/dom/ContextFeatures.h',
- 'core/dom/Document.h',
- 'platform/TraceEvent.h',
-])
-
-
-def generate_interface(interface):
- includes.clear()
- includes.update(INTERFACE_CPP_INCLUDES)
- header_includes = INTERFACE_H_INCLUDES
-
- parent_interface = interface.parent
- if parent_interface:
- header_includes.update(v8_types.includes_for_type(parent_interface))
- extended_attributes = interface.extended_attributes
-
- # [CheckSecurity]
- is_check_security = 'CheckSecurity' in extended_attributes
- if is_check_security:
- includes.add('bindings/v8/BindingSecurity.h')
-
- # [GenerateVisitDOMWrapper]
- generate_visit_dom_wrapper_function = extended_attributes.get('GenerateVisitDOMWrapper')
- if generate_visit_dom_wrapper_function:
- includes.update(['bindings/v8/V8GCController.h',
- 'core/dom/Element.h'])
-
- # [MeasureAs]
- is_measure_as = 'MeasureAs' in extended_attributes
- if is_measure_as:
- includes.add('core/frame/UseCounter.h')
-
- # [SpecialWrapFor]
- if 'SpecialWrapFor' in extended_attributes:
- special_wrap_for = extended_attributes['SpecialWrapFor'].split('|')
- else:
- special_wrap_for = []
- for special_wrap_interface in special_wrap_for:
- v8_types.add_includes_for_type(special_wrap_interface)
-
- # Constructors
- constructors = [generate_constructor(interface, constructor)
- for constructor in interface.constructors
- # FIXME: shouldn't put named constructors with constructors
- # (currently needed for Perl compatibility)
- # Handle named constructors separately
- if constructor.name == 'Constructor']
- generate_constructor_overloads(constructors)
-
- # [CustomConstructor]
- has_custom_constructor = 'CustomConstructor' in extended_attributes
-
- # [EventConstructor]
- has_event_constructor = 'EventConstructor' in extended_attributes
- any_type_attributes = [attribute for attribute in interface.attributes
- if attribute.idl_type == 'any']
- if has_event_constructor:
- includes.add('bindings/v8/Dictionary.h')
- if any_type_attributes:
- includes.add('bindings/v8/SerializedScriptValue.h')
-
- # [NamedConstructor]
- if 'NamedConstructor' in extended_attributes:
- # FIXME: parser should return named constructor separately;
- # included in constructors (and only name stored in extended attribute)
- # for Perl compatibility
- named_constructor = {'name': extended_attributes['NamedConstructor']}
- else:
- named_constructor = None
-
- if (constructors or has_custom_constructor or has_event_constructor or
- named_constructor):
- includes.add('bindings/v8/V8ObjectConstructor.h')
-
- template_contents = {
- 'any_type_attributes': any_type_attributes,
- 'conditional_string': conditional_string(interface), # [Conditional]
- 'constructors': constructors,
- 'cpp_class': cpp_name(interface),
- 'generate_visit_dom_wrapper_function': generate_visit_dom_wrapper_function,
- 'has_custom_constructor': has_custom_constructor,
- 'has_custom_legacy_call_as_function': has_extended_attribute_value(interface, 'Custom', 'LegacyCallAsFunction'), # [Custom=LegacyCallAsFunction]
- 'has_custom_to_v8': has_extended_attribute_value(interface, 'Custom', 'ToV8'), # [Custom=ToV8]
- 'has_custom_wrap': has_extended_attribute_value(interface, 'Custom', 'Wrap'), # [Custom=Wrap]
- 'has_event_constructor': has_event_constructor,
- 'has_visit_dom_wrapper': (
- # [Custom=Wrap], [GenerateVisitDOMWrapper]
- has_extended_attribute_value(interface, 'Custom', 'VisitDOMWrapper') or
- 'GenerateVisitDOMWrapper' in extended_attributes),
- 'header_includes': header_includes,
- 'interface_length': interface_length(interface, constructors),
- 'interface_name': interface.name,
- 'is_active_dom_object': 'ActiveDOMObject' in extended_attributes, # [ActiveDOMObject]
- 'is_check_security': is_check_security,
- 'is_constructor_call_with_document': has_extended_attribute_value(
- interface, 'ConstructorCallWith', 'Document'), # [ConstructorCallWith=Document]
- 'is_constructor_call_with_execution_context': has_extended_attribute_value(
- interface, 'ConstructorCallWith', 'ExecutionContext'), # [ConstructorCallWith=ExeuctionContext]
- 'is_constructor_raises_exception': extended_attributes.get('RaisesException') == 'Constructor', # [RaisesException=Constructor]
- 'is_dependent_lifetime': 'DependentLifetime' in extended_attributes, # [DependentLifetime]
- 'is_event_target': inherits_interface(interface, 'EventTarget'),
- 'is_node': inherits_interface(interface, 'Node'),
- 'measure_as': v8_utilities.measure_as(interface), # [MeasureAs]
- 'named_constructor': named_constructor,
- 'parent_interface': parent_interface,
- 'runtime_enabled_function': runtime_enabled_function_name(interface), # [RuntimeEnabled]
- 'special_wrap_for': special_wrap_for,
- 'v8_class': v8_utilities.v8_class_name(interface),
- }
-
- template_contents.update({
- 'constants': [generate_constant(constant) for constant in interface.constants],
- 'do_not_check_constants': 'DoNotCheckConstants' in extended_attributes,
- })
-
- attributes = [v8_attributes.generate_attribute(interface, attribute)
- for attribute in interface.attributes]
- template_contents.update({
- 'attributes': attributes,
- 'has_accessors': any(attribute['is_expose_js_accessors'] for attribute in attributes),
- 'has_constructor_attributes': any(attribute['constructor_type'] for attribute in attributes),
- 'has_per_context_enabled_attributes': any(attribute['per_context_enabled_function'] for attribute in attributes),
- 'has_replaceable_attributes': any(attribute['is_replaceable'] for attribute in attributes),
- })
-
- methods = [v8_methods.generate_method(interface, method)
- for method in interface.operations]
- generate_overloads(methods)
- for method in methods:
- method['do_generate_method_configuration'] = (
- method['do_not_check_signature'] and
- not method['per_context_enabled_function'] and
- # For overloaded methods, only generate one accessor
- ('overload_index' not in method or method['overload_index'] == 1))
-
- template_contents.update({
- 'has_origin_safe_method_setter': any(
- method['is_check_security_for_frame'] and not method['is_read_only']
- for method in methods),
- 'has_method_configuration': any(method['do_generate_method_configuration'] for method in methods),
- 'has_per_context_enabled_methods': any(method['per_context_enabled_function'] for method in methods),
- 'methods': methods,
- })
-
- return template_contents
-
-
-# [DeprecateAs], [Reflect], [RuntimeEnabled]
-def generate_constant(constant):
- # (Blink-only) string literals are unquoted in tokenizer, must be re-quoted
- # in C++.
- if constant.idl_type == 'DOMString':
- value = '"%s"' % constant.value
- else:
- value = constant.value
-
- constant_parameter = {
- 'name': constant.name,
- # FIXME: use 'reflected_name' as correct 'name'
- 'reflected_name': constant.extended_attributes.get('Reflect', constant.name),
- 'runtime_enabled_function': runtime_enabled_function_name(constant),
- 'value': value,
- }
- return constant_parameter
-
-
-# Overloads
-
-def generate_overloads(methods):
- generate_overloads_by_type(methods, is_static=False) # Regular methods
- generate_overloads_by_type(methods, is_static=True)
-
-
-def generate_overloads_by_type(methods, is_static):
- # Generates |overloads| template values and modifies |methods| in place;
- # |is_static| flag used (instead of partitioning list in 2) because need to
- # iterate over original list of methods to modify in place
- method_counts = {}
- for method in methods:
- if method['is_static'] != is_static:
- continue
- name = method['name']
- method_counts.setdefault(name, 0)
- method_counts[name] += 1
-
- # Filter to only methods that are actually overloaded
- overloaded_method_counts = dict((name, count)
- for name, count in method_counts.iteritems()
- if count > 1)
-
- # Add overload information only to overloaded methods, so template code can
- # easily verify if a function is overloaded
- method_overloads = {}
- for method in methods:
- name = method['name']
- if (method['is_static'] != is_static or
- name not in overloaded_method_counts):
- continue
- # Overload index includes self, so first append, then compute index
- method_overloads.setdefault(name, []).append(method)
- method.update({
- 'overload_index': len(method_overloads[name]),
- 'overload_resolution_expression': overload_resolution_expression(method),
- })
-
- # Resolution function is generated after last overloaded function;
- # package necessary information into |method.overloads| for that method.
- for method in methods:
- if (method['is_static'] != is_static or
- 'overload_index' not in method):
- continue
- name = method['name']
- if method['overload_index'] != overloaded_method_counts[name]:
- continue
- overloads = method_overloads[name]
- method['overloads'] = {
- 'name': name,
- 'methods': overloads,
- 'minimum_number_of_required_arguments': min(
- overload['number_of_required_arguments']
- for overload in overloads),
- }
-
-
-def overload_resolution_expression(method):
- # Expression is an OR of ANDs: each term in the OR corresponds to a
- # possible argument count for a given method, with type checks.
- # FIXME: Blink's overload resolution algorithm is incorrect, per:
- # https://code.google.com/p/chromium/issues/detail?id=293561
- # Properly:
- # 1. Compute effective overload set.
- # 2. First check type list length.
- # 3. If multiple entries for given length, compute distinguishing argument
- # index and have check for that type.
- arguments = method['arguments']
- overload_checks = [overload_check_expression(method, index)
- # check *omitting* optional arguments at |index| and up:
- # index 0 => argument_count 0 (no arguments)
- # index 1 => argument_count 1 (index 0 argument only)
- for index, argument in enumerate(arguments)
- if argument['is_optional']]
- # FIXME: this is wrong if a method has optional arguments and a variadic
- # one, though there are not yet any examples of this
- if not method['is_variadic']:
- # Includes all optional arguments (len = last index + 1)
- overload_checks.append(overload_check_expression(method, len(arguments)))
- return ' || '.join('(%s)' % check for check in overload_checks)
-
-
-def overload_check_expression(method, argument_count):
- overload_checks = ['info.Length() == %s' % argument_count]
- arguments = method['arguments'][:argument_count]
- overload_checks.extend(overload_check_argument(index, argument)
- for index, argument in
- enumerate(arguments))
- return ' && '.join('(%s)' % check for check in overload_checks if check)
-
-
-def overload_check_argument(index, argument):
- cpp_value = 'info[%s]' % index
- idl_type = argument['idl_type']
- # FIXME: proper type checking, sharing code with attributes and methods
- if idl_type == 'DOMString' and argument['is_strict_type_checking']:
- return ' || '.join(['%s->IsNull()' % cpp_value,
- '%s->IsUndefined()' % cpp_value,
- '%s->IsString()' % cpp_value,
- '%s->IsObject()' % cpp_value])
- if v8_types.array_or_sequence_type(idl_type):
- return '%s->IsArray()' % cpp_value
- if v8_types.is_wrapper_type(idl_type):
- type_check = 'V8{idl_type}::hasInstance({cpp_value}, info.GetIsolate(), worldType(info.GetIsolate()))'.format(idl_type=idl_type, cpp_value=cpp_value)
- if argument['is_nullable']:
- type_check = ' || '.join(['%s->IsNull()' % cpp_value, type_check])
- return type_check
- return None
-
-
-# Constructors
-
-# [Constructor]
-def generate_constructor(interface, constructor):
- return {
- 'argument_list': constructor_argument_list(interface, constructor),
- 'arguments': [constructor_argument(argument, index)
- for index, argument in enumerate(constructor.arguments)],
- 'is_constructor': True,
- 'is_variadic': False, # Required for overload resolution
- 'number_of_required_arguments':
- len([argument for argument in constructor.arguments
- if not argument.is_optional]),
- }
-
-
-def constructor_argument_list(interface, constructor):
- arguments = []
- # [ConstructorCallWith=ExecutionContext]
- if has_extended_attribute_value(interface, 'ConstructorCallWith', 'ExecutionContext'):
- arguments.append('context')
- # [ConstructorCallWith=Document]
- if has_extended_attribute_value(interface, 'ConstructorCallWith', 'Document'):
- arguments.append('document')
-
- arguments.extend([argument.name for argument in constructor.arguments])
-
- # [RaisesException=Constructor]
- if interface.extended_attributes.get('RaisesException') == 'Constructor':
- arguments.append('exceptionState')
-
- return arguments
-
-
-def constructor_argument(argument, index):
- return {
- 'has_default': 'Default' in argument.extended_attributes,
- 'idl_type': argument.idl_type,
- 'index': index,
- 'is_nullable': False, # Required for overload resolution
- 'is_optional': argument.is_optional,
- 'is_strict_type_checking': False, # Required for overload resolution
- 'name': argument.name,
- 'v8_value_to_local_cpp_value':
- v8_methods.v8_value_to_local_cpp_value(argument, index),
- }
-
-
-def generate_constructor_overloads(constructors):
- if len(constructors) <= 1:
- return
- for overload_index, constructor in enumerate(constructors):
- constructor.update({
- 'overload_index': overload_index + 1,
- 'overload_resolution_expression':
- overload_resolution_expression(constructor),
- })
-
-
-def interface_length(interface, constructors):
- # Docs: http://heycam.github.io/webidl/#es-interface-call
- if 'EventConstructor' in interface.extended_attributes:
- return 1
- if not constructors:
- return 0
- return min(constructor['number_of_required_arguments']
- for constructor in constructors)
-
-
-# Interface dependencies
-
-def inherits_interface(interface, ancestor):
- # FIXME: support distant ancestors (but don't parse all ancestors!)
- # Do by computing ancestor chain in compute_dependencies.py
- return ancestor in [interface.name, interface.parent]
diff --git a/chromium/third_party/WebKit/Source/bindings/scripts/unstable/v8_methods.py b/chromium/third_party/WebKit/Source/bindings/scripts/unstable/v8_methods.py
deleted file mode 100644
index 13a5c66e2e3..00000000000
--- a/chromium/third_party/WebKit/Source/bindings/scripts/unstable/v8_methods.py
+++ /dev/null
@@ -1,232 +0,0 @@
-# Copyright (C) 2013 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.
-
-"""Generate template values for methods.
-
-FIXME: Not currently used in build.
-This is a rewrite of the Perl IDL compiler in Python, but is not complete.
-Once it is complete, we will switch all IDL files over to Python at once.
-Until then, please work on the Perl IDL compiler.
-For details, see bug http://crbug.com/239771
-"""
-
-from v8_globals import includes
-import v8_types
-import v8_utilities
-from v8_utilities import has_extended_attribute_value
-
-
-def generate_method(interface, method):
- arguments = method.arguments
- extended_attributes = method.extended_attributes
- idl_type = method.idl_type
- is_static = method.is_static
- name = method.name
-
- this_cpp_value = cpp_value(interface, method, len(arguments))
- this_custom_signature = custom_signature(method, arguments)
-
- def function_template():
- if is_static:
- return 'functionTemplate'
- if 'Unforgeable' in extended_attributes:
- return 'instanceTemplate'
- return 'prototypeTemplate'
-
- def signature():
- if this_custom_signature:
- return name + 'Signature'
- if is_static or 'DoNotCheckSignature' in extended_attributes:
- return 'v8::Local<v8::Signature>()'
- return 'defaultSignature'
-
- is_call_with_script_arguments = has_extended_attribute_value(method, 'CallWith', 'ScriptArguments')
- if is_call_with_script_arguments:
- includes.update(['bindings/v8/ScriptCallStackFactory.h',
- 'core/inspector/ScriptArguments.h'])
- is_call_with_script_state = has_extended_attribute_value(method, 'CallWith', 'ScriptState')
- if is_call_with_script_state:
- includes.add('bindings/v8/ScriptState.h')
- is_check_security_for_node = 'CheckSecurity' in extended_attributes
- if is_check_security_for_node:
- includes.add('bindings/v8/BindingSecurity.h')
- is_custom_element_callbacks = 'CustomElementCallbacks' in extended_attributes
- if is_custom_element_callbacks:
- includes.add('core/dom/custom/CustomElementCallbackDispatcher.h')
-
- contents = {
- 'activity_logging_world_list': v8_utilities.activity_logging_world_list(method), # [ActivityLogging]
- 'arguments': [generate_argument(interface, method, argument, index)
- for index, argument in enumerate(arguments)],
- 'conditional_string': v8_utilities.conditional_string(method),
- 'cpp_type': v8_types.cpp_type(idl_type),
- 'cpp_value': this_cpp_value,
- 'custom_signature': this_custom_signature,
- 'deprecate_as': v8_utilities.deprecate_as(method), # [DeprecateAs]
- 'do_not_check_signature': not(this_custom_signature or is_static or
- v8_utilities.has_extended_attribute(method,
- ['DoNotCheckSecurity', 'DoNotCheckSignature', 'NotEnumerable',
- 'ReadOnly', 'RuntimeEnabled', 'Unforgeable'])),
- 'function_template': function_template(),
- 'idl_type': idl_type,
- 'is_call_with_execution_context': has_extended_attribute_value(method, 'CallWith', 'ExecutionContext'),
- 'is_call_with_script_arguments': is_call_with_script_arguments,
- 'is_call_with_script_state': is_call_with_script_state,
- 'is_check_security_for_frame': (
- 'CheckSecurity' in interface.extended_attributes and
- 'DoNotCheckSecurity' not in extended_attributes),
- 'is_check_security_for_node': is_check_security_for_node,
- 'is_custom': 'Custom' in extended_attributes,
- 'is_custom_element_callbacks': is_custom_element_callbacks,
- 'is_do_not_check_security': 'DoNotCheckSecurity' in extended_attributes,
- 'is_per_world_bindings': 'PerWorldBindings' in extended_attributes,
- 'is_raises_exception': 'RaisesException' in extended_attributes,
- 'is_read_only': 'ReadOnly' in extended_attributes,
- 'is_static': is_static,
- 'is_strict_type_checking': 'StrictTypeChecking' in extended_attributes,
- 'is_variadic': arguments and arguments[-1].is_variadic,
- 'measure_as': v8_utilities.measure_as(method), # [MeasureAs]
- 'name': name,
- 'number_of_arguments': len(arguments),
- 'number_of_required_arguments': len([
- argument for argument in arguments
- if not (argument.is_optional or argument.is_variadic)]),
- 'number_of_required_or_variadic_arguments': len([
- argument for argument in arguments
- if not argument.is_optional]),
- 'per_context_enabled_function': v8_utilities.per_context_enabled_function_name(method), # [PerContextEnabled]
- 'property_attributes': property_attributes(method),
- 'runtime_enabled_function': v8_utilities.runtime_enabled_function_name(method), # [RuntimeEnabled]
- 'signature': signature(),
- 'v8_set_return_value': v8_set_return_value(method, this_cpp_value),
- 'world_suffixes': ['', 'ForMainWorld'] if 'PerWorldBindings' in extended_attributes else [''], # [PerWorldBindings]
- }
- return contents
-
-
-def generate_argument(interface, method, argument, index):
- extended_attributes = argument.extended_attributes
- idl_type = argument.idl_type
- this_cpp_value = cpp_value(interface, method, index)
- return {
- 'cpp_type': v8_types.cpp_type(idl_type),
- 'cpp_value': this_cpp_value,
- 'enum_validation_expression': v8_utilities.enum_validation_expression(idl_type),
- 'has_default': 'Default' in extended_attributes,
- 'idl_type': idl_type,
- 'index': index,
- 'is_clamp': 'Clamp' in extended_attributes,
- 'is_nullable': argument.is_nullable,
- 'is_optional': argument.is_optional,
- 'is_strict_type_checking': 'StrictTypeChecking' in extended_attributes,
- 'is_variadic_wrapper_type': argument.is_variadic and v8_types.is_wrapper_type(idl_type),
- 'is_wrapper_type': v8_types.is_wrapper_type(idl_type),
- 'name': argument.name,
- 'v8_set_return_value': v8_set_return_value(method, this_cpp_value),
- 'v8_value_to_local_cpp_value': v8_value_to_local_cpp_value(argument, index),
- }
-
-
-def cpp_value(interface, method, number_of_arguments):
- def cpp_argument(argument):
- if argument.idl_type in ['NodeFilter', 'XPathNSResolver']:
- # FIXME: remove this special case
- return '%s.release()' % argument.name
- return argument.name
-
- # Truncate omitted optional arguments
- arguments = method.arguments[:number_of_arguments]
- cpp_arguments = v8_utilities.call_with_arguments(method)
- cpp_arguments.extend(cpp_argument(argument) for argument in arguments)
- if 'RaisesException' in method.extended_attributes:
- cpp_arguments.append('exceptionState')
-
- cpp_method_name = v8_utilities.scoped_name(interface, method, v8_utilities.cpp_name(method))
- return '%s(%s)' % (cpp_method_name, ', '.join(cpp_arguments))
-
-
-def v8_set_return_value(method, cpp_value):
- idl_type = method.idl_type
- if idl_type == 'void':
- return None
- # [CallWith=ScriptState]
- if has_extended_attribute_value(method, 'CallWith', 'ScriptState'):
- cpp_value = 'result' # use local variable for value
- return v8_types.v8_set_return_value(idl_type, cpp_value, method.extended_attributes)
-
-
-def custom_signature(method, arguments):
- def argument_template(argument):
- idl_type = argument.idl_type
- if (v8_types.is_wrapper_type(idl_type) and
- not v8_types.is_typed_array_type(idl_type) and
- # Compatibility: all other browsers accepts a callable for
- # XPathNSResolver, despite it being against spec.
- not idl_type == 'XPathNSResolver'):
- return 'V8PerIsolateData::from(isolate)->rawDOMTemplate(&V8{idl_type}::wrapperTypeInfo, currentWorldType)'.format(idl_type=idl_type)
- return 'v8::Handle<v8::FunctionTemplate>()'
-
- if (any(argument.is_optional and
- 'Default' not in argument.extended_attributes
- for argument in arguments) or
- all(not v8_types.is_wrapper_type(argument.idl_type)
- for argument in arguments) or
- # For [StrictTypeChecking], type checking is done in the generated code
- 'StrictTypeChecking' in method.extended_attributes):
- return None
- return ', '.join([argument_template(argument) for argument in arguments])
-
-
-# [NotEnumerable]
-def property_attributes(method):
- extended_attributes = method.extended_attributes
- property_attributes_list = []
- if 'NotEnumerable' in extended_attributes:
- property_attributes_list.append('v8::DontEnum')
- if 'ReadOnly' in extended_attributes:
- property_attributes_list.append('v8::ReadOnly')
- if property_attributes_list:
- property_attributes_list.insert(0, 'v8::DontDelete')
- return property_attributes_list
-
-
-def v8_value_to_local_cpp_value(argument, index):
- extended_attributes = argument.extended_attributes
- idl_type = argument.idl_type
- name = argument.name
- if argument.is_variadic:
- return 'V8TRYCATCH_VOID(Vector<{cpp_type}>, {name}, toNativeArguments<{cpp_type}>(info, {index}))'.format(
- cpp_type=v8_types.cpp_type(idl_type), name=name, index=index)
- # [Default=NullString]
- if (argument.is_optional and idl_type == 'DOMString' and
- extended_attributes.get('Default') == 'NullString'):
- v8_value = 'argumentOrNull(info, %s)' % index
- else:
- v8_value = 'info[%s]' % index
- return v8_types.v8_value_to_local_cpp_value(
- idl_type, argument.extended_attributes, v8_value, name, index=index)
diff --git a/chromium/third_party/WebKit/Source/bindings/scripts/unstable/v8_types.py b/chromium/third_party/WebKit/Source/bindings/scripts/unstable/v8_types.py
deleted file mode 100644
index e7ca508865d..00000000000
--- a/chromium/third_party/WebKit/Source/bindings/scripts/unstable/v8_types.py
+++ /dev/null
@@ -1,583 +0,0 @@
-# Copyright (C) 2013 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.
-
-"""Functions for type handling and type conversion (Blink/C++ <-> V8/JS).
-
-Spec:
-http://www.w3.org/TR/WebIDL/#es-type-mapping
-
-FIXME: Not currently used in build.
-This is a rewrite of the Perl IDL compiler in Python, but is not complete.
-Once it is complete, we will switch all IDL files over to Python at once.
-Until then, please work on the Perl IDL compiler.
-For details, see bug http://crbug.com/239771
-"""
-
-import posixpath
-import re
-
-from v8_globals import includes
-import idl_definitions # for UnionType
-from v8_utilities import strip_suffix
-
-################################################################################
-# IDL types
-################################################################################
-
-BASIC_TYPES = set([
- # Built-in, non-composite, non-object data types
- # http://www.w3.org/TR/WebIDL/#dfn-primitive-type
- 'boolean',
- 'float',
- # unrestricted float is not supported
- 'double',
- # unrestricted double is not supported
- # integer types
- # http://www.w3.org/TR/WebIDL/#dfn-integer-type
- 'byte',
- 'octet',
- 'short',
- 'unsigned short',
- # int and unsigned are not IDL types
- 'long',
- 'unsigned long',
- 'long long',
- 'unsigned long long',
- # http://www.w3.org/TR/WebIDL/#idl-types
- 'DOMString',
- 'Date',
- # http://www.w3.org/TR/WebIDL/#es-type-mapping
- 'void',
-])
-
-enum_types = {} # name -> values
-callback_function_types = set()
-
-
-def array_or_sequence_type(idl_type):
- return array_type(idl_type) or sequence_type(idl_type)
-
-
-def array_type(idl_type):
- matched = re.match(r'([\w\s]+)\[\]', idl_type)
- return matched and matched.group(1)
-
-
-def is_basic_type(idl_type):
- return idl_type in BASIC_TYPES
-
-
-def is_callback_function_type(idl_type):
- return idl_type in callback_function_types
-
-
-def set_callback_function_types(callback_functions):
- callback_function_types.update(callback_functions.keys())
-
-
-def is_composite_type(idl_type):
- return (idl_type == 'any' or
- array_type(idl_type) or
- sequence_type(idl_type) or
- is_union_type(idl_type))
-
-
-def is_enum_type(idl_type):
- return idl_type in enum_types
-
-
-def enum_values(idl_type):
- return enum_types.get(idl_type)
-
-
-def set_enum_types(enumerations):
- enum_types.update([[enum.name, enum.values]
- for enum in enumerations.values()])
-
-
-def is_interface_type(idl_type):
- # Anything that is not another type is an interface type.
- # http://www.w3.org/TR/WebIDL/#idl-types
- # http://www.w3.org/TR/WebIDL/#idl-interface
- # In C++ these are RefPtr or PassRefPtr types.
- return not(is_basic_type(idl_type) or
- is_composite_type(idl_type) or
- is_callback_function_type(idl_type) or
- is_enum_type(idl_type) or
- idl_type == 'object' or
- idl_type == 'Promise') # Promise will be basic in future
-
-
-def sequence_type(idl_type):
- matched = re.match(r'sequence<([\w\s]+)>', idl_type)
- return matched and matched.group(1)
-
-
-def is_union_type(idl_type):
- return isinstance(idl_type, idl_definitions.IdlUnionType)
-
-
-################################################################################
-# V8-specific type handling
-################################################################################
-
-DOM_NODE_TYPES = set([
- 'Attr',
- 'CDATASection',
- 'CharacterData',
- 'Comment',
- 'Document',
- 'DocumentFragment',
- 'DocumentType',
- 'Element',
- 'Entity',
- 'HTMLDocument',
- 'Node',
- 'Notation',
- 'ProcessingInstruction',
- 'ShadowRoot',
- 'SVGDocument',
- 'Text',
- 'TestNode',
-])
-NON_WRAPPER_TYPES = set([
- 'CompareHow',
- 'Dictionary',
- 'MediaQueryListListener',
- 'NodeFilter',
- 'SerializedScriptValue',
-])
-TYPED_ARRAYS = {
- # (cpp_type, v8_type), used by constructor templates
- 'ArrayBuffer': None,
- 'ArrayBufferView': None,
- 'Float32Array': ('float', 'v8::kExternalFloatArray'),
- 'Float64Array': ('double', 'v8::kExternalDoubleArray'),
- 'Int8Array': ('signed char', 'v8::kExternalByteArray'),
- 'Int16Array': ('short', 'v8::kExternalShortArray'),
- 'Int32Array': ('int', 'v8::kExternalIntArray'),
- 'Uint8Array': ('unsigned char', 'v8::kExternalUnsignedByteArray'),
- 'Uint8ClampedArray': ('unsigned char', 'v8::kExternalPixelArray'),
- 'Uint16Array': ('unsigned short', 'v8::kExternalUnsignedShortArray'),
- 'Uint32Array': ('unsigned int', 'v8::kExternalUnsignedIntArray'),
-}
-
-
-def constructor_type(idl_type):
- return strip_suffix(idl_type, 'Constructor')
-
-
-def is_dom_node_type(idl_type):
- return (idl_type in DOM_NODE_TYPES or
- (idl_type.startswith(('HTML', 'SVG')) and
- idl_type.endswith('Element')))
-
-
-def is_typed_array_type(idl_type):
- return idl_type in TYPED_ARRAYS
-
-
-def is_wrapper_type(idl_type):
- return (is_interface_type(idl_type) and
- idl_type not in NON_WRAPPER_TYPES)
-
-
-################################################################################
-# C++ types
-################################################################################
-
-CPP_TYPE_SAME_AS_IDL_TYPE = set([
- 'double',
- 'float',
- 'long long',
- 'unsigned long long',
-])
-CPP_INT_TYPES = set([
- 'byte',
- 'long',
- 'short',
-])
-CPP_UNSIGNED_TYPES = set([
- 'octet',
- 'unsigned int',
- 'unsigned long',
- 'unsigned short',
-])
-CPP_SPECIAL_CONVERSION_RULES = {
- 'CompareHow': 'Range::CompareHow',
- 'Date': 'double',
- 'Dictionary': 'Dictionary',
- 'EventHandler': 'EventListener*',
- 'Promise': 'ScriptPromise',
- 'any': 'ScriptValue',
- 'boolean': 'bool',
-}
-
-def cpp_type(idl_type, extended_attributes=None, used_as_argument=False):
- """Returns C++ type corresponding to IDL type."""
- def string_mode():
- # FIXME: the Web IDL spec requires 'EmptyString', not 'NullString',
- # but we use NullString for performance.
- if extended_attributes.get('TreatNullAs') != 'NullString':
- return ''
- if extended_attributes.get('TreatUndefinedAs') != 'NullString':
- return 'WithNullCheck'
- return 'WithUndefinedOrNullCheck'
-
- extended_attributes = extended_attributes or {}
- idl_type = preprocess_idl_type(idl_type)
-
- if idl_type in CPP_TYPE_SAME_AS_IDL_TYPE:
- return idl_type
- if idl_type in CPP_INT_TYPES:
- return 'int'
- if idl_type in CPP_UNSIGNED_TYPES:
- return 'unsigned'
- if idl_type in CPP_SPECIAL_CONVERSION_RULES:
- return CPP_SPECIAL_CONVERSION_RULES[idl_type]
- if (idl_type in NON_WRAPPER_TYPES or
- idl_type == 'XPathNSResolver'): # FIXME: eliminate this special case
- return 'RefPtr<%s>' % idl_type
- if idl_type == 'DOMString':
- if not used_as_argument:
- return 'String'
- return 'V8StringResource<%s>' % string_mode()
- if is_union_type(idl_type):
- raise Exception('UnionType is not supported')
- this_array_or_sequence_type = array_or_sequence_type(idl_type)
- if this_array_or_sequence_type:
- return cpp_template_type('Vector', cpp_type(this_array_or_sequence_type))
-
- if is_typed_array_type and used_as_argument:
- return idl_type + '*'
- if is_interface_type(idl_type) and not used_as_argument:
- return cpp_template_type('RefPtr', idl_type)
- # Default, assume native type is a pointer with same type name as idl type
- return idl_type + '*'
-
-
-def cpp_template_type(template, inner_type):
- """Returns C++ template specialized to type, with space added if needed."""
- if inner_type.endswith('>'):
- format_string = '{template}<{inner_type} >'
- else:
- format_string = '{template}<{inner_type}>'
- return format_string.format(template=template, inner_type=inner_type)
-
-
-def v8_type(interface_type):
- return 'V8' + interface_type
-
-
-################################################################################
-# Includes
-################################################################################
-
-
-def includes_for_cpp_class(class_name, relative_dir_posix):
- return set([posixpath.join('bindings', relative_dir_posix, class_name + '.h')])
-
-
-INCLUDES_FOR_TYPE = {
- 'any': set(['bindings/v8/ScriptValue.h']),
- 'object': set(),
- 'Dictionary': set(['bindings/v8/Dictionary.h']),
- 'EventHandler': set(['bindings/v8/V8AbstractEventListener.h',
- 'bindings/v8/V8EventListenerList.h']),
- 'EventListener': set(['bindings/v8/BindingSecurity.h',
- 'bindings/v8/V8EventListenerList.h',
- 'core/frame/DOMWindow.h']),
- 'MediaQueryListListener': set(['core/css/MediaQueryListListener.h']),
- 'Promise': set(['bindings/v8/ScriptPromise.h']),
- 'SerializedScriptValue': set(['bindings/v8/SerializedScriptValue.h']),
-}
-
-def includes_for_type(idl_type):
- if idl_type in INCLUDES_FOR_TYPE:
- return INCLUDES_FOR_TYPE[idl_type]
- if is_basic_type(idl_type) or is_enum_type(idl_type):
- return set()
- if is_typed_array_type(idl_type):
- return set(['bindings/v8/custom/V8%sCustom.h' % idl_type])
- this_array_or_sequence_type = array_or_sequence_type(idl_type)
- if this_array_or_sequence_type:
- return includes_for_type(this_array_or_sequence_type)
- if idl_type.endswith('Constructor'):
- idl_type = constructor_type(idl_type)
- return set(['V8%s.h' % idl_type])
-
-
-def add_includes_for_type(idl_type):
- includes.update(includes_for_type(idl_type))
-
-
-################################################################################
-# V8 -> C++
-################################################################################
-
-V8_VALUE_TO_CPP_VALUE = {
- # Basic
- 'Date': 'toWebCoreDate({v8_value})',
- 'DOMString': '{v8_value}',
- 'boolean': '{v8_value}->BooleanValue()',
- 'float': 'static_cast<float>({v8_value}->NumberValue())',
- 'double': 'static_cast<double>({v8_value}->NumberValue())',
- 'byte': 'toInt8({arguments})',
- 'octet': 'toUInt8({arguments})',
- 'short': 'toInt16({arguments})',
- 'unsigned short': 'toUInt16({arguments})',
- 'long': 'toInt32({arguments})',
- 'unsigned long': 'toUInt32({arguments})',
- 'long long': 'toInt64({arguments})',
- 'unsigned long long': 'toUInt64({arguments})',
- # Interface types
- 'any': 'ScriptValue({v8_value}, info.GetIsolate())',
- 'CompareHow': 'static_cast<Range::CompareHow>({v8_value}->Int32Value())',
- 'Dictionary': 'Dictionary({v8_value}, info.GetIsolate())',
- 'MediaQueryListListener': 'MediaQueryListListener::create(ScriptValue({v8_value}, info.GetIsolate()))',
- 'NodeFilter': 'toNodeFilter({v8_value}, info.GetIsolate())',
- 'Promise': 'ScriptPromise({v8_value})',
- 'SerializedScriptValue': 'SerializedScriptValue::create({v8_value}, info.GetIsolate())',
- 'XPathNSResolver': 'toXPathNSResolver({v8_value}, info.GetIsolate())',
-}
-
-
-def v8_value_to_cpp_value(idl_type, extended_attributes, v8_value, index):
- this_array_or_sequence_type = array_or_sequence_type(idl_type)
- if this_array_or_sequence_type:
- return v8_value_to_cpp_value_array_or_sequence(this_array_or_sequence_type, v8_value, index)
-
- idl_type = preprocess_idl_type(idl_type)
- add_includes_for_type(idl_type)
-
- if 'EnforceRange' in extended_attributes:
- arguments = ', '.join([v8_value, 'EnforceRange', 'ok'])
- else: # NormalConversion
- arguments = v8_value
-
- if idl_type in V8_VALUE_TO_CPP_VALUE:
- cpp_expression_format = V8_VALUE_TO_CPP_VALUE[idl_type]
- elif is_typed_array_type(idl_type):
- cpp_expression_format = (
- '{v8_value}->Is{idl_type}() ? '
- 'V8{idl_type}::toNative(v8::Handle<v8::{idl_type}>::Cast({v8_value})) : 0')
- else:
- cpp_expression_format = (
- 'V8{idl_type}::hasInstance({v8_value}, info.GetIsolate(), worldType(info.GetIsolate())) ? '
- 'V8{idl_type}::toNative(v8::Handle<v8::Object>::Cast({v8_value})) : 0')
-
- return cpp_expression_format.format(arguments=arguments, idl_type=idl_type, v8_value=v8_value)
-
-
-def v8_value_to_cpp_value_array_or_sequence(this_array_or_sequence_type, v8_value, index):
- # Index is None for setters, index (starting at 0) for method arguments,
- # and is used to provide a human-readable exception message
- if index is None:
- index = 0 # special case, meaning "setter"
- else:
- index += 1 # human-readable index
- if (is_interface_type(this_array_or_sequence_type) and
- this_array_or_sequence_type != 'Dictionary'):
- this_cpp_type = None
- expression_format = '(toRefPtrNativeArray<{array_or_sequence_type}, V8{array_or_sequence_type}>({v8_value}, {index}, info.GetIsolate()))'
- add_includes_for_type(this_array_or_sequence_type)
- else:
- this_cpp_type = cpp_type(this_array_or_sequence_type)
- expression_format = 'toNativeArray<{cpp_type}>({v8_value}, {index}, info.GetIsolate())'
- expression = expression_format.format(array_or_sequence_type=this_array_or_sequence_type, cpp_type=this_cpp_type, index=index, v8_value=v8_value)
- return expression
-
-
-def v8_value_to_local_cpp_value(idl_type, extended_attributes, v8_value, variable_name, index=None):
- """Returns an expression that converts a V8 value to a C++ value and stores it as a local value."""
- this_cpp_type = cpp_type(idl_type, extended_attributes=extended_attributes, used_as_argument=True)
-
- idl_type = preprocess_idl_type(idl_type)
- if idl_type == 'DOMString':
- format_string = 'V8TRYCATCH_FOR_V8STRINGRESOURCE_VOID({cpp_type}, {variable_name}, {cpp_value})'
- elif 'EnforceRange' in extended_attributes:
- format_string = 'V8TRYCATCH_WITH_TYPECHECK_VOID({cpp_type}, {variable_name}, {cpp_value}, info.GetIsolate())'
- else:
- format_string = 'V8TRYCATCH_VOID({cpp_type}, {variable_name}, {cpp_value})'
-
- cpp_value = v8_value_to_cpp_value(idl_type, extended_attributes, v8_value, index)
- return format_string.format(cpp_type=this_cpp_type, cpp_value=cpp_value, variable_name=variable_name)
-
-
-################################################################################
-# C++ -> V8
-################################################################################
-
-
-def preprocess_idl_type(idl_type):
- if is_enum_type(idl_type):
- # Enumerations are internally DOMStrings
- return 'DOMString'
- if is_callback_function_type(idl_type):
- return 'ScriptValue'
- return idl_type
-
-
-def preprocess_idl_type_and_value(idl_type, cpp_value, extended_attributes):
- """Returns IDL type and value, with preliminary type conversions applied."""
- idl_type = preprocess_idl_type(idl_type)
- if idl_type in ['Promise', 'any']:
- idl_type = 'ScriptValue'
- if idl_type in ['long long', 'unsigned long long']:
- # long long and unsigned long long are not representable in ECMAScript;
- # we represent them as doubles.
- idl_type = 'double'
- cpp_value = 'static_cast<double>(%s)' % cpp_value
- # HTML5 says that unsigned reflected attributes should be in the range
- # [0, 2^31). When a value isn't in this range, a default value (or 0)
- # should be returned instead.
- extended_attributes = extended_attributes or {}
- if ('Reflect' in extended_attributes and
- idl_type in ['unsigned long', 'unsigned short']):
- cpp_value = cpp_value.replace('getUnsignedIntegralAttribute',
- 'getIntegralAttribute')
- cpp_value = 'std::max(0, %s)' % cpp_value
- return idl_type, cpp_value
-
-
-def v8_conversion_type(idl_type, extended_attributes):
- """Returns V8 conversion type, adding any additional includes.
-
- The V8 conversion type is used to select the C++ -> V8 conversion function
- or v8SetReturnValue* function; it can be an idl_type, a cpp_type, or a
- separate name for the type of conversion (e.g., 'DOMWrapper').
- """
- extended_attributes = extended_attributes or {}
- # Basic types, without additional includes
- if idl_type in CPP_INT_TYPES:
- return 'int'
- if idl_type in CPP_UNSIGNED_TYPES:
- return 'unsigned'
- if idl_type == 'DOMString':
- if 'TreatReturnedNullStringAs' not in extended_attributes:
- return 'DOMString'
- treat_returned_null_string_as = extended_attributes['TreatReturnedNullStringAs']
- if treat_returned_null_string_as == 'Null':
- return 'StringOrNull'
- if treat_returned_null_string_as == 'Undefined':
- return 'StringOrUndefined'
- raise 'Unrecognized TreatReturnNullStringAs value: "%s"' % treat_returned_null_string_as
- if is_basic_type(idl_type) or idl_type == 'ScriptValue':
- return idl_type
-
- # Data type with potential additional includes
- this_array_or_sequence_type = array_or_sequence_type(idl_type)
- if this_array_or_sequence_type:
- if is_interface_type(this_array_or_sequence_type):
- add_includes_for_type(this_array_or_sequence_type)
- return 'array'
-
- add_includes_for_type(idl_type)
- if idl_type in V8_SET_RETURN_VALUE: # Special v8SetReturnValue treatment
- return idl_type
-
- # Pointer type
- includes.add('wtf/GetPtr.h') # FIXME: remove if can eliminate WTF::getPtr
- includes.add('wtf/RefPtr.h')
- return 'DOMWrapper'
-
-
-V8_SET_RETURN_VALUE = {
- 'boolean': 'v8SetReturnValueBool(info, {cpp_value})',
- 'int': 'v8SetReturnValueInt(info, {cpp_value})',
- 'unsigned': 'v8SetReturnValueUnsigned(info, {cpp_value})',
- 'DOMString': 'v8SetReturnValueString(info, {cpp_value}, info.GetIsolate())',
- # [TreatNullReturnValueAs]
- 'StringOrNull': 'v8SetReturnValueStringOrNull(info, {cpp_value}, info.GetIsolate())',
- 'StringOrUndefined': 'v8SetReturnValueStringOrUndefined(info, {cpp_value}, info.GetIsolate())',
- 'void': '',
- # No special v8SetReturnValue* function (set value directly)
- 'float': 'v8SetReturnValue(info, {cpp_value})',
- 'double': 'v8SetReturnValue(info, {cpp_value})',
- # No special v8SetReturnValue* function, but instead convert value to V8
- # and then use general v8SetReturnValue.
- 'array': 'v8SetReturnValue(info, {cpp_value})',
- 'Date': 'v8SetReturnValue(info, {cpp_value})',
- 'EventHandler': 'v8SetReturnValue(info, {cpp_value})',
- 'ScriptValue': 'v8SetReturnValue(info, {cpp_value})',
- 'SerializedScriptValue': 'v8SetReturnValue(info, {cpp_value})',
- # DOMWrapper
- 'DOMWrapperFast': 'v8SetReturnValueFast(info, {cpp_value}, {script_wrappable})',
- 'DOMWrapperDefault': 'v8SetReturnValue(info, {cpp_value})',
-}
-
-
-def v8_set_return_value(idl_type, cpp_value, extended_attributes=None, script_wrappable=''):
- """Returns a statement that converts a C++ value to a V8 value and sets it as a return value."""
- def dom_wrapper_conversion_type():
- if not script_wrappable:
- return 'DOMWrapperDefault'
- return 'DOMWrapperFast'
-
- idl_type, cpp_value = preprocess_idl_type_and_value(idl_type, cpp_value, extended_attributes)
- this_v8_conversion_type = v8_conversion_type(idl_type, extended_attributes)
- # SetReturn-specific overrides
- if this_v8_conversion_type in ['Date', 'EventHandler', 'ScriptValue', 'SerializedScriptValue', 'array']:
- # Convert value to V8 and then use general v8SetReturnValue
- cpp_value = cpp_value_to_v8_value(idl_type, cpp_value, extended_attributes=extended_attributes)
- if this_v8_conversion_type == 'DOMWrapper':
- this_v8_conversion_type = dom_wrapper_conversion_type()
-
- format_string = V8_SET_RETURN_VALUE[this_v8_conversion_type]
- statement = format_string.format(cpp_value=cpp_value, script_wrappable=script_wrappable)
- return statement
-
-
-CPP_VALUE_TO_V8_VALUE = {
- # Built-in types
- 'Date': 'v8DateOrNull({cpp_value}, {isolate})',
- 'DOMString': 'v8String({isolate}, {cpp_value})',
- 'boolean': 'v8Boolean({cpp_value}, {isolate})',
- 'int': 'v8::Integer::New({isolate}, {cpp_value})',
- 'unsigned': 'v8::Integer::NewFromUnsigned({isolate}, {cpp_value})',
- 'float': 'v8::Number::New({isolate}, {cpp_value})',
- 'double': 'v8::Number::New({isolate}, {cpp_value})',
- 'void': 'v8Undefined()',
- # Special cases
- 'EventHandler': '{cpp_value} ? v8::Handle<v8::Value>(V8AbstractEventListener::cast({cpp_value})->getListenerObject(imp->executionContext())) : v8::Handle<v8::Value>(v8::Null({isolate}))',
- 'ScriptValue': '{cpp_value}.v8Value()',
- 'SerializedScriptValue': '{cpp_value} ? {cpp_value}->deserialize() : v8::Handle<v8::Value>(v8::Null({isolate}))',
- # General
- 'array': 'v8Array({cpp_value}, {isolate})',
- 'DOMWrapper': 'toV8({cpp_value}, {creation_context}, {isolate})',
-}
-
-
-def cpp_value_to_v8_value(idl_type, cpp_value, isolate='info.GetIsolate()', creation_context='', extended_attributes=None):
- """Returns an expression that converts a C++ value to a V8 value."""
- # the isolate parameter is needed for callback interfaces
- idl_type, cpp_value = preprocess_idl_type_and_value(idl_type, cpp_value, extended_attributes)
- this_v8_conversion_type = v8_conversion_type(idl_type, extended_attributes)
- format_string = CPP_VALUE_TO_V8_VALUE[this_v8_conversion_type]
- statement = format_string.format(cpp_value=cpp_value, isolate=isolate, creation_context=creation_context)
- return statement
diff --git a/chromium/third_party/WebKit/Source/bindings/scripts/utilities.py b/chromium/third_party/WebKit/Source/bindings/scripts/utilities.py
new file mode 100644
index 00000000000..0aeabc20b36
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/bindings/scripts/utilities.py
@@ -0,0 +1,171 @@
+# Copyright 2014 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""Utility functions (file reading, simple IDL parsing by regexes) for IDL build.
+
+Design doc: http://www.chromium.org/developers/design-documents/idl-build
+"""
+
+import os
+import cPickle as pickle
+import re
+import string
+
+
+class IdlBadFilenameError(Exception):
+ """Raised if an IDL filename disagrees with the interface name in the file."""
+ pass
+
+
+def idl_filename_to_interface_name(idl_filename):
+ # interface name is the root of the basename: InterfaceName.idl
+ return os.path.splitext(os.path.basename(idl_filename))[0]
+
+
+################################################################################
+# Basic file reading/writing
+################################################################################
+
+def get_file_contents(filename):
+ with open(filename) as f:
+ return f.read()
+
+
+def read_file_to_list(filename):
+ """Returns a list of (stripped) lines for a given filename."""
+ with open(filename) as f:
+ return [line.rstrip('\n') for line in f]
+
+
+def read_pickle_files(pickle_filenames):
+ for pickle_filename in pickle_filenames:
+ with open(pickle_filename) as pickle_file:
+ yield pickle.load(pickle_file)
+
+
+def write_file(new_text, destination_filename, only_if_changed):
+ if only_if_changed and os.path.isfile(destination_filename):
+ with open(destination_filename) as destination_file:
+ if destination_file.read() == new_text:
+ return
+ with open(destination_filename, 'w') as destination_file:
+ destination_file.write(new_text)
+
+
+def write_pickle_file(pickle_filename, data, only_if_changed):
+ if only_if_changed and os.path.isfile(pickle_filename):
+ with open(pickle_filename) as pickle_file:
+ try:
+ if pickle.load(pickle_file) == data:
+ return
+ except (EOFError, pickle.UnpicklingError):
+ # If trouble unpickling, overwrite
+ pass
+ with open(pickle_filename, 'w') as pickle_file:
+ pickle.dump(data, pickle_file)
+
+
+################################################################################
+# IDL parsing
+#
+# We use regular expressions for parsing; this is incorrect (Web IDL is not a
+# regular language), but simple and sufficient in practice.
+# Leading and trailing context (e.g. following '{') used to avoid false matches.
+################################################################################
+
+def get_partial_interface_name_from_idl(file_contents):
+ match = re.search(r'partial\s+interface\s+(\w+)\s*{', file_contents)
+ return match and match.group(1)
+
+
+def get_implements_from_idl(file_contents, interface_name):
+ """Returns lists of implementing and implemented interfaces.
+
+ Rule is: identifier-A implements identifier-B;
+ i.e., implement*ing* implements implement*ed*;
+ http://www.w3.org/TR/WebIDL/#idl-implements-statements
+
+ Returns two lists of interfaces: identifier-As and identifier-Bs.
+ An 'implements' statements can be present in the IDL file for either the
+ implementing or the implemented interface, but not other files.
+ """
+ implements_re = (r'^\s*'
+ r'(\w+)\s+'
+ r'implements\s+'
+ r'(\w+)\s*'
+ r';')
+ implements_matches = re.finditer(implements_re, file_contents, re.MULTILINE)
+ implements_pairs = [match.groups() for match in implements_matches]
+
+ foreign_implements = [pair for pair in implements_pairs
+ if interface_name not in pair]
+ if foreign_implements:
+ left, right = foreign_implements.pop()
+ raise IdlBadFilenameError(
+ 'implements statement found in unrelated IDL file.\n'
+ 'Statement is:\n'
+ ' %s implements %s;\n'
+ 'but filename is unrelated "%s.idl"' %
+ (left, right, interface_name))
+
+ return (
+ [left for left, right in implements_pairs if right == interface_name],
+ [right for left, right in implements_pairs if left == interface_name])
+
+
+def is_callback_interface_from_idl(file_contents):
+ match = re.search(r'callback\s+interface\s+\w+\s*{', file_contents)
+ return bool(match)
+
+
+def get_parent_interface(file_contents):
+ match = re.search(r'interface\s+'
+ r'\w+\s*'
+ r':\s*(\w+)\s*'
+ r'{',
+ file_contents)
+ return match and match.group(1)
+
+
+def get_interface_extended_attributes_from_idl(file_contents):
+ # Strip comments
+ # re.compile needed b/c Python 2.6 doesn't support flags in re.sub
+ single_line_comment_re = re.compile(r'//.*$', flags=re.MULTILINE)
+ block_comment_re = re.compile(r'/\*.*?\*/', flags=re.MULTILINE | re.DOTALL)
+ file_contents = re.sub(single_line_comment_re, '', file_contents)
+ file_contents = re.sub(block_comment_re, '', file_contents)
+
+ match = re.search(r'\[(.*)\]\s*'
+ r'((callback|partial)\s+)?'
+ r'(interface|exception)\s+'
+ r'\w+\s*'
+ r'(:\s*\w+\s*)?'
+ r'{',
+ file_contents, flags=re.DOTALL)
+ if not match:
+ return {}
+
+ extended_attributes_string = match.group(1)
+ extended_attributes = {}
+ # FIXME: this splitting is WRONG: it fails on ExtendedAttributeArgList like
+ # 'NamedConstructor=Foo(a, b)'
+ parts = [extended_attribute.strip()
+ for extended_attribute in extended_attributes_string.split(',')
+ # Discard empty parts, which may exist due to trailing comma
+ if extended_attribute.strip()]
+ for part in parts:
+ name, _, value = map(string.strip, part.partition('='))
+ extended_attributes[name] = value
+ return extended_attributes
+
+
+def get_put_forward_interfaces_from_idl(file_contents):
+ put_forwards_pattern = (r'\[[^\]]*PutForwards=[^\]]*\]\s+'
+ r'readonly\s+'
+ r'attribute\s+'
+ r'(\w+)')
+ return sorted(set(match.group(1)
+ for match in re.finditer(put_forwards_pattern,
+ file_contents,
+ flags=re.DOTALL)))
diff --git a/chromium/third_party/WebKit/Source/bindings/scripts/v8_attributes.py b/chromium/third_party/WebKit/Source/bindings/scripts/v8_attributes.py
new file mode 100644
index 00000000000..d774313bb9b
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/bindings/scripts/v8_attributes.py
@@ -0,0 +1,436 @@
+# Copyright (C) 2013 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.
+
+"""Generate template values for attributes.
+
+Extends IdlType with property |constructor_type_name|.
+
+Design doc: http://www.chromium.org/developers/design-documents/idl-compiler
+"""
+
+import idl_types
+from idl_types import inherits_interface
+from v8_globals import includes, interfaces
+import v8_types
+import v8_utilities
+from v8_utilities import capitalize, cpp_name, has_extended_attribute, has_extended_attribute_value, scoped_name, strip_suffix, uncapitalize
+
+
+def generate_attribute(interface, attribute):
+ idl_type = attribute.idl_type
+ base_idl_type = idl_type.base_type
+ extended_attributes = attribute.extended_attributes
+
+ idl_type.add_includes_for_type()
+
+ # [CheckSecurity]
+ is_check_security_for_node = 'CheckSecurity' in extended_attributes
+ if is_check_security_for_node:
+ includes.add('bindings/v8/BindingSecurity.h')
+ # [Custom]
+ has_custom_getter = ('Custom' in extended_attributes and
+ extended_attributes['Custom'] in [None, 'Getter'])
+ has_custom_setter = (not attribute.is_read_only and
+ 'Custom' in extended_attributes and
+ extended_attributes['Custom'] in [None, 'Setter'])
+ # [CustomElementCallbacks], [Reflect]
+ is_custom_element_callbacks = 'CustomElementCallbacks' in extended_attributes
+ is_reflect = 'Reflect' in extended_attributes
+ if is_custom_element_callbacks or is_reflect:
+ includes.add('core/dom/custom/CustomElementCallbackDispatcher.h')
+ # [PerWorldBindings]
+ if 'PerWorldBindings' in extended_attributes:
+ assert idl_type.is_wrapper_type or 'LogActivity' in extended_attributes, '[PerWorldBindings] should only be used with wrapper types: %s.%s' % (interface.name, attribute.name)
+ # [RaisesException], [RaisesException=Setter]
+ is_setter_raises_exception = (
+ 'RaisesException' in extended_attributes and
+ extended_attributes['RaisesException'] in [None, 'Setter'])
+ # [TypeChecking]
+ has_type_checking_interface = (
+ (has_extended_attribute_value(interface, 'TypeChecking', 'Interface') or
+ has_extended_attribute_value(attribute, 'TypeChecking', 'Interface')) and
+ idl_type.is_wrapper_type)
+ has_type_checking_nullable = (
+ (has_extended_attribute_value(interface, 'TypeChecking', 'Nullable') or
+ has_extended_attribute_value(attribute, 'TypeChecking', 'Nullable')) and
+ idl_type.is_wrapper_type)
+ has_type_checking_unrestricted = (
+ (has_extended_attribute_value(interface, 'TypeChecking', 'Unrestricted') or
+ has_extended_attribute_value(attribute, 'TypeChecking', 'Unrestricted')) and
+ idl_type.name in ('Float', 'Double'))
+
+ if (base_idl_type == 'EventHandler' and
+ interface.name in ['Window', 'WorkerGlobalScope'] and
+ attribute.name == 'onerror'):
+ includes.add('bindings/v8/V8ErrorHandler.h')
+
+ contents = {
+ 'access_control_list': access_control_list(attribute),
+ 'activity_logging_world_list_for_getter': v8_utilities.activity_logging_world_list(attribute, 'Getter'), # [ActivityLogging]
+ 'activity_logging_world_list_for_setter': v8_utilities.activity_logging_world_list(attribute, 'Setter'), # [ActivityLogging]
+ 'activity_logging_include_old_value_for_setter': 'LogPreviousValue' in extended_attributes, # [ActivityLogging]
+ 'activity_logging_world_check': v8_utilities.activity_logging_world_check(attribute), # [ActivityLogging]
+ 'cached_attribute_validation_method': extended_attributes.get('CachedAttribute'),
+ 'conditional_string': v8_utilities.conditional_string(attribute),
+ 'constructor_type': idl_type.constructor_type_name
+ if is_constructor_attribute(attribute) else None,
+ 'cpp_name': cpp_name(attribute),
+ 'cpp_type': idl_type.cpp_type,
+ 'cpp_value_to_v8_value': idl_type.cpp_value_to_v8_value(cpp_value='original', creation_context='info.Holder()'),
+ 'deprecate_as': v8_utilities.deprecate_as(attribute), # [DeprecateAs]
+ 'enum_validation_expression': idl_type.enum_validation_expression,
+ 'has_custom_getter': has_custom_getter,
+ 'has_custom_setter': has_custom_setter,
+ 'has_setter_exception_state':
+ is_setter_raises_exception or has_type_checking_interface or
+ has_type_checking_nullable or has_type_checking_unrestricted or
+ idl_type.is_integer_type or
+ idl_type.name in ('ByteString', 'ScalarValueString'),
+ 'has_type_checking_interface': has_type_checking_interface,
+ 'has_type_checking_nullable': has_type_checking_nullable,
+ 'has_type_checking_unrestricted': has_type_checking_unrestricted,
+ 'idl_type': str(idl_type), # need trailing [] on array for Dictionary::ConversionContext::setConversionType
+ 'is_call_with_execution_context': v8_utilities.has_extended_attribute_value(attribute, 'CallWith', 'ExecutionContext'),
+ 'is_call_with_script_state': v8_utilities.has_extended_attribute_value(attribute, 'CallWith', 'ScriptState'),
+ 'is_check_security_for_node': is_check_security_for_node,
+ 'is_custom_element_callbacks': is_custom_element_callbacks,
+ 'is_expose_js_accessors': 'ExposeJSAccessors' in extended_attributes,
+ 'is_getter_raises_exception': # [RaisesException]
+ 'RaisesException' in extended_attributes and
+ extended_attributes['RaisesException'] in (None, 'Getter'),
+ 'is_initialized_by_event_constructor':
+ 'InitializedByEventConstructor' in extended_attributes,
+ 'is_keep_alive_for_gc': is_keep_alive_for_gc(interface, attribute),
+ 'is_nullable': attribute.idl_type.is_nullable,
+ 'is_partial_interface_member':
+ 'PartialInterfaceImplementedAs' in extended_attributes,
+ 'is_per_world_bindings': 'PerWorldBindings' in extended_attributes,
+ 'is_read_only': attribute.is_read_only,
+ 'is_reflect': is_reflect,
+ 'is_replaceable': 'Replaceable' in attribute.extended_attributes,
+ 'is_setter_call_with_execution_context': v8_utilities.has_extended_attribute_value(attribute, 'SetterCallWith', 'ExecutionContext'),
+ 'is_setter_raises_exception': is_setter_raises_exception,
+ 'is_static': attribute.is_static,
+ 'is_url': 'URL' in extended_attributes,
+ 'is_unforgeable': 'Unforgeable' in extended_attributes,
+ 'measure_as': v8_utilities.measure_as(attribute), # [MeasureAs]
+ 'name': attribute.name,
+ 'per_context_enabled_function': v8_utilities.per_context_enabled_function_name(attribute), # [PerContextEnabled]
+ 'property_attributes': property_attributes(attribute),
+ 'put_forwards': 'PutForwards' in extended_attributes,
+ 'reflect_empty': extended_attributes.get('ReflectEmpty'),
+ 'reflect_invalid': extended_attributes.get('ReflectInvalid', ''),
+ 'reflect_missing': extended_attributes.get('ReflectMissing'),
+ 'reflect_only': extended_attributes['ReflectOnly'].split('|')
+ if 'ReflectOnly' in extended_attributes else None,
+ 'setter_callback': setter_callback_name(interface, attribute),
+ 'v8_type': v8_types.v8_type(base_idl_type),
+ 'runtime_enabled_function': v8_utilities.runtime_enabled_function_name(attribute), # [RuntimeEnabled]
+ 'world_suffixes': ['', 'ForMainWorld']
+ if 'PerWorldBindings' in extended_attributes
+ else [''], # [PerWorldBindings]
+ }
+
+ if is_constructor_attribute(attribute):
+ generate_constructor_getter(interface, attribute, contents)
+ return contents
+ if not has_custom_getter:
+ generate_getter(interface, attribute, contents)
+ if (not has_custom_setter and
+ (not attribute.is_read_only or 'PutForwards' in extended_attributes)):
+ generate_setter(interface, attribute, contents)
+
+ return contents
+
+
+################################################################################
+# Getter
+################################################################################
+
+def generate_getter(interface, attribute, contents):
+ idl_type = attribute.idl_type
+ base_idl_type = idl_type.base_type
+ extended_attributes = attribute.extended_attributes
+
+ cpp_value = getter_expression(interface, attribute, contents)
+ # Normally we can inline the function call into the return statement to
+ # avoid the overhead of using a Ref<> temporary, but for some cases
+ # (nullable types, EventHandler, [CachedAttribute], or if there are
+ # exceptions), we need to use a local variable.
+ # FIXME: check if compilers are smart enough to inline this, and if so,
+ # always use a local variable (for readability and CG simplicity).
+ release = False
+ if (idl_type.is_nullable or
+ base_idl_type == 'EventHandler' or
+ 'CachedAttribute' in extended_attributes or
+ 'ReflectOnly' in extended_attributes or
+ contents['is_getter_raises_exception']):
+ contents['cpp_value_original'] = cpp_value
+ cpp_value = 'v8Value'
+ # EventHandler has special handling
+ if base_idl_type != 'EventHandler' and idl_type.is_interface_type:
+ release = True
+
+ def v8_set_return_value_statement(for_main_world=False):
+ if contents['is_keep_alive_for_gc']:
+ return 'v8SetReturnValue(info, wrapper)'
+ return idl_type.v8_set_return_value(cpp_value, extended_attributes=extended_attributes, script_wrappable='impl', release=release, for_main_world=for_main_world)
+
+ contents.update({
+ 'cpp_value': cpp_value,
+ 'cpp_value_to_v8_value': idl_type.cpp_value_to_v8_value(cpp_value=cpp_value, creation_context='info.Holder()'),
+ 'v8_set_return_value_for_main_world': v8_set_return_value_statement(for_main_world=True),
+ 'v8_set_return_value': v8_set_return_value_statement(),
+ })
+
+
+def getter_expression(interface, attribute, contents):
+ arguments = []
+ this_getter_base_name = getter_base_name(interface, attribute, arguments)
+ getter_name = scoped_name(interface, attribute, this_getter_base_name)
+
+ arguments.extend(v8_utilities.call_with_arguments(
+ attribute.extended_attributes.get('CallWith')))
+ # Members of IDL partial interface definitions are implemented in C++ as
+ # static member functions, which for instance members (non-static members)
+ # take *impl as their first argument
+ if ('PartialInterfaceImplementedAs' in attribute.extended_attributes and
+ not attribute.is_static):
+ arguments.append('*impl')
+ if attribute.idl_type.is_nullable and not contents['has_type_checking_nullable']:
+ arguments.append('isNull')
+ if contents['is_getter_raises_exception']:
+ arguments.append('exceptionState')
+ return '%s(%s)' % (getter_name, ', '.join(arguments))
+
+
+CONTENT_ATTRIBUTE_GETTER_NAMES = {
+ 'boolean': 'fastHasAttribute',
+ 'long': 'getIntegralAttribute',
+ 'unsigned long': 'getUnsignedIntegralAttribute',
+}
+
+
+def getter_base_name(interface, attribute, arguments):
+ extended_attributes = attribute.extended_attributes
+ if 'Reflect' not in extended_attributes:
+ return uncapitalize(cpp_name(attribute))
+
+ content_attribute_name = extended_attributes['Reflect'] or attribute.name.lower()
+ if content_attribute_name in ['class', 'id', 'name']:
+ # Special-case for performance optimization.
+ return 'get%sAttribute' % content_attribute_name.capitalize()
+
+ arguments.append(scoped_content_attribute_name(interface, attribute))
+
+ base_idl_type = attribute.idl_type.base_type
+ if base_idl_type in CONTENT_ATTRIBUTE_GETTER_NAMES:
+ return CONTENT_ATTRIBUTE_GETTER_NAMES[base_idl_type]
+ if 'URL' in attribute.extended_attributes:
+ return 'getURLAttribute'
+ return 'fastGetAttribute'
+
+
+def is_keep_alive_for_gc(interface, attribute):
+ idl_type = attribute.idl_type
+ base_idl_type = idl_type.base_type
+ extended_attributes = attribute.extended_attributes
+ return (
+ # For readonly attributes, for performance reasons we keep the attribute
+ # wrapper alive while the owner wrapper is alive, because the attribute
+ # never changes.
+ (attribute.is_read_only and
+ idl_type.is_wrapper_type and
+ # There are some exceptions, however:
+ not(
+ # Node lifetime is managed by object grouping.
+ inherits_interface(interface.name, 'Node') or
+ inherits_interface(base_idl_type, 'Node') or
+ # A self-reference is unnecessary.
+ attribute.name == 'self' or
+ # FIXME: Remove these hard-coded hacks.
+ base_idl_type in ['EventTarget', 'Window'] or
+ base_idl_type.startswith(('HTML', 'SVG')))))
+
+
+################################################################################
+# Setter
+################################################################################
+
+def generate_setter(interface, attribute, contents):
+ def target_attribute():
+ target_interface_name = attribute.idl_type.base_type
+ target_attribute_name = extended_attributes['PutForwards']
+ target_interface = interfaces[target_interface_name]
+ try:
+ return next(attribute
+ for attribute in target_interface.attributes
+ if attribute.name == target_attribute_name)
+ except StopIteration:
+ raise Exception('[PutForward] target not found:\n'
+ 'Attribute "%s" is not present in interface "%s"' %
+ (target_attribute_name, target_interface_name))
+
+ extended_attributes = attribute.extended_attributes
+
+ if 'PutForwards' in extended_attributes:
+ # Use target attribute in place of original attribute
+ attribute = target_attribute()
+
+ contents.update({
+ 'cpp_setter': setter_expression(interface, attribute, contents),
+ 'v8_value_to_local_cpp_value': attribute.idl_type.v8_value_to_local_cpp_value(extended_attributes, 'v8Value', 'cppValue'),
+ })
+
+
+def setter_expression(interface, attribute, contents):
+ extended_attributes = attribute.extended_attributes
+ arguments = v8_utilities.call_with_arguments(
+ extended_attributes.get('SetterCallWith') or
+ extended_attributes.get('CallWith'))
+
+ this_setter_base_name = setter_base_name(interface, attribute, arguments)
+ setter_name = scoped_name(interface, attribute, this_setter_base_name)
+
+ # Members of IDL partial interface definitions are implemented in C++ as
+ # static member functions, which for instance members (non-static members)
+ # take *impl as their first argument
+ if ('PartialInterfaceImplementedAs' in extended_attributes and
+ not attribute.is_static):
+ arguments.append('*impl')
+ idl_type = attribute.idl_type
+ if idl_type.base_type == 'EventHandler':
+ getter_name = scoped_name(interface, attribute, cpp_name(attribute))
+ contents['event_handler_getter_expression'] = '%s(%s)' % (
+ getter_name, ', '.join(arguments))
+ if (interface.name in ['Window', 'WorkerGlobalScope'] and
+ attribute.name == 'onerror'):
+ includes.add('bindings/v8/V8ErrorHandler.h')
+ arguments.append('V8EventListenerList::findOrCreateWrapper<V8ErrorHandler>(v8Value, true, ScriptState::current(info.GetIsolate()))')
+ else:
+ arguments.append('V8EventListenerList::getEventListener(ScriptState::current(info.GetIsolate()), v8Value, true, ListenerFindOrCreate)')
+ elif idl_type.is_interface_type and not idl_type.array_type:
+ # FIXME: should be able to eliminate WTF::getPtr in most or all cases
+ arguments.append('WTF::getPtr(cppValue)')
+ else:
+ arguments.append('cppValue')
+ if contents['is_setter_raises_exception']:
+ arguments.append('exceptionState')
+
+ return '%s(%s)' % (setter_name, ', '.join(arguments))
+
+
+CONTENT_ATTRIBUTE_SETTER_NAMES = {
+ 'boolean': 'setBooleanAttribute',
+ 'long': 'setIntegralAttribute',
+ 'unsigned long': 'setUnsignedIntegralAttribute',
+}
+
+
+def setter_base_name(interface, attribute, arguments):
+ if 'Reflect' not in attribute.extended_attributes:
+ return 'set%s' % capitalize(cpp_name(attribute))
+ arguments.append(scoped_content_attribute_name(interface, attribute))
+
+ base_idl_type = attribute.idl_type.base_type
+ if base_idl_type in CONTENT_ATTRIBUTE_SETTER_NAMES:
+ return CONTENT_ATTRIBUTE_SETTER_NAMES[base_idl_type]
+ return 'setAttribute'
+
+
+def scoped_content_attribute_name(interface, attribute):
+ content_attribute_name = attribute.extended_attributes['Reflect'] or attribute.name.lower()
+ namespace = 'SVGNames' if interface.name.startswith('SVG') else 'HTMLNames'
+ includes.add('%s.h' % namespace)
+ return '%s::%sAttr' % (namespace, content_attribute_name)
+
+
+################################################################################
+# Attribute configuration
+################################################################################
+
+# [Replaceable]
+def setter_callback_name(interface, attribute):
+ cpp_class_name = cpp_name(interface)
+ extended_attributes = attribute.extended_attributes
+ if (('Replaceable' in extended_attributes and
+ 'PutForwards' not in extended_attributes) or
+ is_constructor_attribute(attribute)):
+ # FIXME: rename to ForceSetAttributeOnThisCallback, since also used for Constructors
+ return '{0}V8Internal::{0}ReplaceableAttributeSetterCallback'.format(cpp_class_name)
+ if attribute.is_read_only and 'PutForwards' not in extended_attributes:
+ return '0'
+ return '%sV8Internal::%sAttributeSetterCallback' % (cpp_class_name, attribute.name)
+
+
+# [DoNotCheckSecurity], [Unforgeable]
+def access_control_list(attribute):
+ extended_attributes = attribute.extended_attributes
+ access_control = []
+ if 'DoNotCheckSecurity' in extended_attributes:
+ do_not_check_security = extended_attributes['DoNotCheckSecurity']
+ if do_not_check_security == 'Setter':
+ access_control.append('v8::ALL_CAN_WRITE')
+ else:
+ access_control.append('v8::ALL_CAN_READ')
+ if (not attribute.is_read_only or
+ 'Replaceable' in extended_attributes):
+ access_control.append('v8::ALL_CAN_WRITE')
+ if 'Unforgeable' in extended_attributes:
+ access_control.append('v8::PROHIBITS_OVERWRITING')
+ return access_control or ['v8::DEFAULT']
+
+
+# [NotEnumerable], [Unforgeable]
+def property_attributes(attribute):
+ extended_attributes = attribute.extended_attributes
+ property_attributes_list = []
+ if ('NotEnumerable' in extended_attributes or
+ is_constructor_attribute(attribute)):
+ property_attributes_list.append('v8::DontEnum')
+ if 'Unforgeable' in extended_attributes:
+ property_attributes_list.append('v8::DontDelete')
+ return property_attributes_list or ['v8::None']
+
+
+################################################################################
+# Constructors
+################################################################################
+
+idl_types.IdlType.constructor_type_name = property(
+ # FIXME: replace this with a [ConstructorAttribute] extended attribute
+ lambda self: strip_suffix(self.base_type, 'Constructor'))
+
+
+def is_constructor_attribute(attribute):
+ # FIXME: replace this with [ConstructorAttribute] extended attribute
+ return attribute.idl_type.base_type.endswith('Constructor')
+
+
+def generate_constructor_getter(interface, attribute, contents):
+ contents['needs_constructor_getter_callback'] = contents['measure_as'] or contents['deprecate_as']
diff --git a/chromium/third_party/WebKit/Source/bindings/scripts/unstable/v8_callback_interface.py b/chromium/third_party/WebKit/Source/bindings/scripts/v8_callback_interface.py
index 2e310d19a10..06c18f2b809 100644
--- a/chromium/third_party/WebKit/Source/bindings/scripts/unstable/v8_callback_interface.py
+++ b/chromium/third_party/WebKit/Source/bindings/scripts/v8_callback_interface.py
@@ -28,81 +28,72 @@
"""Generate template values for a callback interface.
-FIXME: Not currently used in build.
-This is a rewrite of the Perl IDL compiler in Python, but is not complete.
-Once it is complete, we will switch all IDL files over to Python at once.
-Until then, please work on the Perl IDL compiler.
-For details, see bug http://crbug.com/239771
+Extends IdlType with property |callback_cpp_type|.
+
+Design doc: http://www.chromium.org/developers/design-documents/idl-compiler
"""
+from idl_types import IdlType
from v8_globals import includes
import v8_types
import v8_utilities
-CALLBACK_INTERFACE_H_INCLUDES = set([
+CALLBACK_INTERFACE_H_INCLUDES = frozenset([
'bindings/v8/ActiveDOMCallback.h',
'bindings/v8/DOMWrapperWorld.h',
'bindings/v8/ScopedPersistent.h',
])
-CALLBACK_INTERFACE_CPP_INCLUDES = set([
+CALLBACK_INTERFACE_CPP_INCLUDES = frozenset([
'bindings/v8/V8Binding.h',
'bindings/v8/V8Callback.h',
'core/dom/ExecutionContext.h',
'wtf/Assertions.h',
+ 'wtf/GetPtr.h',
+ 'wtf/RefPtr.h',
])
-def cpp_to_v8_conversion(idl_type, name):
- # FIXME: setting creation_context=v8::Handle<v8::Object>() is wrong,
- # as toV8 then implicitly uses the current context, which causes leaks
- # between isolate worlds if a different context should be used.
- cpp_value_to_v8_value = v8_types.cpp_value_to_v8_value(idl_type, name,
- isolate='isolate', creation_context='v8::Handle<v8::Object>()')
- return 'v8::Handle<v8::Value> {name}Handle = {cpp_to_v8};'.format(
- name=name, cpp_to_v8=cpp_value_to_v8_value)
-
-
def cpp_type(idl_type):
# FIXME: remove this function by making callback types consistent
# (always use usual v8_types.cpp_type)
- if idl_type == 'DOMString':
+ idl_type_name = idl_type.name
+ if idl_type_name == 'String':
return 'const String&'
- if idl_type == 'void':
+ if idl_type_name == 'void':
return 'void'
# Callbacks use raw pointers, so used_as_argument=True
- usual_cpp_type = v8_types.cpp_type(idl_type, used_as_argument=True)
- if usual_cpp_type.startswith('Vector'):
+ usual_cpp_type = idl_type.cpp_type_args(used_as_argument=True)
+ if usual_cpp_type.startswith(('Vector', 'HeapVector', 'WillBeHeapVector')):
return 'const %s&' % usual_cpp_type
return usual_cpp_type
+IdlType.callback_cpp_type = property(cpp_type)
+
def generate_callback_interface(callback_interface):
includes.clear()
includes.update(CALLBACK_INTERFACE_CPP_INCLUDES)
- name = callback_interface.name
-
- methods = [generate_method(operation)
- for operation in callback_interface.operations]
- template_contents = {
+ return {
'conditional_string': v8_utilities.conditional_string(callback_interface),
- 'cpp_class': name,
+ 'cpp_class': callback_interface.name,
'v8_class': v8_utilities.v8_class_name(callback_interface),
- 'header_includes': CALLBACK_INTERFACE_H_INCLUDES,
- 'methods': methods,
+ 'header_includes': set(CALLBACK_INTERFACE_H_INCLUDES),
+ 'methods': [generate_method(operation)
+ for operation in callback_interface.operations],
}
- return template_contents
def add_includes_for_operation(operation):
- v8_types.add_includes_for_type(operation.idl_type)
+ operation.idl_type.add_includes_for_type()
for argument in operation.arguments:
- v8_types.add_includes_for_type(argument.idl_type)
+ argument.idl_type.add_includes_for_type()
def generate_method(operation):
extended_attributes = operation.extended_attributes
idl_type = operation.idl_type
- if idl_type not in ['boolean', 'void']:
+ idl_type_str = str(idl_type)
+ if idl_type_str not in ['boolean', 'void']:
raise Exception('We only support callbacks that return boolean or void values.')
is_custom = 'Custom' in extended_attributes
if not is_custom:
@@ -111,10 +102,10 @@ def generate_method(operation):
call_with_this_handle = v8_utilities.extended_attribute_value_contains(call_with, 'ThisValue')
contents = {
'call_with_this_handle': call_with_this_handle,
+ 'cpp_type': idl_type.callback_cpp_type,
'custom': is_custom,
+ 'idl_type': idl_type_str,
'name': operation.name,
- 'return_cpp_type': cpp_type(idl_type),
- 'return_idl_type': idl_type,
}
contents.update(generate_arguments_contents(operation.arguments, call_with_this_handle))
return contents
@@ -123,17 +114,21 @@ def generate_method(operation):
def generate_arguments_contents(arguments, call_with_this_handle):
def generate_argument(argument):
return {
- 'name': argument.name,
- 'cpp_to_v8_conversion': cpp_to_v8_conversion(argument.idl_type, argument.name),
+ 'handle': '%sHandle' % argument.name,
+ # FIXME: setting creation_context=v8::Handle<v8::Object>() is
+ # wrong, as toV8 then implicitly uses the current context, which
+ # causes leaks between isolated worlds if a different context is
+ # used.
+ 'cpp_value_to_v8_value': argument.idl_type.cpp_value_to_v8_value(
+ argument.name, isolate='isolate',
+ creation_context='m_scriptState->context()->Global()'),
}
- argument_declarations = [
- '%s %s' % (cpp_type(argument.idl_type), argument.name)
- for argument in arguments]
- if call_with_this_handle:
- argument_declarations.insert(0, 'ScriptValue thisValue')
+ argument_declarations = ['ScriptValue thisValue'] if call_with_this_handle else []
+ argument_declarations.extend(
+ '%s %s' % (argument.idl_type.callback_cpp_type, argument.name)
+ for argument in arguments)
return {
'argument_declarations': argument_declarations,
'arguments': [generate_argument(argument) for argument in arguments],
- 'handles': ['%sHandle' % argument.name for argument in arguments],
}
diff --git a/chromium/third_party/WebKit/Source/bindings/scripts/unstable/v8_globals.py b/chromium/third_party/WebKit/Source/bindings/scripts/v8_globals.py
index b640703647a..9ca2a3574a9 100644
--- a/chromium/third_party/WebKit/Source/bindings/scripts/unstable/v8_globals.py
+++ b/chromium/third_party/WebKit/Source/bindings/scripts/v8_globals.py
@@ -26,6 +26,7 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-"""Module to share global variables (namely includes) across modules."""
+"""Module to share global variables (includes and interfaces) across modules."""
includes = set()
+interfaces = {}
diff --git a/chromium/third_party/WebKit/Source/bindings/scripts/v8_interface.py b/chromium/third_party/WebKit/Source/bindings/scripts/v8_interface.py
new file mode 100644
index 00000000000..abc23b40b07
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/bindings/scripts/v8_interface.py
@@ -0,0 +1,1087 @@
+# Copyright (C) 2013 Google Inc. All rights reserved.
+# coding=utf-8
+#
+# 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.
+
+"""Generate template values for an interface.
+
+Design doc: http://www.chromium.org/developers/design-documents/idl-compiler
+"""
+
+from collections import defaultdict
+import itertools
+from operator import itemgetter
+
+import idl_types
+from idl_types import IdlType, inherits_interface
+import v8_attributes
+from v8_globals import includes
+import v8_methods
+import v8_types
+from v8_types import cpp_ptr_type, cpp_template_type
+import v8_utilities
+from v8_utilities import capitalize, conditional_string, cpp_name, gc_type, has_extended_attribute_value, runtime_enabled_function_name
+
+
+INTERFACE_H_INCLUDES = frozenset([
+ 'bindings/v8/V8Binding.h',
+ 'bindings/v8/V8DOMWrapper.h',
+ 'bindings/v8/WrapperTypeInfo.h',
+ 'platform/heap/Handle.h',
+])
+INTERFACE_CPP_INCLUDES = frozenset([
+ 'bindings/v8/ExceptionState.h',
+ 'bindings/v8/V8DOMConfiguration.h',
+ 'bindings/v8/V8HiddenValue.h',
+ 'bindings/v8/V8ObjectConstructor.h',
+ 'core/dom/ContextFeatures.h',
+ 'core/dom/Document.h',
+ 'platform/RuntimeEnabledFeatures.h',
+ 'platform/TraceEvent.h',
+ 'wtf/GetPtr.h',
+ 'wtf/RefPtr.h',
+])
+
+
+def generate_interface(interface):
+ includes.clear()
+ includes.update(INTERFACE_CPP_INCLUDES)
+ header_includes = set(INTERFACE_H_INCLUDES)
+
+ parent_interface = interface.parent
+ if parent_interface:
+ header_includes.update(v8_types.includes_for_interface(parent_interface))
+ extended_attributes = interface.extended_attributes
+
+ is_audio_buffer = inherits_interface(interface.name, 'AudioBuffer')
+ if is_audio_buffer:
+ includes.add('modules/webaudio/AudioBuffer.h')
+
+ is_document = inherits_interface(interface.name, 'Document')
+ if is_document:
+ includes.update(['bindings/v8/ScriptController.h',
+ 'bindings/v8/V8WindowShell.h',
+ 'core/frame/LocalFrame.h'])
+
+ # [ActiveDOMObject]
+ is_active_dom_object = 'ActiveDOMObject' in extended_attributes
+
+ # [CheckSecurity]
+ is_check_security = 'CheckSecurity' in extended_attributes
+ if is_check_security:
+ includes.add('bindings/v8/BindingSecurity.h')
+
+ # [DependentLifetime]
+ is_dependent_lifetime = 'DependentLifetime' in extended_attributes
+
+ # [MeasureAs]
+ is_measure_as = 'MeasureAs' in extended_attributes
+ if is_measure_as:
+ includes.add('core/frame/UseCounter.h')
+
+ # [SetWrapperReferenceFrom]
+ reachable_node_function = extended_attributes.get('SetWrapperReferenceFrom')
+ if reachable_node_function:
+ includes.update(['bindings/v8/V8GCController.h',
+ 'core/dom/Element.h'])
+
+ # [SetWrapperReferenceTo]
+ set_wrapper_reference_to_list = [{
+ 'name': argument.name,
+ # FIXME: properly should be:
+ # 'cpp_type': argument.idl_type.cpp_type_args(used_as_argument=True),
+ # (if type is non-wrapper type like NodeFilter, normally RefPtr)
+ # Raw pointers faster though, and NodeFilter hacky anyway.
+ 'cpp_type': argument.idl_type.implemented_as + '*',
+ 'idl_type': argument.idl_type,
+ 'v8_type': v8_types.v8_type(argument.idl_type.name),
+ } for argument in extended_attributes.get('SetWrapperReferenceTo', [])]
+ for set_wrapper_reference_to in set_wrapper_reference_to_list:
+ set_wrapper_reference_to['idl_type'].add_includes_for_type()
+
+ # [SpecialWrapFor]
+ if 'SpecialWrapFor' in extended_attributes:
+ special_wrap_for = extended_attributes['SpecialWrapFor'].split('|')
+ else:
+ special_wrap_for = []
+ for special_wrap_interface in special_wrap_for:
+ v8_types.add_includes_for_interface(special_wrap_interface)
+
+ # [Custom=Wrap], [SetWrapperReferenceFrom]
+ has_visit_dom_wrapper = (
+ has_extended_attribute_value(interface, 'Custom', 'VisitDOMWrapper') or
+ reachable_node_function or
+ set_wrapper_reference_to_list)
+
+ this_gc_type = gc_type(interface)
+
+ template_contents = {
+ 'conditional_string': conditional_string(interface), # [Conditional]
+ 'cpp_class': cpp_name(interface),
+ 'gc_type': this_gc_type,
+ 'has_custom_legacy_call_as_function': has_extended_attribute_value(interface, 'Custom', 'LegacyCallAsFunction'), # [Custom=LegacyCallAsFunction]
+ 'has_custom_to_v8': has_extended_attribute_value(interface, 'Custom', 'ToV8'), # [Custom=ToV8]
+ 'has_custom_wrap': has_extended_attribute_value(interface, 'Custom', 'Wrap'), # [Custom=Wrap]
+ 'has_visit_dom_wrapper': has_visit_dom_wrapper,
+ 'header_includes': header_includes,
+ 'interface_name': interface.name,
+ 'is_active_dom_object': is_active_dom_object,
+ 'is_audio_buffer': is_audio_buffer,
+ 'is_check_security': is_check_security,
+ 'is_dependent_lifetime': is_dependent_lifetime,
+ 'is_document': is_document,
+ 'is_event_target': inherits_interface(interface.name, 'EventTarget'),
+ 'is_exception': interface.is_exception,
+ 'is_node': inherits_interface(interface.name, 'Node'),
+ 'measure_as': v8_utilities.measure_as(interface), # [MeasureAs]
+ 'parent_interface': parent_interface,
+ 'pass_cpp_type': cpp_template_type(
+ cpp_ptr_type('PassRefPtr', 'RawPtr', this_gc_type),
+ cpp_name(interface)),
+ 'reachable_node_function': reachable_node_function,
+ 'runtime_enabled_function': runtime_enabled_function_name(interface), # [RuntimeEnabled]
+ 'set_wrapper_reference_to_list': set_wrapper_reference_to_list,
+ 'special_wrap_for': special_wrap_for,
+ 'v8_class': v8_utilities.v8_class_name(interface),
+ 'wrapper_configuration': 'WrapperConfiguration::Dependent'
+ if (has_visit_dom_wrapper or
+ is_active_dom_object or
+ is_dependent_lifetime)
+ else 'WrapperConfiguration::Independent',
+ }
+
+ # Constructors
+ constructors = [generate_constructor(interface, constructor)
+ for constructor in interface.constructors
+ # FIXME: shouldn't put named constructors with constructors
+ # (currently needed for Perl compatibility)
+ # Handle named constructors separately
+ if constructor.name == 'Constructor']
+ if len(constructors) > 1:
+ template_contents['constructor_overloads'] = generate_overloads(constructors)
+
+ # [CustomConstructor]
+ custom_constructors = [{ # Only needed for computing interface length
+ 'number_of_required_arguments':
+ number_of_required_arguments(constructor),
+ } for constructor in interface.custom_constructors]
+
+ # [EventConstructor]
+ has_event_constructor = 'EventConstructor' in extended_attributes
+ any_type_attributes = [attribute for attribute in interface.attributes
+ if attribute.idl_type.name == 'Any']
+ if has_event_constructor:
+ includes.add('bindings/v8/Dictionary.h')
+ if any_type_attributes:
+ includes.add('bindings/v8/SerializedScriptValue.h')
+
+ # [NamedConstructor]
+ named_constructor = generate_named_constructor(interface)
+
+ if (constructors or custom_constructors or has_event_constructor or
+ named_constructor):
+ includes.add('bindings/v8/V8ObjectConstructor.h')
+ includes.add('core/frame/LocalDOMWindow.h')
+
+ template_contents.update({
+ 'any_type_attributes': any_type_attributes,
+ 'constructors': constructors,
+ 'has_custom_constructor': bool(custom_constructors),
+ 'has_event_constructor': has_event_constructor,
+ 'interface_length':
+ interface_length(interface, constructors + custom_constructors),
+ 'is_constructor_call_with_document': has_extended_attribute_value(
+ interface, 'ConstructorCallWith', 'Document'), # [ConstructorCallWith=Document]
+ 'is_constructor_call_with_execution_context': has_extended_attribute_value(
+ interface, 'ConstructorCallWith', 'ExecutionContext'), # [ConstructorCallWith=ExeuctionContext]
+ 'is_constructor_raises_exception': extended_attributes.get('RaisesException') == 'Constructor', # [RaisesException=Constructor]
+ 'named_constructor': named_constructor,
+ })
+
+ # Constants
+ template_contents.update({
+ 'constants': [generate_constant(constant) for constant in interface.constants],
+ 'do_not_check_constants': 'DoNotCheckConstants' in extended_attributes,
+ })
+
+ # Attributes
+ attributes = [v8_attributes.generate_attribute(interface, attribute)
+ for attribute in interface.attributes]
+ template_contents.update({
+ 'attributes': attributes,
+ 'has_accessors': any(attribute['is_expose_js_accessors'] for attribute in attributes),
+ 'has_attribute_configuration': any(
+ not (attribute['is_expose_js_accessors'] or
+ attribute['is_static'] or
+ attribute['runtime_enabled_function'] or
+ attribute['per_context_enabled_function'])
+ for attribute in attributes),
+ 'has_constructor_attributes': any(attribute['constructor_type'] for attribute in attributes),
+ 'has_per_context_enabled_attributes': any(attribute['per_context_enabled_function'] for attribute in attributes),
+ 'has_replaceable_attributes': any(attribute['is_replaceable'] for attribute in attributes),
+ })
+
+ # Methods
+ methods = [v8_methods.generate_method(interface, method)
+ for method in interface.operations
+ if method.name] # Skip anonymous special operations (methods)
+ generate_method_overloads(methods)
+
+ per_context_enabled_methods = []
+ custom_registration_methods = []
+ method_configuration_methods = []
+
+ for method in methods:
+ # Skip all but one method in each set of overloaded methods.
+ if 'overload_index' in method and 'overloads' not in method:
+ continue
+
+ if 'overloads' in method:
+ overloads = method['overloads']
+ per_context_enabled_function = overloads['per_context_enabled_function_all']
+ runtime_enabled_function = overloads['runtime_enabled_function_all']
+ has_custom_registration = overloads['has_custom_registration_all']
+ else:
+ per_context_enabled_function = method['per_context_enabled_function']
+ runtime_enabled_function = method['runtime_enabled_function']
+ has_custom_registration = method['has_custom_registration']
+
+ if per_context_enabled_function:
+ per_context_enabled_methods.append(method)
+ continue
+ if runtime_enabled_function or has_custom_registration:
+ custom_registration_methods.append(method)
+ continue
+ method_configuration_methods.append(method)
+
+ for method in methods:
+ # The value of the Function object’s “length” property is a Number
+ # determined as follows:
+ # 1. Let S be the effective overload set for regular operations (if the
+ # operation is a regular operation) or for static operations (if the
+ # operation is a static operation) with identifier id on interface I and
+ # with argument count 0.
+ # 2. Return the length of the shortest argument list of the entries in S.
+ # FIXME: This calculation doesn't take into account whether runtime
+ # enabled overloads are actually enabled, so length may be incorrect.
+ # E.g., [RuntimeEnabled=Foo] void f(); void f(long x);
+ # should have length 1 if Foo is not enabled, but length 0 if it is.
+ method['length'] = (method['overloads']['minarg'] if 'overloads' in method else
+ method['number_of_required_arguments'])
+
+ template_contents.update({
+ 'custom_registration_methods': custom_registration_methods,
+ 'has_origin_safe_method_setter': any(
+ method['is_check_security_for_frame'] and not method['is_read_only']
+ for method in methods),
+ 'method_configuration_methods': method_configuration_methods,
+ 'per_context_enabled_methods': per_context_enabled_methods,
+ 'methods': methods,
+ })
+
+ template_contents.update({
+ 'indexed_property_getter': indexed_property_getter(interface),
+ 'indexed_property_setter': indexed_property_setter(interface),
+ 'indexed_property_deleter': indexed_property_deleter(interface),
+ 'is_override_builtins': 'OverrideBuiltins' in extended_attributes,
+ 'named_property_getter': named_property_getter(interface),
+ 'named_property_setter': named_property_setter(interface),
+ 'named_property_deleter': named_property_deleter(interface),
+ })
+
+ return template_contents
+
+
+# [DeprecateAs], [Reflect], [RuntimeEnabled]
+def generate_constant(constant):
+ # (Blink-only) string literals are unquoted in tokenizer, must be re-quoted
+ # in C++.
+ if constant.idl_type.name == 'String':
+ value = '"%s"' % constant.value
+ else:
+ value = constant.value
+
+ extended_attributes = constant.extended_attributes
+ return {
+ 'cpp_class': extended_attributes.get('PartialInterfaceImplementedAs'),
+ 'name': constant.name,
+ # FIXME: use 'reflected_name' as correct 'name'
+ 'reflected_name': extended_attributes.get('Reflect', constant.name),
+ 'runtime_enabled_function': runtime_enabled_function_name(constant),
+ 'value': value,
+ }
+
+
+################################################################################
+# Overloads
+################################################################################
+
+def generate_method_overloads(methods):
+ # Regular methods
+ generate_overloads_by_type([method for method in methods
+ if not method['is_static']])
+ # Static methods
+ generate_overloads_by_type([method for method in methods
+ if method['is_static']])
+
+
+def generate_overloads_by_type(methods):
+ """Generates |method.overload*| template values.
+
+ Called separately for static and non-static (regular) methods,
+ as these are overloaded separately.
+ Modifies |method| in place for |method| in |methods|.
+ Doesn't change the |methods| list itself (only the values, i.e. individual
+ methods), so ok to treat these separately.
+ """
+ # Add overload information only to overloaded methods, so template code can
+ # easily verify if a function is overloaded
+ for name, overloads in method_overloads_by_name(methods):
+ # Resolution function is generated after last overloaded function;
+ # package necessary information into |method.overloads| for that method.
+ overloads[-1]['overloads'] = generate_overloads(overloads)
+ overloads[-1]['overloads']['name'] = name
+
+
+def method_overloads_by_name(methods):
+ """Returns generator of overloaded methods by name: [name, [method]]"""
+ # Filter to only methods that are actually overloaded
+ method_counts = Counter(method['name'] for method in methods)
+ overloaded_method_names = set(name
+ for name, count in method_counts.iteritems()
+ if count > 1)
+ overloaded_methods = [method for method in methods
+ if method['name'] in overloaded_method_names]
+
+ # Group by name (generally will be defined together, but not necessarily)
+ return sort_and_groupby(overloaded_methods, itemgetter('name'))
+
+
+def generate_overloads(overloads):
+ """Returns |overloads| template values for a single name.
+
+ Sets |method.overload_index| in place for |method| in |overloads|
+ and returns dict of overall overload template values.
+ """
+ assert len(overloads) > 1 # only apply to overloaded names
+ for index, method in enumerate(overloads, 1):
+ method['overload_index'] = index
+
+ effective_overloads_by_length = effective_overload_set_by_length(overloads)
+ lengths = [length for length, _ in effective_overloads_by_length]
+ name = overloads[0].get('name', '<constructor>')
+
+ # Check and fail if all overloads with the shortest acceptable arguments
+ # list are runtime enabled, since we would otherwise set 'length' on the
+ # function object to an incorrect value when none of those overloads were
+ # actually enabled at runtime. The exception is if all overloads are
+ # controlled by the same runtime enabled feature, in which case there would
+ # be no function object at all if it is not enabled.
+ shortest_overloads = effective_overloads_by_length[0][1]
+ if (all(method.get('runtime_enabled_function')
+ for method, _, _ in shortest_overloads) and
+ not common_value(overloads, 'runtime_enabled_function')):
+ raise ValueError('Function.length of %s depends on runtime enabled features' % name)
+
+ # Check and fail if overloads disagree on any of the extended attributes
+ # that affect how the method should be registered.
+ # Skip the check for overloaded constructors, since they don't support any
+ # of the extended attributes in question.
+ if not overloads[0].get('is_constructor'):
+ overload_extended_attributes = [
+ method['custom_registration_extended_attributes']
+ for method in overloads]
+ for extended_attribute in v8_methods.CUSTOM_REGISTRATION_EXTENDED_ATTRIBUTES:
+ if common_key(overload_extended_attributes, extended_attribute) is None:
+ raise ValueError('Overloads of %s have conflicting extended attribute %s'
+ % (name, extended_attribute))
+
+ return {
+ 'deprecate_all_as': common_value(overloads, 'deprecate_as'), # [DeprecateAs]
+ 'length_tests_methods': length_tests_methods(effective_overloads_by_length),
+ 'minarg': lengths[0],
+ # 1. Let maxarg be the length of the longest type list of the
+ # entries in S.
+ 'maxarg': lengths[-1],
+ 'measure_all_as': common_value(overloads, 'measure_as'), # [MeasureAs]
+ 'has_custom_registration_all': common_value(overloads, 'has_custom_registration'),
+ 'per_context_enabled_function_all': common_value(overloads, 'per_context_enabled_function'), # [PerContextEnabled]
+ 'runtime_enabled_function_all': common_value(overloads, 'runtime_enabled_function'), # [RuntimeEnabled]
+ 'valid_arities': lengths
+ # Only need to report valid arities if there is a gap in the
+ # sequence of possible lengths, otherwise invalid length means
+ # "not enough arguments".
+ if lengths[-1] - lengths[0] != len(lengths) - 1 else None,
+ }
+
+
+def effective_overload_set(F):
+ """Returns the effective overload set of an overloaded function.
+
+ An effective overload set is the set of overloaded functions + signatures
+ (type list of arguments, with optional and variadic arguments included or
+ not), and is used in the overload resolution algorithm.
+
+ For example, given input [f1(optional long x), f2(DOMString s)], the output
+ is informally [f1(), f1(long), f2(DOMString)], and formally
+ [(f1, [], []), (f1, [long], [optional]), (f2, [DOMString], [required])].
+
+ Currently the optionality list is a list of |is_optional| booleans (True
+ means optional, False means required); to support variadics this needs to
+ be tri-valued as required, optional, or variadic.
+
+ Formally:
+ An effective overload set represents the allowable invocations for a
+ particular operation, constructor (specified with [Constructor] or
+ [NamedConstructor]), legacy caller or callback function.
+
+ An additional argument N (argument count) is needed when overloading
+ variadics, but we don't use that currently.
+
+ Spec: http://heycam.github.io/webidl/#dfn-effective-overload-set
+
+ Formally the input and output lists are sets, but methods are stored
+ internally as dicts, which can't be stored in a set because they are not
+ hashable, so we use lists instead.
+
+ Arguments:
+ F: list of overloads for a given callable name.
+
+ Returns:
+ S: list of tuples of the form (callable, type list, optionality list).
+ """
+ # Code closely follows the algorithm in the spec, for clarity and
+ # correctness, and hence is not very Pythonic.
+
+ # 1. Initialize S to ∅.
+ # (We use a list because we can't use a set, as noted above.)
+ S = []
+
+ # 2. Let F be a set with elements as follows, according to the kind of
+ # effective overload set:
+ # (Passed as argument, nothing to do.)
+
+ # 3. & 4. (maxarg, m) are only needed for variadics, not used.
+
+ # 5. For each operation, extended attribute or callback function X in F:
+ for X in F: # X is the "callable", F is the overloads.
+ arguments = X['arguments']
+ # 1. Let n be the number of arguments X is declared to take.
+ n = len(arguments)
+ # 2. Let t0..n−1 be a list of types, where ti is the type of X’s
+ # argument at index i.
+ # (“type list”)
+ t = tuple(argument['idl_type_object'] for argument in arguments)
+ # 3. Let o0..n−1 be a list of optionality values, where oi is “variadic”
+ # if X’s argument at index i is a final, variadic argument, “optional”
+ # if the argument is optional, and “required” otherwise.
+ # (“optionality list”)
+ # (We’re just using a boolean for optional vs. required.)
+ o = tuple(argument['is_optional'] for argument in arguments)
+ # 4. Add to S the tuple <X, t0..n−1, o0..n−1>.
+ S.append((X, t, o))
+ # 5. If X is declared to be variadic, then:
+ # (Not used, so not implemented.)
+ # 6. Initialize i to n−1.
+ i = n - 1
+ # 7. While i ≥ 0:
+ # Spec bug (fencepost error); should be “While i > 0:”
+ # https://www.w3.org/Bugs/Public/show_bug.cgi?id=25590
+ while i > 0:
+ # 1. If argument i of X is not optional, then break this loop.
+ if not o[i]:
+ break
+ # 2. Otherwise, add to S the tuple <X, t0..i−1, o0..i−1>.
+ S.append((X, t[:i], o[:i]))
+ # 3. Set i to i−1.
+ i = i - 1
+ # 8. If n > 0 and all arguments of X are optional, then add to S the
+ # tuple <X, (), ()> (where “()” represents the empty list).
+ if n > 0 and all(oi for oi in o):
+ S.append((X, [], []))
+ # 6. The effective overload set is S.
+ return S
+
+
+def effective_overload_set_by_length(overloads):
+ def type_list_length(entry):
+ # Entries in the effective overload set are 3-tuples:
+ # (callable, type list, optionality list)
+ return len(entry[1])
+
+ effective_overloads = effective_overload_set(overloads)
+ return list(sort_and_groupby(effective_overloads, type_list_length))
+
+
+def distinguishing_argument_index(entries):
+ """Returns the distinguishing argument index for a sequence of entries.
+
+ Entries are elements of the effective overload set with the same number
+ of arguments (formally, same type list length), each a 3-tuple of the form
+ (callable, type list, optionality list).
+
+ Spec: http://heycam.github.io/webidl/#dfn-distinguishing-argument-index
+
+ If there is more than one entry in an effective overload set that has a
+ given type list length, then for those entries there must be an index i
+ such that for each pair of entries the types at index i are
+ distinguishable.
+ The lowest such index is termed the distinguishing argument index for the
+ entries of the effective overload set with the given type list length.
+ """
+ # Only applicable “If there is more than one entry”
+ assert len(entries) > 1
+ type_lists = [tuple(idl_type.name for idl_type in entry[1])
+ for entry in entries]
+ type_list_length = len(type_lists[0])
+ # Only applicable for entries that “[have] a given type list length”
+ assert all(len(type_list) == type_list_length for type_list in type_lists)
+ name = entries[0][0].get('name', 'Constructor') # for error reporting
+
+ # The spec defines the distinguishing argument index by conditions it must
+ # satisfy, but does not give an algorithm.
+ #
+ # We compute the distinguishing argument index by first computing the
+ # minimum index where not all types are the same, and then checking that
+ # all types in this position are distinguishable (and the optionality lists
+ # up to this point are identical), since "minimum index where not all types
+ # are the same" is a *necessary* condition, and more direct to check than
+ # distinguishability.
+ types_by_index = (set(types) for types in zip(*type_lists))
+ try:
+ # “In addition, for each index j, where j is less than the
+ # distinguishing argument index for a given type list length, the types
+ # at index j in all of the entries’ type lists must be the same”
+ index = next(i for i, types in enumerate(types_by_index)
+ if len(types) > 1)
+ except StopIteration:
+ raise ValueError('No distinguishing index found for %s, length %s:\n'
+ 'All entries have the same type list:\n'
+ '%s' % (name, type_list_length, type_lists[0]))
+ # Check optionality
+ # “and the booleans in the corresponding list indicating argument
+ # optionality must be the same.”
+ # FIXME: spec typo: optionality value is no longer a boolean
+ # https://www.w3.org/Bugs/Public/show_bug.cgi?id=25628
+ initial_optionality_lists = set(entry[2][:index] for entry in entries)
+ if len(initial_optionality_lists) > 1:
+ raise ValueError(
+ 'Invalid optionality lists for %s, length %s:\n'
+ 'Optionality lists differ below distinguishing argument index %s:\n'
+ '%s'
+ % (name, type_list_length, index, set(initial_optionality_lists)))
+
+ # Check distinguishability
+ # http://heycam.github.io/webidl/#dfn-distinguishable
+ # Use names to check for distinct types, since objects are distinct
+ # FIXME: check distinguishability more precisely, for validation
+ distinguishing_argument_type_names = [type_list[index]
+ for type_list in type_lists]
+ if (len(set(distinguishing_argument_type_names)) !=
+ len(distinguishing_argument_type_names)):
+ raise ValueError('Types in distinguishing argument are not distinct:\n'
+ '%s' % distinguishing_argument_type_names)
+
+ return index
+
+
+def length_tests_methods(effective_overloads_by_length):
+ """Returns sorted list of resolution tests and associated methods, by length.
+
+ This builds the main data structure for the overload resolution loop.
+ For a given argument length, bindings test argument at distinguishing
+ argument index, in order given by spec: if it is compatible with
+ (optionality or) type required by an overloaded method, resolve to that
+ method.
+
+ Returns:
+ [(length, [(test, method)])]
+ """
+ return [(length, list(resolution_tests_methods(effective_overloads)))
+ for length, effective_overloads in effective_overloads_by_length]
+
+
+def resolution_tests_methods(effective_overloads):
+ """Yields resolution test and associated method, in resolution order, for effective overloads of a given length.
+
+ This is the heart of the resolution algorithm.
+ http://heycam.github.io/webidl/#dfn-overload-resolution-algorithm
+
+ Note that a given method can be listed multiple times, with different tests!
+ This is to handle implicit type conversion.
+
+ Returns:
+ [(test, method)]
+ """
+ methods = [effective_overload[0]
+ for effective_overload in effective_overloads]
+ if len(methods) == 1:
+ # If only one method with a given length, no test needed
+ yield 'true', methods[0]
+ return
+
+ # 6. If there is more than one entry in S, then set d to be the
+ # distinguishing argument index for the entries of S.
+ index = distinguishing_argument_index(effective_overloads)
+ # (7-9 are for handling |undefined| values for optional arguments before
+ # the distinguishing argument (as “missing”), so you can specify only some
+ # optional arguments. We don’t support this, so we skip these steps.)
+ # 10. If i = d, then:
+ # (d is the distinguishing argument index)
+ # 1. Let V be argi.
+ # Note: This is the argument that will be used to resolve which
+ # overload is selected.
+ cpp_value = 'info[%s]' % index
+
+ # Extract argument and IDL type to simplify accessing these in each loop.
+ arguments = [method['arguments'][index] for method in methods]
+ arguments_methods = zip(arguments, methods)
+ idl_types = [argument['idl_type_object'] for argument in arguments]
+ idl_types_methods = zip(idl_types, methods)
+
+ # We can’t do a single loop through all methods or simply sort them, because
+ # a method may be listed in multiple steps of the resolution algorithm, and
+ # which test to apply differs depending on the step.
+ #
+ # Instead, we need to go through all methods at each step, either finding
+ # first match (if only one test is allowed) or filtering to matches (if
+ # multiple tests are allowed), and generating an appropriate tests.
+
+ # 2. If V is undefined, and there is an entry in S whose list of
+ # optionality values has “optional” at index i, then remove from S all
+ # other entries.
+ try:
+ method = next(method for argument, method in arguments_methods
+ if argument['is_optional'])
+ test = '%s->IsUndefined()' % cpp_value
+ yield test, method
+ except StopIteration:
+ pass
+
+ # 3. Otherwise: if V is null or undefined, and there is an entry in S that
+ # has one of the following types at position i of its type list,
+ # • a nullable type
+ try:
+ method = next(method for idl_type, method in idl_types_methods
+ if idl_type.is_nullable)
+ test = 'isUndefinedOrNull(%s)' % cpp_value
+ yield test, method
+ except StopIteration:
+ pass
+
+ # 4. Otherwise: if V is a platform object – but not a platform array
+ # object – and there is an entry in S that has one of the following
+ # types at position i of its type list,
+ # • an interface type that V implements
+ # (Unlike most of these tests, this can return multiple methods, since we
+ # test if it implements an interface. Thus we need a for loop, not a next.)
+ # (We distinguish wrapper types from built-in interface types.)
+ for idl_type, method in ((idl_type, method)
+ for idl_type, method in idl_types_methods
+ if idl_type.is_wrapper_type):
+ test = 'V8{idl_type}::hasInstance({cpp_value}, isolate)'.format(idl_type=idl_type.base_type, cpp_value=cpp_value)
+ yield test, method
+
+ # 8. Otherwise: if V is any kind of object except for a native Date object,
+ # a native RegExp object, and there is an entry in S that has one of the
+ # following types at position i of its type list,
+ # • an array type
+ # • a sequence type
+ # ...
+ # • a dictionary
+ try:
+ # FIXME: IDL dictionary not implemented, so use Blink Dictionary
+ # http://crbug.com/321462
+ idl_type, method = next((idl_type, method)
+ for idl_type, method in idl_types_methods
+ if (idl_type.array_or_sequence_type or
+ idl_type.name == 'Dictionary'))
+ if idl_type.array_or_sequence_type:
+ # (We test for Array instead of generic Object to type-check.)
+ # FIXME: test for Object during resolution, then have type check for
+ # Array in overloaded method: http://crbug.com/262383
+ test = '%s->IsArray()' % cpp_value
+ else:
+ # FIXME: should be '{1}->IsObject() && !{1}->IsDate() && !{1}->IsRegExp()'.format(cpp_value)
+ # FIXME: the IsDate and IsRegExp checks can be skipped if we've
+ # already generated tests for them.
+ test = '%s->IsObject()' % cpp_value
+ yield test, method
+ except StopIteration:
+ pass
+
+ # (Check for exact type matches before performing automatic type conversion;
+ # only needed if distinguishing between primitive types.)
+ if len([idl_type.is_primitive_type for idl_type in idl_types]) > 1:
+ # (Only needed if match in step 11, otherwise redundant.)
+ if any(idl_type.name == 'String' or idl_type.is_enum
+ for idl_type in idl_types):
+ # 10. Otherwise: if V is a Number value, and there is an entry in S
+ # that has one of the following types at position i of its type
+ # list,
+ # • a numeric type
+ try:
+ method = next(method for idl_type, method in idl_types_methods
+ if idl_type.is_numeric_type)
+ test = '%s->IsNumber()' % cpp_value
+ yield test, method
+ except StopIteration:
+ pass
+
+ # (Perform automatic type conversion, in order. If any of these match,
+ # that’s the end, and no other tests are needed.) To keep this code simple,
+ # we rely on the C++ compiler's dead code elimination to deal with the
+ # redundancy if both cases below trigger.
+
+ # 11. Otherwise: if there is an entry in S that has one of the following
+ # types at position i of its type list,
+ # • DOMString
+ # • an enumeration type
+ # * ByteString
+ # Blink: ScalarValueString is a pending Web IDL addition
+ try:
+ method = next(method for idl_type, method in idl_types_methods
+ if idl_type.name in ('String',
+ 'ByteString',
+ 'ScalarValueString') or
+ idl_type.is_enum)
+ yield 'true', method
+ except StopIteration:
+ pass
+
+ # 12. Otherwise: if there is an entry in S that has one of the following
+ # types at position i of its type list,
+ # • a numeric type
+ try:
+ method = next(method for idl_type, method in idl_types_methods
+ if idl_type.is_numeric_type)
+ yield 'true', method
+ except StopIteration:
+ pass
+
+
+################################################################################
+# Utility functions
+################################################################################
+
+def Counter(iterable):
+ # Once using Python 2.7, using collections.Counter
+ counter = defaultdict(lambda: 0)
+ for item in iterable:
+ counter[item] += 1
+ return counter
+
+
+def common(dicts, f):
+ """Returns common result of f across an iterable of dicts, or None.
+
+ Call f for each dict and return its result if the same across all dicts.
+ """
+ values = (f(d) for d in dicts)
+ first_value = next(values)
+ if all(value == first_value for value in values):
+ return first_value
+ return None
+
+
+def common_key(dicts, key):
+ """Returns common presence of a key across an iterable of dicts, or None.
+
+ True if all dicts have the key, False if none of the dicts have the key,
+ and None if some but not all dicts have the key.
+ """
+ return common(dicts, lambda d: key in d)
+
+
+def common_value(dicts, key):
+ """Returns common value of a key across an iterable of dicts, or None.
+
+ Auxiliary function for overloads, so can consolidate an extended attribute
+ that appears with the same value on all items in an overload set.
+ """
+ return common(dicts, lambda d: d.get(key))
+
+
+def sort_and_groupby(l, key=None):
+ """Returns a generator of (key, list), sorting and grouping list by key."""
+ l.sort(key=key)
+ return ((k, list(g)) for k, g in itertools.groupby(l, key))
+
+
+################################################################################
+# Constructors
+################################################################################
+
+# [Constructor]
+def generate_constructor(interface, constructor):
+ arguments_need_try_catch = any(v8_methods.argument_needs_try_catch(argument)
+ for argument in constructor.arguments)
+
+ return {
+ 'arguments': [v8_methods.generate_argument(interface, constructor, argument, index)
+ for index, argument in enumerate(constructor.arguments)],
+ 'arguments_need_try_catch': arguments_need_try_catch,
+ 'cpp_type': cpp_template_type(
+ cpp_ptr_type('RefPtr', 'RawPtr', gc_type(interface)),
+ cpp_name(interface)),
+ 'cpp_value': v8_methods.cpp_value(
+ interface, constructor, len(constructor.arguments)),
+ 'has_exception_state':
+ # [RaisesException=Constructor]
+ interface.extended_attributes.get('RaisesException') == 'Constructor' or
+ any(argument for argument in constructor.arguments
+ if argument.idl_type.name == 'SerializedScriptValue' or
+ argument.idl_type.is_integer_type),
+ 'is_constructor': True,
+ 'is_named_constructor': False,
+ 'number_of_required_arguments':
+ number_of_required_arguments(constructor),
+ }
+
+
+# [NamedConstructor]
+def generate_named_constructor(interface):
+ extended_attributes = interface.extended_attributes
+ if 'NamedConstructor' not in extended_attributes:
+ return None
+ # FIXME: parser should return named constructor separately;
+ # included in constructors (and only name stored in extended attribute)
+ # for Perl compatibility
+ idl_constructor = interface.constructors[-1]
+ assert idl_constructor.name == 'NamedConstructor'
+ constructor = generate_constructor(interface, idl_constructor)
+ constructor.update({
+ 'name': extended_attributes['NamedConstructor'],
+ 'is_named_constructor': True,
+ })
+ return constructor
+
+
+def number_of_required_arguments(constructor):
+ return len([argument for argument in constructor.arguments
+ if not argument.is_optional])
+
+
+def interface_length(interface, constructors):
+ # Docs: http://heycam.github.io/webidl/#es-interface-call
+ if 'EventConstructor' in interface.extended_attributes:
+ return 1
+ if not constructors:
+ return 0
+ return min(constructor['number_of_required_arguments']
+ for constructor in constructors)
+
+
+################################################################################
+# Special operations (methods)
+# http://heycam.github.io/webidl/#idl-special-operations
+################################################################################
+
+def property_getter(getter, cpp_arguments):
+ def is_null_expression(idl_type):
+ if idl_type.is_union_type:
+ return ' && '.join('!result%sEnabled' % i
+ for i, _ in enumerate(idl_type.member_types))
+ if idl_type.name == 'String':
+ return 'result.isNull()'
+ if idl_type.is_interface_type:
+ return '!result'
+ return ''
+
+ idl_type = getter.idl_type
+ extended_attributes = getter.extended_attributes
+ is_raises_exception = 'RaisesException' in extended_attributes
+
+ # FIXME: make more generic, so can use v8_methods.cpp_value
+ cpp_method_name = 'impl->%s' % cpp_name(getter)
+
+ if is_raises_exception:
+ cpp_arguments.append('exceptionState')
+ union_arguments = idl_type.union_arguments
+ if union_arguments:
+ cpp_arguments.extend(union_arguments)
+
+ cpp_value = '%s(%s)' % (cpp_method_name, ', '.join(cpp_arguments))
+
+ return {
+ 'cpp_type': idl_type.cpp_type,
+ 'cpp_value': cpp_value,
+ 'is_custom':
+ 'Custom' in extended_attributes and
+ (not extended_attributes['Custom'] or
+ has_extended_attribute_value(getter, 'Custom', 'PropertyGetter')),
+ 'is_custom_property_enumerator': has_extended_attribute_value(
+ getter, 'Custom', 'PropertyEnumerator'),
+ 'is_custom_property_query': has_extended_attribute_value(
+ getter, 'Custom', 'PropertyQuery'),
+ 'is_enumerable': 'NotEnumerable' not in extended_attributes,
+ 'is_null_expression': is_null_expression(idl_type),
+ 'is_raises_exception': is_raises_exception,
+ 'name': cpp_name(getter),
+ 'union_arguments': union_arguments,
+ 'v8_set_return_value': idl_type.v8_set_return_value('result', extended_attributes=extended_attributes, script_wrappable='impl', release=idl_type.release),
+ }
+
+
+def property_setter(setter):
+ idl_type = setter.arguments[1].idl_type
+ extended_attributes = setter.extended_attributes
+ is_raises_exception = 'RaisesException' in extended_attributes
+ return {
+ 'has_type_checking_interface':
+ has_extended_attribute_value(setter, 'TypeChecking', 'Interface') and
+ idl_type.is_wrapper_type,
+ 'idl_type': idl_type.base_type,
+ 'is_custom': 'Custom' in extended_attributes,
+ 'has_exception_state': is_raises_exception or
+ idl_type.is_integer_type,
+ 'is_raises_exception': is_raises_exception,
+ 'name': cpp_name(setter),
+ 'v8_value_to_local_cpp_value': idl_type.v8_value_to_local_cpp_value(
+ extended_attributes, 'v8Value', 'propertyValue'),
+ }
+
+
+def property_deleter(deleter):
+ idl_type = deleter.idl_type
+ if str(idl_type) != 'boolean':
+ raise Exception(
+ 'Only deleters with boolean type are allowed, but type is "%s"' %
+ idl_type)
+ extended_attributes = deleter.extended_attributes
+ return {
+ 'is_custom': 'Custom' in extended_attributes,
+ 'is_raises_exception': 'RaisesException' in extended_attributes,
+ 'name': cpp_name(deleter),
+ }
+
+
+################################################################################
+# Indexed properties
+# http://heycam.github.io/webidl/#idl-indexed-properties
+################################################################################
+
+def indexed_property_getter(interface):
+ try:
+ # Find indexed property getter, if present; has form:
+ # getter TYPE [OPTIONAL_IDENTIFIER](unsigned long ARG1)
+ getter = next(
+ method
+ for method in interface.operations
+ if ('getter' in method.specials and
+ len(method.arguments) == 1 and
+ str(method.arguments[0].idl_type) == 'unsigned long'))
+ except StopIteration:
+ return None
+
+ return property_getter(getter, ['index'])
+
+
+def indexed_property_setter(interface):
+ try:
+ # Find indexed property setter, if present; has form:
+ # setter RETURN_TYPE [OPTIONAL_IDENTIFIER](unsigned long ARG1, ARG_TYPE ARG2)
+ setter = next(
+ method
+ for method in interface.operations
+ if ('setter' in method.specials and
+ len(method.arguments) == 2 and
+ str(method.arguments[0].idl_type) == 'unsigned long'))
+ except StopIteration:
+ return None
+
+ return property_setter(setter)
+
+
+def indexed_property_deleter(interface):
+ try:
+ # Find indexed property deleter, if present; has form:
+ # deleter TYPE [OPTIONAL_IDENTIFIER](unsigned long ARG)
+ deleter = next(
+ method
+ for method in interface.operations
+ if ('deleter' in method.specials and
+ len(method.arguments) == 1 and
+ str(method.arguments[0].idl_type) == 'unsigned long'))
+ except StopIteration:
+ return None
+
+ return property_deleter(deleter)
+
+
+################################################################################
+# Named properties
+# http://heycam.github.io/webidl/#idl-named-properties
+################################################################################
+
+def named_property_getter(interface):
+ try:
+ # Find named property getter, if present; has form:
+ # getter TYPE [OPTIONAL_IDENTIFIER](DOMString ARG1)
+ getter = next(
+ method
+ for method in interface.operations
+ if ('getter' in method.specials and
+ len(method.arguments) == 1 and
+ str(method.arguments[0].idl_type) == 'DOMString'))
+ except StopIteration:
+ return None
+
+ getter.name = getter.name or 'anonymousNamedGetter'
+ return property_getter(getter, ['propertyName'])
+
+
+def named_property_setter(interface):
+ try:
+ # Find named property setter, if present; has form:
+ # setter RETURN_TYPE [OPTIONAL_IDENTIFIER](DOMString ARG1, ARG_TYPE ARG2)
+ setter = next(
+ method
+ for method in interface.operations
+ if ('setter' in method.specials and
+ len(method.arguments) == 2 and
+ str(method.arguments[0].idl_type) == 'DOMString'))
+ except StopIteration:
+ return None
+
+ return property_setter(setter)
+
+
+def named_property_deleter(interface):
+ try:
+ # Find named property deleter, if present; has form:
+ # deleter TYPE [OPTIONAL_IDENTIFIER](DOMString ARG)
+ deleter = next(
+ method
+ for method in interface.operations
+ if ('deleter' in method.specials and
+ len(method.arguments) == 1 and
+ str(method.arguments[0].idl_type) == 'DOMString'))
+ except StopIteration:
+ return None
+
+ return property_deleter(deleter)
diff --git a/chromium/third_party/WebKit/Source/bindings/scripts/v8_methods.py b/chromium/third_party/WebKit/Source/bindings/scripts/v8_methods.py
new file mode 100644
index 00000000000..11486410b0f
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/bindings/scripts/v8_methods.py
@@ -0,0 +1,349 @@
+# Copyright (C) 2013 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.
+
+"""Generate template values for methods.
+
+Extends IdlType and IdlUnionType with property |union_arguments|.
+
+Design doc: http://www.chromium.org/developers/design-documents/idl-compiler
+"""
+
+from idl_types import IdlType, IdlUnionType, inherits_interface
+from v8_globals import includes
+import v8_types
+import v8_utilities
+from v8_utilities import has_extended_attribute_value
+
+
+# Methods with any of these require custom method registration code in the
+# interface's configure*Template() function.
+CUSTOM_REGISTRATION_EXTENDED_ATTRIBUTES = frozenset([
+ 'DoNotCheckSecurity',
+ 'DoNotCheckSignature',
+ 'NotEnumerable',
+ 'ReadOnly',
+ 'Unforgeable',
+])
+
+
+def argument_needs_try_catch(argument):
+ idl_type = argument.idl_type
+ base_type = not idl_type.array_or_sequence_type and idl_type.base_type
+
+ return not (
+ # These cases are handled by separate code paths in the
+ # generate_argument() macro in Source/bindings/templates/methods.cpp.
+ idl_type.is_callback_interface or
+ base_type == 'SerializedScriptValue' or
+ (argument.is_variadic and idl_type.is_wrapper_type) or
+ # String and enumeration arguments converted using one of the
+ # TOSTRING_* macros in Source/bindings/v8/V8BindingMacros.h don't
+ # use a v8::TryCatch.
+ (base_type == 'DOMString' and not argument.is_variadic))
+
+
+def generate_method(interface, method):
+ arguments = method.arguments
+ extended_attributes = method.extended_attributes
+ idl_type = method.idl_type
+ is_static = method.is_static
+ name = method.name
+
+ idl_type.add_includes_for_type()
+ this_cpp_value = cpp_value(interface, method, len(arguments))
+
+ def function_template():
+ if is_static:
+ return 'functionTemplate'
+ if 'Unforgeable' in extended_attributes:
+ return 'instanceTemplate'
+ return 'prototypeTemplate'
+
+ is_call_with_script_arguments = has_extended_attribute_value(method, 'CallWith', 'ScriptArguments')
+ if is_call_with_script_arguments:
+ includes.update(['bindings/v8/ScriptCallStackFactory.h',
+ 'core/inspector/ScriptArguments.h'])
+ is_call_with_script_state = has_extended_attribute_value(method, 'CallWith', 'ScriptState')
+ if is_call_with_script_state:
+ includes.add('bindings/v8/ScriptState.h')
+ is_check_security_for_node = 'CheckSecurity' in extended_attributes
+ if is_check_security_for_node:
+ includes.add('bindings/v8/BindingSecurity.h')
+ is_custom_element_callbacks = 'CustomElementCallbacks' in extended_attributes
+ if is_custom_element_callbacks:
+ includes.add('core/dom/custom/CustomElementCallbackDispatcher.h')
+
+ has_event_listener_argument = any(
+ argument for argument in arguments
+ if argument.idl_type.name == 'EventListener')
+ is_check_security_for_frame = (
+ 'CheckSecurity' in interface.extended_attributes and
+ 'DoNotCheckSecurity' not in extended_attributes)
+ is_raises_exception = 'RaisesException' in extended_attributes
+
+ arguments_need_try_catch = any(argument_needs_try_catch(argument)
+ for argument in arguments)
+
+ return {
+ 'activity_logging_world_list': v8_utilities.activity_logging_world_list(method), # [ActivityLogging]
+ 'arguments': [generate_argument(interface, method, argument, index)
+ for index, argument in enumerate(arguments)],
+ 'arguments_need_try_catch': arguments_need_try_catch,
+ 'conditional_string': v8_utilities.conditional_string(method),
+ 'cpp_type': idl_type.cpp_type,
+ 'cpp_value': this_cpp_value,
+ 'custom_registration_extended_attributes':
+ CUSTOM_REGISTRATION_EXTENDED_ATTRIBUTES.intersection(
+ extended_attributes.iterkeys()),
+ 'deprecate_as': v8_utilities.deprecate_as(method), # [DeprecateAs]
+ 'function_template': function_template(),
+ 'has_custom_registration': is_static or
+ v8_utilities.has_extended_attribute(
+ method, CUSTOM_REGISTRATION_EXTENDED_ATTRIBUTES),
+ 'has_event_listener_argument': has_event_listener_argument,
+ 'has_exception_state':
+ has_event_listener_argument or
+ is_raises_exception or
+ is_check_security_for_frame or
+ any(argument for argument in arguments
+ if argument.idl_type.name in ('ByteString',
+ 'ScalarValueString',
+ 'SerializedScriptValue') or
+ argument.idl_type.is_integer_type),
+ 'idl_type': idl_type.base_type,
+ 'is_call_with_execution_context': has_extended_attribute_value(method, 'CallWith', 'ExecutionContext'),
+ 'is_call_with_script_arguments': is_call_with_script_arguments,
+ 'is_call_with_script_state': is_call_with_script_state,
+ 'is_check_security_for_frame': is_check_security_for_frame,
+ 'is_check_security_for_node': is_check_security_for_node,
+ 'is_custom': 'Custom' in extended_attributes,
+ 'is_custom_element_callbacks': is_custom_element_callbacks,
+ 'is_do_not_check_security': 'DoNotCheckSecurity' in extended_attributes,
+ 'is_do_not_check_signature': 'DoNotCheckSignature' in extended_attributes,
+ 'is_partial_interface_member':
+ 'PartialInterfaceImplementedAs' in extended_attributes,
+ 'is_per_world_bindings': 'PerWorldBindings' in extended_attributes,
+ 'is_raises_exception': is_raises_exception,
+ 'is_read_only': 'ReadOnly' in extended_attributes,
+ 'is_static': is_static,
+ 'is_variadic': arguments and arguments[-1].is_variadic,
+ 'measure_as': v8_utilities.measure_as(method), # [MeasureAs]
+ 'name': name,
+ 'number_of_arguments': len(arguments),
+ 'number_of_required_arguments': len([
+ argument for argument in arguments
+ if not (argument.is_optional or argument.is_variadic)]),
+ 'number_of_required_or_variadic_arguments': len([
+ argument for argument in arguments
+ if not argument.is_optional]),
+ 'per_context_enabled_function': v8_utilities.per_context_enabled_function_name(method), # [PerContextEnabled]
+ 'property_attributes': property_attributes(method),
+ 'runtime_enabled_function': v8_utilities.runtime_enabled_function_name(method), # [RuntimeEnabled]
+ 'signature': 'v8::Local<v8::Signature>()' if is_static or 'DoNotCheckSignature' in extended_attributes else 'defaultSignature',
+ 'union_arguments': idl_type.union_arguments,
+ 'v8_set_return_value_for_main_world': v8_set_return_value(interface.name, method, this_cpp_value, for_main_world=True),
+ 'v8_set_return_value': v8_set_return_value(interface.name, method, this_cpp_value),
+ 'world_suffixes': ['', 'ForMainWorld'] if 'PerWorldBindings' in extended_attributes else [''], # [PerWorldBindings]
+ }
+
+
+def generate_argument(interface, method, argument, index):
+ extended_attributes = argument.extended_attributes
+ idl_type = argument.idl_type
+ this_cpp_value = cpp_value(interface, method, index)
+ is_variadic_wrapper_type = argument.is_variadic and idl_type.is_wrapper_type
+
+ return {
+ 'cpp_type': idl_type.cpp_type_args(extended_attributes=extended_attributes,
+ used_as_argument=True,
+ used_as_variadic_argument=argument.is_variadic),
+ 'cpp_value': this_cpp_value,
+ # FIXME: check that the default value's type is compatible with the argument's
+ 'default_value': str(argument.default_value) if argument.default_value else None,
+ 'enum_validation_expression': idl_type.enum_validation_expression,
+ # FIXME: remove once [Default] removed and just use argument.default_value
+ 'has_default': 'Default' in extended_attributes or argument.default_value,
+ 'has_event_listener_argument': any(
+ argument_so_far for argument_so_far in method.arguments[:index]
+ if argument_so_far.idl_type.name == 'EventListener'),
+ 'has_type_checking_interface':
+ (has_extended_attribute_value(interface, 'TypeChecking', 'Interface') or
+ has_extended_attribute_value(method, 'TypeChecking', 'Interface')) and
+ idl_type.is_wrapper_type,
+ 'has_type_checking_unrestricted':
+ (has_extended_attribute_value(interface, 'TypeChecking', 'Unrestricted') or
+ has_extended_attribute_value(method, 'TypeChecking', 'Unrestricted')) and
+ idl_type.name in ('Float', 'Double'),
+ # Dictionary is special-cased, but arrays and sequences shouldn't be
+ 'idl_type': not idl_type.array_or_sequence_type and idl_type.base_type,
+ 'idl_type_object': idl_type,
+ 'index': index,
+ 'is_clamp': 'Clamp' in extended_attributes,
+ 'is_callback_interface': idl_type.is_callback_interface,
+ 'is_nullable': idl_type.is_nullable,
+ 'is_optional': argument.is_optional,
+ 'is_variadic_wrapper_type': is_variadic_wrapper_type,
+ 'vector_type': v8_types.cpp_ptr_type('Vector', 'HeapVector', idl_type.gc_type),
+ 'is_wrapper_type': idl_type.is_wrapper_type,
+ 'name': argument.name,
+ 'v8_set_return_value_for_main_world': v8_set_return_value(interface.name, method, this_cpp_value, for_main_world=True),
+ 'v8_set_return_value': v8_set_return_value(interface.name, method, this_cpp_value),
+ 'v8_value_to_local_cpp_value': v8_value_to_local_cpp_value(argument, index),
+ }
+
+
+################################################################################
+# Value handling
+################################################################################
+
+def cpp_value(interface, method, number_of_arguments):
+ def cpp_argument(argument):
+ idl_type = argument.idl_type
+ if idl_type.name == 'EventListener':
+ if (interface.name == 'EventTarget' and
+ method.name == 'removeEventListener'):
+ # FIXME: remove this special case by moving get() into
+ # EventTarget::removeEventListener
+ return '%s.get()' % argument.name
+ return argument.name
+ if (idl_type.is_callback_interface or
+ idl_type.name in ['NodeFilter', 'XPathNSResolver']):
+ # FIXME: remove this special case
+ return '%s.release()' % argument.name
+ return argument.name
+
+ # Truncate omitted optional arguments
+ arguments = method.arguments[:number_of_arguments]
+ cpp_arguments = []
+ if method.is_constructor:
+ call_with_values = interface.extended_attributes.get('ConstructorCallWith')
+ else:
+ call_with_values = method.extended_attributes.get('CallWith')
+ cpp_arguments.extend(v8_utilities.call_with_arguments(call_with_values))
+ # Members of IDL partial interface definitions are implemented in C++ as
+ # static member functions, which for instance members (non-static members)
+ # take *impl as their first argument
+ if ('PartialInterfaceImplementedAs' in method.extended_attributes and
+ not method.is_static):
+ cpp_arguments.append('*impl')
+ cpp_arguments.extend(cpp_argument(argument) for argument in arguments)
+ this_union_arguments = method.idl_type and method.idl_type.union_arguments
+ if this_union_arguments:
+ cpp_arguments.extend(this_union_arguments)
+
+ if ('RaisesException' in method.extended_attributes or
+ (method.is_constructor and
+ has_extended_attribute_value(interface, 'RaisesException', 'Constructor'))):
+ cpp_arguments.append('exceptionState')
+
+ if method.name == 'Constructor':
+ base_name = 'create'
+ elif method.name == 'NamedConstructor':
+ base_name = 'createForJSConstructor'
+ else:
+ base_name = v8_utilities.cpp_name(method)
+
+ cpp_method_name = v8_utilities.scoped_name(interface, method, base_name)
+ return '%s(%s)' % (cpp_method_name, ', '.join(cpp_arguments))
+
+
+def v8_set_return_value(interface_name, method, cpp_value, for_main_world=False):
+ idl_type = method.idl_type
+ extended_attributes = method.extended_attributes
+ if not idl_type or idl_type.name == 'void':
+ # Constructors and void methods don't have a return type
+ return None
+
+ release = False
+ # [CallWith=ScriptState], [RaisesException]
+ if (has_extended_attribute_value(method, 'CallWith', 'ScriptState') or
+ 'RaisesException' in extended_attributes or
+ idl_type.is_union_type):
+ cpp_value = 'result' # use local variable for value
+ release = idl_type.release
+
+ script_wrappable = 'impl' if inherits_interface(interface_name, 'Node') else ''
+ return idl_type.v8_set_return_value(cpp_value, extended_attributes, script_wrappable=script_wrappable, release=release, for_main_world=for_main_world)
+
+
+def v8_value_to_local_cpp_variadic_value(argument, index):
+ assert argument.is_variadic
+ idl_type = argument.idl_type
+
+ macro = 'TONATIVE_VOID_INTERNAL'
+ macro_args = [
+ argument.name,
+ 'toNativeArguments<%s>(info, %s)' % (idl_type.cpp_type, index),
+ ]
+
+ return '%s(%s)' % (macro, ', '.join(macro_args))
+
+
+def v8_value_to_local_cpp_value(argument, index):
+ extended_attributes = argument.extended_attributes
+ idl_type = argument.idl_type
+ name = argument.name
+ if argument.is_variadic:
+ return v8_value_to_local_cpp_variadic_value(argument, index)
+ # FIXME: This special way of handling string arguments with null defaults
+ # can go away once we fully support default values.
+ if (argument.is_optional and
+ idl_type.name in ('String', 'ByteString', 'ScalarValueString') and
+ argument.default_value and argument.default_value.is_null):
+ v8_value = 'argumentOrNull(info, %s)' % index
+ else:
+ v8_value = 'info[%s]' % index
+ return idl_type.v8_value_to_local_cpp_value(extended_attributes, v8_value,
+ name, index=index, declare_variable=False)
+
+
+################################################################################
+# Auxiliary functions
+################################################################################
+
+# [NotEnumerable]
+def property_attributes(method):
+ extended_attributes = method.extended_attributes
+ property_attributes_list = []
+ if 'NotEnumerable' in extended_attributes:
+ property_attributes_list.append('v8::DontEnum')
+ if 'ReadOnly' in extended_attributes:
+ property_attributes_list.append('v8::ReadOnly')
+ if property_attributes_list:
+ property_attributes_list.insert(0, 'v8::DontDelete')
+ return property_attributes_list
+
+
+def union_arguments(idl_type):
+ """Return list of ['result0Enabled', 'result0', 'result1Enabled', ...] for union types, for use in setting return value"""
+ return [arg
+ for i in range(len(idl_type.member_types))
+ for arg in ['result%sEnabled' % i, 'result%s' % i]]
+
+IdlType.union_arguments = property(lambda self: None)
+IdlUnionType.union_arguments = property(union_arguments)
diff --git a/chromium/third_party/WebKit/Source/bindings/scripts/v8_types.py b/chromium/third_party/WebKit/Source/bindings/scripts/v8_types.py
new file mode 100644
index 00000000000..5f735af235c
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/bindings/scripts/v8_types.py
@@ -0,0 +1,691 @@
+# Copyright (C) 2013 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.
+
+"""Functions for type handling and type conversion (Blink/C++ <-> V8/JS).
+
+Extends IdlType and IdlUnionType with V8-specific properties, methods, and
+class methods.
+
+Spec:
+http://www.w3.org/TR/WebIDL/#es-type-mapping
+
+Design doc: http://www.chromium.org/developers/design-documents/idl-compiler
+"""
+
+import posixpath
+
+from idl_types import IdlType, IdlUnionType
+import v8_attributes # for IdlType.constructor_type_name
+from v8_globals import includes
+
+
+################################################################################
+# V8-specific handling of IDL types
+################################################################################
+
+NON_WRAPPER_TYPES = frozenset([
+ 'CompareHow',
+ 'Dictionary',
+ 'EventHandler',
+ 'EventListener',
+ 'MediaQueryListListener',
+ 'NodeFilter',
+ 'SerializedScriptValue',
+])
+TYPED_ARRAYS = {
+ # (cpp_type, v8_type), used by constructor templates
+ 'ArrayBuffer': None,
+ 'ArrayBufferView': None,
+ 'Float32Array': ('float', 'v8::kExternalFloatArray'),
+ 'Float64Array': ('double', 'v8::kExternalDoubleArray'),
+ 'Int8Array': ('signed char', 'v8::kExternalByteArray'),
+ 'Int16Array': ('short', 'v8::kExternalShortArray'),
+ 'Int32Array': ('int', 'v8::kExternalIntArray'),
+ 'Uint8Array': ('unsigned char', 'v8::kExternalUnsignedByteArray'),
+ 'Uint8ClampedArray': ('unsigned char', 'v8::kExternalPixelArray'),
+ 'Uint16Array': ('unsigned short', 'v8::kExternalUnsignedShortArray'),
+ 'Uint32Array': ('unsigned int', 'v8::kExternalUnsignedIntArray'),
+}
+
+IdlType.is_typed_array_type = property(
+ lambda self: self.base_type in TYPED_ARRAYS)
+
+
+IdlType.is_wrapper_type = property(
+ lambda self: (self.is_interface_type and
+ self.base_type not in NON_WRAPPER_TYPES))
+
+
+################################################################################
+# C++ types
+################################################################################
+
+CPP_TYPE_SAME_AS_IDL_TYPE = set([
+ 'double',
+ 'float',
+ 'long long',
+ 'unsigned long long',
+])
+CPP_INT_TYPES = set([
+ 'byte',
+ 'long',
+ 'short',
+])
+CPP_UNSIGNED_TYPES = set([
+ 'octet',
+ 'unsigned int',
+ 'unsigned long',
+ 'unsigned short',
+])
+CPP_SPECIAL_CONVERSION_RULES = {
+ 'CompareHow': 'Range::CompareHow',
+ 'Date': 'double',
+ 'Dictionary': 'Dictionary',
+ 'EventHandler': 'EventListener*',
+ 'MediaQueryListListener': 'RefPtrWillBeRawPtr<MediaQueryListListener>',
+ 'NodeFilter': 'RefPtrWillBeRawPtr<NodeFilter>',
+ 'Promise': 'ScriptPromise',
+ 'ScriptValue': 'ScriptValue',
+ # FIXME: Eliminate custom bindings for XPathNSResolver http://crbug.com/345529
+ 'XPathNSResolver': 'RefPtrWillBeRawPtr<XPathNSResolver>',
+ 'boolean': 'bool',
+ 'unrestricted double': 'double',
+ 'unrestricted float': 'float',
+}
+
+
+def cpp_type(idl_type, extended_attributes=None, used_as_argument=False, used_as_variadic_argument=False, used_in_cpp_sequence=False):
+ """Returns C++ type corresponding to IDL type.
+
+ |idl_type| argument is of type IdlType, while return value is a string
+
+ Args:
+ idl_type:
+ IdlType
+ used_as_argument:
+ bool, True if idl_type's raw/primitive C++ type should be returned.
+ used_in_cpp_sequence:
+ bool, True if the C++ type is used as an element of an array or sequence.
+ """
+ def string_mode():
+ # FIXME: the Web IDL spec requires 'EmptyString', not 'NullString',
+ # but we use NullString for performance.
+ if extended_attributes.get('TreatNullAs') != 'NullString':
+ return ''
+ if extended_attributes.get('TreatUndefinedAs') != 'NullString':
+ return 'WithNullCheck'
+ return 'WithUndefinedOrNullCheck'
+
+ extended_attributes = extended_attributes or {}
+ idl_type = idl_type.preprocessed_type
+
+ # Composite types
+ if used_as_variadic_argument:
+ array_or_sequence_type = idl_type
+ else:
+ array_or_sequence_type = idl_type.array_or_sequence_type
+ if array_or_sequence_type:
+ vector_type = cpp_ptr_type('Vector', 'HeapVector', array_or_sequence_type.gc_type)
+ return cpp_template_type(vector_type, array_or_sequence_type.cpp_type_args(used_in_cpp_sequence=True))
+
+ # Simple types
+ base_idl_type = idl_type.base_type
+
+ if base_idl_type in CPP_TYPE_SAME_AS_IDL_TYPE:
+ return base_idl_type
+ if base_idl_type in CPP_INT_TYPES:
+ return 'int'
+ if base_idl_type in CPP_UNSIGNED_TYPES:
+ return 'unsigned'
+ if base_idl_type in CPP_SPECIAL_CONVERSION_RULES:
+ return CPP_SPECIAL_CONVERSION_RULES[base_idl_type]
+
+ if base_idl_type in NON_WRAPPER_TYPES:
+ return 'RefPtr<%s>' % base_idl_type
+ if base_idl_type in ('DOMString', 'ByteString', 'ScalarValueString'):
+ if not used_as_argument:
+ return 'String'
+ return 'V8StringResource<%s>' % string_mode()
+
+ if idl_type.is_typed_array_type and used_as_argument:
+ return base_idl_type + '*'
+ if idl_type.is_interface_type:
+ implemented_as_class = idl_type.implemented_as
+ if used_as_argument:
+ return implemented_as_class + '*'
+ new_type = 'Member' if used_in_cpp_sequence else 'RawPtr'
+ ptr_type = cpp_ptr_type('RefPtr', new_type, idl_type.gc_type)
+ return cpp_template_type(ptr_type, implemented_as_class)
+ # Default, assume native type is a pointer with same type name as idl type
+ return base_idl_type + '*'
+
+
+def cpp_type_union(idl_type, extended_attributes=None, used_as_argument=False):
+ return (member_type.cpp_type for member_type in idl_type.member_types)
+
+
+# Allow access as idl_type.cpp_type if no arguments
+IdlType.cpp_type = property(cpp_type)
+IdlUnionType.cpp_type = property(cpp_type_union)
+IdlType.cpp_type_args = cpp_type
+IdlUnionType.cpp_type_args = cpp_type_union
+
+
+def cpp_template_type(template, inner_type):
+ """Returns C++ template specialized to type, with space added if needed."""
+ if inner_type.endswith('>'):
+ format_string = '{template}<{inner_type} >'
+ else:
+ format_string = '{template}<{inner_type}>'
+ return format_string.format(template=template, inner_type=inner_type)
+
+
+def cpp_ptr_type(old_type, new_type, gc_type):
+ if gc_type == 'GarbageCollectedObject':
+ return new_type
+ if gc_type == 'WillBeGarbageCollectedObject':
+ if old_type == 'Vector':
+ return 'WillBe' + new_type
+ return old_type + 'WillBe' + new_type
+ return old_type
+
+
+def v8_type(interface_name):
+ return 'V8' + interface_name
+
+
+# [ImplementedAs]
+# This handles [ImplementedAs] on interface types, not [ImplementedAs] in the
+# interface being generated. e.g., given:
+# Foo.idl: interface Foo {attribute Bar bar};
+# Bar.idl: [ImplementedAs=Zork] interface Bar {};
+# when generating bindings for Foo, the [ImplementedAs] on Bar is needed.
+# This data is external to Foo.idl, and hence computed as global information in
+# compute_interfaces_info.py to avoid having to parse IDLs of all used interfaces.
+IdlType.implemented_as_interfaces = {}
+
+
+def implemented_as(idl_type):
+ base_idl_type = idl_type.base_type
+ if base_idl_type in IdlType.implemented_as_interfaces:
+ return IdlType.implemented_as_interfaces[base_idl_type]
+ return base_idl_type
+
+
+IdlType.implemented_as = property(implemented_as)
+
+IdlType.set_implemented_as_interfaces = classmethod(
+ lambda cls, new_implemented_as_interfaces:
+ cls.implemented_as_interfaces.update(new_implemented_as_interfaces))
+
+
+# [GarbageCollected]
+IdlType.garbage_collected_types = set()
+
+IdlType.is_garbage_collected = property(
+ lambda self: self.base_type in IdlType.garbage_collected_types)
+
+IdlType.set_garbage_collected_types = classmethod(
+ lambda cls, new_garbage_collected_types:
+ cls.garbage_collected_types.update(new_garbage_collected_types))
+
+
+# [WillBeGarbageCollected]
+IdlType.will_be_garbage_collected_types = set()
+
+IdlType.is_will_be_garbage_collected = property(
+ lambda self: self.base_type in IdlType.will_be_garbage_collected_types)
+
+IdlType.set_will_be_garbage_collected_types = classmethod(
+ lambda cls, new_will_be_garbage_collected_types:
+ cls.will_be_garbage_collected_types.update(new_will_be_garbage_collected_types))
+
+
+def gc_type(idl_type):
+ if idl_type.is_garbage_collected:
+ return 'GarbageCollectedObject'
+ if idl_type.is_will_be_garbage_collected:
+ return 'WillBeGarbageCollectedObject'
+ return 'RefCountedObject'
+
+IdlType.gc_type = property(gc_type)
+
+
+################################################################################
+# Includes
+################################################################################
+
+def includes_for_cpp_class(class_name, relative_dir_posix):
+ return set([posixpath.join('bindings', relative_dir_posix, class_name + '.h')])
+
+
+INCLUDES_FOR_TYPE = {
+ 'object': set(),
+ 'CompareHow': set(),
+ 'Dictionary': set(['bindings/v8/Dictionary.h']),
+ 'EventHandler': set(['bindings/v8/V8AbstractEventListener.h',
+ 'bindings/v8/V8EventListenerList.h']),
+ 'EventListener': set(['bindings/v8/BindingSecurity.h',
+ 'bindings/v8/V8EventListenerList.h',
+ 'core/frame/LocalDOMWindow.h']),
+ 'HTMLCollection': set(['bindings/core/v8/V8HTMLCollection.h',
+ 'core/dom/ClassCollection.h',
+ 'core/dom/TagCollection.h',
+ 'core/html/HTMLCollection.h',
+ 'core/html/HTMLFormControlsCollection.h',
+ 'core/html/HTMLTableRowsCollection.h']),
+ 'MediaQueryListListener': set(['core/css/MediaQueryListListener.h']),
+ 'NodeList': set(['bindings/core/v8/V8NodeList.h',
+ 'core/dom/NameNodeList.h',
+ 'core/dom/NodeList.h',
+ 'core/dom/StaticNodeList.h',
+ 'core/html/LabelsNodeList.h']),
+ 'Promise': set(['bindings/v8/ScriptPromise.h']),
+ 'SerializedScriptValue': set(['bindings/v8/SerializedScriptValue.h']),
+ 'ScriptValue': set(['bindings/v8/ScriptValue.h']),
+}
+
+
+def includes_for_type(idl_type):
+ idl_type = idl_type.preprocessed_type
+
+ # Composite types
+ array_or_sequence_type = idl_type.array_or_sequence_type
+ if array_or_sequence_type:
+ return includes_for_type(array_or_sequence_type)
+
+ # Simple types
+ base_idl_type = idl_type.base_type
+ if base_idl_type in INCLUDES_FOR_TYPE:
+ return INCLUDES_FOR_TYPE[base_idl_type]
+ if idl_type.is_basic_type:
+ return set()
+ if idl_type.is_typed_array_type:
+ return set(['bindings/v8/custom/V8%sCustom.h' % base_idl_type])
+ if base_idl_type.endswith('ConstructorConstructor'):
+ # FIXME: rename to NamedConstructor
+ # FIXME: replace with a [NamedConstructorAttribute] extended attribute
+ # Ending with 'ConstructorConstructor' indicates a named constructor,
+ # and these do not have header files, as they are part of the generated
+ # bindings for the interface
+ return set()
+ if base_idl_type.endswith('Constructor'):
+ # FIXME: replace with a [ConstructorAttribute] extended attribute
+ base_idl_type = idl_type.constructor_type_name
+ return set(['bindings/%s/v8/V8%s.h' % (component_dir[base_idl_type],
+ base_idl_type)])
+
+IdlType.includes_for_type = property(includes_for_type)
+IdlUnionType.includes_for_type = property(
+ lambda self: set.union(*[includes_for_type(member_type)
+ for member_type in self.member_types]))
+
+
+def add_includes_for_type(idl_type):
+ includes.update(idl_type.includes_for_type)
+
+IdlType.add_includes_for_type = add_includes_for_type
+IdlUnionType.add_includes_for_type = add_includes_for_type
+
+
+def includes_for_interface(interface_name):
+ return IdlType(interface_name).includes_for_type
+
+
+def add_includes_for_interface(interface_name):
+ includes.update(includes_for_interface(interface_name))
+
+component_dir = {}
+
+
+def set_component_dirs(new_component_dirs):
+ component_dir.update(new_component_dirs)
+
+
+################################################################################
+# V8 -> C++
+################################################################################
+
+V8_VALUE_TO_CPP_VALUE = {
+ # Basic
+ 'Date': 'toCoreDate({v8_value})',
+ 'DOMString': '{v8_value}',
+ 'ByteString': 'toByteString({arguments})',
+ 'ScalarValueString': 'toScalarValueString({arguments})',
+ 'boolean': '{v8_value}->BooleanValue()',
+ 'float': 'static_cast<float>({v8_value}->NumberValue())',
+ 'unrestricted float': 'static_cast<float>({v8_value}->NumberValue())',
+ 'double': 'static_cast<double>({v8_value}->NumberValue())',
+ 'unrestricted double': 'static_cast<double>({v8_value}->NumberValue())',
+ 'byte': 'toInt8({arguments})',
+ 'octet': 'toUInt8({arguments})',
+ 'short': 'toInt16({arguments})',
+ 'unsigned short': 'toUInt16({arguments})',
+ 'long': 'toInt32({arguments})',
+ 'unsigned long': 'toUInt32({arguments})',
+ 'long long': 'toInt64({arguments})',
+ 'unsigned long long': 'toUInt64({arguments})',
+ # Interface types
+ 'CompareHow': 'static_cast<Range::CompareHow>({v8_value}->Int32Value())',
+ 'Dictionary': 'Dictionary({v8_value}, info.GetIsolate())',
+ 'EventTarget': 'V8DOMWrapper::isDOMWrapper({v8_value}) ? toWrapperTypeInfo(v8::Handle<v8::Object>::Cast({v8_value}))->toEventTarget(v8::Handle<v8::Object>::Cast({v8_value})) : 0',
+ 'MediaQueryListListener': 'MediaQueryListListener::create(ScriptState::current(info.GetIsolate()), ScriptValue(ScriptState::current(info.GetIsolate()), {v8_value}))',
+ 'NodeFilter': 'toNodeFilter({v8_value}, info.Holder(), ScriptState::current(info.GetIsolate()))',
+ 'Promise': 'ScriptPromise::cast(ScriptState::current(info.GetIsolate()), {v8_value})',
+ 'SerializedScriptValue': 'SerializedScriptValue::create({v8_value}, info.GetIsolate())',
+ 'ScriptValue': 'ScriptValue(ScriptState::current(info.GetIsolate()), {v8_value})',
+ 'Window': 'toDOMWindow({v8_value}, info.GetIsolate())',
+ 'XPathNSResolver': 'toXPathNSResolver({v8_value}, info.GetIsolate())',
+}
+
+
+def v8_value_to_cpp_value(idl_type, extended_attributes, v8_value, index):
+ # Composite types
+ array_or_sequence_type = idl_type.array_or_sequence_type
+ if array_or_sequence_type:
+ return v8_value_to_cpp_value_array_or_sequence(array_or_sequence_type, v8_value, index)
+
+ # Simple types
+ idl_type = idl_type.preprocessed_type
+ add_includes_for_type(idl_type)
+ base_idl_type = idl_type.base_type
+
+ if 'EnforceRange' in extended_attributes:
+ arguments = ', '.join([v8_value, 'EnforceRange', 'exceptionState'])
+ elif (idl_type.is_integer_type or # NormalConversion
+ idl_type.name in ('ByteString', 'ScalarValueString')):
+ arguments = ', '.join([v8_value, 'exceptionState'])
+ else:
+ arguments = v8_value
+
+ if base_idl_type in V8_VALUE_TO_CPP_VALUE:
+ cpp_expression_format = V8_VALUE_TO_CPP_VALUE[base_idl_type]
+ elif idl_type.is_typed_array_type:
+ cpp_expression_format = (
+ '{v8_value}->Is{idl_type}() ? '
+ 'V8{idl_type}::toNative(v8::Handle<v8::{idl_type}>::Cast({v8_value})) : 0')
+ else:
+ cpp_expression_format = (
+ 'V8{idl_type}::toNativeWithTypeCheck(info.GetIsolate(), {v8_value})')
+
+ return cpp_expression_format.format(arguments=arguments, idl_type=base_idl_type, v8_value=v8_value)
+
+
+def v8_value_to_cpp_value_array_or_sequence(array_or_sequence_type, v8_value, index):
+ # Index is None for setters, index (starting at 0) for method arguments,
+ # and is used to provide a human-readable exception message
+ if index is None:
+ index = 0 # special case, meaning "setter"
+ else:
+ index += 1 # human-readable index
+ if (array_or_sequence_type.is_interface_type and
+ array_or_sequence_type.name != 'Dictionary'):
+ this_cpp_type = None
+ ref_ptr_type = cpp_ptr_type('RefPtr', 'Member', array_or_sequence_type.gc_type)
+ expression_format = '(to{ref_ptr_type}NativeArray<{array_or_sequence_type}, V8{array_or_sequence_type}>({v8_value}, {index}, info.GetIsolate()))'
+ add_includes_for_type(array_or_sequence_type)
+ else:
+ ref_ptr_type = None
+ this_cpp_type = array_or_sequence_type.cpp_type
+ expression_format = 'toNativeArray<{cpp_type}>({v8_value}, {index}, info.GetIsolate())'
+ expression = expression_format.format(array_or_sequence_type=array_or_sequence_type.name, cpp_type=this_cpp_type, index=index, ref_ptr_type=ref_ptr_type, v8_value=v8_value)
+ return expression
+
+
+def v8_value_to_local_cpp_value(idl_type, extended_attributes, v8_value, variable_name, index=None, declare_variable=True):
+ """Returns an expression that converts a V8 value to a C++ value and stores it as a local value."""
+ this_cpp_type = idl_type.cpp_type_args(extended_attributes=extended_attributes, used_as_argument=True)
+
+ idl_type = idl_type.preprocessed_type
+ cpp_value = v8_value_to_cpp_value(idl_type, extended_attributes, v8_value, index)
+ args = [variable_name, cpp_value]
+ if idl_type.base_type == 'DOMString' and not idl_type.array_or_sequence_type:
+ macro = 'TOSTRING_VOID'
+ elif (idl_type.is_integer_type or
+ idl_type.name in ('ByteString', 'ScalarValueString')):
+ macro = 'TONATIVE_VOID_EXCEPTIONSTATE'
+ args.append('exceptionState')
+ else:
+ macro = 'TONATIVE_VOID'
+
+ # Macros come in several variants, to minimize expensive creation of
+ # v8::TryCatch.
+ suffix = ''
+
+ if declare_variable:
+ args.insert(0, this_cpp_type)
+ else:
+ suffix += '_INTERNAL'
+
+ return '%s(%s)' % (macro + suffix, ', '.join(args))
+
+
+IdlType.v8_value_to_local_cpp_value = v8_value_to_local_cpp_value
+IdlUnionType.v8_value_to_local_cpp_value = v8_value_to_local_cpp_value
+
+
+################################################################################
+# C++ -> V8
+################################################################################
+
+def preprocess_idl_type(idl_type):
+ if idl_type.is_enum:
+ # Enumerations are internally DOMStrings
+ return IdlType('DOMString')
+ if (idl_type.name == 'Any' or idl_type.is_callback_function):
+ return IdlType('ScriptValue')
+ return idl_type
+
+IdlType.preprocessed_type = property(preprocess_idl_type)
+IdlUnionType.preprocessed_type = property(preprocess_idl_type)
+
+
+def preprocess_idl_type_and_value(idl_type, cpp_value, extended_attributes):
+ """Returns IDL type and value, with preliminary type conversions applied."""
+ idl_type = idl_type.preprocessed_type
+ if idl_type.name == 'Promise':
+ idl_type = IdlType('ScriptValue')
+ if idl_type.base_type in ['long long', 'unsigned long long']:
+ # long long and unsigned long long are not representable in ECMAScript;
+ # we represent them as doubles.
+ idl_type = IdlType('double', is_nullable=idl_type.is_nullable)
+ cpp_value = 'static_cast<double>(%s)' % cpp_value
+ # HTML5 says that unsigned reflected attributes should be in the range
+ # [0, 2^31). When a value isn't in this range, a default value (or 0)
+ # should be returned instead.
+ extended_attributes = extended_attributes or {}
+ if ('Reflect' in extended_attributes and
+ idl_type.base_type in ['unsigned long', 'unsigned short']):
+ cpp_value = cpp_value.replace('getUnsignedIntegralAttribute',
+ 'getIntegralAttribute')
+ cpp_value = 'std::max(0, %s)' % cpp_value
+ return idl_type, cpp_value
+
+
+def v8_conversion_type(idl_type, extended_attributes):
+ """Returns V8 conversion type, adding any additional includes.
+
+ The V8 conversion type is used to select the C++ -> V8 conversion function
+ or v8SetReturnValue* function; it can be an idl_type, a cpp_type, or a
+ separate name for the type of conversion (e.g., 'DOMWrapper').
+ """
+ extended_attributes = extended_attributes or {}
+
+ # Composite types
+ array_or_sequence_type = idl_type.array_or_sequence_type
+ if array_or_sequence_type:
+ if array_or_sequence_type.is_interface_type:
+ add_includes_for_type(array_or_sequence_type)
+ return 'array'
+
+ # Simple types
+ base_idl_type = idl_type.base_type
+ # Basic types, without additional includes
+ if base_idl_type in CPP_INT_TYPES:
+ return 'int'
+ if base_idl_type in CPP_UNSIGNED_TYPES:
+ return 'unsigned'
+ if base_idl_type in ('DOMString', 'ByteString', 'ScalarValueString'):
+ if 'TreatReturnedNullStringAs' not in extended_attributes:
+ return base_idl_type
+ treat_returned_null_string_as = extended_attributes['TreatReturnedNullStringAs']
+ if treat_returned_null_string_as == 'Null':
+ return 'StringOrNull'
+ if treat_returned_null_string_as == 'Undefined':
+ return 'StringOrUndefined'
+ raise 'Unrecognized TreatReturnNullStringAs value: "%s"' % treat_returned_null_string_as
+ if idl_type.is_basic_type or base_idl_type == 'ScriptValue':
+ return base_idl_type
+
+ # Data type with potential additional includes
+ add_includes_for_type(idl_type)
+ if base_idl_type in V8_SET_RETURN_VALUE: # Special v8SetReturnValue treatment
+ return base_idl_type
+
+ # Pointer type
+ return 'DOMWrapper'
+
+IdlType.v8_conversion_type = v8_conversion_type
+
+
+V8_SET_RETURN_VALUE = {
+ 'boolean': 'v8SetReturnValueBool(info, {cpp_value})',
+ 'int': 'v8SetReturnValueInt(info, {cpp_value})',
+ 'unsigned': 'v8SetReturnValueUnsigned(info, {cpp_value})',
+ 'DOMString': 'v8SetReturnValueString(info, {cpp_value}, info.GetIsolate())',
+ 'ByteString': 'v8SetReturnValueString(info, {cpp_value}, info.GetIsolate())',
+ 'ScalarValueString': 'v8SetReturnValueString(info, {cpp_value}, info.GetIsolate())',
+ # [TreatNullReturnValueAs]
+ 'StringOrNull': 'v8SetReturnValueStringOrNull(info, {cpp_value}, info.GetIsolate())',
+ 'StringOrUndefined': 'v8SetReturnValueStringOrUndefined(info, {cpp_value}, info.GetIsolate())',
+ 'void': '',
+ # No special v8SetReturnValue* function (set value directly)
+ 'float': 'v8SetReturnValue(info, {cpp_value})',
+ 'unrestricted float': 'v8SetReturnValue(info, {cpp_value})',
+ 'double': 'v8SetReturnValue(info, {cpp_value})',
+ 'unrestricted double': 'v8SetReturnValue(info, {cpp_value})',
+ # No special v8SetReturnValue* function, but instead convert value to V8
+ # and then use general v8SetReturnValue.
+ 'array': 'v8SetReturnValue(info, {cpp_value})',
+ 'Date': 'v8SetReturnValue(info, {cpp_value})',
+ 'EventHandler': 'v8SetReturnValue(info, {cpp_value})',
+ 'ScriptValue': 'v8SetReturnValue(info, {cpp_value})',
+ 'SerializedScriptValue': 'v8SetReturnValue(info, {cpp_value})',
+ # DOMWrapper
+ 'DOMWrapperForMainWorld': 'v8SetReturnValueForMainWorld(info, WTF::getPtr({cpp_value}))',
+ 'DOMWrapperFast': 'v8SetReturnValueFast(info, WTF::getPtr({cpp_value}), {script_wrappable})',
+ 'DOMWrapperDefault': 'v8SetReturnValue(info, {cpp_value})',
+}
+
+
+def v8_set_return_value(idl_type, cpp_value, extended_attributes=None, script_wrappable='', release=False, for_main_world=False):
+ """Returns a statement that converts a C++ value to a V8 value and sets it as a return value.
+
+ """
+ def dom_wrapper_conversion_type():
+ if not script_wrappable:
+ return 'DOMWrapperDefault'
+ if for_main_world:
+ return 'DOMWrapperForMainWorld'
+ return 'DOMWrapperFast'
+
+ idl_type, cpp_value = preprocess_idl_type_and_value(idl_type, cpp_value, extended_attributes)
+ this_v8_conversion_type = idl_type.v8_conversion_type(extended_attributes)
+ # SetReturn-specific overrides
+ if this_v8_conversion_type in ['Date', 'EventHandler', 'ScriptValue', 'SerializedScriptValue', 'array']:
+ # Convert value to V8 and then use general v8SetReturnValue
+ cpp_value = idl_type.cpp_value_to_v8_value(cpp_value, extended_attributes=extended_attributes)
+ if this_v8_conversion_type == 'DOMWrapper':
+ this_v8_conversion_type = dom_wrapper_conversion_type()
+
+ format_string = V8_SET_RETURN_VALUE[this_v8_conversion_type]
+ # FIXME: oilpan: Remove .release() once we remove all RefPtrs from generated code.
+ if release:
+ cpp_value = '%s.release()' % cpp_value
+ statement = format_string.format(cpp_value=cpp_value, script_wrappable=script_wrappable)
+ return statement
+
+
+def v8_set_return_value_union(idl_type, cpp_value, extended_attributes=None, script_wrappable='', release=False, for_main_world=False):
+ """
+ release: can be either False (False for all member types) or
+ a sequence (list or tuple) of booleans (if specified individually).
+ """
+
+ return [
+ member_type.v8_set_return_value(cpp_value + str(i),
+ extended_attributes,
+ script_wrappable,
+ release and release[i],
+ for_main_world)
+ for i, member_type in
+ enumerate(idl_type.member_types)]
+
+IdlType.v8_set_return_value = v8_set_return_value
+IdlUnionType.v8_set_return_value = v8_set_return_value_union
+
+IdlType.release = property(lambda self: self.is_interface_type)
+IdlUnionType.release = property(
+ lambda self: [member_type.is_interface_type
+ for member_type in self.member_types])
+
+
+CPP_VALUE_TO_V8_VALUE = {
+ # Built-in types
+ 'Date': 'v8DateOrNaN({cpp_value}, {isolate})',
+ 'DOMString': 'v8String({isolate}, {cpp_value})',
+ 'ByteString': 'v8String({isolate}, {cpp_value})',
+ 'ScalarValueString': 'v8String({isolate}, {cpp_value})',
+ 'boolean': 'v8Boolean({cpp_value}, {isolate})',
+ 'int': 'v8::Integer::New({isolate}, {cpp_value})',
+ 'unsigned': 'v8::Integer::NewFromUnsigned({isolate}, {cpp_value})',
+ 'float': 'v8::Number::New({isolate}, {cpp_value})',
+ 'unrestricted float': 'v8::Number::New({isolate}, {cpp_value})',
+ 'double': 'v8::Number::New({isolate}, {cpp_value})',
+ 'unrestricted double': 'v8::Number::New({isolate}, {cpp_value})',
+ 'void': 'v8Undefined()',
+ # Special cases
+ 'EventHandler': '{cpp_value} ? v8::Handle<v8::Value>(V8AbstractEventListener::cast({cpp_value})->getListenerObject(impl->executionContext())) : v8::Handle<v8::Value>(v8::Null({isolate}))',
+ 'ScriptValue': '{cpp_value}.v8Value()',
+ 'SerializedScriptValue': '{cpp_value} ? {cpp_value}->deserialize() : v8::Handle<v8::Value>(v8::Null({isolate}))',
+ # General
+ 'array': 'v8Array({cpp_value}, {creation_context}, {isolate})',
+ 'DOMWrapper': 'toV8({cpp_value}, {creation_context}, {isolate})',
+}
+
+
+def cpp_value_to_v8_value(idl_type, cpp_value, isolate='info.GetIsolate()', creation_context='info.Holder()', extended_attributes=None):
+ """Returns an expression that converts a C++ value to a V8 value."""
+ # the isolate parameter is needed for callback interfaces
+ idl_type, cpp_value = preprocess_idl_type_and_value(idl_type, cpp_value, extended_attributes)
+ this_v8_conversion_type = idl_type.v8_conversion_type(extended_attributes)
+ format_string = CPP_VALUE_TO_V8_VALUE[this_v8_conversion_type]
+ statement = format_string.format(cpp_value=cpp_value, isolate=isolate, creation_context=creation_context)
+ return statement
+
+IdlType.cpp_value_to_v8_value = cpp_value_to_v8_value
diff --git a/chromium/third_party/WebKit/Source/bindings/scripts/unstable/v8_utilities.py b/chromium/third_party/WebKit/Source/bindings/scripts/v8_utilities.py
index 4752c45ab8c..112ff114a7e 100644
--- a/chromium/third_party/WebKit/Source/bindings/scripts/unstable/v8_utilities.py
+++ b/chromium/third_party/WebKit/Source/bindings/scripts/v8_utilities.py
@@ -28,24 +28,36 @@
"""Functions shared by various parts of the code generator.
-FIXME: Not currently used in build.
-This is a rewrite of the Perl IDL compiler in Python, but is not complete.
-Once it is complete, we will switch all IDL files over to Python at once.
-Until then, please work on the Perl IDL compiler.
-For details, see bug http://crbug.com/239771
-"""
+Extends IdlType and IdlUnion type with |enum_validation_expression| property.
-# FIXME: eliminate this file if possible
+Design doc: http://www.chromium.org/developers/design-documents/idl-compiler
+"""
import re
+from idl_types import IdlType, IdlUnionType
+import idl_types
from v8_globals import includes
import v8_types
-ACRONYMS = ['CSS', 'HTML', 'IME', 'JS', 'SVG', 'URL', 'WOFF', 'XML', 'XSLT']
+ACRONYMS = [
+ 'CSSOM', # must come *before* CSS to match full acronym
+ 'CSS',
+ 'HTML',
+ 'IME',
+ 'JS',
+ 'SVG',
+ 'URL',
+ 'WOFF',
+ 'XML',
+ 'XSLT',
+]
-# Extended attributes
+################################################################################
+# Extended attribute parsing
+################################################################################
+
def extended_attribute_value_contains(extended_attribute_value, value):
return (extended_attribute_value and
value in re.split('[|&]', extended_attribute_value))
@@ -62,7 +74,10 @@ def has_extended_attribute_value(definition_or_member, name, value):
extended_attribute_value_contains(extended_attributes[name], value))
+################################################################################
# String handling
+################################################################################
+
def capitalize(name):
"""Capitalize first letter or initial acronym (used in setter names)."""
for acronym in ACRONYMS:
@@ -84,58 +99,87 @@ def uncapitalize(name):
"""
for acronym in ACRONYMS:
if name.startswith(acronym):
- name.replace(acronym, acronym.lower())
- return name
+ return name.replace(acronym, acronym.lower())
return name[0].lower() + name[1:]
+################################################################################
# C++
+################################################################################
+
def enum_validation_expression(idl_type):
- if not v8_types.is_enum_type(idl_type):
+ # FIXME: Add IdlEnumType, move property to derived type, and remove this check
+ if not idl_type.is_enum:
return None
return ' || '.join(['string == "%s"' % enum_value
- for enum_value in v8_types.enum_values(idl_type)])
+ for enum_value in idl_type.enum_values])
+IdlType.enum_validation_expression = property(enum_validation_expression)
def scoped_name(interface, definition, base_name):
- if definition.is_static:
- return '%s::%s' % (interface.name, base_name)
- return 'imp->%s' % base_name
+ # partial interfaces are implemented as separate classes, with their members
+ # implemented as static member functions
+ partial_interface_implemented_as = definition.extended_attributes.get('PartialInterfaceImplementedAs')
+ if partial_interface_implemented_as:
+ return '%s::%s' % (partial_interface_implemented_as, base_name)
+ if (definition.is_static or
+ definition.name in ('Constructor', 'NamedConstructor')):
+ return '%s::%s' % (cpp_name(interface), base_name)
+ return 'impl->%s' % base_name
def v8_class_name(interface):
return v8_types.v8_type(interface.name)
+################################################################################
+# Specific extended attributes
+################################################################################
+
# [ActivityLogging]
-def activity_logging_world_list(member, access_type=None):
+def activity_logging_world_list(member, access_type=''):
"""Returns a set of world suffixes for which a definition member has activity logging, for specified access type.
access_type can be 'Getter' or 'Setter' if only checking getting or setting.
"""
- if 'ActivityLogging' not in member.extended_attributes:
+ extended_attributes = member.extended_attributes
+ if 'LogActivity' not in extended_attributes:
return set()
- activity_logging = member.extended_attributes['ActivityLogging']
- # [ActivityLogging=For*] (no prefix, starts with the worlds suffix) means
- # "log for all use (method)/access (attribute)", otherwise check that value
- # agrees with specified access_type (Getter/Setter).
- has_logging = (activity_logging.startswith('For') or
- (access_type and activity_logging.startswith(access_type)))
- if not has_logging:
+ log_activity = extended_attributes['LogActivity']
+ if log_activity and not log_activity.startswith(access_type):
return set()
+
includes.add('bindings/v8/V8DOMActivityLogger.h')
- if activity_logging.endswith('ForIsolatedWorlds'):
- return set([''])
- return set(['', 'ForMainWorld']) # endswith('ForAllWorlds')
+ if 'LogAllWorlds' in extended_attributes:
+ return set(['', 'ForMainWorld'])
+ return set(['']) # At minimum, include isolated worlds.
+
+
+# [ActivityLogging]
+def activity_logging_world_check(member):
+ """Returns if an isolated world check is required when generating activity
+ logging code.
+
+ The check is required when there is no per-world binding code and logging is
+ required only for isolated world.
+ """
+ extended_attributes = member.extended_attributes
+ if 'LogActivity' not in extended_attributes:
+ return False
+ if ('PerWorldBindings' not in extended_attributes and
+ 'LogAllWorlds' not in extended_attributes):
+ return True
+ return False
# [CallWith]
CALL_WITH_ARGUMENTS = {
- 'ScriptState': '&state',
- 'ExecutionContext': 'scriptContext',
+ 'ScriptState': 'scriptState',
+ 'ExecutionContext': 'executionContext',
'ScriptArguments': 'scriptArguments.release()',
- 'ActiveWindow': 'activeDOMWindow()',
- 'FirstWindow': 'firstDOMWindow()',
+ 'ActiveWindow': 'callingDOMWindow(info.GetIsolate())',
+ 'FirstWindow': 'enteredDOMWindow(info.GetIsolate())',
+ 'Document': 'document',
}
# List because key order matters, as we want arguments in deterministic order
CALL_WITH_VALUES = [
@@ -144,12 +188,11 @@ CALL_WITH_VALUES = [
'ScriptArguments',
'ActiveWindow',
'FirstWindow',
+ 'Document',
]
-def call_with_arguments(member, call_with_values=None):
- # Optional parameter so setter can override with [SetterCallWith]
- call_with_values = call_with_values or member.extended_attributes.get('CallWith')
+def call_with_arguments(call_with_values):
if not call_with_values:
return []
return [CALL_WITH_ARGUMENTS[value]
@@ -180,6 +223,16 @@ def deprecate_as(member):
return extended_attributes['DeprecateAs']
+# [GarbageCollected], [WillBeGarbageCollected]
+def gc_type(definition):
+ extended_attributes = definition.extended_attributes
+ if 'GarbageCollected' in extended_attributes:
+ return 'GarbageCollectedObject'
+ elif 'WillBeGarbageCollected' in extended_attributes:
+ return 'WillBeGarbageCollectedObject'
+ return 'RefCountedObject'
+
+
# [ImplementedAs]
def cpp_name(definition_or_member):
extended_attributes = definition_or_member.extended_attributes
diff --git a/chromium/third_party/WebKit/Source/bindings/templates/attributes.cpp b/chromium/third_party/WebKit/Source/bindings/templates/attributes.cpp
index cbbe4192db6..c25e298e314 100644
--- a/chromium/third_party/WebKit/Source/bindings/templates/attributes.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/templates/attributes.cpp
@@ -8,71 +8,104 @@ const v8::FunctionCallbackInfo<v8::Value>& info
const v8::PropertyCallbackInfo<v8::Value>& info
{%- endif %})
{
- {% if attribute.is_unforgeable %}
- v8::Handle<v8::Object> holder = info.This()->FindInstanceInPrototypeChain({{v8_class}}::domTemplate(info.GetIsolate(), worldType(info.GetIsolate())));
+ {% if attribute.is_reflect and not attribute.is_url and
+ attribute.idl_type == 'DOMString' and is_node %}
+ {% set cpp_class, v8_class = 'Element', 'V8Element' %}
+ {% endif %}
+ {# holder #}
+ {% if attribute.is_unforgeable and interface_name != 'Window' %}
+ {# perform lookup first #}
+ {# FIXME: can we remove this lookup? #}
+ v8::Handle<v8::Object> holder = {{v8_class}}::findInstanceInPrototypeChain(info.This(), info.GetIsolate());
if (holder.IsEmpty())
return;
- {{cpp_class}}* imp = {{v8_class}}::toNative(holder);
+ {% elif not attribute.is_static %}
+ v8::Handle<v8::Object> holder = info.Holder();
{% endif %}
+ {# impl #}
{% if attribute.cached_attribute_validation_method %}
- v8::Handle<v8::String> propertyName = v8::String::NewFromUtf8(info.GetIsolate(), "{{attribute.name}}", v8::String::kInternalizedString);
- {{cpp_class}}* imp = {{v8_class}}::toNative(info.Holder());
- if (!imp->{{attribute.cached_attribute_validation_method}}()) {
- v8::Handle<v8::Value> jsValue = info.Holder()->GetHiddenValue(propertyName);
- if (!jsValue.IsEmpty()) {
- v8SetReturnValue(info, jsValue);
+ v8::Handle<v8::String> propertyName = v8AtomicString(info.GetIsolate(), "{{attribute.name}}");
+ {{cpp_class}}* impl = {{v8_class}}::toNative(holder);
+ if (!impl->{{attribute.cached_attribute_validation_method}}()) {
+ v8::Handle<v8::Value> v8Value = V8HiddenValue::getHiddenValue(info.GetIsolate(), holder, propertyName);
+ if (!v8Value.IsEmpty()) {
+ v8SetReturnValue(info, v8Value);
return;
}
}
- {% elif not (attribute.is_static or attribute.is_unforgeable) %}
- {{cpp_class}}* imp = {{v8_class}}::toNative(info.Holder());
+ {% elif not attribute.is_static %}
+ {{cpp_class}}* impl = {{v8_class}}::toNative(holder);
+ {% endif %}
+ {% if interface_name == 'Window' and attribute.idl_type == 'EventHandler' %}
+ if (!impl->document())
+ return;
{% endif %}
+ {# Local variables #}
{% if attribute.is_call_with_execution_context %}
- ExecutionContext* scriptContext = getExecutionContext();
+ ExecutionContext* executionContext = currentExecutionContext(info.GetIsolate());
+ {% endif %}
+ {% if attribute.is_call_with_script_state %}
+ ScriptState* scriptState = ScriptState::current(info.GetIsolate());
{% endif %}
- {# Special cases #}
{% if attribute.is_check_security_for_node or
attribute.is_getter_raises_exception %}
- ExceptionState exceptionState(ExceptionState::GetterContext, "{{attribute.name}}", "{{interface_name}}", info.Holder(), info.GetIsolate());
+ ExceptionState exceptionState(ExceptionState::GetterContext, "{{attribute.name}}", "{{interface_name}}", holder, info.GetIsolate());
+ {% endif %}
+ {% if attribute.is_nullable and not attribute.has_type_checking_nullable %}
+ bool isNull = false;
+ {% endif %}
+ {# FIXME: consider always using a local variable for value #}
+ {% if attribute.cached_attribute_validation_method or
+ attribute.is_getter_raises_exception or
+ attribute.is_nullable or
+ attribute.reflect_only or
+ attribute.idl_type == 'EventHandler' %}
+ {{attribute.cpp_type}} {{attribute.cpp_value}} = {{attribute.cpp_value_original}};
+ {% endif %}
+ {# Checks #}
+ {% if attribute.is_getter_raises_exception %}
+ if (UNLIKELY(exceptionState.throwIfNeeded()))
+ return;
{% endif %}
{% if attribute.is_check_security_for_node %}
- {# FIXME: consider using a local variable to not call getter twice #}
- if (!BindingSecurity::shouldAllowAccessToNode({{attribute.cpp_value}}, exceptionState)) {
+ {# FIXME: use a local variable to not call getter twice #}
+ if (!BindingSecurity::shouldAllowAccessToNode(info.GetIsolate(), {{attribute.cpp_value}}, exceptionState)) {
v8SetReturnValueNull(info);
exceptionState.throwIfNeeded();
return;
}
{% endif %}
- {% if attribute.is_getter_raises_exception %}
- {{attribute.cpp_type}} {{attribute.cpp_value}} = {{attribute.cpp_value_original}};
- if (UNLIKELY(exceptionState.throwIfNeeded()))
- return;
+ {% if attribute.reflect_only %}
+ {{release_only_check(attribute.reflect_only, attribute.reflect_missing,
+ attribute.reflect_invalid, attribute.reflect_empty)
+ | indent}}
{% endif %}
{% if attribute.is_nullable %}
- bool isNull = false;
- {{attribute.cpp_type}} {{attribute.cpp_value}} = {{attribute.cpp_value_original}};
+ {% if attribute.has_type_checking_nullable %}
+ if (!{{attribute.cpp_value}}) {
+ {% else %}
if (isNull) {
+ {% endif %}
v8SetReturnValueNull(info);
return;
}
- {% elif attribute.idl_type == 'EventHandler' or
- attribute.cached_attribute_validation_method %}
- {# FIXME: consider merging all these assign to local variable statements #}
- {{attribute.cpp_type}} {{attribute.cpp_value}} = {{attribute.cpp_value_original}};
{% endif %}
{% if attribute.cached_attribute_validation_method %}
- info.Holder()->SetHiddenValue(propertyName, {{attribute.cpp_value}}.v8Value());
+ V8HiddenValue::setHiddenValue(info.GetIsolate(), holder, propertyName, {{attribute.cpp_value_to_v8_value}});
{% endif %}
- {# End special cases #}
+ {# v8SetReturnValue #}
{% if attribute.is_keep_alive_for_gc %}
- {{attribute.cpp_type}} result = {{attribute.cpp_value}};
- if (result && DOMDataStore::setReturnValueFromWrapper<{{attribute.v8_type}}>(info.GetReturnValue(), result.get()))
+ {# FIXME: merge local variable assignment with above #}
+ {{attribute.cpp_type}} result({{attribute.cpp_value}});
+ if (result && DOMDataStore::setReturnValueFromWrapper{{world_suffix}}<{{attribute.v8_type}}>(info.GetReturnValue(), result.get()))
return;
- v8::Handle<v8::Value> wrapper = toV8(result.get(), info.Holder(), info.GetIsolate());
+ v8::Handle<v8::Value> wrapper = toV8(result.get(), holder, info.GetIsolate());
if (!wrapper.IsEmpty()) {
- V8HiddenPropertyName::setNamedHiddenReference(info.Holder(), "{{attribute.name}}", wrapper);
+ V8HiddenValue::setHiddenValue(info.GetIsolate(), holder, v8AtomicString(info.GetIsolate(), "{{attribute.name}}"), wrapper);
{{attribute.v8_set_return_value}};
}
+ {% elif world_suffix %}
+ {{attribute.v8_set_return_value_for_main_world}};
{% else %}
{{attribute.v8_set_return_value}};
{% endif %}
@@ -80,6 +113,39 @@ const v8::PropertyCallbackInfo<v8::Value>& info
{% endfilter %}
{% endmacro %}
+{######################################}
+{% macro release_only_check(reflect_only_values, reflect_missing,
+ reflect_invalid, reflect_empty) %}
+{# Attribute is limited to only known values: check that the attribute value is
+ one of those. If not, set it to the empty string.
+ http://www.whatwg.org/specs/web-apps/current-work/#limited-to-only-known-values #}
+{% if reflect_empty %}
+if (v8Value.isNull()) {
+{% if reflect_missing %}
+ v8Value = "{{reflect_missing}}";
+{% else %}
+ ;
+{% endif %}
+} else if (v8Value.isEmpty()) {
+ v8Value = "{{reflect_empty}}";
+{% else %}
+if (v8Value.isEmpty()) {
+{# FIXME: should use [ReflectEmpty] instead; need to change IDL files #}
+{% if reflect_missing %}
+ v8Value = "{{reflect_missing}}";
+{% else %}
+ ;
+{% endif %}
+{% endif %}
+{% for value in reflect_only_values %}
+} else if (equalIgnoringCase(v8Value, "{{value}}")) {
+ v8Value = "{{value}}";
+{% endfor %}
+} else {
+ v8Value = "{{reflect_invalid}}";
+}
+{% endmacro %}
+
{##############################################################################}
{% macro attribute_getter_callback(attribute, world_suffix) %}
@@ -93,22 +159,46 @@ v8::Local<v8::String>, const v8::PropertyCallbackInfo<v8::Value>& info
{
TRACE_EVENT_SET_SAMPLING_STATE("Blink", "DOMGetter");
{% if attribute.deprecate_as %}
- UseCounter::countDeprecation(activeExecutionContext(), UseCounter::{{attribute.deprecate_as}});
+ UseCounter::countDeprecation(callingExecutionContext(info.GetIsolate()), UseCounter::{{attribute.deprecate_as}});
{% endif %}
{% if attribute.measure_as %}
- UseCounter::count(activeDOMWindow(), UseCounter::{{attribute.measure_as}});
+ UseCounter::count(callingExecutionContext(info.GetIsolate()), UseCounter::{{attribute.measure_as}});
{% endif %}
{% if world_suffix in attribute.activity_logging_world_list_for_getter %}
- V8PerContextData* contextData = V8PerContextData::from(info.GetIsolate()->GetCurrentContext());
+ ScriptState* scriptState = ScriptState::from(info.GetIsolate()->GetCurrentContext());
+ V8PerContextData* contextData = scriptState->perContextData();
+ {% if attribute.activity_logging_world_check %}
+ if (scriptState->world().isIsolatedWorld() && contextData && contextData->activityLogger())
+ {% else %}
if (contextData && contextData->activityLogger())
- contextData->activityLogger()->log("{{interface_name}}.{{attribute.name}}", 0, 0, "Getter");
+ {% endif %}
+ contextData->activityLogger()->logGetter("{{interface_name}}.{{attribute.name}}");
{% endif %}
{% if attribute.has_custom_getter %}
{{v8_class}}::{{attribute.name}}AttributeGetterCustom(info);
{% else %}
{{cpp_class}}V8Internal::{{attribute.name}}AttributeGetter{{world_suffix}}(info);
{% endif %}
- TRACE_EVENT_SET_SAMPLING_STATE("V8", "Execution");
+ TRACE_EVENT_SET_SAMPLING_STATE("V8", "V8Execution");
+}
+{% endfilter %}
+{% endmacro %}
+
+
+{##############################################################################}
+{% macro constructor_getter_callback(attribute, world_suffix) %}
+{% filter conditional(attribute.conditional_string) %}
+static void {{attribute.name}}ConstructorGetterCallback{{world_suffix}}(v8::Local<v8::String> property, const v8::PropertyCallbackInfo<v8::Value>& info)
+{
+ TRACE_EVENT_SET_SAMPLING_STATE("Blink", "DOMGetter");
+ {% if attribute.deprecate_as %}
+ UseCounter::countDeprecation(callingExecutionContext(info.GetIsolate()), UseCounter::{{attribute.deprecate_as}});
+ {% endif %}
+ {% if attribute.measure_as %}
+ UseCounter::count(callingExecutionContext(info.GetIsolate()), UseCounter::{{attribute.measure_as}});
+ {% endif %}
+ {{cpp_class}}V8Internal::{{cpp_class}}ConstructorGetter{{world_suffix}}(property, info);
+ TRACE_EVENT_SET_SAMPLING_STATE("V8", "V8Execution");
}
{% endfilter %}
{% endmacro %}
@@ -119,54 +209,88 @@ v8::Local<v8::String>, const v8::PropertyCallbackInfo<v8::Value>& info
{% filter conditional(attribute.conditional_string) %}
static void {{attribute.name}}AttributeSetter{{world_suffix}}(
{%- if attribute.is_expose_js_accessors %}
-v8::Local<v8::Value> jsValue, const v8::FunctionCallbackInfo<v8::Value>& info
+v8::Local<v8::Value> v8Value, const v8::FunctionCallbackInfo<v8::Value>& info
{%- else %}
-v8::Local<v8::Value> jsValue, const v8::PropertyCallbackInfo<void>& info
+v8::Local<v8::Value> v8Value, const v8::PropertyCallbackInfo<void>& info
{%- endif %})
{
- {% if attribute.is_setter_raises_exception or
- attribute.has_strict_type_checking %}
- ExceptionState exceptionState(ExceptionState::SetterContext, "{{attribute.name}}", "{{interface_name}}", info.Holder(), info.GetIsolate());
+ {% if attribute.is_reflect and attribute.idl_type == 'DOMString' and
+ is_node %}
+ {% set cpp_class, v8_class = 'Element', 'V8Element' %}
+ {% endif %}
+ {# Local variables #}
+ {% if not attribute.is_static %}
+ v8::Handle<v8::Object> holder = info.Holder();
{% endif %}
- {% if attribute.has_strict_type_checking %}
+ {% if attribute.has_setter_exception_state %}
+ ExceptionState exceptionState(ExceptionState::SetterContext, "{{attribute.name}}", "{{interface_name}}", holder, info.GetIsolate());
+ {% endif %}
+ {# Type checking #}
+ {% if attribute.has_type_checking_interface %}
{# Type checking for interface types (if interface not implemented, throw
TypeError), per http://www.w3.org/TR/WebIDL/#es-interface #}
- if (!isUndefinedOrNull(jsValue) && !V8{{attribute.idl_type}}::hasInstance(jsValue, info.GetIsolate(), worldType(info.GetIsolate()))) {
+ if ({% if attribute.is_nullable %}!isUndefinedOrNull(v8Value) && {% endif %}!V8{{attribute.idl_type}}::hasInstance(v8Value, info.GetIsolate())) {
exceptionState.throwTypeError("The provided value is not of type '{{attribute.idl_type}}'.");
exceptionState.throwIfNeeded();
return;
}
{% endif %}
- {% if not attribute.is_static %}
- {{cpp_class}}* imp = {{v8_class}}::toNative(info.Holder());
+ {# impl #}
+ {% if attribute.put_forwards %}
+ {{cpp_class}}* proxyImpl = {{v8_class}}::toNative(holder);
+ {{attribute.cpp_type}} impl = WTF::getPtr(proxyImpl->{{attribute.name}}());
+ if (!impl)
+ return;
+ {% elif not attribute.is_static %}
+ {{cpp_class}}* impl = {{v8_class}}::toNative(holder);
{% endif %}
{% if attribute.idl_type == 'EventHandler' and interface_name == 'Window' %}
- if (!imp->document())
+ if (!impl->document())
return;
{% endif %}
+ {# Convert JS value to C++ value #}
{% if attribute.idl_type != 'EventHandler' %}
{{attribute.v8_value_to_local_cpp_value}};
- {% else %}{# EventHandler hack #}
- transferHiddenDependency(info.Holder(), {{attribute.event_handler_getter_expression}}, jsValue, {{v8_class}}::eventListenerCacheIndex, info.GetIsolate());
+ {% elif not is_node %}{# EventHandler hack #}
+ moveEventListenerToNewWrapper(holder, {{attribute.event_handler_getter_expression}}, v8Value, {{v8_class}}::eventListenerCacheIndex, info.GetIsolate());
{% endif %}
- {% if attribute.enum_validation_expression %}
- {# Setter ignores invalid enum values: http://www.w3.org/TR/WebIDL/#idl-enums #}
+ {# Type checking, possibly throw a TypeError, per:
+ http://www.w3.org/TR/WebIDL/#es-type-mapping #}
+ {% if attribute.has_type_checking_unrestricted %}
+ {# Non-finite floating point values (NaN, +Infinity or −Infinity), per:
+ http://heycam.github.io/webidl/#es-float
+ http://heycam.github.io/webidl/#es-double #}
+ if (!std::isfinite(cppValue)) {
+ exceptionState.throwTypeError("The provided {{attribute.idl_type}} value is non-finite.");
+ exceptionState.throwIfNeeded();
+ return;
+ }
+ {% elif attribute.enum_validation_expression %}
+ {# Setter ignores invalid enum values:
+ http://www.w3.org/TR/WebIDL/#idl-enums #}
String string = cppValue;
if (!({{attribute.enum_validation_expression}}))
return;
{% endif %}
- {% if attribute.is_reflect %}
+ {# Pre-set context #}
+ {% if attribute.is_custom_element_callbacks or
+ (attribute.is_reflect and
+ not(attribute.idl_type == 'DOMString' and is_node)) %}
+ {# Skip on compact node DOMString getters #}
CustomElementCallbackDispatcher::CallbackDeliveryScope deliveryScope;
{% endif %}
- {% if attribute.is_call_with_execution_context %}
- ExecutionContext* scriptContext = getExecutionContext();
+ {% if attribute.is_call_with_execution_context or
+ attribute.is_setter_call_with_execution_context %}
+ ExecutionContext* executionContext = currentExecutionContext(info.GetIsolate());
{% endif %}
+ {# Set #}
{{attribute.cpp_setter}};
+ {# Post-set #}
{% if attribute.is_setter_raises_exception %}
exceptionState.throwIfNeeded();
{% endif %}
{% if attribute.cached_attribute_validation_method %}
- info.Holder()->DeleteHiddenValue(v8::String::NewFromUtf8(info.GetIsolate(), "{{attribute.name}}", v8::String::kInternalizedString)); // Invalidate the cached value.
+ V8HiddenValue::deleteHiddenValue(info.GetIsolate(), holder, v8AtomicString(info.GetIsolate(), "{{attribute.name}}")); // Invalidate the cached value.
{% endif %}
}
{% endfilter %}
@@ -180,35 +304,50 @@ static void {{attribute.name}}AttributeSetterCallback{{world_suffix}}(
{%- if attribute.is_expose_js_accessors %}
const v8::FunctionCallbackInfo<v8::Value>& info
{%- else %}
-v8::Local<v8::String>, v8::Local<v8::Value> jsValue, const v8::PropertyCallbackInfo<void>& info
+v8::Local<v8::String>, v8::Local<v8::Value> v8Value, const v8::PropertyCallbackInfo<void>& info
{%- endif %})
{
{% if attribute.is_expose_js_accessors %}
- v8::Local<v8::Value> jsValue = info[0];
+ v8::Local<v8::Value> v8Value = info[0];
{% endif %}
TRACE_EVENT_SET_SAMPLING_STATE("Blink", "DOMSetter");
{% if attribute.deprecate_as %}
- UseCounter::countDeprecation(activeExecutionContext(), UseCounter::{{attribute.deprecate_as}});
+ UseCounter::countDeprecation(callingExecutionContext(info.GetIsolate()), UseCounter::{{attribute.deprecate_as}});
{% endif %}
{% if attribute.measure_as %}
- UseCounter::count(activeDOMWindow(), UseCounter::{{attribute.measure_as}});
+ UseCounter::count(callingExecutionContext(info.GetIsolate()), UseCounter::{{attribute.measure_as}});
{% endif %}
{% if world_suffix in attribute.activity_logging_world_list_for_setter %}
- V8PerContextData* contextData = V8PerContextData::from(info.GetIsolate()->GetCurrentContext());
+ ScriptState* scriptState = ScriptState::from(info.GetIsolate()->GetCurrentContext());
+ V8PerContextData* contextData = scriptState->perContextData();
+ {% if attribute.activity_logging_world_check %}
+ if (scriptState->world().isIsolatedWorld() && contextData && contextData->activityLogger()) {
+ {% else %}
if (contextData && contextData->activityLogger()) {
- v8::Handle<v8::Value> loggerArg[] = { jsValue };
- contextData->activityLogger()->log("{{interface_name}}.{{attribute.name}}", 1, &loggerArg[0], "Setter");
+ {% endif %}
+ {% if attribute.activity_logging_include_old_value_for_setter %}
+ {{cpp_class}}* impl = {{v8_class}}::toNative(info.Holder());
+ {% if attribute.cpp_value_original %}
+ {{attribute.cpp_type}} original = {{attribute.cpp_value_original}};
+ {% else %}
+ {{attribute.cpp_type}} original = {{attribute.cpp_value}};
+ {% endif %}
+ v8::Handle<v8::Value> originalValue = {{attribute.cpp_value_to_v8_value}};
+ contextData->activityLogger()->logSetter("{{interface_name}}.{{attribute.name}}", v8Value, originalValue);
+ {% else %}
+ contextData->activityLogger()->logSetter("{{interface_name}}.{{attribute.name}}", v8Value);
+ {% endif %}
}
{% endif %}
- {% if attribute.is_reflect %}
+ {% if attribute.is_custom_element_callbacks or attribute.is_reflect %}
CustomElementCallbackDispatcher::CallbackDeliveryScope deliveryScope;
{% endif %}
{% if attribute.has_custom_setter %}
- {{v8_class}}::{{attribute.name}}AttributeSetterCustom(jsValue, info);
+ {{v8_class}}::{{attribute.name}}AttributeSetterCustom(v8Value, info);
{% else %}
- {{cpp_class}}V8Internal::{{attribute.name}}AttributeSetter{{world_suffix}}(jsValue, info);
+ {{cpp_class}}V8Internal::{{attribute.name}}AttributeSetter{{world_suffix}}(v8Value, info);
{% endif %}
- TRACE_EVENT_SET_SAMPLING_STATE("V8", "Execution");
+ TRACE_EVENT_SET_SAMPLING_STATE("V8", "V8Execution");
}
{% endfilter %}
{% endmacro %}
diff --git a/chromium/third_party/WebKit/Source/bindings/templates/callback_interface.cpp b/chromium/third_party/WebKit/Source/bindings/templates/callback_interface.cpp
index ea297b71be5..5f33caa55ab 100644
--- a/chromium/third_party/WebKit/Source/bindings/templates/callback_interface.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/templates/callback_interface.cpp
@@ -1,36 +1,8 @@
-{# http://www.chromium.org/blink/coding-style#TOC-License #}
-/*
- * Copyright (C) 2013 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.
- */
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
-{# FIXME: Rename to Python when switch #}
-// This file has been auto-generated by code_generator_v8.pm. DO NOT MODIFY!
+// This file has been auto-generated by {{code_generator}}. DO NOT MODIFY!
#include "config.h"
{% filter conditional(conditional_string) %}
@@ -39,13 +11,14 @@
{% for filename in cpp_includes %}
#include "{{filename}}"
{% endfor %}
+
namespace WebCore {
-{{v8_class}}::{{v8_class}}(v8::Handle<v8::Function> callback, ExecutionContext* context)
- : ActiveDOMCallback(context)
- , m_callback(toIsolate(context), callback)
- , m_world(DOMWrapperWorld::current())
+{{v8_class}}::{{v8_class}}(v8::Handle<v8::Function> callback, ScriptState* scriptState)
+ : ActiveDOMCallback(scriptState->executionContext())
+ , m_scriptState(scriptState)
{
+ m_callback.set(scriptState->isolate(), callback);
}
{{v8_class}}::~{{v8_class}}()
@@ -53,21 +26,18 @@ namespace WebCore {
}
{% for method in methods if not method.custom %}
-{{method.return_cpp_type}} {{v8_class}}::{{method.name}}({{method.argument_declarations | join(', ')}})
+{{method.cpp_type}} {{v8_class}}::{{method.name}}({{method.argument_declarations | join(', ')}})
{
{% set return_default = 'return true'
- if method.return_idl_type == 'boolean' else 'return' %}{# void #}
+ if method.idl_type == 'boolean' else 'return' %}{# void #}
if (!canInvokeCallback())
{{return_default}};
- v8::Isolate* isolate = v8::Isolate::GetCurrent();
- v8::HandleScope handleScope(isolate);
-
- v8::Handle<v8::Context> v8Context = toV8Context(executionContext(), m_world.get());
- if (v8Context.IsEmpty())
+ v8::Isolate* isolate = m_scriptState->isolate();
+ if (m_scriptState->contextIsEmpty())
{{return_default}};
- v8::Context::Scope scope(v8Context);
+ ScriptState::Scope scope(m_scriptState.get());
{% if method.call_with_this_handle %}
v8::Handle<v8::Value> thisHandle = thisValue.v8Value();
if (thisHandle.IsEmpty()) {
@@ -75,27 +45,26 @@ namespace WebCore {
CRASH();
{{return_default}};
}
- ASSERT(thisHandle->IsObject());
{% endif %}
{% for argument in method.arguments %}
- {{argument.cpp_to_v8_conversion | indent}}
- if ({{argument.name}}Handle.IsEmpty()) {
+ v8::Handle<v8::Value> {{argument.handle}} = {{argument.cpp_value_to_v8_value}};
+ if ({{argument.handle}}.IsEmpty()) {
if (!isScriptControllerTerminating())
CRASH();
{{return_default}};
}
{% endfor %}
{% if method.arguments %}
- v8::Handle<v8::Value> argv[] = { {{method.handles | join(', ')}} };
+ v8::Handle<v8::Value> argv[] = { {{method.arguments | join(', ', 'handle')}} };
{% else %}
v8::Handle<v8::Value> *argv = 0;
{% endif %}
- {% set this_handle_parameter = 'v8::Handle<v8::Object>::Cast(thisHandle), ' if method.call_with_this_handle else '' %}
- {% if method.return_idl_type == 'boolean' %}
- return invokeCallback(m_callback.newLocal(isolate), {{this_handle_parameter}}{{method.arguments | length}}, argv, executionContext(), isolate);
+ {% set this_handle_parameter = 'thisHandle, ' if method.call_with_this_handle else '' %}
+ {% if method.idl_type == 'boolean' %}
+ return invokeCallback(m_scriptState.get(), m_callback.newLocal(isolate), {{this_handle_parameter}}{{method.arguments | length}}, argv);
{% else %}{# void #}
- invokeCallback(m_callback.newLocal(isolate), {{this_handle_parameter}}{{method.arguments | length}}, argv, executionContext(), isolate);
+ invokeCallback(m_scriptState.get(), m_callback.newLocal(isolate), {{this_handle_parameter}}{{method.arguments | length}}, argv);
{% endif %}
}
diff --git a/chromium/third_party/WebKit/Source/bindings/templates/callback_interface.h b/chromium/third_party/WebKit/Source/bindings/templates/callback_interface.h
index acd58673bea..f3b172da294 100644
--- a/chromium/third_party/WebKit/Source/bindings/templates/callback_interface.h
+++ b/chromium/third_party/WebKit/Source/bindings/templates/callback_interface.h
@@ -1,36 +1,8 @@
-{# http://www.chromium.org/blink/coding-style#TOC-License #}
-/*
- * Copyright (C) 2013 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.
- */
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
-{# FIXME: Rename to Python when switch #}
-// This file has been auto-generated by code_generator_v8.pm. DO NOT MODIFY!
+// This file has been auto-generated by {{code_generator}}. DO NOT MODIFY!
#ifndef {{v8_class}}_h
#define {{v8_class}}_h
@@ -42,26 +14,23 @@
namespace WebCore {
-class ExecutionContext;
-
-class {{v8_class}} : public {{cpp_class}}, public ActiveDOMCallback {
+class {{v8_class}} FINAL : public {{cpp_class}}, public ActiveDOMCallback {
public:
- static PassOwnPtr<{{v8_class}}> create(v8::Handle<v8::Function> callback, ExecutionContext* context)
+ static PassOwnPtr<{{v8_class}}> create(v8::Handle<v8::Function> callback, ScriptState* scriptState)
{
- ASSERT(context);
- return adoptPtr(new {{v8_class}}(callback, context));
+ return adoptPtr(new {{v8_class}}(callback, scriptState));
}
virtual ~{{v8_class}}();
{% for method in methods %}
- virtual {{method.return_cpp_type}} {{method.name}}({{method.argument_declarations | join(', ')}});
+ virtual {{method.cpp_type}} {{method.name}}({{method.argument_declarations | join(', ')}}) OVERRIDE;
{% endfor %}
private:
- {{v8_class}}(v8::Handle<v8::Function>, ExecutionContext*);
+ {{v8_class}}(v8::Handle<v8::Function>, ScriptState*);
ScopedPersistent<v8::Function> m_callback;
- RefPtr<DOMWrapperWorld> m_world;
+ RefPtr<ScriptState> m_scriptState;
};
}
diff --git a/chromium/third_party/WebKit/Source/bindings/templates/interface.cpp b/chromium/third_party/WebKit/Source/bindings/templates/interface.cpp
index 5a2703cb96f..7312827a63b 100644
--- a/chromium/third_party/WebKit/Source/bindings/templates/interface.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/templates/interface.cpp
@@ -7,7 +7,10 @@
'%sV8Internal::%sAttributeGetterCallback' %
(cpp_class, attribute.name)
if not attribute.constructor_type else
- '{0}V8Internal::{0}ConstructorGetter'.format(interface_name) %}
+ ('%sV8Internal::%sConstructorGetterCallback' %
+ (cpp_class, attribute.name)
+ if attribute.needs_constructor_getter_callback else
+ '{0}V8Internal::{0}ConstructorGetter'.format(cpp_class)) %}
{% set getter_callback_for_main_world =
'%sV8Internal::%sAttributeGetterCallbackForMainWorld' %
(cpp_class, attribute.name)
@@ -16,7 +19,8 @@
{% set setter_callback_for_main_world =
'%sV8Internal::%sAttributeSetterCallbackForMainWorld' %
(cpp_class, attribute.name)
- if attribute.is_per_world_bindings and not attribute.is_read_only else '0' %}
+ if attribute.is_per_world_bindings and
+ (not attribute.is_read_only or attribute.put_forwards) else '0' %}
{% set wrapper_type_info =
'const_cast<WrapperTypeInfo*>(&V8%s::wrapperTypeInfo)' %
attribute.constructor_type
@@ -25,9 +29,24 @@
' | '.join(attribute.access_control_list) %}
{% set property_attribute = 'static_cast<v8::PropertyAttribute>(%s)' %
' | '.join(attribute.property_attributes) %}
-{% set on_prototype = ', 0 /* on instance */'
- if not attribute.is_expose_js_accessors else '' %}
-{"{{attribute.name}}", {{getter_callback}}, {{setter_callback}}, {{getter_callback_for_main_world}}, {{setter_callback_for_main_world}}, {{wrapper_type_info}}, {{access_control}}, {{property_attribute}}{{on_prototype}}}
+{% set on_prototype = '1 /* on prototype */'
+ if interface_name == 'Window' and attribute.idl_type == 'EventHandler'
+ else '0 /* on instance */' %}
+{% set attribute_configuration_list = [
+ '"%s"' % attribute.name,
+ getter_callback,
+ setter_callback,
+ getter_callback_for_main_world,
+ setter_callback_for_main_world,
+ wrapper_type_info,
+ access_control,
+ property_attribute,
+ ] %}
+{% if not attribute.is_expose_js_accessors %}
+{% set attribute_configuration_list = attribute_configuration_list
+ + [on_prototype] %}
+{% endif %}
+{{'{'}}{{attribute_configuration_list | join(', ')}}{{'}'}}
{%- endmacro %}
@@ -38,14 +57,14 @@
{% set method_callback_for_main_world =
'%sV8Internal::%sMethodCallbackForMainWorld' % (cpp_class, method.name)
if method.is_per_world_bindings else '0' %}
-{"{{method.name}}", {{method_callback}}, {{method_callback_for_main_world}}, {{method.number_of_required_or_variadic_arguments}}}
+{"{{method.name}}", {{method_callback}}, {{method_callback_for_main_world}}, {{method.length}}}
{%- endmacro %}
{##############################################################################}
{% block constructor_getter %}
{% if has_constructor_attributes %}
-static void {{interface_name}}ConstructorGetter(v8::Local<v8::String>, const v8::PropertyCallbackInfo<v8::Value>& info)
+static void {{cpp_class}}ConstructorGetter(v8::Local<v8::String>, const v8::PropertyCallbackInfo<v8::Value>& info)
{
v8::Handle<v8::Value> data = info.Data();
ASSERT(data->IsExternal());
@@ -63,15 +82,26 @@ static void {{interface_name}}ConstructorGetter(v8::Local<v8::String>, const v8:
{% block replaceable_attribute_setter_and_callback %}
{% if has_replaceable_attributes or has_constructor_attributes %}
{# FIXME: rename to ForceSetAttributeOnThis, since also used for Constructors #}
-static void {{interface_name}}ReplaceableAttributeSetter(v8::Local<v8::String> name, v8::Local<v8::Value> jsValue, const v8::PropertyCallbackInfo<void>& info)
+static void {{cpp_class}}ReplaceableAttributeSetter(v8::Local<v8::String> name, v8::Local<v8::Value> v8Value, const v8::PropertyCallbackInfo<void>& info)
{
- info.This()->ForceSet(name, jsValue);
+ {% if is_check_security %}
+ {{cpp_class}}* impl = {{v8_class}}::toNative(info.Holder());
+ v8::Isolate* isolate = info.GetIsolate();
+ v8::String::Utf8Value attributeName(name);
+ ExceptionState exceptionState(ExceptionState::SetterContext, *attributeName, "{{interface_name}}", info.Holder(), isolate);
+ if (!BindingSecurity::shouldAllowAccessToFrame(isolate, impl->frame(), exceptionState)) {
+ exceptionState.throwIfNeeded();
+ return;
+ }
+ {% endif %}
+ if (info.This()->IsObject())
+ v8::Handle<v8::Object>::Cast(info.This())->ForceSet(name, v8Value);
}
{# FIXME: rename to ForceSetAttributeOnThisCallback, since also used for Constructors #}
-static void {{interface_name}}ReplaceableAttributeSetterCallback(v8::Local<v8::String> name, v8::Local<v8::Value> jsValue, const v8::PropertyCallbackInfo<void>& info)
+static void {{cpp_class}}ReplaceableAttributeSetterCallback(v8::Local<v8::String> name, v8::Local<v8::Value> v8Value, const v8::PropertyCallbackInfo<void>& info)
{
- {{interface_name}}V8Internal::{{interface_name}}ReplaceableAttributeSetter(name, jsValue, info);
+ {{cpp_class}}V8Internal::{{cpp_class}}ReplaceableAttributeSetter(name, v8Value, info);
}
{% endif %}
@@ -83,14 +113,409 @@ static void {{interface_name}}ReplaceableAttributeSetterCallback(v8::Local<v8::S
{% if is_check_security and interface_name != 'Window' %}
bool indexedSecurityCheck(v8::Local<v8::Object> host, uint32_t index, v8::AccessType type, v8::Local<v8::Value>)
{
- {{cpp_class}}* imp = {{v8_class}}::toNative(host);
- return BindingSecurity::shouldAllowAccessToFrame(imp->frame(), DoNotReportSecurityError);
+ {{cpp_class}}* impl = {{v8_class}}::toNative(host);
+ return BindingSecurity::shouldAllowAccessToFrame(v8::Isolate::GetCurrent(), impl->frame(), DoNotReportSecurityError);
}
bool namedSecurityCheck(v8::Local<v8::Object> host, v8::Local<v8::Value> key, v8::AccessType type, v8::Local<v8::Value>)
{
- {{cpp_class}}* imp = {{v8_class}}::toNative(host);
- return BindingSecurity::shouldAllowAccessToFrame(imp->frame(), DoNotReportSecurityError);
+ {{cpp_class}}* impl = {{v8_class}}::toNative(host);
+ return BindingSecurity::shouldAllowAccessToFrame(v8::Isolate::GetCurrent(), impl->frame(), DoNotReportSecurityError);
+}
+
+{% endif %}
+{% endblock %}
+
+
+{##############################################################################}
+{% block indexed_property_getter %}
+{% if indexed_property_getter and not indexed_property_getter.is_custom %}
+{% set getter = indexed_property_getter %}
+static void indexedPropertyGetter(uint32_t index, const v8::PropertyCallbackInfo<v8::Value>& info)
+{
+ {{cpp_class}}* impl = {{v8_class}}::toNative(info.Holder());
+ {% if getter.is_raises_exception %}
+ ExceptionState exceptionState(ExceptionState::IndexedGetterContext, "{{interface_name}}", info.Holder(), info.GetIsolate());
+ {% endif %}
+ {% set getter_name = getter.name or 'anonymousIndexedGetter' %}
+ {% set getter_arguments = ['index', 'exceptionState']
+ if getter.is_raises_exception else ['index'] %}
+ {{getter.cpp_type}} result = impl->{{getter_name}}({{getter_arguments | join(', ')}});
+ {% if getter.is_raises_exception %}
+ if (exceptionState.throwIfNeeded())
+ return;
+ {% endif %}
+ if ({{getter.is_null_expression}})
+ return;
+ {{getter.v8_set_return_value}};
+}
+
+{% endif %}
+{% endblock %}
+
+
+{##############################################################################}
+{% block indexed_property_getter_callback %}
+{% if indexed_property_getter %}
+{% set getter = indexed_property_getter %}
+static void indexedPropertyGetterCallback(uint32_t index, const v8::PropertyCallbackInfo<v8::Value>& info)
+{
+ TRACE_EVENT_SET_SAMPLING_STATE("Blink", "DOMIndexedProperty");
+ {% if getter.is_custom %}
+ {{v8_class}}::indexedPropertyGetterCustom(index, info);
+ {% else %}
+ {{cpp_class}}V8Internal::indexedPropertyGetter(index, info);
+ {% endif %}
+ TRACE_EVENT_SET_SAMPLING_STATE("V8", "V8Execution");
+}
+
+{% endif %}
+{% endblock %}
+
+
+{##############################################################################}
+{% block indexed_property_setter %}
+{% if indexed_property_setter and not indexed_property_setter.is_custom %}
+{% set setter = indexed_property_setter %}
+static void indexedPropertySetter(uint32_t index, v8::Local<v8::Value> v8Value, const v8::PropertyCallbackInfo<v8::Value>& info)
+{
+ {{cpp_class}}* impl = {{v8_class}}::toNative(info.Holder());
+ {{setter.v8_value_to_local_cpp_value}};
+ {% if setter.has_exception_state %}
+ ExceptionState exceptionState(ExceptionState::IndexedSetterContext, "{{interface_name}}", info.Holder(), info.GetIsolate());
+ {% endif %}
+ {% if setter.has_type_checking_interface %}
+ {# Type checking for interface types (if interface not implemented, throw
+ TypeError), per http://www.w3.org/TR/WebIDL/#es-interface #}
+ if (!isUndefinedOrNull(v8Value) && !V8{{setter.idl_type}}::hasInstance(v8Value, info.GetIsolate())) {
+ exceptionState.throwTypeError("The provided value is not of type '{{setter.idl_type}}'.");
+ exceptionState.throwIfNeeded();
+ return;
+ }
+ {% endif %}
+ {% set setter_name = setter.name or 'anonymousIndexedSetter' %}
+ {% set setter_arguments = ['index', 'propertyValue', 'exceptionState']
+ if setter.is_raises_exception else ['index', 'propertyValue'] %}
+ bool result = impl->{{setter_name}}({{setter_arguments | join(', ')}});
+ {% if setter.is_raises_exception %}
+ if (exceptionState.throwIfNeeded())
+ return;
+ {% endif %}
+ if (!result)
+ return;
+ v8SetReturnValue(info, v8Value);
+}
+
+{% endif %}
+{% endblock %}
+
+
+{##############################################################################}
+{% block indexed_property_setter_callback %}
+{% if indexed_property_setter %}
+{% set setter = indexed_property_setter %}
+static void indexedPropertySetterCallback(uint32_t index, v8::Local<v8::Value> v8Value, const v8::PropertyCallbackInfo<v8::Value>& info)
+{
+ TRACE_EVENT_SET_SAMPLING_STATE("Blink", "DOMIndexedProperty");
+ {% if setter.is_custom %}
+ {{v8_class}}::indexedPropertySetterCustom(index, v8Value, info);
+ {% else %}
+ {{cpp_class}}V8Internal::indexedPropertySetter(index, v8Value, info);
+ {% endif %}
+ TRACE_EVENT_SET_SAMPLING_STATE("V8", "V8Execution");
+}
+
+{% endif %}
+{% endblock %}
+
+
+{##############################################################################}
+{% block indexed_property_deleter %}
+{% if indexed_property_deleter and not indexed_property_deleter.is_custom %}
+{% set deleter = indexed_property_deleter %}
+static void indexedPropertyDeleter(uint32_t index, const v8::PropertyCallbackInfo<v8::Boolean>& info)
+{
+ {{cpp_class}}* impl = {{v8_class}}::toNative(info.Holder());
+ {% if deleter.is_raises_exception %}
+ ExceptionState exceptionState(ExceptionState::IndexedDeletionContext, "{{interface_name}}", info.Holder(), info.GetIsolate());
+ {% endif %}
+ {% set deleter_name = deleter.name or 'anonymousIndexedDeleter' %}
+ {% set deleter_arguments = ['index', 'exceptionState']
+ if deleter.is_raises_exception else ['index'] %}
+ DeleteResult result = impl->{{deleter_name}}({{deleter_arguments | join(', ')}});
+ {% if deleter.is_raises_exception %}
+ if (exceptionState.throwIfNeeded())
+ return;
+ {% endif %}
+ if (result != DeleteUnknownProperty)
+ return v8SetReturnValueBool(info, result == DeleteSuccess);
+}
+
+{% endif %}
+{% endblock %}
+
+
+{##############################################################################}
+{% block indexed_property_deleter_callback %}
+{% if indexed_property_deleter %}
+{% set deleter = indexed_property_deleter %}
+static void indexedPropertyDeleterCallback(uint32_t index, const v8::PropertyCallbackInfo<v8::Boolean>& info)
+{
+ TRACE_EVENT_SET_SAMPLING_STATE("Blink", "DOMIndexedProperty");
+ {% if deleter.is_custom %}
+ {{v8_class}}::indexedPropertyDeleterCustom(index, info);
+ {% else %}
+ {{cpp_class}}V8Internal::indexedPropertyDeleter(index, info);
+ {% endif %}
+ TRACE_EVENT_SET_SAMPLING_STATE("V8", "V8Execution");
+}
+
+{% endif %}
+{% endblock %}
+
+
+{##############################################################################}
+{% from 'methods.cpp' import union_type_method_call_and_set_return_value %}
+{% block named_property_getter %}
+{% if named_property_getter and not named_property_getter.is_custom %}
+{% set getter = named_property_getter %}
+static void namedPropertyGetter(v8::Local<v8::String> name, const v8::PropertyCallbackInfo<v8::Value>& info)
+{
+ {% if not is_override_builtins %}
+ if (info.Holder()->HasRealNamedProperty(name))
+ return;
+ if (!info.Holder()->GetRealNamedPropertyInPrototypeChain(name).IsEmpty())
+ return;
+
+ {% endif %}
+ {{cpp_class}}* impl = {{v8_class}}::toNative(info.Holder());
+ AtomicString propertyName = toCoreAtomicString(name);
+ {% if getter.is_raises_exception %}
+ v8::String::Utf8Value namedProperty(name);
+ ExceptionState exceptionState(ExceptionState::GetterContext, *namedProperty, "{{interface_name}}", info.Holder(), info.GetIsolate());
+ {% endif %}
+ {% if getter.union_arguments %}
+ {{union_type_method_call_and_set_return_value(getter) | indent}}
+ {% else %}
+ {{getter.cpp_type}} result = {{getter.cpp_value}};
+ {% if getter.is_raises_exception %}
+ if (exceptionState.throwIfNeeded())
+ return;
+ {% endif %}
+ if ({{getter.is_null_expression}})
+ return;
+ {{getter.v8_set_return_value}};
+ {% endif %}
+}
+
+{% endif %}
+{% endblock %}
+
+
+{##############################################################################}
+{% block named_property_getter_callback %}
+{% if named_property_getter %}
+{% set getter = named_property_getter %}
+static void namedPropertyGetterCallback(v8::Local<v8::String> name, const v8::PropertyCallbackInfo<v8::Value>& info)
+{
+ TRACE_EVENT_SET_SAMPLING_STATE("Blink", "DOMNamedProperty");
+ {% if getter.is_custom %}
+ {{v8_class}}::namedPropertyGetterCustom(name, info);
+ {% else %}
+ {{cpp_class}}V8Internal::namedPropertyGetter(name, info);
+ {% endif %}
+ TRACE_EVENT_SET_SAMPLING_STATE("V8", "V8Execution");
+}
+
+{% endif %}
+{% endblock %}
+
+
+{##############################################################################}
+{% block named_property_setter %}
+{% if named_property_setter and not named_property_setter.is_custom %}
+{% set setter = named_property_setter %}
+static void namedPropertySetter(v8::Local<v8::String> name, v8::Local<v8::Value> v8Value, const v8::PropertyCallbackInfo<v8::Value>& info)
+{
+ {% if not is_override_builtins %}
+ if (info.Holder()->HasRealNamedProperty(name))
+ return;
+ if (!info.Holder()->GetRealNamedPropertyInPrototypeChain(name).IsEmpty())
+ return;
+
+ {% endif %}
+ {{cpp_class}}* impl = {{v8_class}}::toNative(info.Holder());
+ {# v8_value_to_local_cpp_value('DOMString', 'name', 'propertyName') #}
+ TOSTRING_VOID(V8StringResource<>, propertyName, name);
+ {{setter.v8_value_to_local_cpp_value}};
+ {% if setter.has_exception_state %}
+ v8::String::Utf8Value namedProperty(name);
+ ExceptionState exceptionState(ExceptionState::SetterContext, *namedProperty, "{{interface_name}}", info.Holder(), info.GetIsolate());
+ {% endif %}
+ {% set setter_name = setter.name or 'anonymousNamedSetter' %}
+ {% set setter_arguments =
+ ['propertyName', 'propertyValue', 'exceptionState']
+ if setter.is_raises_exception else
+ ['propertyName', 'propertyValue'] %}
+ bool result = impl->{{setter_name}}({{setter_arguments | join(', ')}});
+ {% if setter.is_raises_exception %}
+ if (exceptionState.throwIfNeeded())
+ return;
+ {% endif %}
+ if (!result)
+ return;
+ v8SetReturnValue(info, v8Value);
+}
+
+{% endif %}
+{% endblock %}
+
+
+{##############################################################################}
+{% block named_property_setter_callback %}
+{% if named_property_setter %}
+{% set setter = named_property_setter %}
+static void namedPropertySetterCallback(v8::Local<v8::String> name, v8::Local<v8::Value> v8Value, const v8::PropertyCallbackInfo<v8::Value>& info)
+{
+ TRACE_EVENT_SET_SAMPLING_STATE("Blink", "DOMNamedProperty");
+ {% if setter.is_custom %}
+ {{v8_class}}::namedPropertySetterCustom(name, v8Value, info);
+ {% else %}
+ {{cpp_class}}V8Internal::namedPropertySetter(name, v8Value, info);
+ {% endif %}
+ TRACE_EVENT_SET_SAMPLING_STATE("V8", "V8Execution");
+}
+
+{% endif %}
+{% endblock %}
+
+
+{##############################################################################}
+{% block named_property_query %}
+{% if named_property_getter and named_property_getter.is_enumerable and
+ not named_property_getter.is_custom_property_query %}
+{# If there is an enumerator, there MUST be a query method to properly
+ communicate property attributes. #}
+static void namedPropertyQuery(v8::Local<v8::String> name, const v8::PropertyCallbackInfo<v8::Integer>& info)
+{
+ {{cpp_class}}* impl = {{v8_class}}::toNative(info.Holder());
+ AtomicString propertyName = toCoreAtomicString(name);
+ v8::String::Utf8Value namedProperty(name);
+ ExceptionState exceptionState(ExceptionState::GetterContext, *namedProperty, "{{interface_name}}", info.Holder(), info.GetIsolate());
+ bool result = impl->namedPropertyQuery(propertyName, exceptionState);
+ if (exceptionState.throwIfNeeded())
+ return;
+ if (!result)
+ return;
+ v8SetReturnValueInt(info, v8::None);
+}
+
+{% endif %}
+{% endblock %}
+
+
+{##############################################################################}
+{% block named_property_query_callback %}
+{% if named_property_getter and named_property_getter.is_enumerable %}
+{% set getter = named_property_getter %}
+static void namedPropertyQueryCallback(v8::Local<v8::String> name, const v8::PropertyCallbackInfo<v8::Integer>& info)
+{
+ TRACE_EVENT_SET_SAMPLING_STATE("Blink", "DOMNamedProperty");
+ {% if getter.is_custom_property_query %}
+ {{v8_class}}::namedPropertyQueryCustom(name, info);
+ {% else %}
+ {{cpp_class}}V8Internal::namedPropertyQuery(name, info);
+ {% endif %}
+ TRACE_EVENT_SET_SAMPLING_STATE("V8", "V8Execution");
+}
+
+{% endif %}
+{% endblock %}
+
+
+{##############################################################################}
+{% block named_property_deleter %}
+{% if named_property_deleter and not named_property_deleter.is_custom %}
+{% set deleter = named_property_deleter %}
+static void namedPropertyDeleter(v8::Local<v8::String> name, const v8::PropertyCallbackInfo<v8::Boolean>& info)
+{
+ {{cpp_class}}* impl = {{v8_class}}::toNative(info.Holder());
+ AtomicString propertyName = toCoreAtomicString(name);
+ {% if deleter.is_raises_exception %}
+ v8::String::Utf8Value namedProperty(name);
+ ExceptionState exceptionState(ExceptionState::DeletionContext, *namedProperty, "{{interface_name}}", info.Holder(), info.GetIsolate());
+ {% endif %}
+ {% set deleter_name = deleter.name or 'anonymousNamedDeleter' %}
+ {% set deleter_arguments = ['propertyName', 'exceptionState']
+ if deleter.is_raises_exception else ['propertyName'] %}
+ DeleteResult result = impl->{{deleter_name}}({{deleter_arguments | join(', ')}});
+ {% if deleter.is_raises_exception %}
+ if (exceptionState.throwIfNeeded())
+ return;
+ {% endif %}
+ if (result != DeleteUnknownProperty)
+ return v8SetReturnValueBool(info, result == DeleteSuccess);
+}
+
+{% endif %}
+{% endblock %}
+
+
+{##############################################################################}
+{% block named_property_deleter_callback %}
+{% if named_property_deleter %}
+{% set deleter = named_property_deleter %}
+static void namedPropertyDeleterCallback(v8::Local<v8::String> name, const v8::PropertyCallbackInfo<v8::Boolean>& info)
+{
+ TRACE_EVENT_SET_SAMPLING_STATE("Blink", "DOMNamedProperty");
+ {% if deleter.is_custom %}
+ {{v8_class}}::namedPropertyDeleterCustom(name, info);
+ {% else %}
+ {{cpp_class}}V8Internal::namedPropertyDeleter(name, info);
+ {% endif %}
+ TRACE_EVENT_SET_SAMPLING_STATE("V8", "V8Execution");
+}
+
+{% endif %}
+{% endblock %}
+
+
+{##############################################################################}
+{% block named_property_enumerator %}
+{% if named_property_getter and named_property_getter.is_enumerable and
+ not named_property_getter.is_custom_property_enumerator %}
+static void namedPropertyEnumerator(const v8::PropertyCallbackInfo<v8::Array>& info)
+{
+ {{cpp_class}}* impl = {{v8_class}}::toNative(info.Holder());
+ v8::Isolate* isolate = info.GetIsolate();
+ Vector<String> names;
+ ExceptionState exceptionState(ExceptionState::EnumerationContext, "{{interface_name}}", info.Holder(), isolate);
+ impl->namedPropertyEnumerator(names, exceptionState);
+ if (exceptionState.throwIfNeeded())
+ return;
+ v8::Handle<v8::Array> v8names = v8::Array::New(isolate, names.size());
+ for (size_t i = 0; i < names.size(); ++i)
+ v8names->Set(v8::Integer::New(isolate, i), v8String(isolate, names[i]));
+ v8SetReturnValue(info, v8names);
+}
+
+{% endif %}
+{% endblock %}
+
+
+{##############################################################################}
+{% block named_property_enumerator_callback %}
+{% if named_property_getter and named_property_getter.is_enumerable %}
+{% set getter = named_property_getter %}
+static void namedPropertyEnumeratorCallback(const v8::PropertyCallbackInfo<v8::Array>& info)
+{
+ TRACE_EVENT_SET_SAMPLING_STATE("Blink", "DOMNamedProperty");
+ {% if getter.is_custom_property_enumerator %}
+ {{v8_class}}::namedPropertyEnumeratorCustom(info);
+ {% else %}
+ {{cpp_class}}V8Internal::namedPropertyEnumerator(info);
+ {% endif %}
+ TRACE_EVENT_SET_SAMPLING_STATE("V8", "V8Execution");
}
{% endif %}
@@ -100,28 +525,29 @@ bool namedSecurityCheck(v8::Local<v8::Object> host, v8::Local<v8::Value> key, v8
{##############################################################################}
{% block origin_safe_method_setter %}
{% if has_origin_safe_method_setter %}
-static void {{cpp_class}}OriginSafeMethodSetter(v8::Local<v8::String> name, v8::Local<v8::Value> jsValue, const v8::PropertyCallbackInfo<void>& info)
+static void {{cpp_class}}OriginSafeMethodSetter(v8::Local<v8::String> name, v8::Local<v8::Value> v8Value, const v8::PropertyCallbackInfo<void>& info)
{
- {# FIXME: don't call GetIsolate 3 times #}
- v8::Handle<v8::Object> holder = info.This()->FindInstanceInPrototypeChain({{v8_class}}::domTemplate(info.GetIsolate(), worldType(info.GetIsolate())));
+ v8::Isolate* isolate = info.GetIsolate();
+ v8::Handle<v8::Object> holder = {{v8_class}}::findInstanceInPrototypeChain(info.This(), isolate);
if (holder.IsEmpty())
return;
- {{cpp_class}}* imp = {{v8_class}}::toNative(holder);
+ {{cpp_class}}* impl = {{v8_class}}::toNative(holder);
v8::String::Utf8Value attributeName(name);
- ExceptionState exceptionState(ExceptionState::SetterContext, *attributeName, "{{interface_name}}", info.Holder(), info.GetIsolate());
- if (!BindingSecurity::shouldAllowAccessToFrame(imp->frame(), exceptionState)) {
+ ExceptionState exceptionState(ExceptionState::SetterContext, *attributeName, "{{interface_name}}", info.Holder(), isolate);
+ if (!BindingSecurity::shouldAllowAccessToFrame(isolate, impl->frame(), exceptionState)) {
exceptionState.throwIfNeeded();
return;
}
- info.This()->SetHiddenValue(name, jsValue);
+ {# The findInstanceInPrototypeChain() call above only returns a non-empty handle if info.This() is an Object. #}
+ V8HiddenValue::setHiddenValue(isolate, v8::Handle<v8::Object>::Cast(info.This()), name, v8Value);
}
-static void {{cpp_class}}OriginSafeMethodSetterCallback(v8::Local<v8::String> name, v8::Local<v8::Value> jsValue, const v8::PropertyCallbackInfo<void>& info)
+static void {{cpp_class}}OriginSafeMethodSetterCallback(v8::Local<v8::String> name, v8::Local<v8::Value> v8Value, const v8::PropertyCallbackInfo<void>& info)
{
TRACE_EVENT_SET_SAMPLING_STATE("Blink", "DOMSetter");
- {{cpp_class}}V8Internal::{{cpp_class}}OriginSafeMethodSetter(name, jsValue, info);
- TRACE_EVENT_SET_SAMPLING_STATE("V8", "Execution");
+ {{cpp_class}}V8Internal::{{cpp_class}}OriginSafeMethodSetter(name, v8Value, info);
+ TRACE_EVENT_SET_SAMPLING_STATE("V8", "V8Execution");
}
{% endif %}
@@ -134,29 +560,27 @@ static void {{cpp_class}}OriginSafeMethodSetterCallback(v8::Local<v8::String> na
{% if named_constructor %}
{% set to_active_dom_object = '%s::toActiveDOMObject' % v8_class
if is_active_dom_object else '0' %}
-const WrapperTypeInfo {{v8_class}}Constructor::wrapperTypeInfo = { gin::kEmbedderBlink, {{v8_class}}Constructor::domTemplate, {{v8_class}}::derefObject, {{to_active_dom_object}}, 0, 0, {{v8_class}}::installPerContextEnabledMethods, 0, WrapperTypeObjectPrototype };
+{% set to_event_target = '%s::toEventTarget' % v8_class
+ if is_event_target else '0' %}
+const WrapperTypeInfo {{v8_class}}Constructor::wrapperTypeInfo = { gin::kEmbedderBlink, {{v8_class}}Constructor::domTemplate, {{v8_class}}::derefObject, {{to_active_dom_object}}, {{to_event_target}}, 0, {{v8_class}}::installPerContextEnabledMethods, 0, WrapperTypeObjectPrototype, {{gc_type}} };
{{named_constructor_callback(named_constructor)}}
-v8::Handle<v8::FunctionTemplate> {{v8_class}}Constructor::domTemplate(v8::Isolate* isolate, WrapperWorldType currentWorldType)
+v8::Handle<v8::FunctionTemplate> {{v8_class}}Constructor::domTemplate(v8::Isolate* isolate)
{
- // This is only for getting a unique pointer which we can pass to privateTemplate.
- static int privateTemplateUniqueKey;
+ static int domTemplateKey; // This address is used for a key to look up the dom template.
V8PerIsolateData* data = V8PerIsolateData::from(isolate);
- v8::Local<v8::FunctionTemplate> result = data->privateTemplateIfExists(currentWorldType, &privateTemplateUniqueKey);
+ v8::Local<v8::FunctionTemplate> result = data->existingDOMTemplate(&domTemplateKey);
if (!result.IsEmpty())
return result;
TRACE_EVENT_SCOPED_SAMPLING_STATE("Blink", "BuildDOMTemplate");
- v8::EscapableHandleScope scope(isolate);
result = v8::FunctionTemplate::New(isolate, {{v8_class}}ConstructorCallback);
-
v8::Local<v8::ObjectTemplate> instanceTemplate = result->InstanceTemplate();
instanceTemplate->SetInternalFieldCount({{v8_class}}::internalFieldCount);
- result->SetClassName(v8::String::NewFromUtf8(isolate, "{{cpp_class}}", v8::String::kInternalizedString));
- result->Inherit({{v8_class}}::domTemplate(isolate, currentWorldType));
- data->setPrivateTemplate(currentWorldType, &privateTemplateUniqueKey, result);
-
- return scope.Escape(result);
+ result->SetClassName(v8AtomicString(isolate, "{{cpp_class}}"));
+ result->Inherit({{v8_class}}::domTemplate(isolate));
+ data->setDOMTemplate(&domTemplateKey, result);
+ return result;
}
{% endif %}
@@ -164,27 +588,43 @@ v8::Handle<v8::FunctionTemplate> {{v8_class}}Constructor::domTemplate(v8::Isolat
{##############################################################################}
{% block overloaded_constructor %}
-{% if constructors|length > 1 %}
+{% if constructor_overloads %}
static void constructor(const v8::FunctionCallbackInfo<v8::Value>& info)
{
- {% for constructor in constructors %}
- if ({{constructor.overload_resolution_expression}}) {
- {{cpp_class}}V8Internal::constructor{{constructor.overload_index}}(info);
- return;
- }
+ v8::Isolate* isolate = info.GetIsolate();
+ ExceptionState exceptionState(ExceptionState::ConstructionContext, "{{interface_name}}", info.Holder(), isolate);
+ {# 2. Initialize argcount to be min(maxarg, n). #}
+ switch (std::min({{constructor_overloads.maxarg}}, info.Length())) {
+ {# 3. Remove from S all entries whose type list is not of length argcount. #}
+ {% for length, tests_constructors in constructor_overloads.length_tests_methods %}
+ case {{length}}:
+ {# Then resolve by testing argument #}
+ {% for test, constructor in tests_constructors %}
+ {# 10. If i = d, then: #}
+ if ({{test}}) {
+ {{cpp_class}}V8Internal::constructor{{constructor.overload_index}}(info);
+ return;
+ }
+ {% endfor %}
+ break;
{% endfor %}
- {% if interface_length %}
- ExceptionState exceptionState(ExceptionState::ConstructionContext, "{{interface_name}}", info.Holder(), info.GetIsolate());
- if (UNLIKELY(info.Length() < {{interface_length}})) {
- exceptionState.throwTypeError(ExceptionMessages::notEnoughArguments({{interface_length}}, info.Length()));
+ default:
+ {# Invalid arity, throw error #}
+ {# Report full list of valid arities if gaps and above minimum #}
+ {% if constructor_overloads.valid_arities %}
+ if (info.Length() >= {{constructor_overloads.minarg}}) {
+ throwArityTypeError(exceptionState, "{{constructor_overloads.valid_arities}}", info.Length());
+ return;
+ }
+ {% endif %}
+ {# Otherwise just report "not enough arguments" #}
+ exceptionState.throwTypeError(ExceptionMessages::notEnoughArguments({{constructor_overloads.minarg}}, info.Length()));
exceptionState.throwIfNeeded();
return;
}
+ {# No match, throw error #}
exceptionState.throwTypeError("No matching constructor signature.");
exceptionState.throwIfNeeded();
- {% else %}
- throwTypeError(ExceptionMessages::failedToConstruct("{{interface_name}}", "No matching constructor signature."), info.GetIsolate());
- {% endif %}
}
{% endif %}
@@ -196,21 +636,22 @@ static void constructor(const v8::FunctionCallbackInfo<v8::Value>& info)
{% if has_event_constructor %}
static void constructor(const v8::FunctionCallbackInfo<v8::Value>& info)
{
- ExceptionState exceptionState(ExceptionState::ConstructionContext, "{{interface_name}}", info.Holder(), info.GetIsolate());
+ v8::Isolate* isolate = info.GetIsolate();
+ ExceptionState exceptionState(ExceptionState::ConstructionContext, "{{interface_name}}", info.Holder(), isolate);
if (info.Length() < 1) {
exceptionState.throwTypeError("An event name must be provided.");
exceptionState.throwIfNeeded();
return;
}
- V8TRYCATCH_FOR_V8STRINGRESOURCE_VOID(V8StringResource<>, type, info[0]);
+ TOSTRING_VOID(V8StringResource<>, type, info[0]);
{% for attribute in any_type_attributes %}
v8::Local<v8::Value> {{attribute.name}};
{% endfor %}
{{cpp_class}}Init eventInit;
if (info.Length() >= 2) {
- V8TRYCATCH_VOID(Dictionary, options, Dictionary(info[1], info.GetIsolate()));
- if (!initialize{{cpp_class}}(eventInit, options, exceptionState)) {
+ TONATIVE_VOID(Dictionary, options, Dictionary(info[1], isolate));
+ if (!initialize{{cpp_class}}(eventInit, options, exceptionState, info)) {
exceptionState.throwIfNeeded();
return;
}
@@ -219,15 +660,15 @@ static void constructor(const v8::FunctionCallbackInfo<v8::Value>& info)
{% for attribute in any_type_attributes %}
options.get("{{attribute.name}}", {{attribute.name}});
if (!{{attribute.name}}.IsEmpty())
- info.Holder()->SetHiddenValue(V8HiddenPropertyName::{{attribute.name}}(info.GetIsolate()), {{attribute.name}});
+ V8HiddenValue::setHiddenValue(isolate, info.Holder(), v8AtomicString(isolate, "{{attribute.name}}"), {{attribute.name}});
{% endfor %}
}
{% if is_constructor_raises_exception %}
- RefPtr<{{cpp_class}}> event = {{cpp_class}}::create(type, eventInit, exceptionState);
+ RefPtrWillBeRawPtr<{{cpp_class}}> event = {{cpp_class}}::create(type, eventInit, exceptionState);
if (exceptionState.throwIfNeeded())
return;
{% else %}
- RefPtr<{{cpp_class}}> event = {{cpp_class}}::create(type, eventInit);
+ RefPtrWillBeRawPtr<{{cpp_class}}> event = {{cpp_class}}::create(type, eventInit);
{% endif %}
{% if any_type_attributes and not interface_name == 'ErrorEvent' %}
{# If we're in an isolated world, create a SerializedScriptValue and store
@@ -239,16 +680,16 @@ static void constructor(const v8::FunctionCallbackInfo<v8::Value>& info)
thus passing it around would cause leakage.
2) Errors cannot be cloned (or serialized):
http://www.whatwg.org/specs/web-apps/current-work/multipage/common-dom-interfaces.html#safe-passing-of-structured-data #}
- if (isolatedWorldForIsolate(info.GetIsolate())) {
+ if (DOMWrapperWorld::current(isolate).isIsolatedWorld()) {
{% for attribute in any_type_attributes %}
if (!{{attribute.name}}.IsEmpty())
- event->setSerialized{{attribute.name | blink_capitalize}}(SerializedScriptValue::createAndSwallowExceptions({{attribute.name}}, info.GetIsolate()));
+ event->setSerialized{{attribute.name | blink_capitalize}}(SerializedScriptValue::createAndSwallowExceptions({{attribute.name}}, isolate));
{% endfor %}
}
{% endif %}
v8::Handle<v8::Object> wrapper = info.Holder();
- V8DOMWrapper::associateObjectWithWrapper<{{v8_class}}>(event.release(), &{{v8_class}}::wrapperTypeInfo, wrapper, info.GetIsolate(), WrapperConfiguration::Dependent);
+ V8DOMWrapper::associateObjectWithWrapper<{{v8_class}}>(event.release(), &{{v8_class}}::wrapperTypeInfo, wrapper, isolate, {{wrapper_configuration}});
v8SetReturnValue(info, wrapper);
}
@@ -258,14 +699,30 @@ static void constructor(const v8::FunctionCallbackInfo<v8::Value>& info)
{##############################################################################}
{% block visit_dom_wrapper %}
-{% if generate_visit_dom_wrapper_function %}
+{% if reachable_node_function or set_wrapper_reference_to_list %}
void {{v8_class}}::visitDOMWrapper(void* object, const v8::Persistent<v8::Object>& wrapper, v8::Isolate* isolate)
{
{{cpp_class}}* impl = fromInternalPointer(object);
- if (Node* owner = impl->{{generate_visit_dom_wrapper_function}}()) {
- setObjectGroup(V8GCController::opaqueRootForGC(owner, isolate), wrapper, isolate);
+ {% if set_wrapper_reference_to_list %}
+ v8::Local<v8::Object> creationContext = v8::Local<v8::Object>::New(isolate, wrapper);
+ V8WrapperInstantiationScope scope(creationContext, isolate);
+ {% for set_wrapper_reference_to in set_wrapper_reference_to_list %}
+ {{set_wrapper_reference_to.cpp_type}} {{set_wrapper_reference_to.name}} = impl->{{set_wrapper_reference_to.name}}();
+ if ({{set_wrapper_reference_to.name}}) {
+ if (!DOMDataStore::containsWrapper<{{set_wrapper_reference_to.v8_type}}>({{set_wrapper_reference_to.name}}, isolate))
+ wrap({{set_wrapper_reference_to.name}}, creationContext, isolate);
+ DOMDataStore::setWrapperReference<{{set_wrapper_reference_to.v8_type}}>(wrapper, {{set_wrapper_reference_to.name}}, isolate);
+ }
+ {% endfor %}
+ {% endif %}
+ {% if reachable_node_function %}
+ // The {{reachable_node_function}}() method may return a reference or a pointer.
+ if (Node* owner = WTF::getPtr(impl->{{reachable_node_function}}())) {
+ Node* root = V8GCController::opaqueRootForGC(owner, isolate);
+ isolate->SetReferenceFromGroup(v8::UniqueId(reinterpret_cast<intptr_t>(root)), wrapper);
return;
}
+ {% endif %}
setObjectGroup(object, wrapper, isolate);
}
@@ -274,15 +731,29 @@ void {{v8_class}}::visitDOMWrapper(void* object, const v8::Persistent<v8::Object
{##############################################################################}
+{% block shadow_attributes %}
+{% if interface_name == 'Window' %}
+static const V8DOMConfiguration::AttributeConfiguration shadowAttributes[] = {
+ {% for attribute in attributes if attribute.is_unforgeable %}
+ {{attribute_configuration(attribute)}},
+ {% endfor %}
+};
+
+{% endif %}
+{% endblock %}
+
+
+{##############################################################################}
{% block class_attributes %}
{# FIXME: rename to install_attributes and put into configure_class_template #}
-{% if attributes %}
+{% if has_attribute_configuration %}
static const V8DOMConfiguration::AttributeConfiguration {{v8_class}}Attributes[] = {
{% for attribute in attributes
if not (attribute.is_expose_js_accessors or
attribute.is_static or
attribute.runtime_enabled_function or
- attribute.per_context_enabled_function) %}
+ attribute.per_context_enabled_function or
+ (interface_name == 'Window' and attribute.is_unforgeable)) %}
{% filter conditional(attribute.conditional_string) %}
{{attribute_configuration(attribute)}},
{% endfilter %}
@@ -310,9 +781,9 @@ static const V8DOMConfiguration::AccessorConfiguration {{v8_class}}Accessors[] =
{##############################################################################}
{% block class_methods %}
{# FIXME: rename to install_methods and put into configure_class_template #}
-{% if has_method_configuration %}
+{% if method_configuration_methods %}
static const V8DOMConfiguration::MethodConfiguration {{v8_class}}Methods[] = {
- {% for method in methods if method.do_generate_method_configuration %}
+ {% for method in method_configuration_methods %}
{% filter conditional(method.conditional_string) %}
{{method_configuration(method)}},
{% endfilter %}
@@ -326,11 +797,11 @@ static const V8DOMConfiguration::MethodConfiguration {{v8_class}}Methods[] = {
{##############################################################################}
{% block initialize_event %}
{% if has_event_constructor %}
-bool initialize{{cpp_class}}({{cpp_class}}Init& eventInit, const Dictionary& options, ExceptionState& exceptionState, const String& forEventName)
+bool initialize{{cpp_class}}({{cpp_class}}Init& eventInit, const Dictionary& options, ExceptionState& exceptionState, const v8::FunctionCallbackInfo<v8::Value>& info, const String& forEventName)
{
Dictionary::ConversionContext conversionContext(forEventName.isEmpty() ? String("{{interface_name}}") : forEventName, "", exceptionState);
{% if parent_interface %}{# any Event interface except Event itself #}
- if (!initialize{{parent_interface}}(eventInit, options, exceptionState, forEventName.isEmpty() ? String("{{interface_name}}") : forEventName))
+ if (!initialize{{parent_interface}}(eventInit, options, exceptionState, info, forEventName.isEmpty() ? String("{{interface_name}}") : forEventName))
return false;
{% endif %}
@@ -341,7 +812,7 @@ bool initialize{{cpp_class}}({{cpp_class}}Init& eventInit, const Dictionary& opt
{% if attribute.deprecate_as %}
if (options.convert(conversionContext.setConversionType("{{attribute.idl_type}}", {{is_nullable}}), "{{attribute.name}}", eventInit.{{attribute.cpp_name}})) {
if (options.hasProperty("{{attribute.name}}"))
- UseCounter::countDeprecation(activeExecutionContext(), UseCounter::{{attribute.deprecate_as}});
+ UseCounter::countDeprecation(callingExecutionContext(info.GetIsolate()), UseCounter::{{attribute.deprecate_as}});
} else {
return false;
}
@@ -364,14 +835,14 @@ void {{v8_class}}::constructorCallback(const v8::FunctionCallbackInfo<v8::Value>
{
TRACE_EVENT_SCOPED_SAMPLING_STATE("Blink", "DOMConstructor");
{% if measure_as %}
- UseCounter::count(activeDOMWindow(), UseCounter::{{measure_as}});
+ UseCounter::count(callingExecutionContext(info.GetIsolate()), UseCounter::{{measure_as}});
{% endif %}
if (!info.IsConstructCall()) {
- throwTypeError(ExceptionMessages::failedToConstruct("{{interface_name}}", "Please use the 'new' operator, this DOM object constructor cannot be called as a function."), info.GetIsolate());
+ throwTypeError(ExceptionMessages::constructorNotCallableAsFunction("{{interface_name}}"), info.GetIsolate());
return;
}
- if (ConstructorMode::current() == ConstructorMode::WrapExistingObject) {
+ if (ConstructorMode::current(info.GetIsolate()) == ConstructorMode::WrapExistingObject) {
v8SetReturnValue(info, info.Holder());
return;
}
@@ -388,29 +859,50 @@ void {{v8_class}}::constructorCallback(const v8::FunctionCallbackInfo<v8::Value>
{##############################################################################}
+{% block configure_shadow_object_template %}
+{% if interface_name == 'Window' %}
+static void configureShadowObjectTemplate(v8::Handle<v8::ObjectTemplate> templ, v8::Isolate* isolate)
+{
+ V8DOMConfiguration::installAttributes(templ, v8::Handle<v8::ObjectTemplate>(), shadowAttributes, WTF_ARRAY_LENGTH(shadowAttributes), isolate);
+
+ // Install a security handler with V8.
+ templ->SetAccessCheckCallbacks(V8Window::namedSecurityCheckCustom, V8Window::indexedSecurityCheckCustom, v8::External::New(isolate, const_cast<WrapperTypeInfo*>(&V8Window::wrapperTypeInfo)));
+ templ->SetInternalFieldCount(V8Window::internalFieldCount);
+}
+
+{% endif %}
+{% endblock %}
+
+
+{##############################################################################}
{% block configure_class_template %}
{# FIXME: rename to install_dom_template and Install{{v8_class}}DOMTemplate #}
-static v8::Handle<v8::FunctionTemplate> Configure{{v8_class}}Template(v8::Handle<v8::FunctionTemplate> functionTemplate, v8::Isolate* isolate, WrapperWorldType currentWorldType)
+static void configure{{v8_class}}Template(v8::Handle<v8::FunctionTemplate> functionTemplate, v8::Isolate* isolate)
{
functionTemplate->ReadOnlyPrototype();
v8::Local<v8::Signature> defaultSignature;
{% set parent_template =
- 'V8%s::domTemplate(isolate, currentWorldType)' % parent_interface
+ 'V8%s::domTemplate(isolate)' % parent_interface
if parent_interface else 'v8::Local<v8::FunctionTemplate>()' %}
{% if runtime_enabled_function %}
if (!{{runtime_enabled_function}}())
- defaultSignature = V8DOMConfiguration::installDOMClassTemplate(functionTemplate, "", {{parent_template}}, {{v8_class}}::internalFieldCount, 0, 0, 0, 0, 0, 0, isolate, currentWorldType);
+ defaultSignature = V8DOMConfiguration::installDOMClassTemplate(functionTemplate, "", {{parent_template}}, {{v8_class}}::internalFieldCount, 0, 0, 0, 0, 0, 0, isolate);
else
{% endif %}
{% set runtime_enabled_indent = 4 if runtime_enabled_function else 0 %}
{% filter indent(runtime_enabled_indent, true) %}
defaultSignature = V8DOMConfiguration::installDOMClassTemplate(functionTemplate, "{{interface_name}}", {{parent_template}}, {{v8_class}}::internalFieldCount,
- {# Test needed as size 0 constant arrays are not allowed in VC++ #}
+ {# Test needed as size 0 arrays definitions are not allowed per standard
+ (so objects have distinct addresses), which is enforced by MSVC.
+ 8.5.1 Aggregates [dcl.init.aggr]
+ An array of unknown size initialized with a brace-enclosed
+ initializer-list containing n initializer-clauses, where n shall be
+ greater than zero, is defined as having n elements (8.3.4). #}
{% set attributes_name, attributes_length =
('%sAttributes' % v8_class,
'WTF_ARRAY_LENGTH(%sAttributes)' % v8_class)
- if attributes else (0, 0) %}
+ if has_attribute_configuration else (0, 0) %}
{% set accessors_name, accessors_length =
('%sAccessors' % v8_class,
'WTF_ARRAY_LENGTH(%sAccessors)' % v8_class)
@@ -418,51 +910,96 @@ static v8::Handle<v8::FunctionTemplate> Configure{{v8_class}}Template(v8::Handle
{% set methods_name, methods_length =
('%sMethods' % v8_class,
'WTF_ARRAY_LENGTH(%sMethods)' % v8_class)
- if has_method_configuration else (0, 0) %}
+ if method_configuration_methods else (0, 0) %}
{{attributes_name}}, {{attributes_length}},
{{accessors_name}}, {{accessors_length}},
{{methods_name}}, {{methods_length}},
- isolate, currentWorldType);
+ isolate);
{% endfilter %}
{% if constructors or has_custom_constructor or has_event_constructor %}
functionTemplate->SetCallHandler({{v8_class}}::constructorCallback);
functionTemplate->SetLength({{interface_length}});
{% endif %}
- v8::Local<v8::ObjectTemplate> ALLOW_UNUSED instanceTemplate = functionTemplate->InstanceTemplate();
- v8::Local<v8::ObjectTemplate> ALLOW_UNUSED prototypeTemplate = functionTemplate->PrototypeTemplate();
+ v8::Local<v8::ObjectTemplate> instanceTemplate ALLOW_UNUSED = functionTemplate->InstanceTemplate();
+ v8::Local<v8::ObjectTemplate> prototypeTemplate ALLOW_UNUSED = functionTemplate->PrototypeTemplate();
{% if is_check_security and interface_name != 'Window' %}
instanceTemplate->SetAccessCheckCallbacks({{cpp_class}}V8Internal::namedSecurityCheck, {{cpp_class}}V8Internal::indexedSecurityCheck, v8::External::New(isolate, const_cast<WrapperTypeInfo*>(&{{v8_class}}::wrapperTypeInfo)));
{% endif %}
- {% for attribute in attributes if attribute.runtime_enabled_function %}
+ {% for attribute in attributes
+ if attribute.runtime_enabled_function and
+ not attribute.per_context_enabled_function and
+ not attribute.is_static %}
{% filter conditional(attribute.conditional_string) %}
if ({{attribute.runtime_enabled_function}}()) {
static const V8DOMConfiguration::AttributeConfiguration attributeConfiguration =\
{{attribute_configuration(attribute)}};
- V8DOMConfiguration::installAttribute(instanceTemplate, prototypeTemplate, attributeConfiguration, isolate, currentWorldType);
+ V8DOMConfiguration::installAttribute(instanceTemplate, prototypeTemplate, attributeConfiguration, isolate);
}
{% endfilter %}
{% endfor %}
{% if constants %}
{{install_constants() | indent}}
{% endif %}
- {% for method in methods if not method.do_not_check_signature %}
- {% if method.custom_signature and not method.overload_index %}
- {# No custom signature needed for overloaded methods;
- separate check because depends on global check for overloads #}
-
- // Custom Signature '{{method.name}}'
- const int {{method.name}}Argc = {{method.arguments | length}};
- v8::Handle<v8::FunctionTemplate> {{method.name}}Argv[{{method.name}}Argc] = { {{method.custom_signature}} };
- v8::Handle<v8::Signature> {{method.name}}Signature = v8::Signature::New(isolate, functionTemplate, {{method.name}}Argc, {{method.name}}Argv);
+ {# Special operations #}
+ {# V8 has access-check callback API and it's used on Window instead of
+ deleters or enumerators; see ObjectTemplate::SetAccessCheckCallbacks.
+ In addition, the getter should be set on the prototype template, to get
+ the implementation straight out of the Window prototype, regardless of
+ what prototype is actually set on the object. #}
+ {% set set_on_template = 'PrototypeTemplate' if interface_name == 'Window'
+ else 'InstanceTemplate' %}
+ {% if indexed_property_getter %}
+ {# if have indexed properties, MUST have an indexed property getter #}
+ {% set indexed_property_getter_callback =
+ '%sV8Internal::indexedPropertyGetterCallback' % cpp_class %}
+ {% set indexed_property_setter_callback =
+ '%sV8Internal::indexedPropertySetterCallback' % cpp_class
+ if indexed_property_setter else '0' %}
+ {% set indexed_property_query_callback = '0' %}{# Unused #}
+ {% set indexed_property_deleter_callback =
+ '%sV8Internal::indexedPropertyDeleterCallback' % cpp_class
+ if indexed_property_deleter else '0' %}
+ {% set indexed_property_enumerator_callback =
+ 'indexedPropertyEnumerator<%s>' % cpp_class
+ if indexed_property_getter.is_enumerable else '0' %}
+ functionTemplate->{{set_on_template}}()->SetIndexedPropertyHandler({{indexed_property_getter_callback}}, {{indexed_property_setter_callback}}, {{indexed_property_query_callback}}, {{indexed_property_deleter_callback}}, {{indexed_property_enumerator_callback}});
+ {% endif %}
+ {% if named_property_getter %}
+ {# if have named properties, MUST have a named property getter #}
+ {% set named_property_getter_callback =
+ '%sV8Internal::namedPropertyGetterCallback' % cpp_class %}
+ {% set named_property_setter_callback =
+ '%sV8Internal::namedPropertySetterCallback' % cpp_class
+ if named_property_setter else '0' %}
+ {% set named_property_query_callback =
+ '%sV8Internal::namedPropertyQueryCallback' % cpp_class
+ if named_property_getter.is_enumerable else '0' %}
+ {% set named_property_deleter_callback =
+ '%sV8Internal::namedPropertyDeleterCallback' % cpp_class
+ if named_property_deleter else '0' %}
+ {% set named_property_enumerator_callback =
+ '%sV8Internal::namedPropertyEnumeratorCallback' % cpp_class
+ if named_property_getter.is_enumerable else '0' %}
+ functionTemplate->{{set_on_template}}()->SetNamedPropertyHandler({{named_property_getter_callback}}, {{named_property_setter_callback}}, {{named_property_query_callback}}, {{named_property_deleter_callback}}, {{named_property_enumerator_callback}});
{% endif %}
+ {# End special operations #}
+ {% if has_custom_legacy_call_as_function %}
+ functionTemplate->InstanceTemplate()->SetCallAsFunctionHandler({{v8_class}}::legacyCallCustom);
+ {% endif %}
+ {% if interface_name == 'HTMLAllCollection' %}
+ {# Needed for legacy support of document.all #}
+ functionTemplate->InstanceTemplate()->MarkAsUndetectable();
+ {% endif %}
+ {% for method in custom_registration_methods %}
{# install_custom_signature #}
- {% if not method.overload_index or method.overload_index == 1 %}
- {# For overloaded methods, only generate one accessor #}
{% filter conditional(method.conditional_string) %}
+ {% filter runtime_enabled(method.overloads.runtime_enabled_function_all
+ if method.overloads else
+ method.runtime_enabled_function) %}
{% if method.is_do_not_check_security %}
{% if method.is_per_world_bindings %}
- if (currentWorldType == MainWorld) {
+ if (DOMWrapperWorld::current(isolate).isMainWorld()) {
{{install_do_not_check_security_signature(method, 'ForMainWorld')}}
} else {
{{install_do_not_check_security_signature(method)}}
@@ -472,40 +1009,43 @@ static v8::Handle<v8::FunctionTemplate> Configure{{v8_class}}Template(v8::Handle
{% endif %}
{% else %}{# is_do_not_check_security #}
{% if method.is_per_world_bindings %}
- if (currentWorldType == MainWorld) {
- {% filter runtime_enabled(method.runtime_enabled_function) %}
+ if (DOMWrapperWorld::current(isolate).isMainWorld()) {
{{install_custom_signature(method, 'ForMainWorld')}}
- {% endfilter %}
} else {
- {% filter runtime_enabled(method.runtime_enabled_function) %}
{{install_custom_signature(method)}}
- {% endfilter %}
}
{% else %}
- {% filter runtime_enabled(method.runtime_enabled_function) %}
{{install_custom_signature(method)}}
- {% endfilter %}
{% endif %}
{% endif %}{# is_do_not_check_security #}
- {% endfilter %}
- {% endif %}{# install_custom_signature #}
+ {% endfilter %}{# runtime_enabled() #}
+ {% endfilter %}{# conditional() #}
{% endfor %}
{% for attribute in attributes if attribute.is_static %}
{% set getter_callback = '%sV8Internal::%sAttributeGetterCallback' %
- (interface_name, attribute.name) %}
- functionTemplate->SetNativeDataProperty(v8::String::NewFromUtf8(isolate, "{{attribute.name}}", v8::String::kInternalizedString), {{getter_callback}}, {{attribute.setter_callback}}, v8::External::New(isolate, 0), static_cast<v8::PropertyAttribute>(v8::None), v8::Handle<v8::AccessorSignature>(), static_cast<v8::AccessControl>(v8::DEFAULT));
+ (cpp_class, attribute.name) %}
+ {% filter conditional(attribute.conditional_string) %}
+ functionTemplate->SetNativeDataProperty(v8AtomicString(isolate, "{{attribute.name}}"), {{getter_callback}}, {{attribute.setter_callback}}, v8::External::New(isolate, 0), static_cast<v8::PropertyAttribute>(v8::None), v8::Handle<v8::AccessorSignature>(), static_cast<v8::AccessControl>(v8::DEFAULT));
+ {% endfilter %}
{% endfor %}
- {% if has_custom_legacy_call_as_function %}
- functionTemplate->InstanceTemplate()->SetCallAsFunctionHandler({{v8_class}}::legacyCallCustom);
- {% endif %}
- {% if interface_name == 'HTMLAllCollection' %}
- {# Needed for legacy support of document.all #}
- functionTemplate->InstanceTemplate()->MarkAsUndetectable();
+ {# Special interfaces #}
+ {% if interface_name == 'Window' %}
+
+ prototypeTemplate->SetInternalFieldCount(V8Window::internalFieldCount);
+ functionTemplate->SetHiddenPrototype(true);
+ instanceTemplate->SetInternalFieldCount(V8Window::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.
+ instanceTemplate->SetAccessCheckCallbacks(V8Window::namedSecurityCheckCustom, V8Window::indexedSecurityCheckCustom, v8::External::New(isolate, const_cast<WrapperTypeInfo*>(&V8Window::wrapperTypeInfo)), false);
+ {% elif interface_name in [
+ 'HTMLDocument', 'DedicatedWorkerGlobalScope',
+ 'SharedWorkerGlobalScope', 'ServiceWorkerGlobalScope'] %}
+ functionTemplate->SetHiddenPrototype(true);
{% endif %}
// Custom toString template
- functionTemplate->Set(v8::String::NewFromUtf8(isolate, "toString", v8::String::kInternalizedString), V8PerIsolateData::current()->toStringTemplate());
- return functionTemplate;
+ functionTemplate->Set(v8AtomicString(isolate, "toString"), V8PerIsolateData::from(isolate)->toStringTemplate());
}
{% endblock %}
@@ -527,7 +1067,7 @@ static v8::Handle<v8::FunctionTemplate> Configure{{v8_class}}Template(v8::Handle
{% set property_attribute =
'static_cast<v8::PropertyAttribute>(%s)' %
' | '.join(method.property_attributes or ['v8::DontDelete']) %}
-{{method.function_template}}->SetAccessor(v8::String::NewFromUtf8(isolate, "{{method.name}}", v8::String::kInternalizedString), {{getter_callback}}, {{setter_callback}}, v8Undefined(), v8::ALL_CAN_READ, {{property_attribute}});
+{{method.function_template}}->SetAccessor(v8AtomicString(isolate, "{{method.name}}"), {{getter_callback}}, {{setter_callback}}, v8Undefined(), v8::ALL_CAN_READ, {{property_attribute}});
{%- endmacro %}
@@ -535,10 +1075,10 @@ static v8::Handle<v8::FunctionTemplate> Configure{{v8_class}}Template(v8::Handle
{% macro install_custom_signature(method, world_suffix) %}
{# FIXME: move to V8DOMConfiguration::installDOMCallbacksWithCustomSignature #}
{% set method_callback = '%sV8Internal::%sMethodCallback%s' %
- (interface_name, method.name, world_suffix) %}
+ (cpp_class, method.name, world_suffix) %}
{% set property_attribute = 'static_cast<v8::PropertyAttribute>(%s)' %
' | '.join(method.property_attributes) %}
-{{method.function_template}}->Set(v8::String::NewFromUtf8(isolate, "{{method.name}}", v8::String::kInternalizedString), v8::FunctionTemplate::New(isolate, {{method_callback}}, v8Undefined(), {{method.signature}}, {{method.number_of_required_or_variadic_arguments}}){% if method.property_attributes %}, {{property_attribute}}{% endif %});
+{{method.function_template}}->Set(v8AtomicString(isolate, "{{method.name}}"), v8::FunctionTemplate::New(isolate, {{method_callback}}, v8Undefined(), {{method.signature}}, {{method.length}}){% if method.property_attributes %}, {{property_attribute}}{% endif %});
{%- endmacro %}
@@ -562,7 +1102,8 @@ if ({{constant.runtime_enabled_function}}()) {
{# Check constants #}
{% if not do_not_check_constants %}
{% for constant in constants %}
-COMPILE_ASSERT({{constant.value}} == {{cpp_class}}::{{constant.reflected_name}}, TheValueOf{{cpp_class}}_{{constant.reflected_name}}DoesntMatchWithImplementation);
+{% set constant_cpp_class = constant.cpp_class or cpp_class %}
+COMPILE_ASSERT({{constant.value}} == {{constant_cpp_class}}::{{constant.reflected_name}}, TheValueOf{{cpp_class}}_{{constant.reflected_name}}DoesntMatchWithImplementation);
{% endfor %}
{% endif %}
{% endmacro %}
@@ -571,36 +1112,34 @@ COMPILE_ASSERT({{constant.value}} == {{cpp_class}}::{{constant.reflected_name}},
{##############################################################################}
{% block get_template %}
{# FIXME: rename to get_dom_template and GetDOMTemplate #}
-v8::Handle<v8::FunctionTemplate> {{v8_class}}::domTemplate(v8::Isolate* isolate, WrapperWorldType currentWorldType)
+v8::Handle<v8::FunctionTemplate> {{v8_class}}::domTemplate(v8::Isolate* isolate)
{
- V8PerIsolateData* data = V8PerIsolateData::from(isolate);
- V8PerIsolateData::TemplateMap::iterator result = data->templateMap(currentWorldType).find(&wrapperTypeInfo);
- if (result != data->templateMap(currentWorldType).end())
- return result->value.newLocal(isolate);
-
- TRACE_EVENT_SCOPED_SAMPLING_STATE("Blink", "BuildDOMTemplate");
- v8::EscapableHandleScope handleScope(isolate);
- v8::Local<v8::FunctionTemplate> templ =
- Configure{{v8_class}}Template(data->rawDOMTemplate(&wrapperTypeInfo, currentWorldType), isolate, currentWorldType);
- data->templateMap(currentWorldType).add(&wrapperTypeInfo, UnsafePersistent<v8::FunctionTemplate>(isolate, templ));
- return handleScope.Escape(templ);
+ return V8DOMConfiguration::domClassTemplate(isolate, const_cast<WrapperTypeInfo*>(&wrapperTypeInfo), configure{{v8_class}}Template);
}
{% endblock %}
{##############################################################################}
-{% block has_instance_and_has_instance_in_any_world %}
-bool {{v8_class}}::hasInstance(v8::Handle<v8::Value> jsValue, v8::Isolate* isolate, WrapperWorldType currentWorldType)
+{% block has_instance %}
+bool {{v8_class}}::hasInstance(v8::Handle<v8::Value> v8Value, v8::Isolate* isolate)
+{
+ return V8PerIsolateData::from(isolate)->hasInstance(&wrapperTypeInfo, v8Value);
+}
+
+v8::Handle<v8::Object> {{v8_class}}::findInstanceInPrototypeChain(v8::Handle<v8::Value> v8Value, v8::Isolate* isolate)
{
- return V8PerIsolateData::from(isolate)->hasInstance(&wrapperTypeInfo, jsValue, currentWorldType);
+ return V8PerIsolateData::from(isolate)->findInstanceInPrototypeChain(&wrapperTypeInfo, v8Value);
}
-bool {{v8_class}}::hasInstanceInAnyWorld(v8::Handle<v8::Value> jsValue, v8::Isolate* isolate)
+{% endblock %}
+
+
+{##############################################################################}
+{% block to_native_with_type_check %}
+{{cpp_class}}* {{v8_class}}::toNativeWithTypeCheck(v8::Isolate* isolate, v8::Handle<v8::Value> value)
{
- return V8PerIsolateData::from(isolate)->hasInstance(&wrapperTypeInfo, jsValue, MainWorld)
- || V8PerIsolateData::from(isolate)->hasInstance(&wrapperTypeInfo, jsValue, IsolatedWorld)
- || V8PerIsolateData::from(isolate)->hasInstance(&wrapperTypeInfo, jsValue, WorkerWorld);
+ return hasInstance(value, isolate) ? fromInternalPointer(v8::Handle<v8::Object>::Cast(value)->GetAlignedPointerFromInternalField(v8DOMWrapperObjectIndex)) : 0;
}
{% endblock %}
@@ -627,16 +1166,16 @@ void {{v8_class}}::installPerContextEnabledProperties(v8::Handle<v8::Object> ins
{##############################################################################}
{% block install_per_context_methods %}
-{% if has_per_context_enabled_methods %}
+{% if per_context_enabled_methods %}
void {{v8_class}}::installPerContextEnabledMethods(v8::Handle<v8::Object> prototypeTemplate, v8::Isolate* isolate)
{
{# Define per-context enabled operations #}
- v8::Local<v8::Signature> defaultSignature = v8::Signature::New(isolate, domTemplate(isolate, worldType(isolate)));
+ v8::Local<v8::Signature> defaultSignature = v8::Signature::New(isolate, domTemplate(isolate));
ExecutionContext* context = toExecutionContext(prototypeTemplate->CreationContext());
- {% for method in methods if method.per_context_enabled_function %}
+ {% for method in per_context_enabled_methods %}
if (context && context->isDocument() && {{method.per_context_enabled_function}}(toDocument(context)))
- prototypeTemplate->Set(v8::String::NewFromUtf8(isolate, "{{method.name}}", v8::String::kInternalizedString), v8::FunctionTemplate::New(isolate, {{cpp_class}}V8Internal::{{method.name}}MethodCallback, v8Undefined(), defaultSignature, {{method.number_of_required_arguments}})->GetFunction());
+ prototypeTemplate->Set(v8AtomicString(isolate, "{{method.name}}"), v8::FunctionTemplate::New(isolate, {{cpp_class}}V8Internal::{{method.name}}MethodCallback, v8Undefined(), defaultSignature, {{method.number_of_required_arguments}})->GetFunction());
{% endfor %}
}
@@ -669,8 +1208,40 @@ EventTarget* {{v8_class}}::toEventTarget(v8::Handle<v8::Object> object)
{##############################################################################}
+{% block get_shadow_object_template %}
+{% if interface_name == 'Window' %}
+v8::Handle<v8::ObjectTemplate> V8Window::getShadowObjectTemplate(v8::Isolate* isolate)
+{
+ if (DOMWrapperWorld::current(isolate).isMainWorld()) {
+ DEFINE_STATIC_LOCAL(v8::Persistent<v8::ObjectTemplate>, V8WindowShadowObjectCacheForMainWorld, ());
+ if (V8WindowShadowObjectCacheForMainWorld.IsEmpty()) {
+ TRACE_EVENT_SCOPED_SAMPLING_STATE("Blink", "BuildDOMTemplate");
+ v8::Handle<v8::ObjectTemplate> templ = v8::ObjectTemplate::New(isolate);
+ configureShadowObjectTemplate(templ, isolate);
+ V8WindowShadowObjectCacheForMainWorld.Reset(isolate, templ);
+ return templ;
+ }
+ return v8::Local<v8::ObjectTemplate>::New(isolate, V8WindowShadowObjectCacheForMainWorld);
+ } else {
+ DEFINE_STATIC_LOCAL(v8::Persistent<v8::ObjectTemplate>, V8WindowShadowObjectCacheForNonMainWorld, ());
+ if (V8WindowShadowObjectCacheForNonMainWorld.IsEmpty()) {
+ TRACE_EVENT_SCOPED_SAMPLING_STATE("Blink", "BuildDOMTemplate");
+ v8::Handle<v8::ObjectTemplate> templ = v8::ObjectTemplate::New(isolate);
+ configureShadowObjectTemplate(templ, isolate);
+ V8WindowShadowObjectCacheForNonMainWorld.Reset(isolate, templ);
+ return templ;
+ }
+ return v8::Local<v8::ObjectTemplate>::New(isolate, V8WindowShadowObjectCacheForNonMainWorld);
+ }
+}
+
+{% endif %}
+{% endblock %}
+
+
+{##############################################################################}
{% block wrap %}
-{% if special_wrap_for %}
+{% if special_wrap_for or is_document %}
v8::Handle<v8::Object> wrap({{cpp_class}}* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
{
ASSERT(impl);
@@ -679,9 +1250,26 @@ v8::Handle<v8::Object> wrap({{cpp_class}}* impl, v8::Handle<v8::Object> creation
return wrap(to{{special_wrap_interface}}(impl), creationContext, isolate);
{% endfor %}
v8::Handle<v8::Object> wrapper = {{v8_class}}::createWrapper(impl, creationContext, isolate);
+ {% if is_document %}
+ if (wrapper.IsEmpty())
+ return wrapper;
+ DOMWrapperWorld& world = DOMWrapperWorld::current(isolate);
+ if (world.isMainWorld()) {
+ if (LocalFrame* frame = impl->frame())
+ frame->script().windowShell(world)->updateDocumentWrapper(wrapper);
+ }
+ {% endif %}
return wrapper;
}
+{% elif not has_custom_to_v8 and not has_custom_wrap %}
+v8::Handle<v8::Object> wrap({{cpp_class}}* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
+{
+ ASSERT(impl);
+ ASSERT(!DOMDataStore::containsWrapper<{{v8_class}}>(impl, isolate));
+ return {{v8_class}}::createWrapper(impl, creationContext, isolate);
+}
+
{% endif %}
{% endblock %}
@@ -689,27 +1277,42 @@ v8::Handle<v8::Object> wrap({{cpp_class}}* impl, v8::Handle<v8::Object> creation
{##############################################################################}
{% block create_wrapper %}
{% if not has_custom_to_v8 %}
-v8::Handle<v8::Object> {{v8_class}}::createWrapper(PassRefPtr<{{cpp_class}}> impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
+v8::Handle<v8::Object> {{v8_class}}::createWrapper({{pass_cpp_type}} impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
{
ASSERT(impl);
ASSERT(!DOMDataStore::containsWrapper<{{v8_class}}>(impl.get(), isolate));
if (ScriptWrappable::wrapperCanBeStoredInObject(impl.get())) {
- const WrapperTypeInfo* actualInfo = ScriptWrappable::getTypeInfoFromObject(impl.get());
+ const WrapperTypeInfo* actualInfo = ScriptWrappable::fromObject(impl.get())->typeInfo();
// Might be a XXXConstructor::wrapperTypeInfo instead of an XXX::wrapperTypeInfo. These will both have
// the same object de-ref functions, though, so use that as the basis of the check.
RELEASE_ASSERT_WITH_SECURITY_IMPLICATION(actualInfo->derefObjectFunction == wrapperTypeInfo.derefObjectFunction);
}
+ {% if is_document %}
+ if (LocalFrame* frame = impl->frame()) {
+ if (frame->script().initializeMainWorld()) {
+ // initializeMainWorld may have created a wrapper for the object, retry from the start.
+ v8::Handle<v8::Object> wrapper = DOMDataStore::getWrapper<{{v8_class}}>(impl.get(), isolate);
+ if (!wrapper.IsEmpty())
+ return wrapper;
+ }
+ }
+ {% endif %}
v8::Handle<v8::Object> wrapper = V8DOMWrapper::createWrapper(creationContext, &wrapperTypeInfo, toInternalPointer(impl.get()), isolate);
if (UNLIKELY(wrapper.IsEmpty()))
return wrapper;
+ {% if is_audio_buffer %}
+ {# We only setDeallocationObservers on array buffers that are held by some
+ object in the V8 heap, not in the ArrayBuffer constructor itself.
+ This is because V8 GC only cares about memory it can free on GC, and
+ until the object is exposed to JavaScript, V8 GC doesn't affect it. #}
+ for (unsigned i = 0, n = impl->numberOfChannels(); i < n; i++) {
+ Float32Array* channelData = impl->getChannelData(i);
+ channelData->buffer()->setDeallocationObserver(V8ArrayBufferDeallocationObserver::instanceTemplate());
+ }
+ {% endif %}
installPerContextEnabledProperties(wrapper, impl.get(), isolate);
- {% set wrapper_configuration = 'WrapperConfiguration::Dependent'
- if (has_visit_dom_wrapper or
- is_active_dom_object or
- is_dependent_lifetime) else
- 'WrapperConfiguration::Independent' %}
V8DOMWrapper::associateObjectWithWrapper<{{v8_class}}>(impl, &wrapperTypeInfo, wrapper, isolate, {{wrapper_configuration}});
return wrapper;
}
@@ -722,7 +1325,13 @@ v8::Handle<v8::Object> {{v8_class}}::createWrapper(PassRefPtr<{{cpp_class}}> imp
{% block deref_object_and_to_v8_no_inline %}
void {{v8_class}}::derefObject(void* object)
{
+{% if gc_type == 'RefCountedObject' %}
fromInternalPointer(object)->deref();
+{% elif gc_type == 'WillBeGarbageCollectedObject' %}
+{% filter conditional('!ENABLE(OILPAN)') %}
+ fromInternalPointer(object)->deref();
+{% endfilter %}
+{% endif %}
}
template<>
diff --git a/chromium/third_party/WebKit/Source/bindings/templates/interface.h b/chromium/third_party/WebKit/Source/bindings/templates/interface.h
index 0160f37d269..653a2d42935 100644
--- a/chromium/third_party/WebKit/Source/bindings/templates/interface.h
+++ b/chromium/third_party/WebKit/Source/bindings/templates/interface.h
@@ -1,36 +1,8 @@
-{# http://www.chromium.org/blink/coding-style#TOC-License #}
-/*
- * Copyright (C) 2013 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.
- */
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
-{# FIXME: Rename to Python when switch #}
-// This file has been auto-generated by code_generator_v8.pm. DO NOT MODIFY!
+// This file has been auto-generated by {{code_generator}}. DO NOT MODIFY!
#ifndef {{v8_class}}_h
#define {{v8_class}}_h
@@ -48,22 +20,23 @@ class Dictionary;
{% if named_constructor %}
class {{v8_class}}Constructor {
public:
- static v8::Handle<v8::FunctionTemplate> domTemplate(v8::Isolate*, WrapperWorldType);
+ static v8::Handle<v8::FunctionTemplate> domTemplate(v8::Isolate*);
static const WrapperTypeInfo wrapperTypeInfo;
};
{% endif %}
class {{v8_class}} {
public:
- static bool hasInstance(v8::Handle<v8::Value>, v8::Isolate*, WrapperWorldType);
- static bool hasInstanceInAnyWorld(v8::Handle<v8::Value>, v8::Isolate*);
- static v8::Handle<v8::FunctionTemplate> domTemplate(v8::Isolate*, WrapperWorldType);
+ static bool hasInstance(v8::Handle<v8::Value>, v8::Isolate*);
+ static v8::Handle<v8::Object> findInstanceInPrototypeChain(v8::Handle<v8::Value>, v8::Isolate*);
+ static v8::Handle<v8::FunctionTemplate> domTemplate(v8::Isolate*);
static {{cpp_class}}* toNative(v8::Handle<v8::Object> object)
{
return fromInternalPointer(object->GetAlignedPointerFromInternalField(v8DOMWrapperObjectIndex));
}
- static void derefObject(void*);
+ static {{cpp_class}}* toNativeWithTypeCheck(v8::Isolate*, v8::Handle<v8::Value>);
static const WrapperTypeInfo wrapperTypeInfo;
+ static void derefObject(void*);
{% if has_visit_dom_wrapper %}
static void visitDOMWrapper(void*, const v8::Persistent<v8::Object>&, v8::Isolate*);
{% endif %}
@@ -73,6 +46,9 @@ public:
{% if is_event_target %}
static EventTarget* toEventTarget(v8::Handle<v8::Object>);
{% endif %}
+ {% if interface_name == 'Window' %}
+ static v8::Handle<v8::ObjectTemplate> getShadowObjectTemplate(v8::Isolate*);
+ {% endif %}
{% for method in methods if method.is_custom %}
{% filter conditional(method.conditional_string) %}
static void {{method.name}}MethodCustom(const v8::FunctionCallbackInfo<v8::Value>&);
@@ -96,16 +72,63 @@ public:
{% endfilter %}
{% endif %}
{% endfor %}
+ {# Custom special operations #}
+ {% if indexed_property_getter and indexed_property_getter.is_custom %}
+ static void indexedPropertyGetterCustom(uint32_t, const v8::PropertyCallbackInfo<v8::Value>&);
+ {% endif %}
+ {% if indexed_property_setter and indexed_property_setter.is_custom %}
+ static void indexedPropertySetterCustom(uint32_t, v8::Local<v8::Value>, const v8::PropertyCallbackInfo<v8::Value>&);
+ {% endif %}
+ {% if indexed_property_deleter and indexed_property_deleter.is_custom %}
+ static void indexedPropertyDeleterCustom(uint32_t, const v8::PropertyCallbackInfo<v8::Boolean>&);
+ {% endif %}
+ {% if named_property_getter and named_property_getter.is_custom %}
+ static void namedPropertyGetterCustom(v8::Local<v8::String>, const v8::PropertyCallbackInfo<v8::Value>&);
+ {% endif %}
+ {% if named_property_setter and named_property_setter.is_custom %}
+ static void namedPropertySetterCustom(v8::Local<v8::String>, v8::Local<v8::Value>, const v8::PropertyCallbackInfo<v8::Value>&);
+ {% endif %}
+ {% if named_property_getter and
+ named_property_getter.is_custom_property_query %}
+ static void namedPropertyQueryCustom(v8::Local<v8::String>, const v8::PropertyCallbackInfo<v8::Integer>&);
+ {% endif %}
+ {% if named_property_deleter and named_property_deleter.is_custom %}
+ static void namedPropertyDeleterCustom(v8::Local<v8::String>, const v8::PropertyCallbackInfo<v8::Boolean>&);
+ {% endif %}
+ {% if named_property_getter and
+ named_property_getter.is_custom_property_enumerator %}
+ static void namedPropertyEnumeratorCustom(const v8::PropertyCallbackInfo<v8::Array>&);
+ {% endif %}
+ {# END custom special operations #}
{% if has_custom_legacy_call_as_function %}
static void legacyCallCustom(const v8::FunctionCallbackInfo<v8::Value>&);
{% endif %}
+ {# Custom internal fields #}
{% set custom_internal_field_counter = 0 %}
{% if is_event_target and not is_node %}
{# Event listeners on DOM nodes are explicitly supported in the GC controller. #}
- static const int eventListenerCacheIndex = v8DefaultWrapperInternalFieldCount + 0;
+ static const int eventListenerCacheIndex = v8DefaultWrapperInternalFieldCount + {{custom_internal_field_counter}};
{% set custom_internal_field_counter = custom_internal_field_counter + 1 %}
{% endif %}
+ {# persistentHandleIndex must be the last field, if it is present.
+ Detailed explanation: https://codereview.chromium.org/139173012
+ FIXME: Remove this internal field, and share one field for either:
+ * a persistent handle (if the object is in oilpan) or
+ * a C++ pointer to the DOM object (if the object is not in oilpan) #}
+ {% if gc_type == 'GarbageCollectedObject' %}
+ static const int persistentHandleIndex = v8DefaultWrapperInternalFieldCount + {{custom_internal_field_counter}};
+ static const int internalFieldCount = v8DefaultWrapperInternalFieldCount + {{custom_internal_field_counter}} + 1;
+ {% elif gc_type == 'WillBeGarbageCollectedObject' %}
+#if ENABLE(OILPAN)
+ static const int persistentHandleIndex = v8DefaultWrapperInternalFieldCount + {{custom_internal_field_counter}};
+ static const int internalFieldCount = v8DefaultWrapperInternalFieldCount + {{custom_internal_field_counter}} + 1;
+#else
static const int internalFieldCount = v8DefaultWrapperInternalFieldCount + {{custom_internal_field_counter}};
+#endif
+ {% else %}
+ static const int internalFieldCount = v8DefaultWrapperInternalFieldCount + {{custom_internal_field_counter}};
+ {% endif %}
+ {# End custom internal fields #}
static inline void* toInternalPointer({{cpp_class}}* impl)
{
{% if parent_interface %}
@@ -123,26 +146,38 @@ public:
return static_cast<{{cpp_class}}*>(object);
{% endif %}
}
+ {% if interface_name == 'Window' %}
+ static bool namedSecurityCheckCustom(v8::Local<v8::Object> host, v8::Local<v8::Value> key, v8::AccessType, v8::Local<v8::Value> data);
+ static bool indexedSecurityCheckCustom(v8::Local<v8::Object> host, uint32_t index, v8::AccessType, v8::Local<v8::Value> data);
+ {% endif %}
static void installPerContextEnabledProperties(v8::Handle<v8::Object>, {{cpp_class}}*, v8::Isolate*){% if has_per_context_enabled_attributes %};
{% else %} { }
{% endif %}
- static void installPerContextEnabledMethods(v8::Handle<v8::Object>, v8::Isolate*){% if has_per_context_enabled_attributes %};
+ static void installPerContextEnabledMethods(v8::Handle<v8::Object>, v8::Isolate*){% if per_context_enabled_methods %};
{% else %} { }
{% endif %}
+ {# Element wrappers #}
+ {% if interface_name == 'HTMLElement' %}
+ friend v8::Handle<v8::Object> createV8HTMLWrapper(HTMLElement*, v8::Handle<v8::Object> creationContext, v8::Isolate*);
+ friend v8::Handle<v8::Object> createV8HTMLDirectWrapper(HTMLElement*, v8::Handle<v8::Object> creationContext, v8::Isolate*);
+ {% elif interface_name == 'SVGElement' %}
+ friend v8::Handle<v8::Object> createV8SVGWrapper(SVGElement*, v8::Handle<v8::Object> creationContext, v8::Isolate*);
+ friend v8::Handle<v8::Object> createV8SVGDirectWrapper(SVGElement*, v8::Handle<v8::Object> creationContext, v8::Isolate*);
+ friend v8::Handle<v8::Object> createV8SVGFallbackWrapper(SVGElement*, v8::Handle<v8::Object> creationContext, v8::Isolate*);
+ {% elif interface_name == 'HTMLUnknownElement' %}
+ friend v8::Handle<v8::Object> createV8HTMLFallbackWrapper(HTMLUnknownElement*, v8::Handle<v8::Object> creationContext, v8::Isolate*);
+ {% elif interface_name == 'Element' %}
+ // This is a performance optimization hack. See V8Element::wrap.
+ friend v8::Handle<v8::Object> wrap(Node*, v8::Handle<v8::Object> creationContext, v8::Isolate*);
+ {% endif %}
private:
{% if not has_custom_to_v8 %}
friend v8::Handle<v8::Object> wrap({{cpp_class}}*, v8::Handle<v8::Object> creationContext, v8::Isolate*);
- static v8::Handle<v8::Object> createWrapper(PassRefPtr<{{cpp_class}}>, v8::Handle<v8::Object> creationContext, v8::Isolate*);
+ static v8::Handle<v8::Object> createWrapper({{pass_cpp_type}}, v8::Handle<v8::Object> creationContext, v8::Isolate*);
{% endif %}
};
-template<>
-class WrapperTypeTraits<{{cpp_class}} > {
-public:
- static const WrapperTypeInfo* wrapperTypeInfo() { return &{{v8_class}}::wrapperTypeInfo; }
-};
-
{% if has_custom_to_v8 %}
class {{cpp_class}};
v8::Handle<v8::Value> toV8({{cpp_class}}*, v8::Handle<v8::Object> creationContext, v8::Isolate*);
@@ -165,16 +200,7 @@ inline void v8SetReturnValueFast(const CallbackInfo& callbackInfo, {{cpp_class}}
v8SetReturnValue(callbackInfo, toV8(impl, callbackInfo.Holder(), callbackInfo.GetIsolate()));
}
{% else %}{# has_custom_to_v8 #}
-{% if has_custom_wrap or special_wrap_for %}
v8::Handle<v8::Object> wrap({{cpp_class}}* impl, v8::Handle<v8::Object> creationContext, v8::Isolate*);
-{% else %}
-inline v8::Handle<v8::Object> wrap({{cpp_class}}* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
-{
- ASSERT(impl);
- ASSERT(!DOMDataStore::containsWrapper<{{v8_class}}>(impl, isolate));
- return {{v8_class}}::createWrapper(impl, creationContext, isolate);
-}
-{% endif %}
inline v8::Handle<v8::Value> toV8({{cpp_class}}* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
{
@@ -202,7 +228,7 @@ inline void v8SetReturnValue(const CallbackInfo& callbackInfo, {{cpp_class}}* im
template<typename CallbackInfo>
inline void v8SetReturnValueForMainWorld(const CallbackInfo& callbackInfo, {{cpp_class}}* impl)
{
- ASSERT(worldType(callbackInfo.GetIsolate()) == MainWorld);
+ ASSERT(DOMWrapperWorld::current(callbackInfo.GetIsolate()).isMainWorld());
if (UNLIKELY(!impl)) {
v8SetReturnValueNull(callbackInfo);
return;
@@ -227,31 +253,31 @@ inline void v8SetReturnValueFast(const CallbackInfo& callbackInfo, {{cpp_class}}
}
{% endif %}{# has_custom_to_v8 #}
-inline v8::Handle<v8::Value> toV8(PassRefPtr<{{cpp_class}} > impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
+inline v8::Handle<v8::Value> toV8({{pass_cpp_type}} impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
{
return toV8(impl.get(), creationContext, isolate);
}
template<class CallbackInfo>
-inline void v8SetReturnValue(const CallbackInfo& callbackInfo, PassRefPtr<{{cpp_class}} > impl)
+inline void v8SetReturnValue(const CallbackInfo& callbackInfo, {{pass_cpp_type}} impl)
{
v8SetReturnValue(callbackInfo, impl.get());
}
template<class CallbackInfo>
-inline void v8SetReturnValueForMainWorld(const CallbackInfo& callbackInfo, PassRefPtr<{{cpp_class}} > impl)
+inline void v8SetReturnValueForMainWorld(const CallbackInfo& callbackInfo, {{pass_cpp_type}} impl)
{
v8SetReturnValueForMainWorld(callbackInfo, impl.get());
}
template<class CallbackInfo, class Wrappable>
-inline void v8SetReturnValueFast(const CallbackInfo& callbackInfo, PassRefPtr<{{cpp_class}} > impl, Wrappable* wrappable)
+inline void v8SetReturnValueFast(const CallbackInfo& callbackInfo, {{pass_cpp_type}} impl, Wrappable* wrappable)
{
v8SetReturnValueFast(callbackInfo, impl.get(), wrappable);
}
{% if has_event_constructor %}
-bool initialize{{cpp_class}}({{cpp_class}}Init&, const Dictionary&, ExceptionState&, const String& = "");
+bool initialize{{cpp_class}}({{cpp_class}}Init&, const Dictionary&, ExceptionState&, const v8::FunctionCallbackInfo<v8::Value>& info, const String& = "");
{% endif %}
}
diff --git a/chromium/third_party/WebKit/Source/bindings/templates/interface_base.cpp b/chromium/third_party/WebKit/Source/bindings/templates/interface_base.cpp
index 0751bfacf87..dce2cc91b85 100644
--- a/chromium/third_party/WebKit/Source/bindings/templates/interface_base.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/templates/interface_base.cpp
@@ -1,42 +1,14 @@
-{# http://www.chromium.org/blink/coding-style#TOC-License #}
-/*
- * Copyright (C) 2013 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.
- */
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
-{# FIXME: Rename to Python when switch #}
-// This file has been auto-generated by code_generator_v8.pm. DO NOT MODIFY!
+// This file has been auto-generated by {{code_generator}}. DO NOT MODIFY!
#include "config.h"
{% filter conditional(conditional_string) %}
#include "{{v8_class}}.h"
-{% for filename in cpp_includes %}
+{% for filename in cpp_includes if filename != '%s.h' % v8_class %}
#include "{{filename}}"
{% endfor %}
@@ -45,17 +17,21 @@ namespace WebCore {
static void initializeScriptWrappableForInterface({{cpp_class}}* object)
{
if (ScriptWrappable::wrapperCanBeStoredInObject(object))
- ScriptWrappable::setTypeInfoInObject(object, &{{v8_class}}::wrapperTypeInfo);
+ ScriptWrappable::fromObject(object)->setTypeInfo(&{{v8_class}}::wrapperTypeInfo);
else
ASSERT_NOT_REACHED();
}
} // namespace WebCore
-// In ScriptWrappable::init, the use of a local function declaration has an issue on Windows:
-// the local declaration does not pick up the surrounding namespace. Therefore, we provide this function
-// in the global namespace.
-// (More info on the MSVC bug here: http://connect.microsoft.com/VisualStudio/feedback/details/664619/the-namespace-of-local-function-declarations-in-c)
+{#
+In ScriptWrappable::init, the use of a local function declaration has an
+issue on Windows: the local declaration does not pick up the surrounding
+namespace. Therefore, we provide this function in the global namespace.
+More info on the MSVC bug here (Bug 664619):
+The namespace of local function declarations in C++ by Uray M. János
+http://connect.microsoft.com/VisualStudio/feedback/details/664619/the-namespace-of-local-function-declarations-in-c
+#}
void webCoreInitializeScriptWrappableForInterface(WebCore::{{cpp_class}}* object)
{
WebCore::initializeScriptWrappableForInterface(object);
@@ -70,14 +46,17 @@ namespace WebCore {
if has_visit_dom_wrapper else '0' %}
{% set parent_wrapper_type_info = '&V8%s::wrapperTypeInfo' % parent_interface
if parent_interface else '0' %}
-const WrapperTypeInfo {{v8_class}}::wrapperTypeInfo = { gin::kEmbedderBlink, {{v8_class}}::domTemplate, {{v8_class}}::derefObject, {{to_active_dom_object}}, {{to_event_target}}, {{visit_dom_wrapper}}, {{v8_class}}::installPerContextEnabledMethods, {{parent_wrapper_type_info}}, WrapperTypeObjectPrototype };
+{% set wrapper_type_prototype = 'WrapperTypeExceptionPrototype' if is_exception else
+ 'WrapperTypeObjectPrototype' %}
+const WrapperTypeInfo {{v8_class}}::wrapperTypeInfo = { gin::kEmbedderBlink, {{v8_class}}::domTemplate, {{v8_class}}::derefObject, {{to_active_dom_object}}, {{to_event_target}}, {{visit_dom_wrapper}}, {{v8_class}}::installPerContextEnabledMethods, {{parent_wrapper_type_info}}, {{wrapper_type_prototype}}, {{gc_type}} };
namespace {{cpp_class}}V8Internal {
template <typename T> void V8_USE(T) { }
{# Attributes #}
-{% from 'attributes.cpp' import attribute_getter, attribute_getter_callback,
+{% from 'attributes.cpp' import constructor_getter_callback,
+ attribute_getter, attribute_getter_callback,
attribute_setter, attribute_setter_callback
with context %}
{% for attribute in attributes if not attribute.constructor_type %}
@@ -86,7 +65,7 @@ template <typename T> void V8_USE(T) { }
{{attribute_getter(attribute, world_suffix)}}
{% endif %}
{{attribute_getter_callback(attribute, world_suffix)}}
-{% if not attribute.is_read_only %}
+{% if not attribute.is_read_only or attribute.put_forwards %}
{% if not attribute.has_custom_setter %}
{{attribute_setter(attribute, world_suffix)}}
{% endif %}
@@ -95,6 +74,11 @@ template <typename T> void V8_USE(T) { }
{% endfor %}
{% endfor %}
{% block constructor_getter %}{% endblock %}
+{% for attribute in attributes if attribute.needs_constructor_getter_callback %}
+{% for world_suffix in attribute.world_suffixes %}
+{{constructor_getter_callback(attribute, world_suffix)}}
+{% endfor %}
+{% endfor %}
{% block replaceable_attribute_setter_and_callback %}{% endblock %}
{% block security_check_functions %}{% endblock %}
{# Methods #}
@@ -125,22 +109,43 @@ template <typename T> void V8_USE(T) { }
{% endfor %}
{% block overloaded_constructor %}{% endblock %}
{% block event_constructor %}{% endblock %}
+{# Special operations (methods) #}
+{% block indexed_property_getter %}{% endblock %}
+{% block indexed_property_getter_callback %}{% endblock %}
+{% block indexed_property_setter %}{% endblock %}
+{% block indexed_property_setter_callback %}{% endblock %}
+{% block indexed_property_deleter %}{% endblock %}
+{% block indexed_property_deleter_callback %}{% endblock %}
+{% block named_property_getter %}{% endblock %}
+{% block named_property_getter_callback %}{% endblock %}
+{% block named_property_setter %}{% endblock %}
+{% block named_property_setter_callback %}{% endblock %}
+{% block named_property_query %}{% endblock %}
+{% block named_property_query_callback %}{% endblock %}
+{% block named_property_deleter %}{% endblock %}
+{% block named_property_deleter_callback %}{% endblock %}
+{% block named_property_enumerator %}{% endblock %}
+{% block named_property_enumerator_callback %}{% endblock %}
} // namespace {{cpp_class}}V8Internal
{% block visit_dom_wrapper %}{% endblock %}
+{% block shadow_attributes %}{% endblock %}
{% block class_attributes %}{% endblock %}
{% block class_accessors %}{% endblock %}
{% block class_methods %}{% endblock %}
{% block named_constructor %}{% endblock %}
{% block initialize_event %}{% endblock %}
{% block constructor_callback %}{% endblock %}
+{% block configure_shadow_object_template %}{% endblock %}
{% block configure_class_template %}{% endblock %}
{% block get_template %}{% endblock %}
-{% block has_instance_and_has_instance_in_any_world %}{% endblock %}
+{% block has_instance %}{% endblock %}
+{% block to_native_with_type_check %}{% endblock %}
{% block install_per_context_attributes %}{% endblock %}
{% block install_per_context_methods %}{% endblock %}
{% block to_active_dom_object %}{% endblock %}
{% block to_event_target %}{% endblock %}
+{% block get_shadow_object_template %}{% endblock %}
{% block wrap %}{% endblock %}
{% block create_wrapper %}{% endblock %}
{% block deref_object_and_to_v8_no_inline %}{% endblock %}
diff --git a/chromium/third_party/WebKit/Source/bindings/templates/methods.cpp b/chromium/third_party/WebKit/Source/bindings/templates/methods.cpp
index f534272324c..4a44e7228dc 100644
--- a/chromium/third_party/WebKit/Source/bindings/templates/methods.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/templates/methods.cpp
@@ -3,139 +3,225 @@
{% filter conditional(method.conditional_string) %}
static void {{method.name}}{{method.overload_index}}Method{{world_suffix}}(const v8::FunctionCallbackInfo<v8::Value>& info)
{
- {% if method.is_raises_exception or method.is_check_security_for_frame or
- method.name in ['addEventListener', 'removeEventListener'] %}
+ {# Local variables #}
+ {% if method.has_exception_state %}
ExceptionState exceptionState(ExceptionState::ExecutionContext, "{{method.name}}", "{{interface_name}}", info.Holder(), info.GetIsolate());
{% endif %}
- {% if method.name in ['addEventListener', 'removeEventListener'] %}
- {{add_remove_event_listener_method(method.name) | indent}}
- {% else %}
- {% if method.number_of_required_arguments %}
+ {# Overloaded methods have length checked during overload resolution #}
+ {% if method.number_of_required_arguments and not method.overload_index %}
if (UNLIKELY(info.Length() < {{method.number_of_required_arguments}})) {
- {{throw_type_error(method,
- 'ExceptionMessages::notEnoughArguments(%s, info.Length())' %
- method.number_of_required_arguments)}}
+ {{throw_minimum_arity_type_error(method, method.number_of_required_arguments)}};
return;
}
{% endif %}
{% if not method.is_static %}
- {{cpp_class}}* imp = {{v8_class}}::toNative(info.Holder());
+ {{cpp_class}}* impl = {{v8_class}}::toNative(info.Holder());
{% endif %}
{% if method.is_custom_element_callbacks %}
CustomElementCallbackDispatcher::CallbackDeliveryScope deliveryScope;
{% endif %}
- {% if method.is_check_security_for_frame %}
- if (!BindingSecurity::shouldAllowAccessToFrame(imp->frame(), exceptionState)) {
- exceptionState.throwIfNeeded();
+ {# Security checks #}
+ {# FIXME: change to method.is_check_security_for_window #}
+ {% if interface_name == 'EventTarget' %}
+ if (LocalDOMWindow* window = impl->toDOMWindow()) {
+ if (!BindingSecurity::shouldAllowAccessToFrame(info.GetIsolate(), window->frame(), exceptionState)) {
+ {{throw_from_exception_state(method)}};
+ return;
+ }
+ if (!window->document())
+ return;
+ }
+ {% elif method.is_check_security_for_frame %}
+ if (!BindingSecurity::shouldAllowAccessToFrame(info.GetIsolate(), impl->frame(), exceptionState)) {
+ {{throw_from_exception_state(method)}};
return;
}
{% endif %}
{% if method.is_check_security_for_node %}
- if (!BindingSecurity::shouldAllowAccessToNode(imp->{{method.name}}(exceptionState), exceptionState)) {
+ if (!BindingSecurity::shouldAllowAccessToNode(info.GetIsolate(), impl->{{method.name}}(exceptionState), exceptionState)) {
v8SetReturnValueNull(info);
- exceptionState.throwIfNeeded();
+ {{throw_from_exception_state(method)}};
return;
}
{% endif %}
- {% for argument in method.arguments %}
- {{generate_argument(method, argument) | indent}}
- {% endfor %}
+ {# Call method #}
+ {% if method.arguments %}
+ {{generate_arguments(method, world_suffix) | indent}}
+ {% endif %}
+ {% if world_suffix %}
+ {{cpp_method_call(method, method.v8_set_return_value_for_main_world, method.cpp_value) | indent}}
+ {% else %}
{{cpp_method_call(method, method.v8_set_return_value, method.cpp_value) | indent}}
- {% endif %}{# addEventListener, removeEventListener #}
+ {% endif %}
+ {# Post-call #}
+ {% if method.has_event_listener_argument %}
+ {{hidden_dependency_action(method.name) | indent}}
+ {% endif %}
}
{% endfilter %}
{% endmacro %}
{######################################}
-{% macro add_remove_event_listener_method(method_name) %}
-{# Set template values for addEventListener vs. removeEventListener #}
-{% set listener_lookup_type, listener, hidden_dependency_action =
- ('ListenerFindOrCreate', 'listener', 'createHiddenDependency')
- if method_name == 'addEventListener' else
- ('ListenerFindOnly', 'listener.get()', 'removeHiddenDependency')
-%}
-EventTarget* impl = {{v8_class}}::toNative(info.Holder());
-if (DOMWindow* window = impl->toDOMWindow()) {
- if (!BindingSecurity::shouldAllowAccessToFrame(window->frame(), exceptionState)) {
- exceptionState.throwIfNeeded();
- return;
- }
- if (!window->document())
- return;
-}
-RefPtr<EventListener> listener = V8EventListenerList::getEventListener(info[1], false, {{listener_lookup_type}});
-if (listener) {
- V8TRYCATCH_FOR_V8STRINGRESOURCE_VOID(V8StringResource<WithNullCheck>, eventName, info[0]);
- impl->{{method_name}}(eventName, {{listener}}, info[2]->BooleanValue());
- if (!impl->toNode())
- {{hidden_dependency_action}}(info.Holder(), info[1], {{v8_class}}::eventListenerCacheIndex, info.GetIsolate());
+{% macro hidden_dependency_action(method_name) %}
+if (listener && !impl->toNode())
+ {% if method_name == 'addEventListener' %}
+ addHiddenValueToArray(info.Holder(), info[1], {{v8_class}}::eventListenerCacheIndex, info.GetIsolate());
+ {% else %}{# method_name == 'removeEventListener' #}
+ removeHiddenValueFromArray(info.Holder(), info[1], {{v8_class}}::eventListenerCacheIndex, info.GetIsolate());
+ {% endif %}
+{% endmacro %}
+
+
+{######################################}
+{% macro generate_arguments(method, world_suffix) %}
+{% for argument in method.arguments %}
+{{generate_argument_var_declaration(argument)}};
+{% endfor %}
+{
+ {% if method.arguments_need_try_catch %}
+ v8::TryCatch block;
+ V8RethrowTryCatchScope rethrow(block);
+ {% endif %}
+ {% for argument in method.arguments %}
+ {{generate_argument(method, argument, world_suffix) | indent}}
+ {% endfor %}
}
{% endmacro %}
{######################################}
-{% macro generate_argument(method, argument) %}
+{% macro generate_argument_var_declaration(argument) %}
+{% if argument.is_callback_interface %}
+{# FIXME: remove EventListener special case #}
+{% if argument.idl_type == 'EventListener' %}
+RefPtr<{{argument.idl_type}}> {{argument.name}}
+{%- else %}
+OwnPtr<{{argument.idl_type}}> {{argument.name}}
+{%- endif %}{# argument.idl_type == 'EventListener' #}
+{%- elif argument.is_clamp %}{# argument.is_callback_interface #}
+{# NaN is treated as 0: http://www.w3.org/TR/WebIDL/#es-type-mapping #}
+{{argument.cpp_type}} {{argument.name}} = 0
+{%- else %}
+{{argument.cpp_type}} {{argument.name}}
+{%- endif %}
+{% endmacro %}
+
+
+{######################################}
+{% macro generate_argument(method, argument, world_suffix) %}
{% if argument.is_optional and not argument.has_default and
- argument.idl_type != 'Dictionary' %}
+ argument.idl_type != 'Dictionary' and
+ not argument.is_callback_interface %}
{# Optional arguments without a default value generate an early call with
fewer arguments if they are omitted.
Optional Dictionary arguments default to empty dictionary. #}
if (UNLIKELY(info.Length() <= {{argument.index}})) {
+ {% if world_suffix %}
+ {{cpp_method_call(method, argument.v8_set_return_value_for_main_world, argument.cpp_value) | indent}}
+ {% else %}
{{cpp_method_call(method, argument.v8_set_return_value, argument.cpp_value) | indent}}
+ {% endif %}
+ {% if argument.has_event_listener_argument %}
+ {{hidden_dependency_action(method.name) | indent}}
+ {% endif %}
return;
}
{% endif %}
-{% if method.is_strict_type_checking and argument.is_wrapper_type %}
+{% if argument.has_type_checking_interface %}
{# Type checking for wrapper interface types (if interface not implemented,
- throw TypeError), per http://www.w3.org/TR/WebIDL/#es-interface #}
-if (info.Length() > {{argument.index}} && !isUndefinedOrNull(info[{{argument.index}}]) && !V8{{argument.idl_type}}::hasInstance(info[{{argument.index}}], info.GetIsolate(), worldType(info.GetIsolate()))) {
+ throw a TypeError), per http://www.w3.org/TR/WebIDL/#es-interface #}
+if (info.Length() > {{argument.index}} && {% if argument.is_nullable %}!isUndefinedOrNull(info[{{argument.index}}]) && {% endif %}!V8{{argument.idl_type}}::hasInstance(info[{{argument.index}}], info.GetIsolate())) {
{{throw_type_error(method, '"parameter %s is not of type \'%s\'."' %
- (argument.index + 1, argument.idl_type))}}
+ (argument.index + 1, argument.idl_type)) | indent}}
return;
}
-{% endif %}
-{% if argument.is_clamp %}
+{% endif %}{# argument.has_type_checking_interface #}
+{% if argument.is_callback_interface %}
+{# FIXME: remove EventListener special case #}
+{% if argument.idl_type == 'EventListener' %}
+{% if method.name == 'removeEventListener' %}
+{{argument.name}} = V8EventListenerList::getEventListener(ScriptState::current(info.GetIsolate()), info[1], false, ListenerFindOnly);
+{% else %}{# method.name == 'addEventListener' #}
+{{argument.name}} = V8EventListenerList::getEventListener(ScriptState::current(info.GetIsolate()), info[1], false, ListenerFindOrCreate);
+{% endif %}{# method.name #}
+{% else %}{# argument.idl_type == 'EventListener' #}
+{# Callback functions must be functions:
+ http://www.w3.org/TR/WebIDL/#es-callback-function #}
+{% if argument.is_optional %}
+if (info.Length() > {{argument.index}} && !isUndefinedOrNull(info[{{argument.index}}])) {
+ if (!info[{{argument.index}}]->IsFunction()) {
+ {{throw_type_error(method,
+ '"The callback provided as parameter %s is not a function."' %
+ (argument.index + 1)) | indent(8)}}
+ return;
+ }
+ {{argument.name}} = V8{{argument.idl_type}}::create(v8::Handle<v8::Function>::Cast(info[{{argument.index}}]), ScriptState::current(info.GetIsolate()));
+}
+{% else %}{# argument.is_optional #}
+if (info.Length() <= {{argument.index}} || !{% if argument.is_nullable %}(info[{{argument.index}}]->IsFunction() || info[{{argument.index}}]->IsNull()){% else %}info[{{argument.index}}]->IsFunction(){% endif %}) {
+ {{throw_type_error(method,
+ '"The callback provided as parameter %s is not a function."' %
+ (argument.index + 1)) | indent }}
+ return;
+}
+{{argument.name}} = {% if argument.is_nullable %}info[{{argument.index}}]->IsNull() ? nullptr : {% endif %}V8{{argument.idl_type}}::create(v8::Handle<v8::Function>::Cast(info[{{argument.index}}]), ScriptState::current(info.GetIsolate()));
+{% endif %}{# argument.is_optional #}
+{% endif %}{# argument.idl_type == 'EventListener' #}
+{% elif argument.is_clamp %}{# argument.is_callback_interface #}
{# NaN is treated as 0: http://www.w3.org/TR/WebIDL/#es-type-mapping #}
-{{argument.cpp_type}} {{argument.name}} = 0;
-V8TRYCATCH_VOID(double, {{argument.name}}NativeValue, info[{{argument.index}}]->NumberValue());
+double {{argument.name}}NativeValue;
+TONATIVE_VOID_INTERNAL({{argument.name}}NativeValue, info[{{argument.index}}]->NumberValue());
if (!std::isnan({{argument.name}}NativeValue))
{# IDL type is used for clamping, for the right bounds, since different
IDL integer types have same internal C++ type (int or unsigned) #}
{{argument.name}} = clampTo<{{argument.idl_type}}>({{argument.name}}NativeValue);
{% elif argument.idl_type == 'SerializedScriptValue' %}
-{% set did_throw = argument.name + 'DidThrow' %}
-bool {{did_throw}} = false;
-{{argument.cpp_type}} {{argument.name}} = SerializedScriptValue::create(info[{{argument.index}}], 0, 0, {{did_throw}}, info.GetIsolate());
-if ({{did_throw}})
+{{argument.name}} = SerializedScriptValue::create(info[{{argument.index}}], 0, 0, exceptionState, info.GetIsolate());
+if (exceptionState.hadException()) {
+ {{throw_from_exception_state(method)}};
return;
+}
{% elif argument.is_variadic_wrapper_type %}
-Vector<{{argument.cpp_type}} > {{argument.name}};
for (int i = {{argument.index}}; i < info.Length(); ++i) {
- if (!V8{{argument.idl_type}}::hasInstance(info[i], info.GetIsolate(), worldType(info.GetIsolate()))) {
+ if (!V8{{argument.idl_type}}::hasInstance(info[i], info.GetIsolate())) {
{{throw_type_error(method, '"parameter %s is not of type \'%s\'."' %
- (argument.index + 1, argument.idl_type))}}
+ (argument.index + 1, argument.idl_type)) | indent(8)}}
return;
}
{{argument.name}}.append(V8{{argument.idl_type}}::toNative(v8::Handle<v8::Object>::Cast(info[i])));
}
-{% else %}
+{% else %}{# argument.is_nullable #}
{{argument.v8_value_to_local_cpp_value}};
-{% endif %}
-{% if argument.enum_validation_expression %}
-{# Methods throw on invalid enum values: http://www.w3.org/TR/WebIDL/#idl-enums #}
+{% endif %}{# argument.is_nullable #}
+{# Type checking, possibly throw a TypeError, per:
+ http://www.w3.org/TR/WebIDL/#es-type-mapping #}
+{% if argument.has_type_checking_unrestricted %}
+{# Non-finite floating point values (NaN, +Infinity or −Infinity), per:
+ http://heycam.github.io/webidl/#es-float
+ http://heycam.github.io/webidl/#es-double #}
+if (!std::isfinite({{argument.name}})) {
+ {{throw_type_error(method, '"%s parameter %s is non-finite."' %
+ (argument.idl_type, argument.index + 1)) | indent}}
+ return;
+}
+{% elif argument.enum_validation_expression %}
+{# Invalid enum values: http://www.w3.org/TR/WebIDL/#idl-enums #}
String string = {{argument.name}};
if (!({{argument.enum_validation_expression}})) {
{{throw_type_error(method,
'"parameter %s (\'" + string + "\') is not a valid enum value."' %
- (argument.index + 1))}}
+ (argument.index + 1)) | indent}}
return;
}
-{% endif %}
-{% if argument.idl_type in ['Dictionary', 'Promise'] %}
+{% elif argument.idl_type in ['Dictionary', 'Promise'] %}
+{# Dictionaries must have type Undefined, Null or Object:
+http://heycam.github.io/webidl/#es-dictionary
+We also require this for our implementation of promises, though not in spec:
+http://heycam.github.io/webidl/#es-promise #}
if (!{{argument.name}}.isUndefinedOrNull() && !{{argument.name}}.isObject()) {
{{throw_type_error(method, '"parameter %s (\'%s\') is not an object."' %
- (argument.index + 1, argument.name))}}
+ (argument.index + 1, argument.name)) | indent}}
return;
}
{% endif %}
@@ -144,46 +230,102 @@ if (!{{argument.name}}.isUndefinedOrNull() && !{{argument.name}}.isObject()) {
{######################################}
{% macro cpp_method_call(method, v8_set_return_value, cpp_value) %}
+{# Local variables #}
{% if method.is_call_with_script_state %}
-ScriptState* currentState = ScriptState::current();
-if (!currentState)
- return;
-ScriptState& state = *currentState;
+ScriptState* scriptState = ScriptState::current(info.GetIsolate());
{% endif %}
{% if method.is_call_with_execution_context %}
-ExecutionContext* scriptContext = getExecutionContext();
+ExecutionContext* executionContext = currentExecutionContext(info.GetIsolate());
{% endif %}
{% if method.is_call_with_script_arguments %}
-RefPtr<ScriptArguments> scriptArguments(createScriptArguments(info, {{method.number_of_arguments}}));
+RefPtrWillBeRawPtr<ScriptArguments> scriptArguments(createScriptArguments(scriptState, info, {{method.number_of_arguments}}));
{% endif %}
+{# Call #}
{% if method.idl_type == 'void' %}
{{cpp_value}};
-{% elif method.is_call_with_script_state %}
+{% elif method.is_constructor %}
+{{method.cpp_type}} impl = {{cpp_value}};
+{% elif method.is_call_with_script_state or method.is_raises_exception %}
{# FIXME: consider always using a local variable #}
{{method.cpp_type}} result = {{cpp_value}};
{% endif %}
+{# Post-call #}
{% if method.is_raises_exception %}
-if (exceptionState.throwIfNeeded())
- return;
-{% endif %}
-{% if method.is_call_with_script_state %}
-if (state.hadException()) {
- v8::Local<v8::Value> exception = state.exception();
- state.clearException();
- throwError(exception, info.GetIsolate());
+if (exceptionState.hadException()) {
+ {{throw_from_exception_state(method)}};
return;
}
{% endif %}
-{% if v8_set_return_value %}{{v8_set_return_value}};{% endif %}{# None for void #}
+{# Set return value #}
+{% if method.is_constructor %}
+{{generate_constructor_wrapper(method)}}{% elif method.union_arguments %}
+{{union_type_method_call_and_set_return_value(method)}}
+{% elif v8_set_return_value %}{{v8_set_return_value}};{% endif %}{# None for void #}
{% endmacro %}
{######################################}
+{% macro union_type_method_call_and_set_return_value(method) %}
+{% for cpp_type in method.cpp_type %}
+bool result{{loop.index0}}Enabled = false;
+{{cpp_type}} result{{loop.index0}};
+{% endfor %}
+{{method.cpp_value}};
+{% if method.is_null_expression %}{# used by getters #}
+if ({{method.is_null_expression}})
+ return;
+{% endif %}
+{% for v8_set_return_value in method.v8_set_return_value %}
+if (result{{loop.index0}}Enabled) {
+ {{v8_set_return_value}};
+ return;
+}
+{% endfor %}
+{# Fall back to null if none of the union members results are returned #}
+v8SetReturnValueNull(info);
+{%- endmacro %}
+
+
+{######################################}
{% macro throw_type_error(method, error_message) %}
-{% if method.is_constructor %}
+{% if method.has_exception_state %}
+exceptionState.throwTypeError({{error_message}});
+{{throw_from_exception_state(method)}};
+{% elif method.is_constructor %}
throwTypeError(ExceptionMessages::failedToConstruct("{{interface_name}}", {{error_message}}), info.GetIsolate());
-{%- else %}
+{% else %}{# method.has_exception_state #}
throwTypeError(ExceptionMessages::failedToExecute("{{method.name}}", "{{interface_name}}", {{error_message}}), info.GetIsolate());
+{% endif %}{# method.has_exception_state #}
+{% endmacro %}
+
+
+{######################################}
+{# FIXME: return a rejected Promise if method.idl_type == 'Promise' #}
+{% macro throw_from_exception_state(method) %}
+exceptionState.throwIfNeeded()
+{%- endmacro %}
+
+
+{######################################}
+{% macro throw_arity_type_error(method, valid_arities) %}
+{% if method.has_exception_state %}
+throwArityTypeError(exceptionState, {{valid_arities}}, info.Length())
+{%- elif method.is_constructor %}
+throwArityTypeErrorForConstructor("{{interface_name}}", {{valid_arities}}, info.Length(), info.GetIsolate())
+{%- else %}
+throwArityTypeErrorForMethod("{{method.name}}", "{{interface_name}}", {{valid_arities}}, info.Length(), info.GetIsolate())
+{%- endif %}
+{% endmacro %}
+
+
+{######################################}
+{% macro throw_minimum_arity_type_error(method, number_of_required_arguments) %}
+{% if method.has_exception_state %}
+throwMinimumArityTypeError(exceptionState, {{number_of_required_arguments}}, info.Length())
+{%- elif method.is_constructor %}
+throwMinimumArityTypeErrorForConstructor("{{interface_name}}", {{number_of_required_arguments}}, info.Length(), info.GetIsolate())
+{%- else %}
+throwMinimumArityTypeErrorForMethod("{{method.name}}", "{{interface_name}}", {{number_of_required_arguments}}, info.Length(), info.GetIsolate())
{%- endif %}
{% endmacro %}
@@ -192,24 +334,56 @@ throwTypeError(ExceptionMessages::failedToExecute("{{method.name}}", "{{interfac
{% macro overload_resolution_method(overloads, world_suffix) %}
static void {{overloads.name}}Method{{world_suffix}}(const v8::FunctionCallbackInfo<v8::Value>& info)
{
- {% for method in overloads.methods %}
- if ({{method.overload_resolution_expression}}) {
- {{method.name}}{{method.overload_index}}Method{{world_suffix}}(info);
- return;
- }
+ v8::Isolate* isolate = info.GetIsolate();
+ ExceptionState exceptionState(ExceptionState::ExecutionContext, "{{overloads.name}}", "{{interface_name}}", info.Holder(), isolate);
+ {% if overloads.measure_all_as %}
+ UseCounter::count(callingExecutionContext(isolate), UseCounter::{{overloads.measure_all_as}});
+ {% endif %}
+ {% if overloads.deprecate_all_as %}
+ UseCounter::countDeprecation(callingExecutionContext(isolate), UseCounter::{{overloads.deprecate_all_as}});
+ {% endif %}
+ {# First resolve by length #}
+ {# 2. Initialize argcount to be min(maxarg, n). #}
+ switch (std::min({{overloads.maxarg}}, info.Length())) {
+ {# 3. Remove from S all entries whose type list is not of length argcount. #}
+ {% for length, tests_methods in overloads.length_tests_methods %}
+ {# 10. If i = d, then: #}
+ case {{length}}:
+ {# Then resolve by testing argument #}
+ {% for test, method in tests_methods %}
+ {% filter runtime_enabled(not overloads.runtime_enabled_function_all and
+ method.runtime_enabled_function) %}
+ if ({{test}}) {
+ {% if method.measure_as and not overloads.measure_all_as %}
+ UseCounter::count(callingExecutionContext(isolate), UseCounter::{{method.measure_as}});
+ {% endif %}
+ {% if method.deprecate_as and not overloads.deprecate_all_as %}
+ UseCounter::countDeprecation(callingExecutionContext(isolate), UseCounter::{{method.deprecate_as}});
+ {% endif %}
+ {{method.name}}{{method.overload_index}}Method{{world_suffix}}(info);
+ return;
+ }
+ {% endfilter %}
+ {% endfor %}
+ break;
{% endfor %}
- {% if overloads.minimum_number_of_required_arguments %}
- ExceptionState exceptionState(ExceptionState::ExecutionContext, "{{overloads.name}}", "{{interface_name}}", info.Holder(), info.GetIsolate());
- if (UNLIKELY(info.Length() < {{overloads.minimum_number_of_required_arguments}})) {
- exceptionState.throwTypeError(ExceptionMessages::notEnoughArguments({{overloads.minimum_number_of_required_arguments}}, info.Length()));
+ default:
+ {# Invalid arity, throw error #}
+ {# Report full list of valid arities if gaps and above minimum #}
+ {% if overloads.valid_arities %}
+ if (info.Length() >= {{overloads.minarg}}) {
+ throwArityTypeError(exceptionState, "{{overloads.valid_arities}}", info.Length());
+ return;
+ }
+ {% endif %}
+ {# Otherwise just report "not enough arguments" #}
+ exceptionState.throwTypeError(ExceptionMessages::notEnoughArguments({{overloads.minarg}}, info.Length()));
exceptionState.throwIfNeeded();
return;
}
+ {# No match, throw error #}
exceptionState.throwTypeError("No function was found that matched the signature provided.");
exceptionState.throwIfNeeded();
- {% else %}
- {{throw_type_error(overloads, '"No function was found that matched the signature provided."')}}
- {% endif %}
}
{% endmacro %}
@@ -220,19 +394,26 @@ static void {{overloads.name}}Method{{world_suffix}}(const v8::FunctionCallbackI
static void {{method.name}}MethodCallback{{world_suffix}}(const v8::FunctionCallbackInfo<v8::Value>& info)
{
TRACE_EVENT_SET_SAMPLING_STATE("Blink", "DOMMethod");
+ {% if not method.overloads %}{# Overloaded methods are measured in overload_resolution_method() #}
{% if method.measure_as %}
- UseCounter::count(activeDOMWindow(), UseCounter::{{method.measure_as}});
+ UseCounter::count(callingExecutionContext(info.GetIsolate()), UseCounter::{{method.measure_as}});
{% endif %}
{% if method.deprecate_as %}
- UseCounter::countDeprecation(activeExecutionContext(), UseCounter::{{method.deprecate_as}});
+ UseCounter::countDeprecation(callingExecutionContext(info.GetIsolate()), UseCounter::{{method.deprecate_as}});
{% endif %}
+ {% endif %}{# not method.overloads #}
{% if world_suffix in method.activity_logging_world_list %}
- V8PerContextData* contextData = V8PerContextData::from(info.GetIsolate()->GetCurrentContext());
+ ScriptState* scriptState = ScriptState::from(info.GetIsolate()->GetCurrentContext());
+ V8PerContextData* contextData = scriptState->perContextData();
+ {% if method.activity_logging_world_check %}
+ if (scriptState->world().isIsolatedWorld() && contextData && contextData->activityLogger())
+ {% else %}
if (contextData && contextData->activityLogger()) {
+ {% endif %}
{# FIXME: replace toVectorOfArguments with toNativeArguments(info, 0)
and delete toVectorOfArguments #}
Vector<v8::Handle<v8::Value> > loggerArgs = toNativeArguments<v8::Handle<v8::Value> >(info, 0);
- contextData->activityLogger()->log("{{interface_name}}.{{method.name}}", info.Length(), loggerArgs.data(), "Method");
+ contextData->activityLogger()->logMethod("{{interface_name}}.{{method.name}}", info.Length(), loggerArgs.data());
}
{% endif %}
{% if method.is_custom %}
@@ -240,7 +421,7 @@ static void {{method.name}}MethodCallback{{world_suffix}}(const v8::FunctionCall
{% else %}
{{cpp_class}}V8Internal::{{method.name}}Method{{world_suffix}}(info);
{% endif %}
- TRACE_EVENT_SET_SAMPLING_STATE("V8", "Execution");
+ TRACE_EVENT_SET_SAMPLING_STATE("V8", "V8Execution");
}
{% endfilter %}
{% endmacro %}
@@ -250,30 +431,32 @@ static void {{method.name}}MethodCallback{{world_suffix}}(const v8::FunctionCall
{% macro origin_safe_method_getter(method, world_suffix) %}
static void {{method.name}}OriginSafeMethodGetter{{world_suffix}}(const v8::PropertyCallbackInfo<v8::Value>& info)
{
- {# FIXME: don't call GetIsolate() so often #}
- // This is only for getting a unique pointer which we can pass to privateTemplate.
- static int privateTemplateUniqueKey;
- WrapperWorldType currentWorldType = worldType(info.GetIsolate());
- V8PerIsolateData* data = V8PerIsolateData::from(info.GetIsolate());
+ {% set signature = 'v8::Local<v8::Signature>()'
+ if method.is_do_not_check_signature else
+ 'v8::Signature::New(isolate, %s::domTemplate(isolate))' % v8_class %}
+ v8::Isolate* isolate = info.GetIsolate();
+ static int domTemplateKey; // This address is used for a key to look up the dom template.
+ V8PerIsolateData* data = V8PerIsolateData::from(isolate);
{# FIXME: 1 case of [DoNotCheckSignature] in Window.idl may differ #}
- v8::Handle<v8::FunctionTemplate> privateTemplate = data->privateTemplate(currentWorldType, &privateTemplateUniqueKey, {{cpp_class}}V8Internal::{{method.name}}MethodCallback{{world_suffix}}, v8Undefined(), v8::Signature::New(info.GetIsolate(), V8PerIsolateData::from(info.GetIsolate())->rawDOMTemplate(&{{v8_class}}::wrapperTypeInfo, currentWorldType)), {{method.number_of_required_or_variadic_arguments}});
+ v8::Handle<v8::FunctionTemplate> privateTemplate = data->domTemplate(&domTemplateKey, {{cpp_class}}V8Internal::{{method.name}}MethodCallback{{world_suffix}}, v8Undefined(), {{signature}}, {{method.length}});
- v8::Handle<v8::Object> holder = info.This()->FindInstanceInPrototypeChain({{v8_class}}::domTemplate(info.GetIsolate(), currentWorldType));
+ v8::Handle<v8::Object> holder = {{v8_class}}::findInstanceInPrototypeChain(info.This(), isolate);
if (holder.IsEmpty()) {
// This is only reachable via |object.__proto__.func|, in which case it
// has already passed the same origin security check
v8SetReturnValue(info, privateTemplate->GetFunction());
return;
}
- {{cpp_class}}* imp = {{v8_class}}::toNative(holder);
- if (!BindingSecurity::shouldAllowAccessToFrame(imp->frame(), DoNotReportSecurityError)) {
- static int sharedTemplateUniqueKey;
- v8::Handle<v8::FunctionTemplate> sharedTemplate = data->privateTemplate(currentWorldType, &sharedTemplateUniqueKey, {{cpp_class}}V8Internal::{{method.name}}MethodCallback{{world_suffix}}, v8Undefined(), v8::Signature::New(info.GetIsolate(), V8PerIsolateData::from(info.GetIsolate())->rawDOMTemplate(&{{v8_class}}::wrapperTypeInfo, currentWorldType)), {{method.number_of_required_or_variadic_arguments}});
+ {{cpp_class}}* impl = {{v8_class}}::toNative(holder);
+ if (!BindingSecurity::shouldAllowAccessToFrame(isolate, impl->frame(), DoNotReportSecurityError)) {
+ static int sharedTemplateKey; // This address is used for a key to look up the dom template.
+ v8::Handle<v8::FunctionTemplate> sharedTemplate = data->domTemplate(&sharedTemplateKey, {{cpp_class}}V8Internal::{{method.name}}MethodCallback{{world_suffix}}, v8Undefined(), {{signature}}, {{method.length}});
v8SetReturnValue(info, sharedTemplate->GetFunction());
return;
}
- v8::Local<v8::Value> hiddenValue = info.This()->GetHiddenValue(v8::String::NewFromUtf8(info.GetIsolate(), "{{method.name}}", v8::String::kInternalizedString));
+ {# The findInstanceInPrototypeChain() call above only returns a non-empty handle if info.This() is an Object. #}
+ v8::Local<v8::Value> hiddenValue = v8::Handle<v8::Object>::Cast(info.This())->GetHiddenValue(v8AtomicString(isolate, "{{method.name}}"));
if (!hiddenValue.IsEmpty()) {
v8SetReturnValue(info, hiddenValue);
return;
@@ -286,7 +469,7 @@ static void {{method.name}}OriginSafeMethodGetterCallback{{world_suffix}}(v8::Lo
{
TRACE_EVENT_SET_SAMPLING_STATE("Blink", "DOMGetter");
{{cpp_class}}V8Internal::{{method.name}}OriginSafeMethodGetter{{world_suffix}}(info);
- TRACE_EVENT_SET_SAMPLING_STATE("V8", "Execution");
+ TRACE_EVENT_SET_SAMPLING_STATE("V8", "V8Execution");
}
{% endmacro %}
@@ -295,69 +478,94 @@ static void {{method.name}}OriginSafeMethodGetterCallback{{world_suffix}}(v8::Lo
{% macro generate_constructor(constructor) %}
static void constructor{{constructor.overload_index}}(const v8::FunctionCallbackInfo<v8::Value>& info)
{
+ v8::Isolate* isolate = info.GetIsolate();
+ {% if constructor.has_exception_state %}
+ ExceptionState exceptionState(ExceptionState::ConstructionContext, "{{interface_name}}", info.Holder(), isolate);
+ {% endif %}
+ {# Overloaded constructors have length checked during overload resolution #}
{% if interface_length and not constructor.overload_index %}
- {# FIXME: remove this UNLIKELY: constructors are heavy, so no difference. #}
+ {# FIXME: remove UNLIKELY: constructors are expensive, so no difference. #}
if (UNLIKELY(info.Length() < {{interface_length}})) {
- {{throw_type_error({'name': 'Constructor'},
- 'ExceptionMessages::notEnoughArguments(%s, info.Length())' %
- interface_length)}}
+ {{throw_minimum_arity_type_error(constructor, interface_length)}};
return;
}
{% endif %}
- {% if is_constructor_raises_exception %}
- ExceptionState exceptionState(ExceptionState::ConstructionContext, "{{interface_name}}", info.Holder(), info.GetIsolate());
+ {% if constructor.arguments %}
+ {{generate_arguments(constructor) | indent}}
{% endif %}
- {% for argument in constructor.arguments %}
- {{generate_argument(constructor, argument) | indent}}
- {% endfor %}
{% if is_constructor_call_with_execution_context %}
- ExecutionContext* context = getExecutionContext();
+ ExecutionContext* executionContext = currentExecutionContext(isolate);
{% endif %}
{% if is_constructor_call_with_document %}
- Document& document = *toDocument(getExecutionContext());
+ Document& document = *toDocument(currentExecutionContext(isolate));
{% endif %}
- RefPtr<{{cpp_class}}> impl = {{cpp_class}}::create({{constructor.argument_list | join(', ')}});
- v8::Handle<v8::Object> wrapper = info.Holder();
+ {{constructor.cpp_type}} impl = {{constructor.cpp_value}};
{% if is_constructor_raises_exception %}
if (exceptionState.throwIfNeeded())
return;
{% endif %}
- {# FIXME: Should probably be Independent unless [ActiveDOMObject]
- or [DependentLifetime]. #}
- V8DOMWrapper::associateObjectWithWrapper<{{v8_class}}>(impl.release(), &{{v8_class}}::wrapperTypeInfo, wrapper, info.GetIsolate(), WrapperConfiguration::Dependent);
- v8SetReturnValue(info, wrapper);
+ {{generate_constructor_wrapper(constructor) | indent}}
}
{% endmacro %}
{##############################################################################}
+{% macro generate_constructor_wrapper(constructor) %}
+{% if has_custom_wrap %}
+v8::Handle<v8::Object> wrapper = wrap(impl.get(), info.Holder(), isolate);
+{% else %}
+{% set constructor_class = v8_class + ('Constructor'
+ if constructor.is_named_constructor else
+ '') %}
+v8::Handle<v8::Object> wrapper = info.Holder();
+V8DOMWrapper::associateObjectWithWrapper<{{v8_class}}>(impl.release(), &{{constructor_class}}::wrapperTypeInfo, wrapper, isolate, {{wrapper_configuration}});
+{% endif %}
+v8SetReturnValue(info, wrapper);
+{% endmacro %}
+
+
+{##############################################################################}
{% macro named_constructor_callback(constructor) %}
static void {{v8_class}}ConstructorCallback(const v8::FunctionCallbackInfo<v8::Value>& info)
{
+ v8::Isolate* isolate = info.GetIsolate();
if (!info.IsConstructCall()) {
- throwTypeError(ExceptionMessages::failedToConstruct("{{constructor.name}}", "Please use the 'new' operator, this DOM object constructor cannot be called as a function."), info.GetIsolate());
+ throwTypeError(ExceptionMessages::constructorNotCallableAsFunction("{{constructor.name}}"), isolate);
return;
}
- if (ConstructorMode::current() == ConstructorMode::WrapExistingObject) {
+ if (ConstructorMode::current(isolate) == ConstructorMode::WrapExistingObject) {
v8SetReturnValue(info, info.Holder());
return;
}
- Document* document = currentDocument();
- ASSERT(document);
+ Document* documentPtr = currentDOMWindow(isolate)->document();
+ ASSERT(documentPtr);
+ Document& document = *documentPtr;
// Make sure the document is added to the DOM Node map. Otherwise, the {{cpp_class}} instance
// may end up being the only node in the map and get garbage-collected prematurely.
- toV8(document, info.Holder(), info.GetIsolate());
+ toV8(documentPtr, info.Holder(), isolate);
- {# FIXME: arguments #}
- {% set argument_list = ['*document'] %}
- RefPtr<{{cpp_class}}> impl = {{cpp_class}}::createForJSConstructor({{argument_list | join(', ')}});
- v8::Handle<v8::Object> wrapper = info.Holder();
+ {% if constructor.has_exception_state %}
+ ExceptionState exceptionState(ExceptionState::ConstructionContext, "{{interface_name}}", info.Holder(), isolate);
+ {% endif %}
+ {% if constructor.number_of_required_arguments %}
+ if (UNLIKELY(info.Length() < {{constructor.number_of_required_arguments}})) {
+ {{throw_minimum_arity_type_error(constructor, constructor.number_of_required_arguments)}};
+ return;
+ }
+ {% endif %}
+ {% if constructor.arguments %}
+ {{generate_arguments(constructor) | indent}}
+ {% endif %}
+ {{constructor.cpp_type}} impl = {{constructor.cpp_value}};
+ {% if is_constructor_raises_exception %}
+ if (exceptionState.throwIfNeeded())
+ return;
+ {% endif %}
- V8DOMWrapper::associateObjectWithWrapper<{{v8_class}}>(impl.release(), &{{v8_class}}Constructor::wrapperTypeInfo, wrapper, info.GetIsolate(), WrapperConfiguration::Dependent);
- v8SetReturnValue(info, wrapper);
+ {{generate_constructor_wrapper(constructor) | indent}}
}
{% endmacro %}
diff --git a/chromium/third_party/WebKit/Source/bindings/templates/templates.gni b/chromium/third_party/WebKit/Source/bindings/templates/templates.gni
new file mode 100644
index 00000000000..133c5065329
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/bindings/templates/templates.gni
@@ -0,0 +1,17 @@
+# Copyright 2014 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# Paths should be absolute so this file can be imported from anywhere.
+code_generator_template_files =
+ get_path_info(
+ [
+ "attributes.cpp",
+ "callback_interface.cpp",
+ "callback_interface.h",
+ "interface_base.cpp",
+ "interface.cpp",
+ "interface.h",
+ "methods.cpp",
+ ],
+ "abspath")
diff --git a/chromium/third_party/WebKit/Source/bindings/templates/templates.gypi b/chromium/third_party/WebKit/Source/bindings/templates/templates.gypi
new file mode 100644
index 00000000000..a019fab8d28
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/bindings/templates/templates.gypi
@@ -0,0 +1,17 @@
+# Copyright 2014 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+{
+ 'variables': {
+ 'code_generator_template_files': [
+ 'attributes.cpp',
+ 'callback_interface.cpp',
+ 'callback_interface.h',
+ 'interface_base.cpp',
+ 'interface.cpp',
+ 'interface.h',
+ 'methods.cpp',
+ ],
+ },
+}
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/ArrayValue.cpp b/chromium/third_party/WebKit/Source/bindings/v8/ArrayValue.cpp
index 1280548b9f6..065fd2f8815 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/ArrayValue.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/ArrayValue.cpp
@@ -62,7 +62,7 @@ bool ArrayValue::get(size_t index, Dictionary& value) const
ASSERT(m_isolate);
ASSERT(m_isolate == v8::Isolate::GetCurrent());
- v8::Local<v8::Value> indexedValue = m_array->Get(v8::Integer::NewFromUnsigned(index, m_isolate));
+ v8::Local<v8::Value> indexedValue = m_array->Get(v8::Integer::NewFromUnsigned(m_isolate, index));
if (indexedValue.IsEmpty() || !indexedValue->IsObject())
return false;
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/BindingSecurity.cpp b/chromium/third_party/WebKit/Source/bindings/v8/BindingSecurity.cpp
index 7f9db62257d..126b2ba6519 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/BindingSecurity.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/BindingSecurity.cpp
@@ -34,65 +34,69 @@
#include "bindings/v8/V8Binding.h"
#include "core/dom/Document.h"
#include "core/html/HTMLFrameElementBase.h"
-#include "core/frame/DOMWindow.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalDOMWindow.h"
+#include "core/frame/LocalFrame.h"
#include "core/frame/Settings.h"
#include "platform/weborigin/SecurityOrigin.h"
namespace WebCore {
-static bool isDocumentAccessibleFromDOMWindow(Document* targetDocument, DOMWindow* activeWindow)
+static bool isDocumentAccessibleFromDOMWindow(Document* targetDocument, LocalDOMWindow* callingWindow)
{
if (!targetDocument)
return false;
- if (!activeWindow)
+ if (!callingWindow)
return false;
- if (activeWindow->document()->securityOrigin()->canAccess(targetDocument->securityOrigin()))
+ if (callingWindow->document()->securityOrigin()->canAccess(targetDocument->securityOrigin()))
return true;
return false;
}
-static bool canAccessDocument(Document* targetDocument, ExceptionState& exceptionState)
+static bool canAccessDocument(v8::Isolate* isolate, Document* targetDocument, ExceptionState& exceptionState)
{
- DOMWindow* activeWindow = activeDOMWindow();
- if (isDocumentAccessibleFromDOMWindow(targetDocument, activeWindow))
+ LocalDOMWindow* callingWindow = callingDOMWindow(isolate);
+ if (isDocumentAccessibleFromDOMWindow(targetDocument, callingWindow))
return true;
if (targetDocument->domWindow())
- exceptionState.throwSecurityError(targetDocument->domWindow()->sanitizedCrossDomainAccessErrorMessage(activeWindow), targetDocument->domWindow()->crossDomainAccessErrorMessage(activeWindow));
+ exceptionState.throwSecurityError(targetDocument->domWindow()->sanitizedCrossDomainAccessErrorMessage(callingWindow), targetDocument->domWindow()->crossDomainAccessErrorMessage(callingWindow));
return false;
}
-static bool canAccessDocument(Document* targetDocument, SecurityReportingOption reportingOption = ReportSecurityError)
+static bool canAccessDocument(v8::Isolate* isolate, Document* targetDocument, SecurityReportingOption reportingOption = ReportSecurityError)
{
- DOMWindow* activeWindow = activeDOMWindow();
- if (isDocumentAccessibleFromDOMWindow(targetDocument, activeWindow))
+ LocalDOMWindow* callingWindow = callingDOMWindow(isolate);
+ if (isDocumentAccessibleFromDOMWindow(targetDocument, callingWindow))
return true;
if (reportingOption == ReportSecurityError && targetDocument->domWindow()) {
- if (Frame* frame = targetDocument->frame())
- frame->domWindow()->printErrorMessage(targetDocument->domWindow()->crossDomainAccessErrorMessage(activeWindow));
+ if (LocalFrame* frame = targetDocument->frame())
+ frame->domWindow()->printErrorMessage(targetDocument->domWindow()->crossDomainAccessErrorMessage(callingWindow));
}
return false;
}
-bool BindingSecurity::shouldAllowAccessToFrame(Frame* target, SecurityReportingOption reportingOption)
+bool BindingSecurity::shouldAllowAccessToFrame(v8::Isolate* isolate, Frame* target, SecurityReportingOption reportingOption)
{
- return target && canAccessDocument(target->document(), reportingOption);
+ if (!target || !target->isLocalFrame())
+ return false;
+ return canAccessDocument(isolate, toLocalFrame(target)->document(), reportingOption);
}
-bool BindingSecurity::shouldAllowAccessToFrame(Frame* target, ExceptionState& exceptionState)
+bool BindingSecurity::shouldAllowAccessToFrame(v8::Isolate* isolate, Frame* target, ExceptionState& exceptionState)
{
- return target && canAccessDocument(target->document(), exceptionState);
+ if (!target || !target->isLocalFrame())
+ return false;
+ return canAccessDocument(isolate, toLocalFrame(target)->document(), exceptionState);
}
-bool BindingSecurity::shouldAllowAccessToNode(Node* target, ExceptionState& exceptionState)
+bool BindingSecurity::shouldAllowAccessToNode(v8::Isolate* isolate, Node* target, ExceptionState& exceptionState)
{
- return target && canAccessDocument(&target->document(), exceptionState);
+ return target && canAccessDocument(isolate, &target->document(), exceptionState);
}
}
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/BindingSecurity.h b/chromium/third_party/WebKit/Source/bindings/v8/BindingSecurity.h
index 253a7f25781..b6e5bba893d 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/BindingSecurity.h
+++ b/chromium/third_party/WebKit/Source/bindings/v8/BindingSecurity.h
@@ -31,13 +31,15 @@
#ifndef BindingSecurity_h
#define BindingSecurity_h
+// FIXME: The LocalFrame include should not be necessary, clients should be including it where they use it.
+#include "core/frame/LocalFrame.h"
#include "wtf/text/WTFString.h"
+#include <v8.h>
namespace WebCore {
-class DOMWindow;
+class LocalDOMWindow;
class ExceptionState;
-class Frame;
class Node;
enum SecurityReportingOption {
@@ -47,9 +49,9 @@ enum SecurityReportingOption {
class BindingSecurity {
public:
- static bool shouldAllowAccessToNode(Node*, ExceptionState&);
- static bool shouldAllowAccessToFrame(Frame*, SecurityReportingOption = ReportSecurityError);
- static bool shouldAllowAccessToFrame(Frame*, ExceptionState&);
+ static bool shouldAllowAccessToNode(v8::Isolate*, Node*, ExceptionState&);
+ static bool shouldAllowAccessToFrame(v8::Isolate*, Frame*, SecurityReportingOption = ReportSecurityError);
+ static bool shouldAllowAccessToFrame(v8::Isolate*, Frame*, ExceptionState&);
};
}
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/CallbackPromiseAdapter.h b/chromium/third_party/WebKit/Source/bindings/v8/CallbackPromiseAdapter.h
index 19b5a543918..21719792209 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/CallbackPromiseAdapter.h
+++ b/chromium/third_party/WebKit/Source/bindings/v8/CallbackPromiseAdapter.h
@@ -31,8 +31,7 @@
#ifndef CallbackPromiseAdapter_h
#define CallbackPromiseAdapter_h
-#include "bindings/v8/DOMRequestState.h"
-#include "bindings/v8/ScriptPromiseResolver.h"
+#include "bindings/v8/ScriptPromiseResolverWithContext.h"
#include "public/platform/WebCallbacks.h"
namespace WebCore {
@@ -40,16 +39,25 @@ namespace WebCore {
// This class provides an easy way to convert from a Script-exposed
// class (i.e. a class that has a toV8() overload) that uses Promises
// to a WebKit API class that uses WebCallbacks. You can define
-// seperate Success and Error classes, but this example just uses one
+// separate Success and Error classes, but this example just uses one
// object for both.
//
// To use:
//
// class MyClass ... {
// typedef blink::WebMyClass WebType;
-// static PassRefPtr<MyClass> from(blink::WebMyClass* webInstance) {
+// static PassRefPtr<MyClass> from(ScriptPromiseResolverWithContext* resolver,
+// blink::WebMyClass* webInstance) {
// // convert/create as appropriate, but often it's just:
// return MyClass::create(adoptPtr(webInstance));
+//
+// // Since promise resolving is done as an async task, it's not
+// // guaranteed that the script context has seen the promise resolve
+// // immediately after calling onSuccess/onError. You can use the
+// // ScriptPromise from the resolver to schedule a task that executes
+// // after resolving:
+// ScriptState::Scope scope(resolver->scriptState());
+// resolver->promise().then(...);
// }
//
// Now when calling into a WebKit API that requires a WebCallbacks<blink::WebMyClass, blink::WebMyClass>*:
@@ -61,28 +69,24 @@ namespace WebCore {
// example that ownership of the WebCallbacks instance is being passed
// in and it is up to the callee to free the WebCallbacks instace.
template<typename S, typename T>
-class CallbackPromiseAdapter : public blink::WebCallbacks<typename S::WebType, typename T::WebType> {
+class CallbackPromiseAdapter FINAL : public blink::WebCallbacks<typename S::WebType, typename T::WebType> {
public:
- explicit CallbackPromiseAdapter(PassRefPtr<ScriptPromiseResolver> resolver, ExecutionContext* context)
+ CallbackPromiseAdapter(PassRefPtr<ScriptPromiseResolverWithContext> resolver)
: m_resolver(resolver)
- , m_requestState(context)
{
}
virtual ~CallbackPromiseAdapter() { }
virtual void onSuccess(typename S::WebType* result) OVERRIDE
{
- DOMRequestState::Scope scope(m_requestState);
- m_resolver->resolve(S::from(result));
+ m_resolver->resolve(S::from(m_resolver.get(), result));
}
- void onError(typename T::WebType* error) OVERRIDE
+ virtual void onError(typename T::WebType* error) OVERRIDE
{
- DOMRequestState::Scope scope(m_requestState);
- m_resolver->reject(T::from(error));
+ m_resolver->reject(T::from(m_resolver.get(), error));
}
private:
- RefPtr<ScriptPromiseResolver> m_resolver;
- DOMRequestState m_requestState;
+ RefPtr<ScriptPromiseResolverWithContext> m_resolver;
WTF_MAKE_NONCOPYABLE(CallbackPromiseAdapter);
};
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/CustomElementBinding.cpp b/chromium/third_party/WebKit/Source/bindings/v8/CustomElementBinding.cpp
index 25ba61792f3..7a692394496 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/CustomElementBinding.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/CustomElementBinding.cpp
@@ -43,7 +43,7 @@ CustomElementBinding::CustomElementBinding(v8::Isolate* isolate, v8::Handle<v8::
, m_prototype(isolate, prototype)
, m_wrapperType(wrapperType)
{
- ASSERT(m_prototype.value());
+ ASSERT(!m_prototype.isEmpty());
ASSERT(m_wrapperType);
}
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/CustomElementBinding.h b/chromium/third_party/WebKit/Source/bindings/v8/CustomElementBinding.h
index 3fa394a0b09..b989e361823 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/CustomElementBinding.h
+++ b/chromium/third_party/WebKit/Source/bindings/v8/CustomElementBinding.h
@@ -31,7 +31,7 @@
#ifndef CustomElementBinding_h
#define CustomElementBinding_h
-#include "bindings/v8/UnsafePersistent.h"
+#include "bindings/v8/ScopedPersistent.h"
#include "wtf/PassOwnPtr.h"
#include <v8.h>
@@ -43,7 +43,7 @@ class CustomElementBinding {
public:
static PassOwnPtr<CustomElementBinding> create(v8::Isolate*, v8::Handle<v8::Object> prototype, const WrapperTypeInfo*);
- ~CustomElementBinding() { m_prototype.dispose(); }
+ ~CustomElementBinding() { }
v8::Handle<v8::Object> prototype() { return m_prototype.newLocal(m_isolate); }
const WrapperTypeInfo* wrapperType() { return m_wrapperType; }
@@ -52,7 +52,7 @@ private:
CustomElementBinding(v8::Isolate*, v8::Handle<v8::Object> prototype, const WrapperTypeInfo*);
v8::Isolate* m_isolate;
- UnsafePersistent<v8::Object> m_prototype;
+ ScopedPersistent<v8::Object> m_prototype;
const WrapperTypeInfo* m_wrapperType;
};
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/CustomElementConstructorBuilder.cpp b/chromium/third_party/WebKit/Source/bindings/v8/CustomElementConstructorBuilder.cpp
index b13466635ae..a8e43a1012e 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/CustomElementConstructorBuilder.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/CustomElementConstructorBuilder.cpp
@@ -31,20 +31,18 @@
#include "config.h"
#include "bindings/v8/CustomElementConstructorBuilder.h"
-#include "HTMLNames.h"
-#include "SVGNames.h"
-#include "V8Document.h"
-#include "V8HTMLElementWrapperFactory.h"
-#include "V8SVGElementWrapperFactory.h"
+#include "bindings/core/v8/V8Document.h"
#include "bindings/v8/CustomElementBinding.h"
#include "bindings/v8/DOMWrapperWorld.h"
#include "bindings/v8/Dictionary.h"
#include "bindings/v8/ExceptionState.h"
-#include "bindings/v8/ScriptState.h"
-#include "bindings/v8/UnsafePersistent.h"
#include "bindings/v8/V8Binding.h"
-#include "bindings/v8/V8HiddenPropertyName.h"
+#include "bindings/v8/V8HiddenValue.h"
#include "bindings/v8/V8PerContextData.h"
+#include "core/HTMLNames.h"
+#include "core/SVGNames.h"
+#include "core/V8HTMLElementWrapperFactory.h" // FIXME: should be bindings/core/v8
+#include "core/V8SVGElementWrapperFactory.h" // FIXME: should be bindings/core/v8
#include "core/dom/Document.h"
#include "core/dom/custom/CustomElementCallbackDispatcher.h"
#include "core/dom/custom/CustomElementDefinition.h"
@@ -56,44 +54,58 @@ namespace WebCore {
static void constructCustomElement(const v8::FunctionCallbackInfo<v8::Value>&);
-CustomElementConstructorBuilder::CustomElementConstructorBuilder(ScriptState* state, const Dictionary* options)
- : m_context(state->context())
+CustomElementConstructorBuilder::CustomElementConstructorBuilder(ScriptState* scriptState, const Dictionary* options)
+ : m_scriptState(scriptState)
, m_options(options)
, m_wrapperType(0)
{
- ASSERT(m_context == v8::Isolate::GetCurrent()->GetCurrentContext());
+ ASSERT(m_scriptState->context() == m_scriptState->isolate()->GetCurrentContext());
}
bool CustomElementConstructorBuilder::isFeatureAllowed() const
{
- // Check that we are in the main world
- return !DOMWrapperWorld::isolatedWorld(m_context);
+ return m_scriptState->world().isMainWorld();
}
bool CustomElementConstructorBuilder::validateOptions(const AtomicString& type, QualifiedName& tagName, ExceptionState& exceptionState)
{
ASSERT(m_prototype.IsEmpty());
+ v8::TryCatch tryCatch;
+
ScriptValue prototypeScriptValue;
if (m_options->get("prototype", prototypeScriptValue) && !prototypeScriptValue.isNull()) {
+ ASSERT(!tryCatch.HasCaught());
if (!prototypeScriptValue.isObject()) {
CustomElementException::throwException(CustomElementException::PrototypeNotAnObject, type, exceptionState);
+ tryCatch.ReThrow();
return false;
}
m_prototype = prototypeScriptValue.v8Value().As<v8::Object>();
- } else {
- m_prototype = v8::Object::New();
- v8::Local<v8::Object> basePrototype = V8PerContextData::from(m_context)->prototypeForType(&V8HTMLElement::wrapperTypeInfo);
+ } else if (!tryCatch.HasCaught()) {
+ m_prototype = v8::Object::New(m_scriptState->isolate());
+ v8::Local<v8::Object> basePrototype = m_scriptState->perContextData()->prototypeForType(&V8HTMLElement::wrapperTypeInfo);
if (!basePrototype.IsEmpty())
m_prototype->SetPrototype(basePrototype);
}
- String extends;
+ if (tryCatch.HasCaught()) {
+ tryCatch.ReThrow();
+ return false;
+ }
+
+ AtomicString extends;
bool extendsProvidedAndNonNull = m_options->get("extends", extends);
- if (!V8PerContextData::from(m_context)) {
+ if (tryCatch.HasCaught()) {
+ tryCatch.ReThrow();
+ return false;
+ }
+
+ if (!m_scriptState->perContextData()) {
// FIXME: This should generate an InvalidContext exception at a later point.
CustomElementException::throwException(CustomElementException::ContextDestroyedCheckingPrototype, type, exceptionState);
+ tryCatch.ReThrow();
return false;
}
@@ -101,6 +113,8 @@ bool CustomElementConstructorBuilder::validateOptions(const AtomicString& type,
if (hasValidPrototypeChainFor(&V8SVGElement::wrapperTypeInfo))
namespaceURI = SVGNames::svgNamespaceURI;
+ ASSERT(!tryCatch.HasCaught());
+
AtomicString localName;
if (extendsProvidedAndNonNull) {
@@ -108,15 +122,18 @@ bool CustomElementConstructorBuilder::validateOptions(const AtomicString& type,
if (!Document::isValidName(localName)) {
CustomElementException::throwException(CustomElementException::ExtendsIsInvalidName, type, exceptionState);
+ tryCatch.ReThrow();
return false;
}
if (CustomElement::isValidName(localName)) {
CustomElementException::throwException(CustomElementException::ExtendsIsCustomElementName, type, exceptionState);
+ tryCatch.ReThrow();
return false;
}
} else {
if (namespaceURI == SVGNames::svgNamespaceURI) {
CustomElementException::throwException(CustomElementException::ExtendsIsInvalidName, type, exceptionState);
+ tryCatch.ReThrow();
return false;
}
localName = type;
@@ -129,6 +146,7 @@ bool CustomElementConstructorBuilder::validateOptions(const AtomicString& type,
else
m_wrapperType = findWrapperTypeForSVGTagName(localName);
+ ASSERT(!tryCatch.HasCaught());
ASSERT(m_wrapperType);
tagName = QualifiedName(nullAtom, localName, namespaceURI);
return m_wrapperType;
@@ -138,18 +156,16 @@ PassRefPtr<CustomElementLifecycleCallbacks> CustomElementConstructorBuilder::cre
{
ASSERT(!m_prototype.IsEmpty());
- RefPtr<ExecutionContext> executionContext(toExecutionContext(m_context));
-
v8::TryCatch exceptionCatcher;
exceptionCatcher.SetVerbose(true);
- v8::Isolate* isolate = v8::Isolate::GetCurrent();
+ v8::Isolate* isolate = m_scriptState->isolate();
v8::Handle<v8::Function> created = retrieveCallback(isolate, "createdCallback");
v8::Handle<v8::Function> attached = retrieveCallback(isolate, "attachedCallback");
v8::Handle<v8::Function> detached = retrieveCallback(isolate, "detachedCallback");
v8::Handle<v8::Function> attributeChanged = retrieveCallback(isolate, "attributeChangedCallback");
- m_callbacks = V8CustomElementLifecycleCallbacks::create(executionContext.get(), m_prototype, created, attached, detached, attributeChanged);
+ m_callbacks = V8CustomElementLifecycleCallbacks::create(m_scriptState.get(), m_prototype, created, attached, detached, attributeChanged);
return m_callbacks.get();
}
@@ -167,7 +183,7 @@ bool CustomElementConstructorBuilder::createConstructor(Document* document, Cust
ASSERT(m_constructor.IsEmpty());
ASSERT(document);
- v8::Isolate* isolate = m_context->GetIsolate();
+ v8::Isolate* isolate = m_scriptState->isolate();
if (!prototypeIsValid(definition->descriptor().type(), exceptionState))
return false;
@@ -191,10 +207,10 @@ bool CustomElementConstructorBuilder::createConstructor(Document* document, Cust
m_constructor->SetName(v8Type->IsNull() ? v8TagName : v8Type.As<v8::String>());
- V8HiddenPropertyName::setNamedHiddenReference(m_constructor, "customElementDocument", toV8(document, m_context->Global(), isolate));
- V8HiddenPropertyName::setNamedHiddenReference(m_constructor, "customElementNamespaceURI", v8String(isolate, descriptor.namespaceURI()));
- V8HiddenPropertyName::setNamedHiddenReference(m_constructor, "customElementTagName", v8TagName);
- V8HiddenPropertyName::setNamedHiddenReference(m_constructor, "customElementType", v8Type);
+ V8HiddenValue::setHiddenValue(isolate, m_constructor, V8HiddenValue::customElementDocument(isolate), toV8(document, m_scriptState->context()->Global(), isolate));
+ V8HiddenValue::setHiddenValue(isolate, m_constructor, V8HiddenValue::customElementNamespaceURI(isolate), v8String(isolate, descriptor.namespaceURI()));
+ V8HiddenValue::setHiddenValue(isolate, m_constructor, V8HiddenValue::customElementTagName(isolate), v8TagName);
+ V8HiddenValue::setHiddenValue(isolate, m_constructor, V8HiddenValue::customElementType(isolate), v8Type);
v8::Handle<v8::String> prototypeKey = v8String(isolate, "prototype");
ASSERT(m_constructor->HasOwnProperty(prototypeKey));
@@ -207,7 +223,7 @@ bool CustomElementConstructorBuilder::createConstructor(Document* document, Cust
// property.
m_constructor->ForceSet(prototypeKey, m_prototype, v8::PropertyAttribute(v8::ReadOnly | v8::DontEnum | v8::DontDelete));
- V8HiddenPropertyName::setNamedHiddenReference(m_prototype, "customElementIsInterfacePrototypeObject", v8::True(isolate));
+ V8HiddenValue::setHiddenValue(isolate, m_prototype, V8HiddenValue::customElementIsInterfacePrototypeObject(isolate), v8::True(isolate));
m_prototype->ForceSet(v8String(isolate, "constructor"), m_constructor, v8::DontEnum);
return true;
@@ -215,12 +231,12 @@ bool CustomElementConstructorBuilder::createConstructor(Document* document, Cust
bool CustomElementConstructorBuilder::prototypeIsValid(const AtomicString& type, ExceptionState& exceptionState) const
{
- if (m_prototype->InternalFieldCount() || !m_prototype->GetHiddenValue(V8HiddenPropertyName::customElementIsInterfacePrototypeObject(m_context->GetIsolate())).IsEmpty()) {
+ if (m_prototype->InternalFieldCount() || !V8HiddenValue::getHiddenValue(m_scriptState->isolate(), m_prototype, V8HiddenValue::customElementIsInterfacePrototypeObject(m_scriptState->isolate())).IsEmpty()) {
CustomElementException::throwException(CustomElementException::PrototypeInUse, type, exceptionState);
return false;
}
- if (m_prototype->GetPropertyAttributes(v8String(m_context->GetIsolate(), "constructor")) & v8::DontDelete) {
+ if (m_prototype->GetPropertyAttributes(v8String(m_scriptState->isolate(), "constructor")) & v8::DontDelete) {
CustomElementException::throwException(CustomElementException::ConstructorPropertyNotConfigurable, type, exceptionState);
return false;
}
@@ -232,17 +248,17 @@ bool CustomElementConstructorBuilder::didRegisterDefinition(CustomElementDefinit
{
ASSERT(!m_constructor.IsEmpty());
- return m_callbacks->setBinding(definition, CustomElementBinding::create(m_context->GetIsolate(), m_prototype, m_wrapperType));
+ return m_callbacks->setBinding(definition, CustomElementBinding::create(m_scriptState->isolate(), m_prototype, m_wrapperType));
}
ScriptValue CustomElementConstructorBuilder::bindingsReturnValue() const
{
- return ScriptValue(m_constructor, m_context->GetIsolate());
+ return ScriptValue(m_scriptState.get(), m_constructor);
}
bool CustomElementConstructorBuilder::hasValidPrototypeChainFor(const WrapperTypeInfo* type) const
{
- v8::Handle<v8::Object> elementPrototype = V8PerContextData::from(m_context)->prototypeForType(type);
+ v8::Handle<v8::Object> elementPrototype = m_scriptState->perContextData()->prototypeForType(type);
if (elementPrototype.IsEmpty())
return false;
@@ -266,22 +282,28 @@ static void constructCustomElement(const v8::FunctionCallbackInfo<v8::Value>& in
}
if (info.Length() > 0) {
- throwUninformativeAndGenericTypeError(isolate);
+ throwTypeError("This constructor should be called without arguments.", isolate);
return;
}
- Document* document = V8Document::toNative(info.Callee()->GetHiddenValue(V8HiddenPropertyName::customElementDocument(isolate)).As<v8::Object>());
- V8TRYCATCH_FOR_V8STRINGRESOURCE_VOID(V8StringResource<>, namespaceURI, info.Callee()->GetHiddenValue(V8HiddenPropertyName::customElementNamespaceURI(isolate)));
- V8TRYCATCH_FOR_V8STRINGRESOURCE_VOID(V8StringResource<>, tagName, info.Callee()->GetHiddenValue(V8HiddenPropertyName::customElementTagName(isolate)));
- v8::Handle<v8::Value> maybeType = info.Callee()->GetHiddenValue(V8HiddenPropertyName::customElementType(isolate));
- V8TRYCATCH_FOR_V8STRINGRESOURCE_VOID(V8StringResource<>, type, maybeType);
+ Document* document = V8Document::toNative(V8HiddenValue::getHiddenValue(info.GetIsolate(), info.Callee(), V8HiddenValue::customElementDocument(isolate)).As<v8::Object>());
+ TOSTRING_VOID(V8StringResource<>, namespaceURI, V8HiddenValue::getHiddenValue(isolate, info.Callee(), V8HiddenValue::customElementNamespaceURI(isolate)));
+ TOSTRING_VOID(V8StringResource<>, tagName, V8HiddenValue::getHiddenValue(isolate, info.Callee(), V8HiddenValue::customElementTagName(isolate)));
+ v8::Handle<v8::Value> maybeType = V8HiddenValue::getHiddenValue(info.GetIsolate(), info.Callee(), V8HiddenValue::customElementType(isolate));
+ TOSTRING_VOID(V8StringResource<>, type, maybeType);
ExceptionState exceptionState(ExceptionState::ConstructionContext, "CustomElement", info.Holder(), info.GetIsolate());
CustomElementCallbackDispatcher::CallbackDeliveryScope deliveryScope;
- RefPtr<Element> element = document->createElementNS(namespaceURI, tagName, maybeType->IsNull() ? nullAtom : type, exceptionState);
+ RefPtrWillBeRawPtr<Element> element = document->createElementNS(namespaceURI, tagName, maybeType->IsNull() ? nullAtom : type, exceptionState);
if (exceptionState.throwIfNeeded())
return;
+#if ENABLE(OILPAN)
+ // FIXME: Oilpan: We don't have RawPtr<Eement> version of
+ // v8SetReturnValueFast until Node.idl has WillBeGarbageCollected.
+ v8SetReturnValueFast(info, element.get(), document);
+#else
v8SetReturnValueFast(info, element.release(), document);
+#endif
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/CustomElementConstructorBuilder.h b/chromium/third_party/WebKit/Source/bindings/v8/CustomElementConstructorBuilder.h
index 21f81e8c787..623244d2a70 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/CustomElementConstructorBuilder.h
+++ b/chromium/third_party/WebKit/Source/bindings/v8/CustomElementConstructorBuilder.h
@@ -49,7 +49,6 @@ class Document;
class Element;
class ExceptionState;
class QualifiedName;
-class ScriptState;
class V8PerContextData;
struct WrapperTypeInfo;
@@ -82,7 +81,7 @@ private:
bool prototypeIsValid(const AtomicString& type, ExceptionState&) const;
v8::Handle<v8::Function> retrieveCallback(v8::Isolate*, const char* name);
- v8::Handle<v8::Context> m_context;
+ RefPtr<ScriptState> m_scriptState;
const Dictionary* m_options;
v8::Handle<v8::Object> m_prototype;
const WrapperTypeInfo* m_wrapperType;
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/CustomElementWrapper.cpp b/chromium/third_party/WebKit/Source/bindings/v8/CustomElementWrapper.cpp
index 128c1e417e2..abd8830ea8b 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/CustomElementWrapper.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/CustomElementWrapper.cpp
@@ -31,13 +31,13 @@
#include "config.h"
#include "bindings/v8/CustomElementWrapper.h"
-#include "V8HTMLElement.h"
-#include "V8HTMLElementWrapperFactory.h"
-#include "V8SVGElement.h"
-#include "V8SVGElementWrapperFactory.h"
+#include "bindings/core/v8/V8HTMLElement.h"
+#include "bindings/core/v8/V8SVGElement.h"
#include "bindings/v8/DOMDataStore.h"
#include "bindings/v8/DOMWrapperWorld.h"
#include "bindings/v8/V8PerContextData.h"
+#include "core/V8HTMLElementWrapperFactory.h" // FIXME: should be bindings/core/v8
+#include "core/V8SVGElementWrapperFactory.h" // FIXME: should be bindings/core/v8
#include "core/dom/custom/CustomElement.h"
#include "core/html/HTMLElement.h"
#include "core/html/HTMLUnknownElement.h"
@@ -86,23 +86,21 @@ v8::Handle<v8::Object> createUpgradeCandidateWrapper(ElementType* element, v8::H
}
template<typename ElementType, typename WrapperType>
-v8::Handle<v8::Object> CustomElementWrapper<ElementType, WrapperType>::wrap(PassRefPtr<ElementType> element, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate, v8::Handle<v8::Object> (*createSpecificWrapper)(ElementType* element, v8::Handle<v8::Object> creationContext, v8::Isolate*))
+v8::Handle<v8::Object> CustomElementWrapper<ElementType, WrapperType>::wrap(PassRefPtrWillBeRawPtr<ElementType> element, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate, v8::Handle<v8::Object> (*createSpecificWrapper)(ElementType* element, v8::Handle<v8::Object> creationContext, v8::Isolate*))
{
ASSERT(DOMDataStore::getWrapper<V8Element>(element.get(), isolate).IsEmpty());
- // FIXME: creationContext.IsEmpty() should never happen. Remove
- // this when callers (like InspectorController::inspect) are fixed
- // to never pass an empty creation context.
- v8::Handle<v8::Context> context = creationContext.IsEmpty() ? isolate->GetCurrentContext() : creationContext->CreationContext();
+ ASSERT(!creationContext.IsEmpty());
+ v8::Handle<v8::Context> context = creationContext->CreationContext();
- if (!element->isUpgradedCustomElement() || DOMWrapperWorld::isolatedWorld(context))
+ if (!element->isUpgradedCustomElement() || DOMWrapperWorld::world(context).isIsolatedWorld())
return createUpgradeCandidateWrapper(element.get(), creationContext, isolate, createSpecificWrapper);
V8PerContextData* perContextData = V8PerContextData::from(context);
if (!perContextData)
return v8::Handle<v8::Object>();
- CustomElementBinding* binding = perContextData->customElementBinding(CustomElement::definitionFor(element.get()));
+ CustomElementBinding* binding = perContextData->customElementBinding(element->customElementDefinition());
v8::Handle<v8::Object> wrapper = V8DOMWrapper::createWrapper(creationContext, binding->wrapperType(), element.get(), isolate);
if (wrapper.IsEmpty())
return v8::Handle<v8::Object>();
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/CustomElementWrapper.h b/chromium/third_party/WebKit/Source/bindings/v8/CustomElementWrapper.h
index c3cbbe8e58d..bf3ba6e8dce 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/CustomElementWrapper.h
+++ b/chromium/third_party/WebKit/Source/bindings/v8/CustomElementWrapper.h
@@ -31,6 +31,7 @@
#ifndef CustomElementWrapper_h
#define CustomElementWrapper_h
+#include "platform/heap/Handle.h"
#include "wtf/PassRefPtr.h"
#include <v8.h>
@@ -47,7 +48,7 @@ private:
friend v8::Handle<v8::Object> createV8HTMLWrapper(HTMLElement*, v8::Handle<v8::Object>, v8::Isolate*);
friend v8::Handle<v8::Object> createV8SVGWrapper(SVGElement*, v8::Handle<v8::Object>, v8::Isolate*);
- static v8::Handle<v8::Object> wrap(PassRefPtr<ElementType>, v8::Handle<v8::Object> creationContext, v8::Isolate*, v8::Handle<v8::Object> (*createSpecificWrapper)(ElementType* element, v8::Handle<v8::Object> creationContext, v8::Isolate*));
+ static v8::Handle<v8::Object> wrap(PassRefPtrWillBeRawPtr<ElementType>, v8::Handle<v8::Object> creationContext, v8::Isolate*, v8::Handle<v8::Object> (*createSpecificWrapper)(ElementType* element, v8::Handle<v8::Object> creationContext, v8::Isolate*));
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/DOMDataStore.cpp b/chromium/third_party/WebKit/Source/bindings/v8/DOMDataStore.cpp
index fcfb12f00e7..c9ef7c4195c 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/DOMDataStore.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/DOMDataStore.cpp
@@ -37,40 +37,21 @@
namespace WebCore {
-DOMDataStore::DOMDataStore(WrapperWorldType type)
- : m_type(type)
+DOMDataStore::DOMDataStore(bool isMainWorld)
+ : m_isMainWorld(isMainWorld)
, m_wrapperMap(v8::Isolate::GetCurrent()) // FIXME Don't call GetCurrent twice.
{
- V8PerIsolateData::current()->registerDOMDataStore(this);
}
DOMDataStore::~DOMDataStore()
{
- ASSERT(m_type != MainWorld); // We never actually destruct the main world's DOMDataStore.
- V8PerIsolateData::current()->unregisterDOMDataStore(this);
+ ASSERT(!m_isMainWorld); // We never actually destruct the main world's DOMDataStore.
m_wrapperMap.clear();
}
-DOMDataStore& DOMDataStore::mainWorldStore()
-{
- DEFINE_STATIC_LOCAL(DOMDataStore, mainWorldDOMDataStore, (MainWorld));
- ASSERT(isMainThread());
- return mainWorldDOMDataStore;
-}
-
DOMDataStore& DOMDataStore::current(v8::Isolate* isolate)
{
- V8PerIsolateData* data = isolate ? V8PerIsolateData::from(isolate) : V8PerIsolateData::current();
- if (UNLIKELY(!!data->workerDOMDataStore()))
- return *data->workerDOMDataStore();
-
- if (DOMWrapperWorld::isolatedWorldsExist()) {
- DOMWrapperWorld* isolatedWorld = DOMWrapperWorld::isolatedWorld(isolate->GetEnteredContext());
- if (UNLIKELY(!!isolatedWorld))
- return isolatedWorld->isolatedWorldDOMDataStore();
- }
-
- return mainWorldStore();
+ return DOMWrapperWorld::current(isolate).domDataStore();
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/DOMDataStore.h b/chromium/third_party/WebKit/Source/bindings/v8/DOMDataStore.h
index a75d38f02d5..852e8110a32 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/DOMDataStore.h
+++ b/chromium/third_party/WebKit/Source/bindings/v8/DOMDataStore.h
@@ -46,24 +46,39 @@ class Node;
class DOMDataStore {
WTF_MAKE_NONCOPYABLE(DOMDataStore);
public:
- explicit DOMDataStore(WrapperWorldType);
+ explicit DOMDataStore(bool isMainWorld);
~DOMDataStore();
static DOMDataStore& current(v8::Isolate*);
+ // We can use a wrapper stored in a ScriptWrappable when we're in the main world.
+ // This method does the fast check if we're in the main world. If this method returns true,
+ // it is guaranteed that we're in the main world. On the other hand, if this method returns
+ // false, nothing is guaranteed (we might be in the main world).
+ template<typename T>
+ static bool canUseScriptWrappable(T* object)
+ {
+ return !DOMWrapperWorld::isolatedWorldsExist()
+ && !canExistInWorker(object)
+ && ScriptWrappable::wrapperCanBeStoredInObject(object);
+ }
+
template<typename V8T, typename T, typename Wrappable>
static bool setReturnValueFromWrapperFast(v8::ReturnValue<v8::Value> returnValue, T* object, v8::Local<v8::Object> holder, Wrappable* wrappable)
{
- // What we'd really like to check here is whether we're in the
- // main world or in an isolated world. The fastest way to do that
- // is to check that there is no isolated world and the 'object'
- // is an object that can exist in the main world. The second fastest
- // way is to check whether the wrappable's wrapper is the same as
- // the holder.
- if ((!DOMWrapperWorld::isolatedWorldsExist() && !canExistInWorker(object)) || holderContainsWrapper(holder, wrappable)) {
- if (ScriptWrappable::wrapperCanBeStoredInObject(object))
- return ScriptWrappable::setReturnValueWithSecurityCheck<V8T>(returnValue, object);
- return mainWorldStore().m_wrapperMap.setReturnValueFrom(returnValue, V8T::toInternalPointer(object));
+ if (canUseScriptWrappable(object)) {
+ ScriptWrappable::assertWrapperSanity<V8T, T>(object, object);
+ return ScriptWrappable::fromObject(object)->setReturnValue(returnValue);
+ }
+ // The second fastest way to check if we're in the main world is to check if
+ // the wrappable's wrapper is the same as the holder.
+ // FIXME: Investigate if it's worth having this check for performance.
+ if (holderContainsWrapper(holder, wrappable)) {
+ if (ScriptWrappable::wrapperCanBeStoredInObject(object)) {
+ ScriptWrappable::assertWrapperSanity<V8T, T>(object, object);
+ return ScriptWrappable::fromObject(object)->setReturnValue(returnValue);
+ }
+ return DOMWrapperWorld::mainWorld().domDataStore().m_wrapperMap.setReturnValueFrom(returnValue, V8T::toInternalPointer(object));
}
return current(returnValue.GetIsolate()).template setReturnValueFrom<V8T>(returnValue, object);
}
@@ -71,9 +86,9 @@ public:
template<typename V8T, typename T>
static bool setReturnValueFromWrapper(v8::ReturnValue<v8::Value> returnValue, T* object)
{
- if (ScriptWrappable::wrapperCanBeStoredInObject(object) && !canExistInWorker(object)) {
- if (LIKELY(!DOMWrapperWorld::isolatedWorldsExist()))
- return ScriptWrappable::setReturnValueWithSecurityCheck<V8T>(returnValue, object);
+ if (canUseScriptWrappable(object)) {
+ ScriptWrappable::assertWrapperSanity<V8T, T>(object, object);
+ return ScriptWrappable::fromObject(object)->setReturnValue(returnValue);
}
return current(returnValue.GetIsolate()).template setReturnValueFrom<V8T>(returnValue, object);
}
@@ -82,20 +97,18 @@ public:
static bool setReturnValueFromWrapperForMainWorld(v8::ReturnValue<v8::Value> returnValue, T* object)
{
if (ScriptWrappable::wrapperCanBeStoredInObject(object))
- return ScriptWrappable::setReturnValue(returnValue, object);
- return mainWorldStore().m_wrapperMap.setReturnValueFrom(returnValue, V8T::toInternalPointer(object));
+ return ScriptWrappable::fromObject(object)->setReturnValue(returnValue);
+ return DOMWrapperWorld::mainWorld().domDataStore().m_wrapperMap.setReturnValueFrom(returnValue, V8T::toInternalPointer(object));
}
template<typename V8T, typename T>
static v8::Handle<v8::Object> getWrapper(T* object, v8::Isolate* isolate)
{
- if (ScriptWrappable::wrapperCanBeStoredInObject(object) && !canExistInWorker(object)) {
- if (LIKELY(!DOMWrapperWorld::isolatedWorldsExist())) {
- v8::Handle<v8::Object> result = ScriptWrappable::getUnsafeWrapperFromObject(object).newLocal(isolate);
- // Security: always guard against malicious tampering.
- RELEASE_ASSERT_WITH_SECURITY_IMPLICATION(result.IsEmpty() || result->GetAlignedPointerFromInternalField(v8DOMWrapperObjectIndex) == V8T::toInternalPointer(object));
- return result;
- }
+ if (canUseScriptWrappable(object)) {
+ v8::Handle<v8::Object> result = ScriptWrappable::fromObject(object)->newLocalWrapper(isolate);
+ // Security: always guard against malicious tampering.
+ ScriptWrappable::assertWrapperSanity<V8T, T>(result, object);
+ return result;
}
return current(isolate).template get<V8T>(object, isolate);
}
@@ -103,13 +116,10 @@ public:
template<typename V8T, typename T>
static void setWrapperReference(const v8::Persistent<v8::Object>& parent, T* child, v8::Isolate* isolate)
{
- if (ScriptWrappable::wrapperCanBeStoredInObject(child) && !canExistInWorker(child)) {
- if (LIKELY(!DOMWrapperWorld::isolatedWorldsExist())) {
- UnsafePersistent<v8::Object> unsafePersistent = ScriptWrappable::getUnsafeWrapperFromObject(child);
- // Security: always guard against malicious tampering.
- RELEASE_ASSERT_WITH_SECURITY_IMPLICATION(unsafePersistent.isEmpty() || unsafePersistent.value()->GetAlignedPointerFromInternalField(v8DOMWrapperObjectIndex) == V8T::toInternalPointer(child));
- unsafePersistent.setReferenceFrom(parent, isolate);
- }
+ if (canUseScriptWrappable(child)) {
+ ScriptWrappable::assertWrapperSanity<V8T, T>(child, child);
+ ScriptWrappable::fromObject(child)->setReference(parent, isolate);
+ return;
}
current(isolate).template setReference<V8T>(parent, child, isolate);
}
@@ -117,11 +127,9 @@ public:
template<typename V8T, typename T>
static void setWrapper(T* object, v8::Handle<v8::Object> wrapper, v8::Isolate* isolate, const WrapperConfiguration& configuration)
{
- if (ScriptWrappable::wrapperCanBeStoredInObject(object) && !canExistInWorker(object)) {
- if (LIKELY(!DOMWrapperWorld::isolatedWorldsExist())) {
- ScriptWrappable::setWrapperInObject(object, wrapper, isolate, configuration);
- return;
- }
+ if (canUseScriptWrappable(object)) {
+ ScriptWrappable::fromObject(object)->setWrapper(wrapper, isolate, configuration);
+ return;
}
return current(isolate).template set<V8T>(object, wrapper, isolate, configuration);
}
@@ -135,16 +143,16 @@ public:
template<typename V8T, typename T>
inline v8::Handle<v8::Object> get(T* object, v8::Isolate* isolate)
{
- if (ScriptWrappable::wrapperCanBeStoredInObject(object) && m_type == MainWorld)
- return ScriptWrappable::getUnsafeWrapperFromObject(object).newLocal(isolate);
+ if (ScriptWrappable::wrapperCanBeStoredInObject(object) && m_isMainWorld)
+ return ScriptWrappable::fromObject(object)->newLocalWrapper(isolate);
return m_wrapperMap.newLocal(V8T::toInternalPointer(object), isolate);
}
template<typename V8T, typename T>
inline void setReference(const v8::Persistent<v8::Object>& parent, T* child, v8::Isolate* isolate)
{
- if (ScriptWrappable::wrapperCanBeStoredInObject(child) && m_type == MainWorld) {
- ScriptWrappable::getUnsafeWrapperFromObject(child).setReferenceFrom(parent, isolate);
+ if (ScriptWrappable::wrapperCanBeStoredInObject(child) && m_isMainWorld) {
+ ScriptWrappable::fromObject(child)->setReference(parent, isolate);
return;
}
m_wrapperMap.setReference(parent, V8T::toInternalPointer(child), isolate);
@@ -153,16 +161,16 @@ public:
template<typename V8T, typename T>
inline bool setReturnValueFrom(v8::ReturnValue<v8::Value> returnValue, T* object)
{
- if (ScriptWrappable::wrapperCanBeStoredInObject(object) && m_type == MainWorld)
- return ScriptWrappable::setReturnValue(returnValue, object);
+ if (ScriptWrappable::wrapperCanBeStoredInObject(object) && m_isMainWorld)
+ return ScriptWrappable::fromObject(object)->setReturnValue(returnValue);
return m_wrapperMap.setReturnValueFrom(returnValue, V8T::toInternalPointer(object));
}
template<typename V8T, typename T>
inline bool containsWrapper(T* object)
{
- if (ScriptWrappable::wrapperCanBeStoredInObject(object) && m_type == MainWorld)
- return !ScriptWrappable::getUnsafeWrapperFromObject(object).isEmpty();
+ if (ScriptWrappable::wrapperCanBeStoredInObject(object) && m_isMainWorld)
+ return ScriptWrappable::fromObject(object)->containsWrapper();
return m_wrapperMap.containsKey(V8T::toInternalPointer(object));
}
@@ -172,15 +180,13 @@ private:
{
ASSERT(!!object);
ASSERT(!wrapper.IsEmpty());
- if (ScriptWrappable::wrapperCanBeStoredInObject(object) && m_type == MainWorld) {
- ScriptWrappable::setWrapperInObject(object, wrapper, isolate, configuration);
+ if (ScriptWrappable::wrapperCanBeStoredInObject(object) && m_isMainWorld) {
+ ScriptWrappable::fromObject(object)->setWrapper(wrapper, isolate, configuration);
return;
}
m_wrapperMap.set(V8T::toInternalPointer(object), wrapper, configuration);
}
- static DOMDataStore& mainWorldStore();
-
static bool canExistInWorker(void*) { return true; }
static bool canExistInWorker(Node*) { return false; }
@@ -192,12 +198,12 @@ private:
static bool holderContainsWrapper(v8::Local<v8::Object> holder, ScriptWrappable* wrappable)
{
// Verify our assumptions about the main world.
- UnsafePersistent<v8::Object> unsafePersistent = wrappable->unsafePersistent();
- ASSERT(unsafePersistent.isEmpty() || !(holder == *unsafePersistent.persistent()) || current(v8::Isolate::GetCurrent()).m_type == MainWorld);
- return holder == *unsafePersistent.persistent();
+ ASSERT(wrappable);
+ ASSERT(!wrappable->containsWrapper() || !wrappable->isEqualTo(holder) || current(v8::Isolate::GetCurrent()).m_isMainWorld);
+ return wrappable->isEqualTo(holder);
}
- WrapperWorldType m_type;
+ bool m_isMainWorld;
DOMWrapperMap<void> m_wrapperMap;
};
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/DOMRequestState.h b/chromium/third_party/WebKit/Source/bindings/v8/DOMRequestState.h
deleted file mode 100644
index 710f3d371b0..00000000000
--- a/chromium/third_party/WebKit/Source/bindings/v8/DOMRequestState.h
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright (C) 2012 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 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 DOMRequestState_h
-#define DOMRequestState_h
-
-#include "bindings/v8/DOMWrapperWorld.h"
-#include "bindings/v8/V8Binding.h"
-#include "core/dom/ExecutionContext.h"
-#include "v8.h"
-#include "wtf/RefPtr.h"
-
-namespace WebCore {
-
-class DOMRequestState {
-public:
- explicit DOMRequestState(ExecutionContext* executionContext)
- : m_executionContext(executionContext)
- , m_world(DOMWrapperWorld::current())
- , m_isolate(toIsolate(executionContext))
- {
- ASSERT(m_executionContext);
- }
-
- void clear()
- {
- m_executionContext = 0;
- m_world.clear();
- }
-
- class Scope {
- public:
- explicit Scope(DOMRequestState& state)
- : m_handleScope(state.isolate())
- , m_contextScope(state.context())
- {
- }
- private:
- v8::HandleScope m_handleScope;
- v8::Context::Scope m_contextScope;
- };
-
- v8::Local<v8::Context> context()
- {
- ASSERT(m_executionContext);
- return toV8Context(m_executionContext, m_world.get());
- }
-
- v8::Isolate* isolate() const
- {
- return m_isolate;
- }
-
- bool isValid() const { return m_executionContext; }
-
-private:
- ExecutionContext* m_executionContext;
- RefPtr<DOMWrapperWorld> m_world;
- v8::Isolate* m_isolate;
-};
-
-}
-#endif
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/DOMWrapperMap.h b/chromium/third_party/WebKit/Source/bindings/v8/DOMWrapperMap.h
index 5987f57ace8..1ebbc53fb7c 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/DOMWrapperMap.h
+++ b/chromium/third_party/WebKit/Source/bindings/v8/DOMWrapperMap.h
@@ -31,9 +31,8 @@
#ifndef DOMWrapperMap_h
#define DOMWrapperMap_h
-#include "bindings/v8/UnsafePersistent.h"
-#include "bindings/v8/V8Utilities.h"
#include "bindings/v8/WrapperTypeInfo.h"
+#include <v8-util.h>
#include <v8.h>
#include "wtf/HashMap.h"
@@ -42,96 +41,127 @@ namespace WebCore {
template<class KeyType>
class DOMWrapperMap {
public:
- typedef HashMap<KeyType*, UnsafePersistent<v8::Object> > MapType;
-
explicit DOMWrapperMap(v8::Isolate* isolate)
: m_isolate(isolate)
+ , m_map(isolate)
{
}
v8::Handle<v8::Object> newLocal(KeyType* key, v8::Isolate* isolate)
{
- return m_map.get(key).newLocal(isolate);
+ return m_map.Get(key);
}
bool setReturnValueFrom(v8::ReturnValue<v8::Value> returnValue, KeyType* key)
{
- typename MapType::iterator it = m_map.find(key);
- if (it == m_map.end())
- return false;
- returnValue.Set(*(it->value.persistent()));
- return true;
+ return m_map.SetReturnValue(key, returnValue);
}
void setReference(const v8::Persistent<v8::Object>& parent, KeyType* key, v8::Isolate* isolate)
{
- m_map.get(key).setReferenceFrom(parent, isolate);
+ m_map.SetReference(key, parent);
}
bool containsKey(KeyType* key)
{
- return m_map.find(key) != m_map.end();
- }
-
- bool containsKeyAndValue(KeyType* key, v8::Handle<v8::Object> value)
- {
- typename MapType::iterator it = m_map.find(key);
- if (it == m_map.end())
- return false;
- return *(it->value.persistent()) == value;
+ return m_map.Contains(key);
}
void set(KeyType* key, v8::Handle<v8::Object> wrapper, const WrapperConfiguration& configuration)
{
ASSERT(static_cast<KeyType*>(toNative(wrapper)) == key);
- v8::Persistent<v8::Object> persistent(m_isolate, wrapper);
- configuration.configureWrapper(&persistent);
- persistent.SetWeak(this, &setWeakCallback);
- typename MapType::AddResult result = m_map.add(key, UnsafePersistent<v8::Object>());
- ASSERT(result.isNewEntry);
- // FIXME: Stop handling this case once duplicate wrappers are guaranteed not to be created.
- if (!result.isNewEntry)
- result.iterator->value.dispose();
- result.iterator->value = UnsafePersistent<v8::Object>(persistent);
+ RELEASE_ASSERT(!containsKey(key)); // See crbug.com/368095
+ v8::UniquePersistent<v8::Object> unique(m_isolate, wrapper);
+ configuration.configureWrapper(&unique);
+ m_map.Set(key, unique.Pass());
}
void clear()
{
- while (!m_map.isEmpty()) {
- // Swap out m_map on each iteration to ensure any wrappers added due to side effects of the loop are cleared.
- MapType map;
- map.swap(m_map);
- for (typename MapType::iterator it = map.begin(); it != map.end(); ++it) {
- toWrapperTypeInfo(*(it->value.persistent()))->derefObject(it->key);
- it->value.dispose();
- }
- }
+ m_map.Clear();
}
void removeAndDispose(KeyType* key)
{
- typename MapType::iterator it = m_map.find(key);
- ASSERT_WITH_SECURITY_IMPLICATION(it != m_map.end());
- it->value.dispose();
- m_map.remove(it);
+ ASSERT(containsKey(key));
+ m_map.Remove(key);
}
private:
- static void setWeakCallback(const v8::WeakCallbackData<v8::Object, DOMWrapperMap<KeyType> >&);
+ class PersistentValueMapTraits {
+ public:
+ // Map traits:
+ typedef HashMap<KeyType*, v8::PersistentContainerValue> Impl;
+ typedef typename Impl::iterator Iterator;
+ static size_t Size(const Impl* impl) { return impl->size(); }
+ static bool Empty(Impl* impl) { return impl->isEmpty(); }
+ static void Swap(Impl& impl, Impl& other) { impl.swap(other); }
+ static Iterator Begin(Impl* impl) { return impl->begin(); }
+ static Iterator End(Impl* impl) { return impl->end(); }
+ static v8::PersistentContainerValue Value(Iterator& iter)
+ {
+ return iter->value;
+ }
+ static KeyType* Key(Iterator& iter) { return iter->key; }
+ static v8::PersistentContainerValue Set(
+ Impl* impl, KeyType* key, v8::PersistentContainerValue value)
+ {
+ v8::PersistentContainerValue oldValue = Get(impl, key);
+ impl->set(key, value);
+ return oldValue;
+ }
+ static v8::PersistentContainerValue Get(const Impl* impl, KeyType* key)
+ {
+ return impl->get(key);
+ }
+
+ static v8::PersistentContainerValue Remove(Impl* impl, KeyType* key)
+ {
+ return impl->take(key);
+ }
+
+ // Weak traits:
+ static const v8::PersistentContainerCallbackType kCallbackType = v8::kWeak;
+ typedef v8::PersistentValueMap<KeyType*, v8::Object, PersistentValueMapTraits> MapType;
+ typedef MapType WeakCallbackDataType;
+
+ static WeakCallbackDataType* WeakCallbackParameter(MapType* map, KeyType* key, v8::Local<v8::Object>& value)
+ {
+ return map;
+ }
+
+ static void DisposeCallbackData(WeakCallbackDataType* callbackData) { }
+
+ static MapType* MapFromWeakCallbackData(
+ const v8::WeakCallbackData<v8::Object, WeakCallbackDataType>& data)
+ {
+ return data.GetParameter();
+ }
+
+ static KeyType* KeyFromWeakCallbackData(
+ const v8::WeakCallbackData<v8::Object, WeakCallbackDataType>& data)
+ {
+ return static_cast<KeyType*>(toNative(data.GetValue()));
+ }
+
+ // Dispose traits:
+ // Generally nothing to do, but see below for a specialization for
+ // DomWrapperMap<void>.
+ static void Dispose(v8::Isolate* isolate, v8::UniquePersistent<v8::Object> value, KeyType* key) { }
+ };
v8::Isolate* m_isolate;
- MapType m_map;
+ typename PersistentValueMapTraits::MapType m_map;
};
-template<>
-inline void DOMWrapperMap<void>::setWeakCallback(const v8::WeakCallbackData<v8::Object, DOMWrapperMap<void> >& data)
+template <>
+inline void DOMWrapperMap<void>::PersistentValueMapTraits::Dispose(
+ v8::Isolate* isolate,
+ v8::UniquePersistent<v8::Object> value,
+ void* key)
{
- const WrapperTypeInfo* type = toWrapperTypeInfo(data.GetValue());
- ASSERT(type->derefObjectFunction);
- void* key = static_cast<void*>(toNative(data.GetValue()));
- ASSERT(*(data.GetParameter()->m_map.get(key).persistent()) == data.GetValue());
- data.GetParameter()->removeAndDispose(key);
- type->derefObject(key);
+ RELEASE_ASSERT(!value.IsEmpty()); // See crbug.com/368095.
+ releaseObject(v8::Local<v8::Object>::New(isolate, value));
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/DOMWrapperWorld.cpp b/chromium/third_party/WebKit/Source/bindings/v8/DOMWrapperWorld.cpp
index d014206817f..59cb4505716 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/DOMWrapperWorld.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/DOMWrapperWorld.cpp
@@ -31,7 +31,7 @@
#include "config.h"
#include "bindings/v8/DOMWrapperWorld.h"
-#include "V8Window.h"
+#include "bindings/core/v8/V8Window.h"
#include "bindings/v8/DOMDataStore.h"
#include "bindings/v8/ScriptController.h"
#include "bindings/v8/V8Binding.h"
@@ -41,70 +41,30 @@
#include "bindings/v8/WrapperTypeInfo.h"
#include "core/dom/ExecutionContext.h"
#include "wtf/HashTraits.h"
-#include "wtf/MainThread.h"
#include "wtf/StdLibExtras.h"
namespace WebCore {
unsigned DOMWrapperWorld::isolatedWorldCount = 0;
-static bool initializingWindow = false;
+DOMWrapperWorld* DOMWrapperWorld::worldOfInitializingWindow = 0;
-void DOMWrapperWorld::setInitializingWindow(bool initializing)
+PassRefPtr<DOMWrapperWorld> DOMWrapperWorld::create(int worldId, int extensionGroup)
{
- initializingWindow = initializing;
-}
-
-PassRefPtr<DOMWrapperWorld> DOMWrapperWorld::createMainWorld()
-{
- return adoptRef(new DOMWrapperWorld(MainWorldId, mainWorldExtensionGroup));
+ return adoptRef(new DOMWrapperWorld(worldId, extensionGroup));
}
DOMWrapperWorld::DOMWrapperWorld(int worldId, int extensionGroup)
: m_worldId(worldId)
, m_extensionGroup(extensionGroup)
+ , m_domDataStore(adoptPtr(new DOMDataStore(isMainWorld())))
{
- if (isIsolatedWorld())
- m_domDataStore = adoptPtr(new DOMDataStore(IsolatedWorld));
-}
-
-DOMWrapperWorld* DOMWrapperWorld::current()
-{
- v8::Isolate* isolate = v8::Isolate::GetCurrent();
- ASSERT(isolate->InContext());
- v8::Handle<v8::Context> context = isolate->GetCurrentContext();
- if (!V8DOMWrapper::isWrapperOfType(toInnerGlobalObject(context), &V8Window::wrapperTypeInfo))
- return 0;
- ASSERT(isMainThread());
- if (DOMWrapperWorld* world = isolatedWorld(context))
- return world;
- return mainThreadNormalWorld();
}
-DOMWrapperWorld* mainThreadNormalWorld()
+DOMWrapperWorld& DOMWrapperWorld::mainWorld()
{
ASSERT(isMainThread());
- DEFINE_STATIC_REF(DOMWrapperWorld, cachedNormalWorld, (DOMWrapperWorld::createMainWorld()));
- return cachedNormalWorld;
-}
-
-// FIXME: Remove this function. There is currently an issue with the inspector related to the call to dispatchDidClearWindowObjectInWorld in ScriptController::windowShell.
-DOMWrapperWorld* existingWindowShellWorkaroundWorld()
-{
- DEFINE_STATIC_REF(DOMWrapperWorld, world, (adoptRef(new DOMWrapperWorld(MainWorldId - 1, DOMWrapperWorld::mainWorldExtensionGroup - 1))));
- return world;
-}
-
-bool DOMWrapperWorld::contextHasCorrectPrototype(v8::Handle<v8::Context> context)
-{
- ASSERT(isMainThread());
- if (initializingWindow)
- return true;
- return V8DOMWrapper::isWrapperOfType(toInnerGlobalObject(context), &V8Window::wrapperTypeInfo);
-}
-
-void DOMWrapperWorld::setIsolatedWorldField(v8::Handle<v8::Context> context)
-{
- V8PerContextDataHolder::from(context)->setIsolatedWorld(isMainWorld() ? 0 : this);
+ DEFINE_STATIC_REF(DOMWrapperWorld, cachedMainWorld, (DOMWrapperWorld::create(MainWorldId, mainWorldExtensionGroup)));
+ return *cachedMainWorld;
}
typedef HashMap<int, DOMWrapperWorld*> WorldMap;
@@ -115,9 +75,10 @@ static WorldMap& isolatedWorldMap()
return map;
}
-void DOMWrapperWorld::getAllWorlds(Vector<RefPtr<DOMWrapperWorld> >& worlds)
+void DOMWrapperWorld::allWorldsInMainThread(Vector<RefPtr<DOMWrapperWorld> >& worlds)
{
- worlds.append(mainThreadNormalWorld());
+ ASSERT(isMainThread());
+ worlds.append(&mainWorld());
WorldMap& isolatedWorlds = isolatedWorldMap();
for (WorldMap::iterator it = isolatedWorlds.begin(); it != isolatedWorlds.end(); ++it)
worlds.append(it->value);
@@ -127,48 +88,57 @@ DOMWrapperWorld::~DOMWrapperWorld()
{
ASSERT(!isMainWorld());
+ dispose();
+
if (!isIsolatedWorld())
return;
WorldMap& map = isolatedWorldMap();
- WorldMap::iterator i = map.find(m_worldId);
- if (i == map.end()) {
+ WorldMap::iterator it = map.find(m_worldId);
+ if (it == map.end()) {
ASSERT_NOT_REACHED();
return;
}
- ASSERT(i->value == this);
+ ASSERT(it->value == this);
- map.remove(i);
+ map.remove(it);
isolatedWorldCount--;
ASSERT(map.size() == isolatedWorldCount);
}
+void DOMWrapperWorld::dispose()
+{
+ m_domDataStore.clear();
+}
+
+#ifndef NDEBUG
+static bool isIsolatedWorldId(int worldId)
+{
+ return MainWorldId < worldId && worldId < IsolatedWorldIdLimit;
+}
+#endif
+
PassRefPtr<DOMWrapperWorld> DOMWrapperWorld::ensureIsolatedWorld(int worldId, int extensionGroup)
{
- ASSERT(worldId > MainWorldId);
+ ASSERT(isIsolatedWorldId(worldId));
WorldMap& map = isolatedWorldMap();
WorldMap::AddResult result = map.add(worldId, 0);
- RefPtr<DOMWrapperWorld> world = result.iterator->value;
+ RefPtr<DOMWrapperWorld> world = result.storedValue->value;
if (world) {
ASSERT(world->worldId() == worldId);
ASSERT(world->extensionGroup() == extensionGroup);
return world.release();
}
- world = adoptRef(new DOMWrapperWorld(worldId, extensionGroup));
- result.iterator->value = world.get();
+ world = DOMWrapperWorld::create(worldId, extensionGroup);
+ result.storedValue->value = world.get();
isolatedWorldCount++;
ASSERT(map.size() == isolatedWorldCount);
return world.release();
}
-v8::Handle<v8::Context> DOMWrapperWorld::context(ScriptController& controller)
-{
- return controller.windowShell(this)->context();
-}
-
typedef HashMap<int, RefPtr<SecurityOrigin> > IsolatedWorldSecurityOriginMap;
static IsolatedWorldSecurityOriginMap& isolatedWorldSecurityOrigins()
{
@@ -185,19 +155,13 @@ SecurityOrigin* DOMWrapperWorld::isolatedWorldSecurityOrigin()
return it == origins.end() ? 0 : it->value.get();
}
-void DOMWrapperWorld::setIsolatedWorldSecurityOrigin(int worldID, PassRefPtr<SecurityOrigin> securityOrigin)
+void DOMWrapperWorld::setIsolatedWorldSecurityOrigin(int worldId, PassRefPtr<SecurityOrigin> securityOrigin)
{
- ASSERT(DOMWrapperWorld::isIsolatedWorldId(worldID));
+ ASSERT(isIsolatedWorldId(worldId));
if (securityOrigin)
- isolatedWorldSecurityOrigins().set(worldID, securityOrigin);
+ isolatedWorldSecurityOrigins().set(worldId, securityOrigin);
else
- isolatedWorldSecurityOrigins().remove(worldID);
-}
-
-void DOMWrapperWorld::clearIsolatedWorldSecurityOrigin(int worldID)
-{
- ASSERT(DOMWrapperWorld::isIsolatedWorldId(worldID));
- isolatedWorldSecurityOrigins().remove(worldID);
+ isolatedWorldSecurityOrigins().remove(worldId);
}
typedef HashMap<int, bool> IsolatedWorldContentSecurityPolicyMap;
@@ -216,39 +180,13 @@ bool DOMWrapperWorld::isolatedWorldHasContentSecurityPolicy()
return it == policies.end() ? false : it->value;
}
-void DOMWrapperWorld::setIsolatedWorldContentSecurityPolicy(int worldID, const String& policy)
+void DOMWrapperWorld::setIsolatedWorldContentSecurityPolicy(int worldId, const String& policy)
{
- ASSERT(DOMWrapperWorld::isIsolatedWorldId(worldID));
+ ASSERT(isIsolatedWorldId(worldId));
if (!policy.isEmpty())
- isolatedWorldContentSecurityPolicies().set(worldID, true);
+ isolatedWorldContentSecurityPolicies().set(worldId, true);
else
- isolatedWorldContentSecurityPolicies().remove(worldID);
-}
-
-void DOMWrapperWorld::clearIsolatedWorldContentSecurityPolicy(int worldID)
-{
- ASSERT(DOMWrapperWorld::isIsolatedWorldId(worldID));
- isolatedWorldContentSecurityPolicies().remove(worldID);
-}
-
-typedef HashMap<int, OwnPtr<V8DOMActivityLogger>, WTF::IntHash<int>, WTF::UnsignedWithZeroKeyHashTraits<int> > DOMActivityLoggerMap;
-static DOMActivityLoggerMap& domActivityLoggers()
-{
- ASSERT(isMainThread());
- DEFINE_STATIC_LOCAL(DOMActivityLoggerMap, map, ());
- return map;
-}
-
-void DOMWrapperWorld::setActivityLogger(int worldId, PassOwnPtr<V8DOMActivityLogger> logger)
-{
- domActivityLoggers().set(worldId, logger);
-}
-
-V8DOMActivityLogger* DOMWrapperWorld::activityLogger(int worldId)
-{
- DOMActivityLoggerMap& loggers = domActivityLoggers();
- DOMActivityLoggerMap::iterator it = loggers.find(worldId);
- return it == loggers.end() ? 0 : it->value.get();
+ isolatedWorldContentSecurityPolicies().remove(worldId);
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/DOMWrapperWorld.h b/chromium/third_party/WebKit/Source/bindings/v8/DOMWrapperWorld.h
index 201e019309f..aa294a1fcfb 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/DOMWrapperWorld.h
+++ b/chromium/third_party/WebKit/Source/bindings/v8/DOMWrapperWorld.h
@@ -31,54 +31,67 @@
#ifndef DOMWrapperWorld_h
#define DOMWrapperWorld_h
-#include "bindings/v8/V8DOMActivityLogger.h"
-#include "bindings/v8/V8PerContextData.h"
+#include "bindings/v8/ScriptState.h"
#include "platform/weborigin/SecurityOrigin.h"
-#include <v8.h>
+#include "wtf/MainThread.h"
#include "wtf/PassRefPtr.h"
#include "wtf/RefCounted.h"
#include "wtf/RefPtr.h"
#include "wtf/text/WTFString.h"
+#include <v8.h>
namespace WebCore {
class DOMDataStore;
-class ScriptController;
class ExecutionContext;
+class ScriptController;
enum WorldIdConstants {
MainWorldId = 0,
+ // Embedder isolated worlds can use IDs in [1, 1<<29).
EmbedderWorldIdLimit = (1 << 29),
- ScriptPreprocessorIsolatedWorldId
+ ScriptPreprocessorIsolatedWorldId,
+ IsolatedWorldIdLimit,
+ WorkerWorldId,
+ TestingWorldId,
};
// This class represent a collection of DOM wrappers for a specific world.
class DOMWrapperWorld : public RefCounted<DOMWrapperWorld> {
public:
+ static PassRefPtr<DOMWrapperWorld> create(int worldId = -1, int extensionGroup = -1);
+
static const int mainWorldExtensionGroup = 0;
static PassRefPtr<DOMWrapperWorld> ensureIsolatedWorld(int worldId, int extensionGroup);
~DOMWrapperWorld();
+ void dispose();
static bool isolatedWorldsExist() { return isolatedWorldCount; }
- static bool isIsolatedWorldId(int worldId) { return worldId > MainWorldId; }
- static void getAllWorlds(Vector<RefPtr<DOMWrapperWorld> >& worlds);
+ static void allWorldsInMainThread(Vector<RefPtr<DOMWrapperWorld> >& worlds);
- void setIsolatedWorldField(v8::Handle<v8::Context>);
+ static DOMWrapperWorld& world(v8::Handle<v8::Context> context)
+ {
+ return ScriptState::from(context)->world();
+ }
- static DOMWrapperWorld* isolatedWorld(v8::Handle<v8::Context> context)
+ static DOMWrapperWorld& current(v8::Isolate* isolate)
{
- ASSERT(contextHasCorrectPrototype(context));
- return V8PerContextDataHolder::from(context)->isolatedWorld();
+ if (isMainThread() && worldOfInitializingWindow) {
+ // It's possible that current() is being called while window is being initialized.
+ // In order to make current() workable during the initialization phase,
+ // we cache the world of the initializing window on worldOfInitializingWindow.
+ // If there is no initiazing window, worldOfInitializingWindow is 0.
+ return *worldOfInitializingWindow;
+ }
+ return world(isolate->GetCurrentContext());
}
- // Will return null if there is no DOMWrapperWorld for the current v8::Context
- static DOMWrapperWorld* current();
+ static DOMWrapperWorld& mainWorld();
// Associates an isolated world (see above for description) with a security
// origin. XMLHttpRequest instances used in that world will be considered
// to come from that origin, not the frame's.
- static void setIsolatedWorldSecurityOrigin(int worldID, PassRefPtr<SecurityOrigin>);
- static void clearIsolatedWorldSecurityOrigin(int worldID);
+ static void setIsolatedWorldSecurityOrigin(int worldId, PassRefPtr<SecurityOrigin>);
SecurityOrigin* isolatedWorldSecurityOrigin();
// Associated an isolated world with a Content Security Policy. Resources
@@ -89,50 +102,36 @@ public:
// FIXME: Right now, resource injection simply bypasses the main world's
// DOM. More work is necessary to allow the isolated world's policy to be
// applied correctly.
- static void setIsolatedWorldContentSecurityPolicy(int worldID, const String& policy);
- static void clearIsolatedWorldContentSecurityPolicy(int worldID);
+ static void setIsolatedWorldContentSecurityPolicy(int worldId, const String& policy);
bool isolatedWorldHasContentSecurityPolicy();
- // Associate a logger with the world identified by worldId (worlId may be 0
- // identifying the main world).
- static void setActivityLogger(int worldId, PassOwnPtr<V8DOMActivityLogger>);
- static V8DOMActivityLogger* activityLogger(int worldId);
-
bool isMainWorld() const { return m_worldId == MainWorldId; }
- bool isIsolatedWorld() const { return isIsolatedWorldId(m_worldId); }
+ bool isWorkerWorld() const { return m_worldId == WorkerWorldId; }
+ bool isIsolatedWorld() const { return MainWorldId < m_worldId && m_worldId < IsolatedWorldIdLimit; }
int worldId() const { return m_worldId; }
int extensionGroup() const { return m_extensionGroup; }
- DOMDataStore& isolatedWorldDOMDataStore() const
+ DOMDataStore& domDataStore() const { return *m_domDataStore; }
+
+ static void setWorldOfInitializingWindow(DOMWrapperWorld* world)
{
- ASSERT(isIsolatedWorld());
- return *m_domDataStore;
+ ASSERT(isMainThread());
+ worldOfInitializingWindow = world;
}
- v8::Handle<v8::Context> context(ScriptController&);
-
- static void setInitializingWindow(bool);
+ // FIXME: Remove this method once we fix crbug.com/345014.
+ static bool windowIsBeingInitialized() { return !!worldOfInitializingWindow; }
private:
- static unsigned isolatedWorldCount;
- static PassRefPtr<DOMWrapperWorld> createMainWorld();
- static bool contextHasCorrectPrototype(v8::Handle<v8::Context>);
-
DOMWrapperWorld(int worldId, int extensionGroup);
+ static unsigned isolatedWorldCount;
+ static DOMWrapperWorld* worldOfInitializingWindow;
+
const int m_worldId;
const int m_extensionGroup;
OwnPtr<DOMDataStore> m_domDataStore;
-
- friend DOMWrapperWorld* mainThreadNormalWorld();
- friend DOMWrapperWorld* existingWindowShellWorkaroundWorld();
};
-DOMWrapperWorld* mainThreadNormalWorld();
-
-// FIXME: this is a workaround for a problem in ScriptController
-// Do not use this anywhere else!!
-DOMWrapperWorld* existingWindowShellWorkaroundWorld();
-
} // namespace WebCore
#endif // DOMWrapperWorld_h
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/DebuggerScript.js b/chromium/third_party/WebKit/Source/bindings/v8/DebuggerScript.js
index 2f92b48013e..bec40048c12 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/DebuggerScript.js
+++ b/chromium/third_party/WebKit/Source/bindings/v8/DebuggerScript.js
@@ -33,11 +33,17 @@
var DebuggerScript = {};
DebuggerScript.PauseOnExceptionsState = {
- DontPauseOnExceptions : 0,
- PauseOnAllExceptions : 1,
+ DontPauseOnExceptions: 0,
+ PauseOnAllExceptions: 1,
PauseOnUncaughtExceptions: 2
};
+DebuggerScript.ScopeInfoDetails = {
+ AllScopes: 0,
+ FastAsyncScopes: 1,
+ NoScopes: 2
+};
+
DebuggerScript._pauseOnExceptionsState = DebuggerScript.PauseOnExceptionsState.DontPauseOnExceptions;
Debug.clearBreakOnException();
Debug.clearBreakOnUncaughtException();
@@ -70,10 +76,10 @@ DebuggerScript.getFunctionScopes = function(fun)
return null;
var result = [];
for (var i = 0; i < count; i++) {
- var scopeMirror = mirror.scope(i);
+ var scopeDetails = mirror.scope(i).details();
result[i] = {
- type: scopeMirror.scopeType(),
- object: DebuggerScript._buildScopeObject(scopeMirror)
+ type: scopeDetails.type(),
+ object: DebuggerScript._buildScopeObject(scopeDetails.type(), scopeDetails.object())
};
}
return result;
@@ -199,15 +205,23 @@ DebuggerScript.setPauseOnExceptionsState = function(newState)
Debug.clearBreakOnUncaughtException();
}
-DebuggerScript.currentCallFrame = function(execState, maximumLimit)
+DebuggerScript.frameCount = function(execState)
{
+ return execState.frameCount();
+}
+
+DebuggerScript.currentCallFrame = function(execState, data)
+{
+ var maximumLimit = data >> 2;
+ var scopeDetailsLevel = data & 3;
+
var frameCount = execState.frameCount();
- if (maximumLimit >= 0 && maximumLimit < frameCount)
+ if (maximumLimit && maximumLimit < frameCount)
frameCount = maximumLimit;
var topFrame = undefined;
for (var i = frameCount - 1; i >= 0; i--) {
var frameMirror = execState.frame(i);
- topFrame = DebuggerScript._frameMirrorToJSCallFrame(frameMirror, topFrame);
+ topFrame = DebuggerScript._frameMirrorToJSCallFrame(frameMirror, topFrame, scopeDetailsLevel);
}
return topFrame;
}
@@ -219,14 +233,12 @@ DebuggerScript.stepIntoStatement = function(execState)
DebuggerScript.stepOverStatement = function(execState, callFrame)
{
- var frameMirror = callFrame ? callFrame.frameMirror : undefined;
- execState.prepareStep(Debug.StepAction.StepNext, 1, frameMirror);
+ execState.prepareStep(Debug.StepAction.StepNext, 1);
}
DebuggerScript.stepOutOfFunction = function(execState, callFrame)
{
- var frameMirror = callFrame ? callFrame.frameMirror : undefined;
- execState.prepareStep(Debug.StepAction.StepOut, 1, frameMirror);
+ execState.prepareStep(Debug.StepAction.StepOut, 1);
}
// Returns array in form:
@@ -310,43 +322,95 @@ DebuggerScript.isEvalCompilation = function(eventData)
return (script.compilationType() === Debug.ScriptCompilationType.Eval);
}
-DebuggerScript._frameMirrorToJSCallFrame = function(frameMirror, callerFrame)
+// NOTE: This function is performance critical, as it can be run on every
+// statement that generates an async event (like addEventListener) to support
+// asynchronous call stacks. Thus, when possible, initialize the data lazily.
+DebuggerScript._frameMirrorToJSCallFrame = function(frameMirror, callerFrame, scopeDetailsLevel)
{
- // Get function name and display name.
+ // Stuff that can not be initialized lazily (i.e. valid while paused with a valid break_id).
+ // The frameMirror and scopeMirror can be accessed only while paused on the debugger.
+ var frameDetails = frameMirror.details();
+
+ var funcObject = frameDetails.func();
+ var sourcePosition = frameDetails.sourcePosition();
+ var thisObject = frameDetails.receiver();
+
+ var isAtReturn = !!frameDetails.isAtReturn();
+ var returnValue = isAtReturn ? frameDetails.returnValue() : undefined;
+
+ var scopeMirrors = (scopeDetailsLevel === DebuggerScript.ScopeInfoDetails.NoScopes ? [] : frameMirror.allScopes(scopeDetailsLevel === DebuggerScript.ScopeInfoDetails.FastAsyncScopes));
+ var scopeTypes = new Array(scopeMirrors.length);
+ var scopeObjects = new Array(scopeMirrors.length);
+ for (var i = 0; i < scopeMirrors.length; ++i) {
+ var scopeDetails = scopeMirrors[i].details();
+ scopeTypes[i] = scopeDetails.type();
+ scopeObjects[i] = scopeDetails.object();
+ }
+
+ // Calculated lazily.
+ var scopeChain;
var funcMirror;
- var displayName;
- try {
- funcMirror = frameMirror.func();
- if (funcMirror) {
- var valueMirror = funcMirror.property("displayName").value();
- if (valueMirror && valueMirror.isString())
- displayName = valueMirror.value();
+ var location;
+
+ function lazyScopeChain()
+ {
+ if (!scopeChain) {
+ scopeChain = [];
+ for (var i = 0; i < scopeObjects.length; ++i)
+ scopeChain.push(DebuggerScript._buildScopeObject(scopeTypes[i], scopeObjects[i]));
+ scopeObjects = null; // Free for GC.
+ }
+ return scopeChain;
+ }
+
+ function ensureFuncMirror()
+ {
+ if (!funcMirror) {
+ funcMirror = MakeMirror(funcObject);
+ if (!funcMirror.isFunction())
+ funcMirror = new UnresolvedFunctionMirror(funcObject);
}
- } catch(e) {
+ return funcMirror;
}
- var functionName;
- if (funcMirror)
- functionName = displayName || funcMirror.name() || funcMirror.inferredName();
- // Get script ID.
- var script = funcMirror.script();
- var sourceID = script && script.id();
+ function ensureLocation()
+ {
+ if (!location) {
+ var script = ensureFuncMirror().script();
+ if (script)
+ location = script.locationFromPosition(sourcePosition, true);
+ if (!location)
+ location = { line: 0, column: 0 };
+ }
+ return location;
+ }
- // Get location.
- var location = frameMirror.sourceLocation();
+ function line()
+ {
+ return ensureLocation().line;
+ }
- // Get this object.
- var thisObject = frameMirror.details_.receiver();
+ function column()
+ {
+ return ensureLocation().column;
+ }
- var isAtReturn = !!frameMirror.details_.isAtReturn();
- var returnValue = isAtReturn ? frameMirror.details_.returnValue() : undefined;
+ function sourceID()
+ {
+ var script = ensureFuncMirror().script();
+ return script && script.id();
+ }
- var scopeChain = [];
- var scopeType = [];
- for (var i = 0; i < frameMirror.scopeCount(); i++) {
- var scopeMirror = frameMirror.scope(i);
- scopeType.push(scopeMirror.scopeType());
- scopeChain.push(DebuggerScript._buildScopeObject(scopeMirror));
+ function functionName()
+ {
+ var func = ensureFuncMirror();
+ if (!func.resolved())
+ return undefined;
+ var displayName;
+ var valueMirror = func.property("displayName").value();
+ if (valueMirror && valueMirror.isString())
+ displayName = valueMirror.value();
+ return displayName || func.name() || func.inferredName();
}
function evaluate(expression)
@@ -370,7 +434,7 @@ DebuggerScript._frameMirrorToJSCallFrame = function(frameMirror, callerFrame)
var stepInPositionsProtocol;
if (stepInPositionsV8) {
stepInPositionsProtocol = [];
- var script = frameMirror.func().script();
+ var script = ensureFuncMirror().script();
if (script) {
var scriptId = String(script.id());
for (var i = 0; i < stepInPositionsV8.length; i++) {
@@ -388,54 +452,55 @@ DebuggerScript._frameMirrorToJSCallFrame = function(frameMirror, callerFrame)
return {
"sourceID": sourceID,
- "line": location ? location.line : 0,
- "column": location ? location.column : 0,
+ "line": line,
+ "column": column,
"functionName": functionName,
"thisObject": thisObject,
- "scopeChain": scopeChain,
- "scopeType": scopeType,
+ "scopeChain": lazyScopeChain,
+ "scopeType": scopeTypes,
"evaluate": evaluate,
"caller": callerFrame,
"restart": restart,
"setVariableValue": setVariableValue,
"stepInPositions": stepInPositions,
"isAtReturn": isAtReturn,
- "returnValue": returnValue,
- "frameMirror": frameMirror
+ "returnValue": returnValue
};
}
-DebuggerScript._buildScopeObject = function(scopeMirror) {
- var scopeObject;
- switch (scopeMirror.scopeType()) {
+DebuggerScript._buildScopeObject = function(scopeType, scopeObject)
+{
+ var result;
+ switch (scopeType) {
case ScopeType.Local:
case ScopeType.Closure:
case ScopeType.Catch:
// For transient objects we create a "persistent" copy that contains
// the same properties.
- scopeObject = {};
// Reset scope object prototype to null so that the proto properties
// don't appear in the local scope section.
- scopeObject.__proto__ = null;
- var scopeObjectMirror = scopeMirror.scopeObject();
- var properties = scopeObjectMirror.properties();
+ result = { __proto__: null };
+ var properties = MakeMirror(scopeObject, true /* transient */).properties();
for (var j = 0; j < properties.length; j++) {
var name = properties[j].name();
if (name.charAt(0) === ".")
continue; // Skip internal variables like ".arguments"
- scopeObject[name] = properties[j].value_;
+ result[name] = properties[j].value_;
}
break;
case ScopeType.Global:
case ScopeType.With:
- scopeObject = scopeMirror.details_.object();
+ result = scopeObject;
break;
case ScopeType.Block:
// Unsupported yet. Mustn't be reachable.
break;
}
- return scopeObject;
+ return result;
}
+// We never resolve Mirror by its handle so to avoid memory leaks caused by Mirrors in the cache we disable it.
+ToggleMirrorCache(false);
+
return DebuggerScript;
})();
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/Dictionary.cpp b/chromium/third_party/WebKit/Source/bindings/v8/Dictionary.cpp
index 6431d5b1738..156eede687c 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/Dictionary.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/Dictionary.cpp
@@ -26,36 +26,35 @@
#include "config.h"
#include "bindings/v8/Dictionary.h"
-#include "V8DOMError.h"
-#include "V8EventTarget.h"
-#include "V8IDBKeyRange.h"
-#include "V8MIDIPort.h"
-#include "V8MediaKeyError.h"
-#include "V8SpeechRecognitionError.h"
-#include "V8SpeechRecognitionResult.h"
-#include "V8SpeechRecognitionResultList.h"
-#include "V8Storage.h"
-#include "V8VoidCallback.h"
-#include "V8Window.h"
+#include "bindings/core/v8/V8DOMError.h"
+#include "bindings/core/v8/V8EventTarget.h"
+#include "bindings/core/v8/V8MediaKeyError.h"
+#include "bindings/core/v8/V8MessagePort.h"
+#include "bindings/core/v8/V8Storage.h"
+#include "bindings/core/v8/V8TextTrack.h"
+#include "bindings/core/v8/V8VoidCallback.h"
+#include "bindings/core/v8/V8Window.h"
+#include "bindings/modules/v8/V8Gamepad.h"
+#include "bindings/modules/v8/V8HeaderMap.h"
+#include "bindings/modules/v8/V8IDBKeyRange.h"
+#include "bindings/modules/v8/V8MIDIPort.h"
+#include "bindings/modules/v8/V8MediaStream.h"
+#include "bindings/modules/v8/V8SpeechRecognitionResult.h"
+#include "bindings/modules/v8/V8SpeechRecognitionResultList.h"
#include "bindings/v8/ArrayValue.h"
#include "bindings/v8/ExceptionMessages.h"
#include "bindings/v8/ExceptionState.h"
#include "bindings/v8/V8Binding.h"
-#include "bindings/v8/V8Utilities.h"
#include "bindings/v8/custom/V8ArrayBufferViewCustom.h"
#include "bindings/v8/custom/V8Uint8ArrayCustom.h"
+#include "core/html/track/TrackBase.h"
+#include "modules/gamepad/Gamepad.h"
#include "modules/indexeddb/IDBKeyRange.h"
-#include "modules/speech/SpeechRecognitionError.h"
+#include "modules/mediastream/MediaStream.h"
#include "modules/speech/SpeechRecognitionResult.h"
#include "modules/speech/SpeechRecognitionResultList.h"
#include "wtf/MathExtras.h"
-#include "V8TextTrack.h"
-#include "core/html/track/TrackBase.h"
-
-#include "V8MediaStream.h"
-#include "modules/mediastream/MediaStream.h"
-
namespace WebCore {
Dictionary::Dictionary()
@@ -174,7 +173,7 @@ bool Dictionary::get(const String& key, double& value, bool& hasValue) const
}
hasValue = true;
- V8TRYCATCH_RETURN(v8::Local<v8::Number>, v8Number, v8Value->ToNumber(), false);
+ TONATIVE_DEFAULT(v8::Local<v8::Number>, v8Number, v8Value->ToNumber(), false);
if (v8Number.IsEmpty())
return false;
value = v8Number->Value();
@@ -199,17 +198,28 @@ bool Dictionary::convert(ConversionContext& context, const String& key, double&
return true;
}
-bool Dictionary::get(const String& key, String& value) const
+template<typename StringType>
+inline bool Dictionary::getStringType(const String& key, StringType& value) const
{
v8::Local<v8::Value> v8Value;
if (!getKey(key, v8Value))
return false;
- V8TRYCATCH_FOR_V8STRINGRESOURCE_RETURN(V8StringResource<>, stringValue, v8Value, false);
+ TOSTRING_DEFAULT(V8StringResource<>, stringValue, v8Value, false);
value = stringValue;
return true;
}
+bool Dictionary::get(const String& key, String& value) const
+{
+ return getStringType(key, value);
+}
+
+bool Dictionary::get(const String& key, AtomicString& value) const
+{
+ return getStringType(key, value);
+}
+
bool Dictionary::convert(ConversionContext& context, const String& key, String& value) const
{
ConversionContextScope scope(context);
@@ -218,7 +228,7 @@ bool Dictionary::convert(ConversionContext& context, const String& key, String&
if (!getKey(key, v8Value))
return true;
- V8TRYCATCH_FOR_V8STRINGRESOURCE_RETURN(V8StringResource<>, stringValue, v8Value, false);
+ TOSTRING_DEFAULT(V8StringResource<>, stringValue, v8Value, false);
value = stringValue;
return true;
}
@@ -229,7 +239,7 @@ bool Dictionary::get(const String& key, ScriptValue& value) const
if (!getKey(key, v8Value))
return false;
- value = ScriptValue(v8Value, m_isolate);
+ value = ScriptValue(ScriptState::current(m_isolate), v8Value);
return true;
}
@@ -299,7 +309,7 @@ bool Dictionary::get(const String& key, unsigned long long& value) const
if (!getKey(key, v8Value))
return false;
- V8TRYCATCH_RETURN(v8::Local<v8::Number>, v8Number, v8Value->ToNumber(), false);
+ TONATIVE_DEFAULT(v8::Local<v8::Number>, v8Number, v8Value->ToNumber(), false);
if (v8Number.IsEmpty())
return false;
double d = v8Number->Value();
@@ -307,7 +317,7 @@ bool Dictionary::get(const String& key, unsigned long long& value) const
return true;
}
-bool Dictionary::get(const String& key, RefPtr<DOMWindow>& value) const
+bool Dictionary::get(const String& key, RefPtrWillBeMember<LocalDOMWindow>& value) const
{
v8::Local<v8::Value> v8Value;
if (!getKey(key, v8Value))
@@ -315,25 +325,17 @@ bool Dictionary::get(const String& key, RefPtr<DOMWindow>& value) const
// We need to handle a DOMWindow specially, because a DOMWindow wrapper
// exists on a prototype chain of v8Value.
- value = 0;
- if (v8Value->IsObject()) {
- v8::Handle<v8::Object> wrapper = v8::Handle<v8::Object>::Cast(v8Value);
- v8::Handle<v8::Object> window = wrapper->FindInstanceInPrototypeChain(V8Window::domTemplate(m_isolate, worldTypeInMainThread(m_isolate)));
- if (!window.IsEmpty())
- value = V8Window::toNative(window);
- }
+ value = toDOMWindow(v8Value, m_isolate);
return true;
}
-bool Dictionary::get(const String& key, RefPtr<Storage>& value) const
+bool Dictionary::get(const String& key, RefPtrWillBeMember<Storage>& value) const
{
v8::Local<v8::Value> v8Value;
if (!getKey(key, v8Value))
return false;
- value = 0;
- if (V8Storage::hasInstance(v8Value, m_isolate, worldType(m_isolate)))
- value = V8Storage::toNative(v8::Handle<v8::Object>::Cast(v8Value));
+ value = V8Storage::toNativeWithTypeCheck(m_isolate, v8Value);
return true;
}
@@ -345,7 +347,11 @@ bool Dictionary::get(const String& key, MessagePortArray& value) const
ASSERT(m_isolate);
ASSERT(m_isolate == v8::Isolate::GetCurrent());
- return getMessagePortArray(v8Value, key, value, m_isolate);
+ if (WebCore::isUndefinedOrNull(v8Value))
+ return true;
+ bool success = false;
+ value = toRefPtrNativeArray<MessagePort, V8MessagePort>(v8Value, key, m_isolate, &success);
+ return success;
}
bool Dictionary::convert(ConversionContext& context, const String& key, MessagePortArray& value) const
@@ -373,8 +379,8 @@ bool Dictionary::get(const String& key, HashSet<AtomicString>& value) const
ASSERT(m_isolate == v8::Isolate::GetCurrent());
v8::Local<v8::Array> v8Array = v8::Local<v8::Array>::Cast(v8Value);
for (size_t i = 0; i < v8Array->Length(); ++i) {
- v8::Local<v8::Value> indexedValue = v8Array->Get(v8::Integer::New(i, m_isolate));
- V8TRYCATCH_FOR_V8STRINGRESOURCE_RETURN(V8StringResource<>, stringValue, indexedValue, false);
+ v8::Local<v8::Value> indexedValue = v8Array->Get(v8::Integer::New(m_isolate, i));
+ TOSTRING_DEFAULT(V8StringResource<>, stringValue, indexedValue, false);
value.add(stringValue);
}
@@ -406,7 +412,7 @@ bool Dictionary::getWithUndefinedOrNullCheck(const String& key, String& value) c
if (!getKey(key, v8Value) || WebCore::isUndefinedOrNull(v8Value))
return false;
- V8TRYCATCH_FOR_V8STRINGRESOURCE_RETURN(V8StringResource<>, stringValue, v8Value, false);
+ TOSTRING_DEFAULT(V8StringResource<>, stringValue, v8Value, false);
value = stringValue;
return true;
}
@@ -417,9 +423,7 @@ bool Dictionary::get(const String& key, RefPtr<Uint8Array>& value) const
if (!getKey(key, v8Value))
return false;
- value = 0;
- if (V8Uint8Array::hasInstance(v8Value, m_isolate, worldType(m_isolate)))
- value = V8Uint8Array::toNative(v8::Handle<v8::Object>::Cast(v8Value));
+ value = V8Uint8Array::toNativeWithTypeCheck(m_isolate, v8Value);
return true;
}
@@ -429,21 +433,17 @@ bool Dictionary::get(const String& key, RefPtr<ArrayBufferView>& value) const
if (!getKey(key, v8Value))
return false;
- value = 0;
- if (V8ArrayBufferView::hasInstance(v8Value, m_isolate, worldType(m_isolate)))
- value = V8ArrayBufferView::toNative(v8::Handle<v8::Object>::Cast(v8Value));
+ value = V8ArrayBufferView::toNativeWithTypeCheck(m_isolate, v8Value);
return true;
}
-bool Dictionary::get(const String& key, RefPtr<MIDIPort>& value) const
+bool Dictionary::get(const String& key, RefPtrWillBeMember<MIDIPort>& value) const
{
v8::Local<v8::Value> v8Value;
if (!getKey(key, v8Value))
return false;
- value = 0;
- if (V8MIDIPort::hasInstance(v8Value, m_isolate, worldType(m_isolate)))
- value = V8MIDIPort::toNative(v8::Handle<v8::Object>::Cast(v8Value));
+ value = V8MIDIPort::toNativeWithTypeCheck(m_isolate, v8Value);
return true;
}
@@ -453,13 +453,11 @@ bool Dictionary::get(const String& key, RefPtr<MediaKeyError>& value) const
if (!getKey(key, v8Value))
return false;
- value = 0;
- if (V8MediaKeyError::hasInstance(v8Value, m_isolate, worldType(m_isolate)))
- value = V8MediaKeyError::toNative(v8::Handle<v8::Object>::Cast(v8Value));
+ value = V8MediaKeyError::toNativeWithTypeCheck(m_isolate, v8Value);
return true;
}
-bool Dictionary::get(const String& key, RefPtr<TrackBase>& value) const
+bool Dictionary::get(const String& key, RefPtrWillBeMember<TrackBase>& value) const
{
v8::Local<v8::Value> v8Value;
if (!getKey(key, v8Value))
@@ -471,7 +469,7 @@ bool Dictionary::get(const String& key, RefPtr<TrackBase>& value) const
// FIXME: this will need to be changed so it can also return an AudioTrack or a VideoTrack once
// we add them.
- v8::Handle<v8::Object> track = wrapper->FindInstanceInPrototypeChain(V8TextTrack::domTemplate(m_isolate, worldType(m_isolate)));
+ v8::Handle<v8::Object> track = V8TextTrack::findInstanceInPrototypeChain(wrapper, m_isolate);
if (!track.IsEmpty())
source = V8TextTrack::toNative(track);
}
@@ -479,39 +477,33 @@ bool Dictionary::get(const String& key, RefPtr<TrackBase>& value) const
return true;
}
-bool Dictionary::get(const String& key, RefPtr<SpeechRecognitionError>& value) const
+bool Dictionary::get(const String& key, Member<SpeechRecognitionResult>& value) const
{
v8::Local<v8::Value> v8Value;
if (!getKey(key, v8Value))
return false;
- value = 0;
- if (V8SpeechRecognitionError::hasInstance(v8Value, m_isolate, worldType(m_isolate)))
- value = V8SpeechRecognitionError::toNative(v8::Handle<v8::Object>::Cast(v8Value));
+ value = V8SpeechRecognitionResult::toNativeWithTypeCheck(m_isolate, v8Value);
return true;
}
-bool Dictionary::get(const String& key, RefPtr<SpeechRecognitionResult>& value) const
+bool Dictionary::get(const String& key, Member<SpeechRecognitionResultList>& value) const
{
v8::Local<v8::Value> v8Value;
if (!getKey(key, v8Value))
return false;
- value = 0;
- if (V8SpeechRecognitionResult::hasInstance(v8Value, m_isolate, worldType(m_isolate)))
- value = V8SpeechRecognitionResult::toNative(v8::Handle<v8::Object>::Cast(v8Value));
+ value = V8SpeechRecognitionResultList::toNativeWithTypeCheck(m_isolate, v8Value);
return true;
}
-bool Dictionary::get(const String& key, RefPtr<SpeechRecognitionResultList>& value) const
+bool Dictionary::get(const String& key, Member<Gamepad>& value) const
{
v8::Local<v8::Value> v8Value;
if (!getKey(key, v8Value))
return false;
- value = 0;
- if (V8SpeechRecognitionResultList::hasInstance(v8Value, m_isolate, worldType(m_isolate)))
- value = V8SpeechRecognitionResultList::toNative(v8::Handle<v8::Object>::Cast(v8Value));
+ value = V8Gamepad::toNativeWithTypeCheck(m_isolate, v8Value);
return true;
}
@@ -521,24 +513,22 @@ bool Dictionary::get(const String& key, RefPtr<MediaStream>& value) const
if (!getKey(key, v8Value))
return false;
- value = 0;
- if (V8MediaStream::hasInstance(v8Value, m_isolate, worldType(m_isolate)))
- value = V8MediaStream::toNative(v8::Handle<v8::Object>::Cast(v8Value));
+ value = V8MediaStream::toNativeWithTypeCheck(m_isolate, v8Value);
return true;
}
-bool Dictionary::get(const String& key, RefPtr<EventTarget>& value) const
+bool Dictionary::get(const String& key, RefPtrWillBeMember<EventTarget>& value) const
{
v8::Local<v8::Value> v8Value;
if (!getKey(key, v8Value))
return false;
- value = 0;
- // We need to handle a DOMWindow specially, because a DOMWindow wrapper
+ value = nullptr;
+ // We need to handle a LocalDOMWindow specially, because a LocalDOMWindow wrapper
// exists on a prototype chain of v8Value.
if (v8Value->IsObject()) {
v8::Handle<v8::Object> wrapper = v8::Handle<v8::Object>::Cast(v8Value);
- v8::Handle<v8::Object> window = wrapper->FindInstanceInPrototypeChain(V8Window::domTemplate(m_isolate, worldTypeInMainThread(m_isolate)));
+ v8::Handle<v8::Object> window = V8Window::findInstanceInPrototypeChain(wrapper, m_isolate);
if (!window.IsEmpty()) {
value = toWrapperTypeInfo(window)->toEventTarget(window);
return true;
@@ -567,6 +557,16 @@ bool Dictionary::get(const String& key, Dictionary& value) const
return true;
}
+bool Dictionary::get(const String& key, RefPtr<HeaderMap>& value) const
+{
+ v8::Local<v8::Value> v8Value;
+ if (!getKey(key, v8Value))
+ return false;
+
+ value = V8HeaderMap::toNativeWithTypeCheck(m_isolate, v8Value);
+ return true;
+}
+
bool Dictionary::convert(ConversionContext& context, const String& key, Dictionary& value) const
{
ConversionContextScope scope(context);
@@ -596,8 +596,8 @@ bool Dictionary::get(const String& key, Vector<String>& value) const
v8::Local<v8::Array> v8Array = v8::Local<v8::Array>::Cast(v8Value);
for (size_t i = 0; i < v8Array->Length(); ++i) {
- v8::Local<v8::Value> indexedValue = v8Array->Get(v8::Uint32::New(i, m_isolate));
- V8TRYCATCH_FOR_V8STRINGRESOURCE_RETURN(V8StringResource<>, stringValue, indexedValue, false);
+ v8::Local<v8::Value> indexedValue = v8Array->Get(v8::Uint32::New(m_isolate, i));
+ TOSTRING_DEFAULT(V8StringResource<>, stringValue, indexedValue, false);
value.append(stringValue);
}
@@ -657,33 +657,13 @@ bool Dictionary::convert(ConversionContext& context, const String& key, ArrayVal
return get(key, value);
}
-bool Dictionary::get(const String& key, RefPtr<DOMError>& value) const
-{
- v8::Local<v8::Value> v8Value;
- if (!getKey(key, v8Value))
- return false;
-
- DOMError* error = 0;
- if (v8Value->IsObject()) {
- v8::Handle<v8::Object> wrapper = v8::Handle<v8::Object>::Cast(v8Value);
- v8::Handle<v8::Object> domError = wrapper->FindInstanceInPrototypeChain(V8DOMError::domTemplate(m_isolate, worldType(m_isolate)));
- if (!domError.IsEmpty())
- error = V8DOMError::toNative(domError);
- }
- value = error;
- return true;
-}
-
-bool Dictionary::get(const String& key, OwnPtr<VoidCallback>& value) const
+bool Dictionary::get(const String& key, RefPtrWillBeMember<DOMError>& value) const
{
v8::Local<v8::Value> v8Value;
if (!getKey(key, v8Value))
return false;
- if (!v8Value->IsFunction())
- return false;
-
- value = V8VoidCallback::create(v8::Handle<v8::Function>::Cast(v8Value), getExecutionContext());
+ value = V8DOMError::toNativeWithTypeCheck(m_isolate, v8Value);
return true;
}
@@ -705,8 +685,8 @@ bool Dictionary::getOwnPropertiesAsStringHashMap(HashMap<String, String>& hashMa
continue;
v8::Local<v8::Value> value = options->Get(key);
- V8TRYCATCH_FOR_V8STRINGRESOURCE_RETURN(V8StringResource<>, stringKey, key, false);
- V8TRYCATCH_FOR_V8STRINGRESOURCE_RETURN(V8StringResource<>, stringValue, value, false);
+ TOSTRING_DEFAULT(V8StringResource<>, stringKey, key, false);
+ TOSTRING_DEFAULT(V8StringResource<>, stringValue, value, false);
if (!static_cast<const String&>(stringKey).isEmpty())
hashMap.set(stringKey, stringValue);
}
@@ -730,7 +710,7 @@ bool Dictionary::getOwnPropertyNames(Vector<String>& names) const
v8::Local<v8::String> key = properties->Get(i)->ToString();
if (!options->Has(key))
continue;
- V8TRYCATCH_FOR_V8STRINGRESOURCE_RETURN(V8StringResource<>, stringKey, key, false);
+ TOSTRING_DEFAULT(V8StringResource<>, stringKey, key, false);
names.append(stringKey);
}
@@ -758,12 +738,7 @@ Dictionary::ConversionContext& Dictionary::ConversionContext::setConversionType(
void Dictionary::ConversionContext::throwTypeError(const String& detail)
{
- if (forConstructor()) {
- exceptionState().throwTypeError(detail);
- } else {
- ASSERT(!methodName().isEmpty());
- exceptionState().throwTypeError(ExceptionMessages::failedToExecute(interfaceName(), methodName(), detail));
- }
+ exceptionState().throwTypeError(detail);
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/Dictionary.h b/chromium/third_party/WebKit/Source/bindings/v8/Dictionary.h
index 3f29651e876..2268c63bd2f 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/Dictionary.h
+++ b/chromium/third_party/WebKit/Source/bindings/v8/Dictionary.h
@@ -28,6 +28,7 @@
#include "bindings/v8/ExceptionMessages.h"
#include "bindings/v8/ExceptionState.h"
+#include "bindings/v8/Nullable.h"
#include "bindings/v8/ScriptValue.h"
#include "bindings/v8/V8Binding.h"
#include "bindings/v8/V8BindingMacros.h"
@@ -44,12 +45,14 @@ namespace WebCore {
class ArrayValue;
class DOMError;
-class DOMWindow;
+class LocalDOMWindow;
+class Gamepad;
+class MediaStream;
+class HeaderMap;
class IDBKeyRange;
class MIDIPort;
class MediaKeyError;
class Notification;
-class SpeechRecognitionError;
class SpeechRecognitionResult;
class SpeechRecognitionResultList;
class Storage;
@@ -57,6 +60,7 @@ class TrackBase;
class VoidCallback;
class Dictionary {
+ ALLOW_ONLY_INLINE_ALLOCATION();
public:
Dictionary();
Dictionary(const v8::Handle<v8::Value>& options, v8::Isolate*);
@@ -72,32 +76,33 @@ public:
bool get(const String&, double&, bool& hasValue) const;
bool get(const String&, double&) const;
bool get(const String&, String&) const;
+ bool get(const String&, AtomicString&) const;
bool get(const String&, ScriptValue&) const;
bool get(const String&, short&) const;
bool get(const String&, unsigned short&) const;
bool get(const String&, unsigned&) const;
bool get(const String&, unsigned long&) const;
bool get(const String&, unsigned long long&) const;
- bool get(const String&, RefPtr<DOMWindow>&) const;
- bool get(const String&, RefPtr<Storage>&) const;
+ bool get(const String&, RefPtrWillBeMember<LocalDOMWindow>&) const;
+ bool get(const String&, RefPtrWillBeMember<Storage>&) const;
bool get(const String&, MessagePortArray&) const;
bool get(const String&, RefPtr<Uint8Array>&) const;
bool get(const String&, RefPtr<ArrayBufferView>&) const;
- bool get(const String&, RefPtr<MIDIPort>&) const;
+ bool get(const String&, RefPtrWillBeMember<MIDIPort>&) const;
bool get(const String&, RefPtr<MediaKeyError>&) const;
- bool get(const String&, RefPtr<TrackBase>&) const;
- bool get(const String&, RefPtr<SpeechRecognitionError>&) const;
- bool get(const String&, RefPtr<SpeechRecognitionResult>&) const;
- bool get(const String&, RefPtr<SpeechRecognitionResultList>&) const;
+ bool get(const String&, RefPtrWillBeMember<TrackBase>&) const;
+ bool get(const String&, Member<SpeechRecognitionResult>&) const;
+ bool get(const String&, Member<SpeechRecognitionResultList>&) const;
+ bool get(const String&, Member<Gamepad>&) const;
bool get(const String&, RefPtr<MediaStream>&) const;
- bool get(const String&, RefPtr<EventTarget>&) const;
+ bool get(const String&, RefPtrWillBeMember<EventTarget>&) const;
bool get(const String&, HashSet<AtomicString>&) const;
bool get(const String&, Dictionary&) const;
bool get(const String&, Vector<String>&) const;
bool get(const String&, ArrayValue&) const;
- bool get(const String&, RefPtr<DOMError>&) const;
- bool get(const String&, OwnPtr<VoidCallback>&) const;
+ bool get(const String&, RefPtrWillBeMember<DOMError>&) const;
bool get(const String&, v8::Local<v8::Value>&) const;
+ bool get(const String&, RefPtr<HeaderMap>&) const;
class ConversionContext {
public:
@@ -152,14 +157,20 @@ public:
bool convert(ConversionContext&, const String&, ScriptValue&) const;
template<typename IntegralType>
- bool convert(ConversionContext &, const String&, IntegralType&) const;
- bool convert(ConversionContext &, const String&, MessagePortArray&) const;
- bool convert(ConversionContext &, const String&, HashSet<AtomicString>&) const;
- bool convert(ConversionContext &, const String&, Dictionary&) const;
- bool convert(ConversionContext &, const String&, Vector<String>&) const;
- bool convert(ConversionContext &, const String&, ArrayValue&) const;
- template<typename T>
- bool convert(ConversionContext &, const String&, RefPtr<T>&) const;
+ bool convert(ConversionContext&, const String&, IntegralType&) const;
+ template<typename IntegralType>
+ bool convert(ConversionContext&, const String&, Nullable<IntegralType>&) const;
+
+ bool convert(ConversionContext&, const String&, MessagePortArray&) const;
+ bool convert(ConversionContext&, const String&, HashSet<AtomicString>&) const;
+ bool convert(ConversionContext&, const String&, Dictionary&) const;
+ bool convert(ConversionContext&, const String&, Vector<String>&) const;
+ bool convert(ConversionContext&, const String&, ArrayValue&) const;
+ template<template <typename> class PointerType, typename T>
+ bool convert(ConversionContext&, const String&, PointerType<T>&) const;
+
+ template<typename StringType>
+ bool getStringType(const String&, StringType&) const;
bool getOwnPropertiesAsStringHashMap(HashMap<String, String>&) const;
bool getOwnPropertyNames(Vector<String>&) const;
@@ -168,13 +179,7 @@ public:
bool hasProperty(const String&) const;
- // Only allow inline allocation.
- void* operator new(size_t, NotNullTag, void* location) { return location; }
-
private:
- // Disallow new allocation.
- void* operator new(size_t);
-
bool getKey(const String& key, v8::Local<v8::Value>&) const;
v8::Handle<v8::Value> m_options;
@@ -195,90 +200,90 @@ struct IntegralTypeTraits {
template <>
struct IntegralTypeTraits<uint8_t> {
- static inline uint8_t toIntegral(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, bool& ok)
+ static inline uint8_t toIntegral(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, ExceptionState& exceptionState)
{
- return toUInt8(value, configuration, ok);
+ return toUInt8(value, configuration, exceptionState);
}
static const String typeName() { return "UInt8"; }
};
template <>
struct IntegralTypeTraits<int8_t> {
- static inline int8_t toIntegral(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, bool& ok)
+ static inline int8_t toIntegral(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, ExceptionState& exceptionState)
{
- return toInt8(value, configuration, ok);
+ return toInt8(value, configuration, exceptionState);
}
static const String typeName() { return "Int8"; }
};
template <>
struct IntegralTypeTraits<unsigned short> {
- static inline uint16_t toIntegral(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, bool& ok)
+ static inline uint16_t toIntegral(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, ExceptionState& exceptionState)
{
- return toUInt16(value, configuration, ok);
+ return toUInt16(value, configuration, exceptionState);
}
static const String typeName() { return "UInt16"; }
};
template <>
struct IntegralTypeTraits<short> {
- static inline int16_t toIntegral(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, bool& ok)
+ static inline int16_t toIntegral(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, ExceptionState& exceptionState)
{
- return toInt16(value, configuration, ok);
+ return toInt16(value, configuration, exceptionState);
}
static const String typeName() { return "Int16"; }
};
template <>
struct IntegralTypeTraits<unsigned> {
- static inline uint32_t toIntegral(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, bool& ok)
+ static inline uint32_t toIntegral(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, ExceptionState& exceptionState)
{
- return toUInt32(value, configuration, ok);
+ return toUInt32(value, configuration, exceptionState);
}
static const String typeName() { return "UInt32"; }
};
template <>
struct IntegralTypeTraits<unsigned long> {
- static inline uint32_t toIntegral(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, bool& ok)
+ static inline uint32_t toIntegral(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, ExceptionState& exceptionState)
{
- return toUInt32(value, configuration, ok);
+ return toUInt32(value, configuration, exceptionState);
}
static const String typeName() { return "UInt32"; }
};
template <>
struct IntegralTypeTraits<int> {
- static inline int32_t toIntegral(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, bool& ok)
+ static inline int32_t toIntegral(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, ExceptionState& exceptionState)
{
- return toInt32(value, configuration, ok);
+ return toInt32(value, configuration, exceptionState);
}
static const String typeName() { return "Int32"; }
};
template <>
struct IntegralTypeTraits<long> {
- static inline int32_t toIntegral(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, bool& ok)
+ static inline int32_t toIntegral(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, ExceptionState& exceptionState)
{
- return toInt32(value, configuration, ok);
+ return toInt32(value, configuration, exceptionState);
}
static const String typeName() { return "Int32"; }
};
template <>
struct IntegralTypeTraits<unsigned long long> {
- static inline unsigned long long toIntegral(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, bool& ok)
+ static inline unsigned long long toIntegral(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, ExceptionState& exceptionState)
{
- return toUInt64(value, configuration, ok);
+ return toUInt64(value, configuration, exceptionState);
}
static const String typeName() { return "UInt64"; }
};
template <>
struct IntegralTypeTraits<long long> {
- static inline long long toIntegral(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, bool& ok)
+ static inline long long toIntegral(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, ExceptionState& exceptionState)
{
- return toInt64(value, configuration, ok);
+ return toInt64(value, configuration, exceptionState);
}
static const String typeName() { return "Int64"; }
};
@@ -291,18 +296,36 @@ template<typename T> bool Dictionary::convert(ConversionContext& context, const
if (!getKey(key, v8Value))
return true;
- bool ok = false;
- value = IntegralTypeTraits<T>::toIntegral(v8Value, NormalConversion, ok);
- if (ok)
+ value = IntegralTypeTraits<T>::toIntegral(v8Value, NormalConversion, context.exceptionState());
+ if (context.exceptionState().throwIfNeeded())
+ return false;
+
+ return true;
+}
+
+template<typename T> bool Dictionary::convert(ConversionContext& context, const String& key, Nullable<T>& value) const
+{
+ ConversionContextScope scope(context);
+
+ v8::Local<v8::Value> v8Value;
+ if (!getKey(key, v8Value))
return true;
- V8TRYCATCH_RETURN(v8::Local<v8::Number>, v8Number, v8Value->ToNumber(), false);
- ASSERT(v8Number.IsEmpty());
- context.throwTypeError(ExceptionMessages::incorrectPropertyType(key, "does not have type " + IntegralTypeTraits<T>::typeName() + "."));
- return false;
+ if (context.isNullable() && WebCore::isUndefinedOrNull(v8Value)) {
+ value = Nullable<T>();
+ return true;
+ }
+
+ T converted = IntegralTypeTraits<T>::toIntegral(v8Value, NormalConversion, context.exceptionState());
+
+ if (context.exceptionState().throwIfNeeded())
+ return false;
+
+ value = Nullable<T>(converted);
+ return true;
}
-template<typename T> bool Dictionary::convert(ConversionContext& context, const String& key, RefPtr<T>& value) const
+template<template <typename> class PointerType, typename T> bool Dictionary::convert(ConversionContext& context, const String& key, PointerType<T>& value) const
{
ConversionContextScope scope(context);
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/ExceptionMessages.cpp b/chromium/third_party/WebKit/Source/bindings/v8/ExceptionMessages.cpp
index beea8bef6d3..c65e04703d4 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/ExceptionMessages.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/ExceptionMessages.cpp
@@ -31,33 +31,59 @@
#include "config.h"
#include "bindings/v8/ExceptionMessages.h"
+#include "platform/Decimal.h"
#include "wtf/MathExtras.h"
namespace WebCore {
-String ExceptionMessages::failedToConstruct(const String& type, const String& detail)
+String ExceptionMessages::failedToConstruct(const char* type, const String& detail)
{
- return "Failed to construct '" + type + (!detail.isEmpty() ? String("': " + detail) : String("'"));
+ return "Failed to construct '" + String(type) + (!detail.isEmpty() ? String("': " + detail) : String("'"));
}
-String ExceptionMessages::failedToExecute(const String& method, const String& type, const String& detail)
+String ExceptionMessages::failedToEnumerate(const char* type, const String& detail)
{
- return "Failed to execute '" + method + "' on '" + type + (!detail.isEmpty() ? String("': " + detail) : String("'"));
+ return "Failed to enumerate the properties of '" + String(type) + (!detail.isEmpty() ? String("': " + detail) : String("'"));
}
-String ExceptionMessages::failedToGet(const String& property, const String& type, const String& detail)
+String ExceptionMessages::failedToExecute(const char* method, const char* type, const String& detail)
{
- return "Failed to read the '" + property + "' property from '" + type + "': " + detail;
+ return "Failed to execute '" + String(method) + "' on '" + String(type) + (!detail.isEmpty() ? String("': " + detail) : String("'"));
}
-String ExceptionMessages::failedToSet(const String& property, const String& type, const String& detail)
+String ExceptionMessages::failedToGet(const char* property, const char* type, const String& detail)
{
- return "Failed to set the '" + property + "' property on '" + type + "': " + detail;
+ return "Failed to read the '" + String(property) + "' property from '" + String(type) + "': " + detail;
}
-String ExceptionMessages::failedToDelete(const String& property, const String& type, const String& detail)
+String ExceptionMessages::failedToSet(const char* property, const char* type, const String& detail)
{
- return "Failed to delete the '" + property + "' property from '" + type + "': " + detail;
+ return "Failed to set the '" + String(property) + "' property on '" + String(type) + "': " + detail;
+}
+
+String ExceptionMessages::failedToDelete(const char* property, const char* type, const String& detail)
+{
+ return "Failed to delete the '" + String(property) + "' property from '" + String(type) + "': " + detail;
+}
+
+String ExceptionMessages::failedToGetIndexed(const char* type, const String& detail)
+{
+ return "Failed to read an indexed property from '" + String(type) + "': " + detail;
+}
+
+String ExceptionMessages::failedToSetIndexed(const char* type, const String& detail)
+{
+ return "Failed to set an indexed property on '" + String(type) + "': " + detail;
+}
+
+String ExceptionMessages::failedToDeleteIndexed(const char* type, const String& detail)
+{
+ return "Failed to delete an indexed property from '" + String(type) + "': " + detail;
+}
+
+String ExceptionMessages::constructorNotCallableAsFunction(const char* type)
+{
+ return failedToConstruct(type, "Please use the 'new' operator, this DOM object constructor cannot be called as a function.");
}
String ExceptionMessages::incorrectPropertyType(const String& property, const String& detail)
@@ -65,9 +91,14 @@ String ExceptionMessages::incorrectPropertyType(const String& property, const St
return "The '" + property + "' property " + detail;
}
-String ExceptionMessages::incorrectArgumentType(int argumentIndex, const String& detail)
+String ExceptionMessages::invalidArity(const char* expected, unsigned provided)
{
- return "The " + ordinalNumber(argumentIndex) + " argument " + detail;
+ return "Valid arities are: " + String(expected) + ", but " + String::number(provided) + " arguments provided.";
+}
+
+String ExceptionMessages::argumentNullOrIncorrectType(int argumentIndex, const String& expectedType)
+{
+ return "The " + ordinalNumber(argumentIndex) + " argument provided is either null, or an invalid " + expectedType + " object.";
}
String ExceptionMessages::notAnArrayTypeArgumentOrValue(int argumentIndex)
@@ -90,10 +121,16 @@ String ExceptionMessages::notEnoughArguments(unsigned expected, unsigned provide
return String::number(expected) + " argument" + (expected > 1 ? "s" : "") + " required, but only " + String::number(provided) + " present.";
}
-String ExceptionMessages::notAFiniteNumber(double value)
+String ExceptionMessages::notAFiniteNumber(double value, const char* name)
{
ASSERT(!std::isfinite(value));
- return std::isinf(value) ? "The value provided is infinite." : "The value provided is not a number.";
+ return String::format("The %s is %s.", name, std::isinf(value) ? "infinite" : "not a number");
+}
+
+String ExceptionMessages::notAFiniteNumber(const Decimal& value, const char* name)
+{
+ ASSERT(!value.isFinite());
+ return String::format("The %s is %s.", name, value.isInfinity() ? "infinite" : "not a number");
}
String ExceptionMessages::ordinalNumber(int number)
@@ -116,4 +153,22 @@ String ExceptionMessages::ordinalNumber(int number)
return String::number(number) + suffix;
}
+String ExceptionMessages::readOnly(const char* detail)
+{
+ DEFINE_STATIC_LOCAL(String, readOnly, ("This object is read-only."));
+ return detail ? String::format("This object is read-only, because %s.", detail) : readOnly;
+}
+
+template <>
+String ExceptionMessages::formatNumber<float>(float number)
+{
+ return formatPotentiallyNonFiniteNumber(number);
+}
+
+template <>
+String ExceptionMessages::formatNumber<double>(double number)
+{
+ return formatPotentiallyNonFiniteNumber(number);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/ExceptionMessages.h b/chromium/third_party/WebKit/Source/bindings/v8/ExceptionMessages.h
index 92f8a9f5879..a74819b3970 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/ExceptionMessages.h
+++ b/chromium/third_party/WebKit/Source/bindings/v8/ExceptionMessages.h
@@ -31,33 +31,134 @@
#ifndef ExceptionMessages_h
#define ExceptionMessages_h
+#include "wtf/MathExtras.h"
+#include "wtf/text/StringBuilder.h"
#include "wtf/text/WTFString.h"
namespace WebCore {
+class Decimal;
+
class ExceptionMessages {
public:
- static String failedToConstruct(const String& type, const String& detail = String());
- static String failedToExecute(const String& method, const String& type, const String& detail = String());
- static String failedToGet(const String& property, const String& type, const String& detail);
- static String failedToSet(const String& property, const String& type, const String& detail);
- static String failedToDelete(const String& property, const String& type, const String& detail);
+ enum BoundType {
+ InclusiveBound,
+ ExclusiveBound,
+ };
+
+ static String argumentNullOrIncorrectType(int argumentIndex, const String& expectedType);
+ static String constructorNotCallableAsFunction(const char* type);
+
+ static String failedToConstruct(const char* type, const String& detail);
+ static String failedToEnumerate(const char* type, const String& detail);
+ static String failedToExecute(const char* method, const char* type, const String& detail);
+ static String failedToGet(const char* property, const char* type, const String& detail);
+ static String failedToSet(const char* property, const char* type, const String& detail);
+ static String failedToDelete(const char* property, const char* type, const String& detail);
+ static String failedToGetIndexed(const char* type, const String& detail);
+ static String failedToSetIndexed(const char* type, const String& detail);
+ static String failedToDeleteIndexed(const char* type, const String& detail);
+
+ template <typename NumType>
+ static String formatNumber(NumType number)
+ {
+ return formatFiniteNumber(number);
+ }
- static String incorrectArgumentType(int argumentIndex, const String& detail);
static String incorrectPropertyType(const String& property, const String& detail);
+ template <typename NumberType>
+ static String indexExceedsMaximumBound(const char* name, NumberType given, NumberType bound)
+ {
+ bool eq = given == bound;
+ StringBuilder result;
+ result.append("The ");
+ result.append(name);
+ result.append(" provided (");
+ result.append(formatNumber(given));
+ result.append(") is greater than ");
+ result.append(eq ? "or equal to " : "");
+ result.append("the maximum bound (");
+ result.append(formatNumber(bound));
+ result.append(").");
+ return result.toString();
+ }
+
+ template <typename NumberType>
+ static String indexExceedsMinimumBound(const char* name, NumberType given, NumberType bound)
+ {
+ bool eq = given == bound;
+ StringBuilder result;
+ result.append("The ");
+ result.append(name);
+ result.append(" provided (");
+ result.append(formatNumber(given));
+ result.append(") is less than ");
+ result.append(eq ? "or equal to " : "");
+ result.append("the minimum bound (");
+ result.append(formatNumber(bound));
+ result.append(").");
+ return result.toString();
+ }
+
+ template <typename NumberType>
+ static String indexOutsideRange(const char* name, NumberType given, NumberType lowerBound, BoundType lowerType, NumberType upperBound, BoundType upperType)
+ {
+ StringBuilder result;
+ result.append("The ");
+ result.append(name);
+ result.append(" provided (");
+ result.append(formatNumber(given));
+ result.append(") is outside the range ");
+ result.append(lowerType == ExclusiveBound ? '(' : '[');
+ result.append(formatNumber(lowerBound));
+ result.append(", ");
+ result.append(formatNumber(upperBound));
+ result.append(upperType == ExclusiveBound ? ')' : ']');
+ result.append('.');
+ return result.toString();
+ }
+
+ static String invalidArity(const char* expected, unsigned provided);
+
// If > 0, the argument index that failed type check (1-indexed.)
// If == 0, a (non-argument) value (e.g., a setter) failed the same check.
static String notAnArrayTypeArgumentOrValue(int argumentIndex);
static String notASequenceTypeProperty(const String& propertyName);
- static String notAFiniteNumber(double value);
+ static String notAFiniteNumber(double value, const char* name = "value provided");
+ static String notAFiniteNumber(const Decimal& value, const char* name = "value provided");
static String notEnoughArguments(unsigned expected, unsigned providedleastNumMandatoryParams);
+ static String readOnly(const char* detail = 0);
+
private:
+ template <typename NumType>
+ static String formatFiniteNumber(NumType number)
+ {
+ if (number > 1e20 || number < -1e20)
+ return String::format("%e", 1.0*number);
+ return String::number(number);
+ }
+
+ template <typename NumType>
+ static String formatPotentiallyNonFiniteNumber(NumType number)
+ {
+ if (std::isnan(number))
+ return "NaN";
+ if (std::isinf(number))
+ return number > 0 ? "Infinity" : "-Infinity";
+ if (number > 1e20 || number < -1e20)
+ return String::format("%e", number);
+ return String::number(number);
+ }
+
static String ordinalNumber(int number);
};
+template <> String ExceptionMessages::formatNumber<float>(float number);
+template <> String ExceptionMessages::formatNumber<double>(double number);
+
} // namespace WebCore
#endif // ExceptionMessages_h
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/ExceptionState.cpp b/chromium/third_party/WebKit/Source/bindings/v8/ExceptionState.cpp
index 77c9103d7be..d51325cc41d 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/ExceptionState.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/ExceptionState.cpp
@@ -47,21 +47,26 @@ void ExceptionState::throwDOMException(const ExceptionCode& ec, const String& me
{
ASSERT(ec);
ASSERT(m_isolate);
+ ASSERT(!m_creationContext.IsEmpty());
// SecurityError is thrown via ::throwSecurityError, and _careful_ consideration must be given to the data exposed to JavaScript via the 'sanitizedMessage'.
ASSERT(ec != SecurityError);
m_code = ec;
String processedMessage = addExceptionContext(message);
+ m_message = processedMessage;
setException(V8ThrowException::createDOMException(ec, processedMessage, m_creationContext, m_isolate));
}
void ExceptionState::throwSecurityError(const String& sanitizedMessage, const String& unsanitizedMessage)
{
ASSERT(m_isolate);
+ ASSERT(!m_creationContext.IsEmpty());
m_code = SecurityError;
String finalSanitized = addExceptionContext(sanitizedMessage);
+ m_message = finalSanitized;
String finalUnsanitized = addExceptionContext(unsanitizedMessage);
+
setException(V8ThrowException::createDOMException(SecurityError, finalSanitized, finalUnsanitized, m_creationContext, m_isolate));
}
@@ -76,26 +81,57 @@ void ExceptionState::setException(v8::Handle<v8::Value> exception)
m_exception.set(m_isolate, exception);
}
+void ExceptionState::throwException()
+{
+ ASSERT(!m_exception.isEmpty());
+ V8ThrowException::throwError(m_exception.newLocal(m_isolate), m_isolate);
+}
+
void ExceptionState::throwTypeError(const String& message)
{
ASSERT(m_isolate);
m_code = TypeError;
+ m_message = message;
setException(V8ThrowException::createTypeError(addExceptionContext(message), m_isolate));
}
+void NonThrowableExceptionState::throwDOMException(const ExceptionCode& ec, const String& message)
+{
+ ASSERT_NOT_REACHED();
+ m_code = ec;
+ m_message = message;
+}
+
+void NonThrowableExceptionState::throwTypeError(const String& message)
+{
+ ASSERT_NOT_REACHED();
+ m_code = TypeError;
+ m_message = message;
+}
+
+void NonThrowableExceptionState::throwSecurityError(const String& sanitizedMessage, const String&)
+{
+ ASSERT_NOT_REACHED();
+ m_code = SecurityError;
+ m_message = sanitizedMessage;
+}
+
void TrackExceptionState::throwDOMException(const ExceptionCode& ec, const String& message)
{
m_code = ec;
+ m_message = message;
}
-void TrackExceptionState::throwTypeError(const String&)
+void TrackExceptionState::throwTypeError(const String& message)
{
m_code = TypeError;
+ m_message = message;
}
-void TrackExceptionState::throwSecurityError(const String&, const String&)
+void TrackExceptionState::throwSecurityError(const String& sanitizedMessage, const String&)
{
m_code = SecurityError;
+ m_message = sanitizedMessage;
}
String ExceptionState::addExceptionContext(const String& message) const
@@ -113,8 +149,17 @@ String ExceptionState::addExceptionContext(const String& message) const
processedMessage = ExceptionMessages::failedToGet(propertyName(), interfaceName(), message);
else if (m_context == SetterContext)
processedMessage = ExceptionMessages::failedToSet(propertyName(), interfaceName(), message);
- } else if (!propertyName() && interfaceName() && m_context == ConstructionContext) {
- processedMessage = ExceptionMessages::failedToConstruct(interfaceName(), message);
+ } else if (!propertyName() && interfaceName()) {
+ if (m_context == ConstructionContext)
+ processedMessage = ExceptionMessages::failedToConstruct(interfaceName(), message);
+ else if (m_context == EnumerationContext)
+ processedMessage = ExceptionMessages::failedToEnumerate(interfaceName(), message);
+ else if (m_context == IndexedDeletionContext)
+ processedMessage = ExceptionMessages::failedToDeleteIndexed(interfaceName(), message);
+ else if (m_context == IndexedGetterContext)
+ processedMessage = ExceptionMessages::failedToGetIndexed(interfaceName(), message);
+ else if (m_context == IndexedSetterContext)
+ processedMessage = ExceptionMessages::failedToSetIndexed(interfaceName(), message);
}
return processedMessage;
}
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/ExceptionState.h b/chromium/third_party/WebKit/Source/bindings/v8/ExceptionState.h
index bfe2790e16a..d9c2b05b8ef 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/ExceptionState.h
+++ b/chromium/third_party/WebKit/Source/bindings/v8/ExceptionState.h
@@ -50,17 +50,14 @@ public:
DeletionContext,
GetterContext,
SetterContext,
+ EnumerationContext,
+ QueryContext,
+ IndexedGetterContext,
+ IndexedSetterContext,
+ IndexedDeletionContext,
UnknownContext, // FIXME: Remove this once we've flipped over to the new API.
};
- explicit ExceptionState(const v8::Handle<v8::Object>& creationContext, v8::Isolate* isolate)
- : m_code(0)
- , m_context(UnknownContext)
- , m_propertyName(0)
- , m_interfaceName(0)
- , m_creationContext(creationContext)
- , m_isolate(isolate) { }
-
ExceptionState(Context context, const char* propertyName, const char* interfaceName, const v8::Handle<v8::Object>& creationContext, v8::Isolate* isolate)
: m_code(0)
, m_context(context)
@@ -75,30 +72,23 @@ public:
, m_propertyName(0)
, m_interfaceName(interfaceName)
, m_creationContext(creationContext)
- , m_isolate(isolate) { ASSERT(m_context == ConstructionContext); }
+ , m_isolate(isolate) { ASSERT(m_context == ConstructionContext || m_context == EnumerationContext || m_context == IndexedSetterContext || m_context == IndexedGetterContext || m_context == IndexedDeletionContext); }
virtual void throwDOMException(const ExceptionCode&, const String& message);
virtual void throwTypeError(const String& message);
virtual void throwSecurityError(const String& sanitizedMessage, const String& unsanitizedMessage = String());
- // Please don't use these methods. Use ::throwDOMException and ::throwTypeError, and pass in a useful exception message.
- virtual void throwUninformativeAndGenericDOMException(const ExceptionCode& ec) { throwDOMException(ec, String()); }
- virtual void throwUninformativeAndGenericTypeError() { throwTypeError(String()); }
-
bool hadException() const { return !m_exception.isEmpty() || m_code; }
void clearException();
ExceptionCode code() const { return m_code; }
+ const String& message() const { return m_message; }
bool throwIfNeeded()
{
- if (m_exception.isEmpty()) {
- if (!m_code)
- return false;
- throwUninformativeAndGenericDOMException(m_code);
- }
-
- V8ThrowException::throwError(m_exception.newLocal(m_isolate), m_isolate);
+ if (!hadException())
+ return false;
+ throwException();
return true;
}
@@ -106,14 +96,21 @@ public:
const char* propertyName() const { return m_propertyName; }
const char* interfaceName() const { return m_interfaceName; }
+ void rethrowV8Exception(v8::Handle<v8::Value> value)
+ {
+ setException(value);
+ }
+
protected:
ExceptionCode m_code;
Context m_context;
+ String m_message;
const char* m_propertyName;
const char* m_interfaceName;
private:
void setException(v8::Handle<v8::Value>);
+ void throwException();
String addExceptionContext(const String&) const;
@@ -122,12 +119,22 @@ private:
v8::Isolate* m_isolate;
};
-class TrackExceptionState : public ExceptionState {
+// Used if exceptions can/should not be directly thrown.
+class NonThrowableExceptionState FINAL : public ExceptionState {
+public:
+ NonThrowableExceptionState(): ExceptionState(ExceptionState::UnknownContext, 0, 0, v8::Handle<v8::Object>(), v8::Isolate::GetCurrent()) { }
+ virtual void throwDOMException(const ExceptionCode&, const String& message) OVERRIDE;
+ virtual void throwTypeError(const String& message = String()) OVERRIDE;
+ virtual void throwSecurityError(const String& sanitizedMessage, const String& unsanitizedMessage = String()) OVERRIDE;
+};
+
+// Used if any exceptions thrown are ignorable.
+class TrackExceptionState FINAL : public ExceptionState {
public:
- TrackExceptionState(): ExceptionState(v8::Handle<v8::Object>(), 0) { }
- virtual void throwDOMException(const ExceptionCode&, const String& message) OVERRIDE FINAL;
- virtual void throwTypeError(const String& message = String()) OVERRIDE FINAL;
- virtual void throwSecurityError(const String& sanitizedMessage, const String& unsanitizedMessage = String()) OVERRIDE FINAL;
+ TrackExceptionState(): ExceptionState(ExceptionState::UnknownContext, 0, 0, v8::Handle<v8::Object>(), v8::Isolate::GetCurrent()) { }
+ virtual void throwDOMException(const ExceptionCode&, const String& message) OVERRIDE;
+ virtual void throwTypeError(const String& message = String()) OVERRIDE;
+ virtual void throwSecurityError(const String& sanitizedMessage, const String& unsanitizedMessage = String()) OVERRIDE;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/ExceptionStatePlaceholder.cpp b/chromium/third_party/WebKit/Source/bindings/v8/ExceptionStatePlaceholder.cpp
index 9d33119c814..6cfb6b2452e 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/ExceptionStatePlaceholder.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/ExceptionStatePlaceholder.cpp
@@ -33,10 +33,10 @@
namespace WebCore {
-#if !ASSERT_DISABLED
+#if ASSERT_ENABLED
NoExceptionStateAssertionChecker::NoExceptionStateAssertionChecker(const char* file, int line)
- : ExceptionState(v8::Handle<v8::Object>(), 0)
+ : ExceptionState(ExceptionState::UnknownContext, 0, 0, v8::Handle<v8::Object>(), 0)
, m_file(file)
, m_line(line) { }
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/ExceptionStatePlaceholder.h b/chromium/third_party/WebKit/Source/bindings/v8/ExceptionStatePlaceholder.h
index 84f6eb0b0f6..6df5b1ab9bb 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/ExceptionStatePlaceholder.h
+++ b/chromium/third_party/WebKit/Source/bindings/v8/ExceptionStatePlaceholder.h
@@ -34,6 +34,7 @@
#include "bindings/v8/ExceptionState.h"
#include "wtf/Assertions.h"
#include "wtf/text/WTFString.h"
+#include <v8.h>
namespace WebCore {
@@ -41,30 +42,26 @@ class ExceptionState;
typedef int ExceptionCode;
-class IgnorableExceptionState : public ExceptionState {
+class IgnorableExceptionState FINAL : public ExceptionState {
public:
- IgnorableExceptionState(): ExceptionState(v8::Handle<v8::Object>(), 0) { }
+ IgnorableExceptionState(): ExceptionState(ExceptionState::UnknownContext, 0, 0, v8::Handle<v8::Object>(), 0) { }
ExceptionState& returnThis() { return *this; }
- virtual void throwDOMException(const ExceptionCode&, const String& message = String()) OVERRIDE FINAL { };
- virtual void throwTypeError(const String& message = String()) OVERRIDE FINAL { }
- virtual void throwSecurityError(const String& sanitizedMessage, const String& unsanitizedMessage = String()) OVERRIDE FINAL { }
+ virtual void throwDOMException(const ExceptionCode&, const String& message = String()) OVERRIDE { }
+ virtual void throwTypeError(const String& message = String()) OVERRIDE { }
+ virtual void throwSecurityError(const String& sanitizedMessage, const String& unsanitizedMessage = String()) OVERRIDE { }
};
#define IGNORE_EXCEPTION (::WebCore::IgnorableExceptionState().returnThis())
-#if ASSERT_DISABLED
+#if ASSERT_ENABLED
-#define ASSERT_NO_EXCEPTION (::WebCore::IgnorableExceptionState().returnThis())
-
-#else
-
-class NoExceptionStateAssertionChecker : public ExceptionState {
+class NoExceptionStateAssertionChecker FINAL : public ExceptionState {
public:
NoExceptionStateAssertionChecker(const char* file, int line);
ExceptionState& returnThis() { return *this; }
- virtual void throwDOMException(const ExceptionCode&, const String& message = String()) OVERRIDE FINAL;
- virtual void throwTypeError(const String& message = String()) OVERRIDE FINAL;
- virtual void throwSecurityError(const String& sanitizedMessage, const String& unsanitizedMessage = String()) OVERRIDE FINAL;
+ virtual void throwDOMException(const ExceptionCode&, const String& message = String()) OVERRIDE;
+ virtual void throwTypeError(const String& message = String()) OVERRIDE;
+ virtual void throwSecurityError(const String& sanitizedMessage, const String& unsanitizedMessage = String()) OVERRIDE;
private:
const char* m_file;
@@ -73,6 +70,10 @@ private:
#define ASSERT_NO_EXCEPTION (::WebCore::NoExceptionStateAssertionChecker(__FILE__, __LINE__).returnThis())
+#else
+
+#define ASSERT_NO_EXCEPTION (::WebCore::IgnorableExceptionState().returnThis())
+
#endif
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/IDBBindingUtilities.cpp b/chromium/third_party/WebKit/Source/bindings/v8/IDBBindingUtilities.cpp
index 1676649e556..bc50f3c7a8a 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/IDBBindingUtilities.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/IDBBindingUtilities.cpp
@@ -26,23 +26,25 @@
#include "config.h"
#include "bindings/v8/IDBBindingUtilities.h"
-#include "V8DOMStringList.h"
-#include "V8IDBCursor.h"
-#include "V8IDBCursorWithValue.h"
-#include "V8IDBDatabase.h"
-#include "V8IDBIndex.h"
-#include "V8IDBKeyRange.h"
-#include "V8IDBObjectStore.h"
-#include "V8IDBTransaction.h"
-#include "bindings/v8/DOMRequestState.h"
+#include "bindings/core/v8/V8DOMStringList.h"
+#include "bindings/modules/v8/V8IDBCursor.h"
+#include "bindings/modules/v8/V8IDBCursorWithValue.h"
+#include "bindings/modules/v8/V8IDBDatabase.h"
+#include "bindings/modules/v8/V8IDBIndex.h"
+#include "bindings/modules/v8/V8IDBKeyRange.h"
+#include "bindings/modules/v8/V8IDBObjectStore.h"
+#include "bindings/modules/v8/V8IDBRequest.h"
+#include "bindings/modules/v8/V8IDBTransaction.h"
#include "bindings/v8/SerializedScriptValue.h"
#include "bindings/v8/V8Binding.h"
+#include "bindings/v8/V8HiddenValue.h"
#include "bindings/v8/custom/V8ArrayBufferViewCustom.h"
#include "bindings/v8/custom/V8Uint8ArrayCustom.h"
#include "modules/indexeddb/IDBKey.h"
#include "modules/indexeddb/IDBKeyPath.h"
#include "modules/indexeddb/IDBKeyRange.h"
#include "modules/indexeddb/IDBTracing.h"
+#include "platform/RuntimeEnabledFeatures.h"
#include "platform/SharedBuffer.h"
#include "wtf/ArrayBufferView.h"
#include "wtf/MathExtras.h"
@@ -51,7 +53,7 @@
namespace WebCore {
-v8::Handle<v8::Value> deserializeIDBValueBuffer(SharedBuffer*, v8::Isolate*);
+static v8::Handle<v8::Value> deserializeIDBValueBuffer(v8::Isolate*, SharedBuffer*, const Vector<blink::WebBlobInfo>*);
static v8::Handle<v8::Value> toV8(const IDBKeyPath& value, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
{
@@ -61,7 +63,7 @@ static v8::Handle<v8::Value> toV8(const IDBKeyPath& value, v8::Handle<v8::Object
case IDBKeyPath::StringType:
return v8String(isolate, value.string());
case IDBKeyPath::ArrayType:
- RefPtr<DOMStringList> keyPaths = DOMStringList::create();
+ RefPtrWillBeRawPtr<DOMStringList> keyPaths = DOMStringList::create();
for (Vector<String>::const_iterator it = value.array().begin(); it != value.array().end(); ++it)
keyPaths->append(*it);
return toV8(keyPaths.release(), creationContext, isolate);
@@ -70,7 +72,7 @@ static v8::Handle<v8::Value> toV8(const IDBKeyPath& value, v8::Handle<v8::Object
return v8::Undefined(isolate);
}
-v8::Handle<v8::Value> toV8(const IDBKey* key, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
+static v8::Handle<v8::Value> toV8(const IDBKey* key, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
{
if (!key) {
// This should be undefined, not null.
@@ -104,7 +106,7 @@ v8::Handle<v8::Value> toV8(const IDBKey* key, v8::Handle<v8::Object> creationCon
return v8Undefined();
}
-v8::Handle<v8::Value> toV8(const IDBAny* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
+static v8::Handle<v8::Value> toV8(const IDBAny* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
{
if (!impl)
return v8::Null(isolate);
@@ -116,10 +118,22 @@ v8::Handle<v8::Value> toV8(const IDBAny* impl, v8::Handle<v8::Object> creationCo
return v8::Null(isolate);
case IDBAny::DOMStringListType:
return toV8(impl->domStringList(), creationContext, isolate);
- case IDBAny::IDBCursorType:
- return toV8(impl->idbCursor(), creationContext, isolate);
- case IDBAny::IDBCursorWithValueType:
- return toV8(impl->idbCursorWithValue(), creationContext, isolate);
+ case IDBAny::IDBCursorType: {
+ // Ensure request wrapper is kept alive at least as long as the cursor wrapper,
+ // so that event listeners are retained.
+ v8::Handle<v8::Value> cursor = toV8(impl->idbCursor(), creationContext, isolate);
+ v8::Handle<v8::Value> request = toV8(impl->idbCursor()->request(), creationContext, isolate);
+ V8HiddenValue::setHiddenValue(isolate, cursor->ToObject(), V8HiddenValue::idbCursorRequest(isolate), request);
+ return cursor;
+ }
+ case IDBAny::IDBCursorWithValueType: {
+ // Ensure request wrapper is kept alive at least as long as the cursor wrapper,
+ // so that event listeners are retained.
+ v8::Handle<v8::Value> cursor = toV8(impl->idbCursorWithValue(), creationContext, isolate);
+ v8::Handle<v8::Value> request = toV8(impl->idbCursorWithValue()->request(), creationContext, isolate);
+ V8HiddenValue::setHiddenValue(isolate, cursor->ToObject(), V8HiddenValue::idbCursorRequest(isolate), request);
+ return cursor;
+ }
case IDBAny::IDBDatabaseType:
return toV8(impl->idbDatabase(), creationContext, isolate);
case IDBAny::IDBIndexType:
@@ -129,7 +143,7 @@ v8::Handle<v8::Value> toV8(const IDBAny* impl, v8::Handle<v8::Object> creationCo
case IDBAny::IDBTransactionType:
return toV8(impl->idbTransaction(), creationContext, isolate);
case IDBAny::BufferType:
- return deserializeIDBValueBuffer(impl->buffer(), isolate);
+ return deserializeIDBValueBuffer(isolate, impl->buffer(), impl->blobInfo());
case IDBAny::StringType:
return v8String(isolate, impl->string());
case IDBAny::IntegerType:
@@ -139,9 +153,9 @@ v8::Handle<v8::Value> toV8(const IDBAny* impl, v8::Handle<v8::Object> creationCo
case IDBAny::KeyPathType:
return toV8(impl->keyPath(), creationContext, isolate);
case IDBAny::BufferKeyAndKeyPathType: {
- v8::Handle<v8::Value> value = deserializeIDBValueBuffer(impl->buffer(), isolate);
+ v8::Handle<v8::Value> value = deserializeIDBValueBuffer(isolate, impl->buffer(), impl->blobInfo());
v8::Handle<v8::Value> key = toV8(impl->key(), creationContext, isolate);
- bool injected = injectV8KeyIntoV8Value(key, value, impl->keyPath(), isolate);
+ bool injected = injectV8KeyIntoV8Value(isolate, key, value, impl->keyPath());
ASSERT_UNUSED(injected, injected);
return value;
}
@@ -153,7 +167,7 @@ v8::Handle<v8::Value> toV8(const IDBAny* impl, v8::Handle<v8::Object> creationCo
static const size_t maximumDepth = 2000;
-static PassRefPtr<IDBKey> createIDBKeyFromValue(v8::Handle<v8::Value> value, Vector<v8::Handle<v8::Array> >& stack, v8::Isolate* isolate)
+static IDBKey* createIDBKeyFromValue(v8::Isolate* isolate, v8::Handle<v8::Value> value, Vector<v8::Handle<v8::Array> >& stack, bool allowExperimentalTypes = false)
{
if (value->IsNumber() && !std::isnan(value->NumberValue()))
return IDBKey::createNumber(value->NumberValue());
@@ -161,6 +175,14 @@ static PassRefPtr<IDBKey> createIDBKeyFromValue(v8::Handle<v8::Value> value, Vec
return IDBKey::createString(toCoreString(value.As<v8::String>()));
if (value->IsDate() && !std::isnan(value->NumberValue()))
return IDBKey::createDate(value->NumberValue());
+ if (value->IsUint8Array() && (allowExperimentalTypes || RuntimeEnabledFeatures::indexedDBExperimentalEnabled())) {
+ // Per discussion in https://www.w3.org/Bugs/Public/show_bug.cgi?id=23332 the
+ // input type is constrained to Uint8Array to match the output type.
+ ArrayBufferView* view = WebCore::V8ArrayBufferView::toNative(value->ToObject());
+ const char* start = static_cast<const char*>(view->baseAddress());
+ size_t length = view->byteLength();
+ return IDBKey::createBinary(SharedBuffer::create(start, length));
+ }
if (value->IsArray()) {
v8::Handle<v8::Array> array = v8::Handle<v8::Array>::Cast(value);
@@ -173,8 +195,8 @@ static PassRefPtr<IDBKey> createIDBKeyFromValue(v8::Handle<v8::Value> value, Vec
IDBKey::KeyArray subkeys;
uint32_t length = array->Length();
for (uint32_t i = 0; i < length; ++i) {
- v8::Local<v8::Value> item = array->Get(v8::Int32::New(i, isolate));
- RefPtr<IDBKey> subkey = createIDBKeyFromValue(item, stack, isolate);
+ v8::Local<v8::Value> item = array->Get(v8::Int32::New(isolate, i));
+ IDBKey* subkey = createIDBKeyFromValue(isolate, item, stack, allowExperimentalTypes);
if (!subkey)
subkeys.append(IDBKey::createInvalid());
else
@@ -187,11 +209,10 @@ static PassRefPtr<IDBKey> createIDBKeyFromValue(v8::Handle<v8::Value> value, Vec
return 0;
}
-static PassRefPtr<IDBKey> createIDBKeyFromValue(v8::Handle<v8::Value> value, v8::Isolate* isolate)
+static IDBKey* createIDBKeyFromValue(v8::Isolate* isolate, v8::Handle<v8::Value> value, bool allowExperimentalTypes = false)
{
Vector<v8::Handle<v8::Array> > stack;
- RefPtr<IDBKey> key = createIDBKeyFromValue(value, stack, isolate);
- if (key)
+ if (IDBKey* key = createIDBKeyFromValue(isolate, value, stack, allowExperimentalTypes))
return key;
return IDBKey::createInvalid();
}
@@ -213,7 +234,7 @@ static bool setValue(v8::Handle<v8::Value>& v8Object, T indexOrName, const v8::H
return object->Set(indexOrName, v8Value);
}
-static bool get(v8::Handle<v8::Value>& object, const String& keyPathElement, v8::Handle<v8::Value>& result, v8::Isolate* isolate)
+static bool get(v8::Isolate* isolate, v8::Handle<v8::Value>& object, const String& keyPathElement, v8::Handle<v8::Value>& result)
{
if (object->IsString() && keyPathElement == "length") {
int32_t length = v8::Handle<v8::String>::Cast(object)->Length();
@@ -228,25 +249,25 @@ static bool canSet(v8::Handle<v8::Value>& object, const String& keyPathElement)
return object->IsObject();
}
-static bool set(v8::Handle<v8::Value>& object, const String& keyPathElement, const v8::Handle<v8::Value>& v8Value, v8::Isolate* isolate)
+static bool set(v8::Isolate* isolate, v8::Handle<v8::Value>& object, const String& keyPathElement, const v8::Handle<v8::Value>& v8Value)
{
return canSet(object, keyPathElement) && setValue(object, v8String(isolate, keyPathElement), v8Value);
}
-static v8::Handle<v8::Value> getNthValueOnKeyPath(v8::Handle<v8::Value>& rootValue, const Vector<String>& keyPathElements, size_t index, v8::Isolate* isolate)
+static v8::Handle<v8::Value> getNthValueOnKeyPath(v8::Isolate* isolate, v8::Handle<v8::Value>& rootValue, const Vector<String>& keyPathElements, size_t index)
{
v8::Handle<v8::Value> currentValue(rootValue);
ASSERT(index <= keyPathElements.size());
for (size_t i = 0; i < index; ++i) {
v8::Handle<v8::Value> parentValue(currentValue);
- if (!get(parentValue, keyPathElements[i], currentValue, isolate))
+ if (!get(isolate, parentValue, keyPathElements[i], currentValue))
return v8Undefined();
}
return currentValue;
}
-static bool canInjectNthValueOnKeyPath(v8::Handle<v8::Value>& rootValue, const Vector<String>& keyPathElements, size_t index, v8::Isolate* isolate)
+static bool canInjectNthValueOnKeyPath(v8::Isolate* isolate, v8::Handle<v8::Value>& rootValue, const Vector<String>& keyPathElements, size_t index)
{
if (!rootValue->IsObject())
return false;
@@ -257,14 +278,14 @@ static bool canInjectNthValueOnKeyPath(v8::Handle<v8::Value>& rootValue, const V
for (size_t i = 0; i < index; ++i) {
v8::Handle<v8::Value> parentValue(currentValue);
const String& keyPathElement = keyPathElements[i];
- if (!get(parentValue, keyPathElement, currentValue, isolate))
+ if (!get(isolate, parentValue, keyPathElement, currentValue))
return canSet(parentValue, keyPathElement);
}
return true;
}
-static v8::Handle<v8::Value> ensureNthValueOnKeyPath(v8::Handle<v8::Value>& rootValue, const Vector<String>& keyPathElements, size_t index, v8::Isolate* isolate)
+static v8::Handle<v8::Value> ensureNthValueOnKeyPath(v8::Isolate* isolate, v8::Handle<v8::Value>& rootValue, const Vector<String>& keyPathElements, size_t index)
{
v8::Handle<v8::Value> currentValue(rootValue);
@@ -272,9 +293,9 @@ static v8::Handle<v8::Value> ensureNthValueOnKeyPath(v8::Handle<v8::Value>& root
for (size_t i = 0; i < index; ++i) {
v8::Handle<v8::Value> parentValue(currentValue);
const String& keyPathElement = keyPathElements[i];
- if (!get(parentValue, keyPathElement, currentValue, isolate)) {
- v8::Handle<v8::Object> object = v8::Object::New();
- if (!set(parentValue, keyPathElement, object, isolate))
+ if (!get(isolate, parentValue, keyPathElement, currentValue)) {
+ v8::Handle<v8::Object> object = v8::Object::New(isolate);
+ if (!set(isolate, parentValue, keyPathElement, object))
return v8Undefined();
currentValue = object;
}
@@ -283,7 +304,7 @@ static v8::Handle<v8::Value> ensureNthValueOnKeyPath(v8::Handle<v8::Value>& root
return currentValue;
}
-static PassRefPtr<IDBKey> createIDBKeyFromScriptValueAndKeyPath(const ScriptValue& value, const String& keyPath, v8::Isolate* isolate)
+static IDBKey* createIDBKeyFromScriptValueAndKeyPathInternal(v8::Isolate* isolate, const ScriptValue& value, const String& keyPath, bool allowExperimentalTypes)
{
Vector<String> keyPathElements;
IDBKeyPathParseError error;
@@ -293,24 +314,21 @@ static PassRefPtr<IDBKey> createIDBKeyFromScriptValueAndKeyPath(const ScriptValu
v8::HandleScope handleScope(isolate);
v8::Handle<v8::Value> v8Value(value.v8Value());
- v8::Handle<v8::Value> v8Key(getNthValueOnKeyPath(v8Value, keyPathElements, keyPathElements.size(), isolate));
+ v8::Handle<v8::Value> v8Key(getNthValueOnKeyPath(isolate, v8Value, keyPathElements, keyPathElements.size()));
if (v8Key.IsEmpty())
return 0;
- return createIDBKeyFromValue(v8Key, isolate);
+ return createIDBKeyFromValue(isolate, v8Key, allowExperimentalTypes);
}
-PassRefPtr<IDBKey> createIDBKeyFromScriptValueAndKeyPath(DOMRequestState* state, const ScriptValue& value, const IDBKeyPath& keyPath)
+static IDBKey* createIDBKeyFromScriptValueAndKeyPathInternal(v8::Isolate* isolate, const ScriptValue& value, const IDBKeyPath& keyPath, bool allowExperimentalTypes = false)
{
- IDB_TRACE("createIDBKeyFromScriptValueAndKeyPath");
ASSERT(!keyPath.isNull());
- v8::Isolate* isolate = state ? state->context()->GetIsolate() : v8::Isolate::GetCurrent();
- ASSERT(isolate->InContext());
v8::HandleScope handleScope(isolate);
if (keyPath.type() == IDBKeyPath::ArrayType) {
IDBKey::KeyArray result;
const Vector<String>& array = keyPath.array();
for (size_t i = 0; i < array.size(); ++i) {
- RefPtr<IDBKey> key = createIDBKeyFromScriptValueAndKeyPath(value, array[i], isolate);
+ IDBKey* key = createIDBKeyFromScriptValueAndKeyPathInternal(isolate, value, array[i], allowExperimentalTypes);
if (!key)
return 0;
result.append(key);
@@ -319,10 +337,16 @@ PassRefPtr<IDBKey> createIDBKeyFromScriptValueAndKeyPath(DOMRequestState* state,
}
ASSERT(keyPath.type() == IDBKeyPath::StringType);
- return createIDBKeyFromScriptValueAndKeyPath(value, keyPath.string(), isolate);
+ return createIDBKeyFromScriptValueAndKeyPathInternal(isolate, value, keyPath.string(), allowExperimentalTypes);
+}
+
+IDBKey* createIDBKeyFromScriptValueAndKeyPath(v8::Isolate* isolate, const ScriptValue& value, const IDBKeyPath& keyPath)
+{
+ IDB_TRACE("createIDBKeyFromScriptValueAndKeyPath");
+ return createIDBKeyFromScriptValueAndKeyPathInternal(isolate, value, keyPath);
}
-v8::Handle<v8::Value> deserializeIDBValueBuffer(SharedBuffer* buffer, v8::Isolate* isolate)
+static v8::Handle<v8::Value> deserializeIDBValueBuffer(v8::Isolate* isolate, SharedBuffer* buffer, const Vector<blink::WebBlobInfo>* blobInfo)
{
ASSERT(isolate->InContext());
if (!buffer)
@@ -332,10 +356,10 @@ v8::Handle<v8::Value> deserializeIDBValueBuffer(SharedBuffer* buffer, v8::Isolat
Vector<uint8_t> value;
value.append(buffer->data(), buffer->size());
RefPtr<SerializedScriptValue> serializedValue = SerializedScriptValue::createFromWireBytes(value);
- return serializedValue->deserialize(isolate);
+ return serializedValue->deserialize(isolate, 0, blobInfo);
}
-bool injectV8KeyIntoV8Value(v8::Handle<v8::Value> key, v8::Handle<v8::Value> value, const IDBKeyPath& keyPath, v8::Isolate* isolate)
+bool injectV8KeyIntoV8Value(v8::Isolate* isolate, v8::Handle<v8::Value> key, v8::Handle<v8::Value> value, const IDBKeyPath& keyPath)
{
IDB_TRACE("injectIDBV8KeyIntoV8Value");
ASSERT(isolate->InContext());
@@ -350,17 +374,17 @@ bool injectV8KeyIntoV8Value(v8::Handle<v8::Value> key, v8::Handle<v8::Value> val
return false;
v8::HandleScope handleScope(isolate);
- v8::Handle<v8::Value> parent(ensureNthValueOnKeyPath(value, keyPathElements, keyPathElements.size() - 1, isolate));
+ v8::Handle<v8::Value> parent(ensureNthValueOnKeyPath(isolate, value, keyPathElements, keyPathElements.size() - 1));
if (parent.IsEmpty())
return false;
- if (!set(parent, keyPathElements.last(), key, isolate))
+ if (!set(isolate, parent, keyPathElements.last(), key))
return false;
return true;
}
-bool canInjectIDBKeyIntoScriptValue(DOMRequestState* state, const ScriptValue& scriptValue, const IDBKeyPath& keyPath)
+bool canInjectIDBKeyIntoScriptValue(v8::Isolate* isolate, const ScriptValue& scriptValue, const IDBKeyPath& keyPath)
{
IDB_TRACE("canInjectIDBKeyIntoScriptValue");
ASSERT(keyPath.type() == IDBKeyPath::StringType);
@@ -373,63 +397,54 @@ bool canInjectIDBKeyIntoScriptValue(DOMRequestState* state, const ScriptValue& s
return false;
v8::Handle<v8::Value> v8Value(scriptValue.v8Value());
- return canInjectNthValueOnKeyPath(v8Value, keyPathElements, keyPathElements.size() - 1, state->context()->GetIsolate());
+ return canInjectNthValueOnKeyPath(isolate, v8Value, keyPathElements, keyPathElements.size() - 1);
}
-ScriptValue idbAnyToScriptValue(DOMRequestState* state, PassRefPtr<IDBAny> any)
+ScriptValue idbAnyToScriptValue(ScriptState* scriptState, IDBAny* any)
{
- v8::Isolate* isolate = state ? state->context()->GetIsolate() : v8::Isolate::GetCurrent();
- ASSERT(isolate->InContext());
- v8::Local<v8::Context> context = state ? state->context() : isolate->GetCurrentContext();
+ v8::Isolate* isolate = scriptState->isolate();
v8::HandleScope handleScope(isolate);
- v8::Handle<v8::Value> v8Value(toV8(any.get(), context->Global(), isolate));
- return ScriptValue(v8Value, isolate);
+ v8::Handle<v8::Value> v8Value(toV8(any, scriptState->context()->Global(), isolate));
+ return ScriptValue(scriptState, v8Value);
}
-ScriptValue idbKeyToScriptValue(DOMRequestState* state, PassRefPtr<IDBKey> key)
+ScriptValue idbKeyToScriptValue(ScriptState* scriptState, IDBKey* key)
{
- v8::Isolate* isolate = state ? state->context()->GetIsolate() : v8::Isolate::GetCurrent();
- ASSERT(isolate->InContext());
- v8::Local<v8::Context> context = state ? state->context() : isolate->GetCurrentContext();
+ v8::Isolate* isolate = scriptState->isolate();
v8::HandleScope handleScope(isolate);
- v8::Handle<v8::Value> v8Value(toV8(key.get(), context->Global(), isolate));
- return ScriptValue(v8Value, isolate);
+ v8::Handle<v8::Value> v8Value(toV8(key, scriptState->context()->Global(), isolate));
+ return ScriptValue(scriptState, v8Value);
}
-PassRefPtr<IDBKey> scriptValueToIDBKey(DOMRequestState* state, const ScriptValue& scriptValue)
+IDBKey* scriptValueToIDBKey(v8::Isolate* isolate, const ScriptValue& scriptValue)
{
- v8::Isolate* isolate = state ? state->context()->GetIsolate() : v8::Isolate::GetCurrent();
ASSERT(isolate->InContext());
v8::HandleScope handleScope(isolate);
v8::Handle<v8::Value> v8Value(scriptValue.v8Value());
- return createIDBKeyFromValue(v8Value, isolate);
+ return createIDBKeyFromValue(isolate, v8Value);
}
-PassRefPtr<IDBKeyRange> scriptValueToIDBKeyRange(DOMRequestState* state, const ScriptValue& scriptValue)
+IDBKeyRange* scriptValueToIDBKeyRange(v8::Isolate* isolate, const ScriptValue& scriptValue)
{
- v8::Isolate* isolate = state ? state->context()->GetIsolate() : v8::Isolate::GetCurrent();
v8::HandleScope handleScope(isolate);
v8::Handle<v8::Value> value(scriptValue.v8Value());
- if (V8IDBKeyRange::hasInstance(value, isolate, worldType(isolate)))
- return V8IDBKeyRange::toNative(value.As<v8::Object>());
- return 0;
+ return V8IDBKeyRange::toNativeWithTypeCheck(isolate, value);
}
#ifndef NDEBUG
-void assertPrimaryKeyValidOrInjectable(DOMRequestState* state, PassRefPtr<SharedBuffer> buffer, PassRefPtr<IDBKey> prpKey, const IDBKeyPath& keyPath)
+void assertPrimaryKeyValidOrInjectable(ScriptState* scriptState, PassRefPtr<SharedBuffer> buffer, const Vector<blink::WebBlobInfo>* blobInfo, IDBKey* key, const IDBKeyPath& keyPath)
{
- RefPtr<IDBKey> key(prpKey);
-
- DOMRequestState::Scope scope(*state);
- v8::Isolate* isolate = state ? state->context()->GetIsolate() : v8::Isolate::GetCurrent();
-
- ScriptValue keyValue = idbKeyToScriptValue(state, key);
- ScriptValue scriptValue(deserializeIDBValueBuffer(buffer.get(), isolate), isolate);
+ ScriptState::Scope scope(scriptState);
+ v8::Isolate* isolate = scriptState->isolate();
+ ScriptValue keyValue = idbKeyToScriptValue(scriptState, key);
+ ScriptValue scriptValue(scriptState, deserializeIDBValueBuffer(isolate, buffer.get(), blobInfo));
- RefPtr<IDBKey> expectedKey = createIDBKeyFromScriptValueAndKeyPath(state, scriptValue, keyPath);
- ASSERT(!expectedKey || expectedKey->isEqual(key.get()));
+ // This assertion is about already persisted data, so allow experimental types.
+ const bool allowExperimentalTypes = true;
+ IDBKey* expectedKey = createIDBKeyFromScriptValueAndKeyPathInternal(isolate, scriptValue, keyPath, allowExperimentalTypes);
+ ASSERT(!expectedKey || expectedKey->isEqual(key));
- bool injected = injectV8KeyIntoV8Value(keyValue.v8Value(), scriptValue.v8Value(), keyPath, isolate);
+ bool injected = injectV8KeyIntoV8Value(isolate, keyValue.v8Value(), scriptValue.v8Value(), keyPath);
ASSERT_UNUSED(injected, injected);
}
#endif
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/IDBBindingUtilities.h b/chromium/third_party/WebKit/Source/bindings/v8/IDBBindingUtilities.h
index b36c71cb03d..fba64423937 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/IDBBindingUtilities.h
+++ b/chromium/third_party/WebKit/Source/bindings/v8/IDBBindingUtilities.h
@@ -26,13 +26,19 @@
#ifndef IDBBindingUtilities_h
#define IDBBindingUtilities_h
+#include "bindings/v8/ScriptState.h"
#include "bindings/v8/ScriptValue.h"
#include <v8.h>
#include "wtf/Forward.h"
+namespace blink {
+
+class WebBlobInfo;
+
+}
+
namespace WebCore {
-class DOMRequestState;
class IDBAny;
class IDBKey;
class IDBKeyPath;
@@ -41,18 +47,18 @@ class SerializedScriptValue;
class SharedBuffer;
// Exposed for unit testing:
-bool injectV8KeyIntoV8Value(v8::Handle<v8::Value> key, v8::Handle<v8::Value>, const IDBKeyPath&, v8::Isolate*);
+bool injectV8KeyIntoV8Value(v8::Isolate*, v8::Handle<v8::Value> key, v8::Handle<v8::Value>, const IDBKeyPath&);
// For use by Source/modules/indexeddb:
-PassRefPtr<IDBKey> createIDBKeyFromScriptValueAndKeyPath(DOMRequestState*, const ScriptValue&, const IDBKeyPath&);
-bool canInjectIDBKeyIntoScriptValue(DOMRequestState*, const ScriptValue&, const IDBKeyPath&);
-ScriptValue idbAnyToScriptValue(DOMRequestState*, PassRefPtr<IDBAny>);
-ScriptValue idbKeyToScriptValue(DOMRequestState*, PassRefPtr<IDBKey>);
-PassRefPtr<IDBKey> scriptValueToIDBKey(DOMRequestState*, const ScriptValue&);
-PassRefPtr<IDBKeyRange> scriptValueToIDBKeyRange(DOMRequestState*, const ScriptValue&);
+IDBKey* createIDBKeyFromScriptValueAndKeyPath(v8::Isolate*, const ScriptValue&, const IDBKeyPath&);
+bool canInjectIDBKeyIntoScriptValue(v8::Isolate*, const ScriptValue&, const IDBKeyPath&);
+ScriptValue idbAnyToScriptValue(ScriptState*, IDBAny*);
+ScriptValue idbKeyToScriptValue(ScriptState*, IDBKey*);
+IDBKey* scriptValueToIDBKey(v8::Isolate*, const ScriptValue&);
+IDBKeyRange* scriptValueToIDBKeyRange(v8::Isolate*, const ScriptValue&);
#ifndef NDEBUG
-void assertPrimaryKeyValidOrInjectable(DOMRequestState*, PassRefPtr<SharedBuffer>, PassRefPtr<IDBKey>, const IDBKeyPath&);
+void assertPrimaryKeyValidOrInjectable(ScriptState*, PassRefPtr<SharedBuffer>, const Vector<blink::WebBlobInfo>*, IDBKey*, const IDBKeyPath&);
#endif
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/IDBBindingUtilitiesTest.cpp b/chromium/third_party/WebKit/Source/bindings/v8/IDBBindingUtilitiesTest.cpp
index 0f6ff63ee32..b984d04ceeb 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/IDBBindingUtilitiesTest.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/IDBBindingUtilitiesTest.cpp
@@ -28,64 +28,60 @@
#include "bindings/v8/V8Binding.h"
#include "bindings/v8/V8PerIsolateData.h"
-#include "bindings/v8/V8Utilities.h"
#include "modules/indexeddb/IDBKey.h"
#include "modules/indexeddb/IDBKeyPath.h"
-
#include <gtest/gtest.h>
using namespace WebCore;
namespace {
-PassRefPtr<IDBKey> checkKeyFromValueAndKeyPathInternal(const ScriptValue& value, const String& keyPath)
+IDBKey* checkKeyFromValueAndKeyPathInternal(v8::Isolate* isolate, const ScriptValue& value, const String& keyPath)
{
IDBKeyPath idbKeyPath(keyPath);
EXPECT_TRUE(idbKeyPath.isValid());
- return createIDBKeyFromScriptValueAndKeyPath(0, value, idbKeyPath);
+ return createIDBKeyFromScriptValueAndKeyPath(isolate, value, idbKeyPath);
}
-void checkKeyPathNullValue(const ScriptValue& value, const String& keyPath)
+void checkKeyPathNullValue(v8::Isolate* isolate, const ScriptValue& value, const String& keyPath)
{
- RefPtr<IDBKey> idbKey = checkKeyFromValueAndKeyPathInternal(value, keyPath);
- ASSERT_FALSE(idbKey.get());
+ ASSERT_FALSE(checkKeyFromValueAndKeyPathInternal(isolate, value, keyPath));
}
-bool injectKey(PassRefPtr<IDBKey> key, ScriptValue& value, const String& keyPath)
+bool injectKey(ScriptState* scriptState, IDBKey* key, ScriptValue& value, const String& keyPath)
{
IDBKeyPath idbKeyPath(keyPath);
EXPECT_TRUE(idbKeyPath.isValid());
- ScriptValue keyValue = idbKeyToScriptValue(0, key);
- return injectV8KeyIntoV8Value(keyValue.v8Value(), value.v8Value(), idbKeyPath, v8::Isolate::GetCurrent());
+ ScriptValue keyValue = idbKeyToScriptValue(scriptState, key);
+ return injectV8KeyIntoV8Value(scriptState->isolate(), keyValue.v8Value(), value.v8Value(), idbKeyPath);
}
-void checkInjection(PassRefPtr<IDBKey> prpKey, ScriptValue& value, const String& keyPath)
+void checkInjection(ScriptState* scriptState, IDBKey* key, ScriptValue& value, const String& keyPath)
{
- RefPtr<IDBKey> key = prpKey;
- bool result = injectKey(key, value, keyPath);
+ bool result = injectKey(scriptState, key, value, keyPath);
ASSERT_TRUE(result);
- RefPtr<IDBKey> extractedKey = checkKeyFromValueAndKeyPathInternal(value, keyPath);
- EXPECT_TRUE(key->isEqual(extractedKey.get()));
+ IDBKey* extractedKey = checkKeyFromValueAndKeyPathInternal(scriptState->isolate(), value, keyPath);
+ EXPECT_TRUE(key->isEqual(extractedKey));
}
-void checkInjectionFails(PassRefPtr<IDBKey> key, ScriptValue& value, const String& keyPath)
+void checkInjectionFails(ScriptState* scriptState, IDBKey* key, ScriptValue& value, const String& keyPath)
{
- EXPECT_FALSE(injectKey(key, value, keyPath));
+ EXPECT_FALSE(injectKey(scriptState, key, value, keyPath));
}
-void checkKeyPathStringValue(const ScriptValue& value, const String& keyPath, const String& expected)
+void checkKeyPathStringValue(v8::Isolate* isolate, const ScriptValue& value, const String& keyPath, const String& expected)
{
- RefPtr<IDBKey> idbKey = checkKeyFromValueAndKeyPathInternal(value, keyPath);
- ASSERT_TRUE(idbKey.get());
+ IDBKey* idbKey = checkKeyFromValueAndKeyPathInternal(isolate, value, keyPath);
+ ASSERT_TRUE(idbKey);
ASSERT_EQ(IDBKey::StringType, idbKey->type());
ASSERT_TRUE(expected == idbKey->string());
}
-void checkKeyPathNumberValue(const ScriptValue& value, const String& keyPath, int expected)
+void checkKeyPathNumberValue(v8::Isolate* isolate, const ScriptValue& value, const String& keyPath, int expected)
{
- RefPtr<IDBKey> idbKey = checkKeyFromValueAndKeyPathInternal(value, keyPath);
- ASSERT_TRUE(idbKey.get());
+ IDBKey* idbKey = checkKeyFromValueAndKeyPathInternal(isolate, value, keyPath);
+ ASSERT_TRUE(idbKey);
ASSERT_EQ(IDBKey::NumberType, idbKey->type());
ASSERT_TRUE(expected == idbKey->number());
}
@@ -93,49 +89,52 @@ void checkKeyPathNumberValue(const ScriptValue& value, const String& keyPath, in
class IDBKeyFromValueAndKeyPathTest : public testing::Test {
public:
IDBKeyFromValueAndKeyPathTest()
- : m_handleScope(v8::Isolate::GetCurrent())
- , m_scope(v8::Context::New(v8::Isolate::GetCurrent()))
+ : m_scope(v8::Isolate::GetCurrent())
{
}
+ ScriptState* scriptState() const { return m_scope.scriptState(); }
+
private:
- v8::HandleScope m_handleScope;
- v8::Context::Scope m_scope;
+ V8TestingScope m_scope;
};
TEST_F(IDBKeyFromValueAndKeyPathTest, TopLevelPropertyStringValue)
{
- v8::Local<v8::Object> object = v8::Object::New();
- object->Set(v8::String::NewFromUtf8(v8::Isolate::GetCurrent(), "foo"), v8::String::NewFromUtf8(v8::Isolate::GetCurrent(), "zoo"));
+ v8::Isolate* isolate = v8::Isolate::GetCurrent();
+ v8::Local<v8::Object> object = v8::Object::New(isolate);
+ object->Set(v8AtomicString(isolate, "foo"), v8AtomicString(isolate, "zoo"));
- ScriptValue scriptValue(object, v8::Isolate::GetCurrent());
+ ScriptValue scriptValue(scriptState(), object);
- checkKeyPathStringValue(scriptValue, "foo", "zoo");
- checkKeyPathNullValue(scriptValue, "bar");
+ checkKeyPathStringValue(isolate, scriptValue, "foo", "zoo");
+ checkKeyPathNullValue(isolate, scriptValue, "bar");
}
TEST_F(IDBKeyFromValueAndKeyPathTest, TopLevelPropertyNumberValue)
{
- v8::Local<v8::Object> object = v8::Object::New();
- object->Set(v8::String::NewFromUtf8(v8::Isolate::GetCurrent(), "foo"), v8::Number::New(456));
+ v8::Isolate* isolate = v8::Isolate::GetCurrent();
+ v8::Local<v8::Object> object = v8::Object::New(isolate);
+ object->Set(v8AtomicString(isolate, "foo"), v8::Number::New(isolate, 456));
- ScriptValue scriptValue(object, v8::Isolate::GetCurrent());
+ ScriptValue scriptValue(scriptState(), object);
- checkKeyPathNumberValue(scriptValue, "foo", 456);
- checkKeyPathNullValue(scriptValue, "bar");
+ checkKeyPathNumberValue(isolate, scriptValue, "foo", 456);
+ checkKeyPathNullValue(isolate, scriptValue, "bar");
}
TEST_F(IDBKeyFromValueAndKeyPathTest, SubProperty)
{
- v8::Local<v8::Object> object = v8::Object::New();
- v8::Local<v8::Object> subProperty = v8::Object::New();
- subProperty->Set(v8::String::NewFromUtf8(v8::Isolate::GetCurrent(), "bar"), v8::String::NewFromUtf8(v8::Isolate::GetCurrent(), "zee"));
- object->Set(v8::String::NewFromUtf8(v8::Isolate::GetCurrent(), "foo"), subProperty);
+ v8::Isolate* isolate = v8::Isolate::GetCurrent();
+ v8::Local<v8::Object> object = v8::Object::New(isolate);
+ v8::Local<v8::Object> subProperty = v8::Object::New(isolate);
+ subProperty->Set(v8AtomicString(isolate, "bar"), v8AtomicString(isolate, "zee"));
+ object->Set(v8AtomicString(isolate, "foo"), subProperty);
- ScriptValue scriptValue(object, v8::Isolate::GetCurrent());
+ ScriptValue scriptValue(scriptState(), object);
- checkKeyPathStringValue(scriptValue, "foo.bar", "zee");
- checkKeyPathNullValue(scriptValue, "bar");
+ checkKeyPathStringValue(isolate, scriptValue, "foo.bar", "zee");
+ checkKeyPathNullValue(isolate, scriptValue, "bar");
}
class InjectIDBKeyTest : public IDBKeyFromValueAndKeyPathTest {
@@ -143,33 +142,35 @@ class InjectIDBKeyTest : public IDBKeyFromValueAndKeyPathTest {
TEST_F(InjectIDBKeyTest, TopLevelPropertyStringValue)
{
- v8::Local<v8::Object> object = v8::Object::New();
- object->Set(v8::String::NewFromUtf8(v8::Isolate::GetCurrent(), "foo"), v8::String::NewFromUtf8(v8::Isolate::GetCurrent(), "zoo"));
+ v8::Isolate* isolate = v8::Isolate::GetCurrent();
+ v8::Local<v8::Object> object = v8::Object::New(isolate);
+ object->Set(v8AtomicString(isolate, "foo"), v8AtomicString(isolate, "zoo"));
- ScriptValue foozoo(object, v8::Isolate::GetCurrent());
- checkInjection(IDBKey::createString("myNewKey"), foozoo, "bar");
- checkInjection(IDBKey::createNumber(1234), foozoo, "bar");
+ ScriptValue foozoo(scriptState(), object);
+ checkInjection(scriptState(), IDBKey::createString("myNewKey"), foozoo, "bar");
+ checkInjection(scriptState(), IDBKey::createNumber(1234), foozoo, "bar");
- checkInjectionFails(IDBKey::createString("key"), foozoo, "foo.bar");
+ checkInjectionFails(scriptState(), IDBKey::createString("key"), foozoo, "foo.bar");
}
TEST_F(InjectIDBKeyTest, SubProperty)
{
- v8::Local<v8::Object> object = v8::Object::New();
- v8::Local<v8::Object> subProperty = v8::Object::New();
- subProperty->Set(v8::String::NewFromUtf8(v8::Isolate::GetCurrent(), "bar"), v8::String::NewFromUtf8(v8::Isolate::GetCurrent(), "zee"));
- object->Set(v8::String::NewFromUtf8(v8::Isolate::GetCurrent(), "foo"), subProperty);
-
- ScriptValue scriptObject(object, v8::Isolate::GetCurrent());
- checkInjection(IDBKey::createString("myNewKey"), scriptObject, "foo.baz");
- checkInjection(IDBKey::createNumber(789), scriptObject, "foo.baz");
- checkInjection(IDBKey::createDate(4567), scriptObject, "foo.baz");
- checkInjection(IDBKey::createDate(4567), scriptObject, "bar");
- checkInjection(IDBKey::createArray(IDBKey::KeyArray()), scriptObject, "foo.baz");
- checkInjection(IDBKey::createArray(IDBKey::KeyArray()), scriptObject, "bar");
-
- checkInjectionFails(IDBKey::createString("zoo"), scriptObject, "foo.bar.baz");
- checkInjection(IDBKey::createString("zoo"), scriptObject, "foo.xyz.foo");
+ v8::Isolate* isolate = v8::Isolate::GetCurrent();
+ v8::Local<v8::Object> object = v8::Object::New(isolate);
+ v8::Local<v8::Object> subProperty = v8::Object::New(isolate);
+ subProperty->Set(v8AtomicString(isolate, "bar"), v8AtomicString(isolate, "zee"));
+ object->Set(v8AtomicString(isolate, "foo"), subProperty);
+
+ ScriptValue scriptObject(scriptState(), object);
+ checkInjection(scriptState(), IDBKey::createString("myNewKey"), scriptObject, "foo.baz");
+ checkInjection(scriptState(), IDBKey::createNumber(789), scriptObject, "foo.baz");
+ checkInjection(scriptState(), IDBKey::createDate(4567), scriptObject, "foo.baz");
+ checkInjection(scriptState(), IDBKey::createDate(4567), scriptObject, "bar");
+ checkInjection(scriptState(), IDBKey::createArray(IDBKey::KeyArray()), scriptObject, "foo.baz");
+ checkInjection(scriptState(), IDBKey::createArray(IDBKey::KeyArray()), scriptObject, "bar");
+
+ checkInjectionFails(scriptState(), IDBKey::createString("zoo"), scriptObject, "foo.bar.baz");
+ checkInjection(scriptState(), IDBKey::createString("zoo"), scriptObject, "foo.xyz.foo");
}
} // namespace
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/NPV8Object.cpp b/chromium/third_party/WebKit/Source/bindings/v8/NPV8Object.cpp
index e094bf92563..11f34a44d97 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/NPV8Object.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/NPV8Object.cpp
@@ -38,8 +38,8 @@
#include "bindings/v8/WrapperTypeInfo.h"
#include "bindings/v8/npruntime_impl.h"
#include "bindings/v8/npruntime_priv.h"
-#include "core/frame/DOMWindow.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalDOMWindow.h"
+#include "core/frame/LocalFrame.h"
#include "platform/UserGestureIndicator.h"
#include "wtf/OwnPtr.h"
@@ -53,7 +53,7 @@ namespace WebCore {
const WrapperTypeInfo* npObjectTypeInfo()
{
- static const WrapperTypeInfo typeInfo = { gin::kEmbedderBlink, 0, 0, 0, 0, 0, 0, 0, WrapperTypeObjectPrototype };
+ static const WrapperTypeInfo typeInfo = { gin::kEmbedderBlink, 0, 0, 0, 0, 0, 0, 0, WrapperTypeObjectPrototype, RefCountedObject };
return &typeInfo;
}
@@ -77,14 +77,16 @@ static NPClass V8NPObjectClass = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
-static v8::Local<v8::Context> toV8Context(NPP npp, NPObject* npObject)
+static ScriptState* mainWorldScriptState(v8::Isolate* isolate, NPP npp, NPObject* npObject)
{
ASSERT(npObject->_class == &V8NPObjectClass);
V8NPObject* object = reinterpret_cast<V8NPObject*>(npObject);
- DOMWindow* window = object->rootObject;
+ LocalDOMWindow* window = object->rootObject;
if (!window || !window->isCurrentlyDisplayedInFrame())
- return v8::Local<v8::Context>();
- return ScriptController::mainWorldContext(object->rootObject->frame());
+ return 0;
+ v8::HandleScope handleScope(isolate);
+ v8::Handle<v8::Context> context = toV8Context(object->rootObject->frame(), DOMWrapperWorld::mainWorld());
+ return ScriptState::from(context);
}
static PassOwnPtr<v8::Handle<v8::Value>[]> createValueListFromVariantArgs(const NPVariant* arguments, uint32_t argumentCount, NPObject* owner, v8::Isolate* isolate)
@@ -114,7 +116,7 @@ NPObject* v8ObjectToNPObject(v8::Handle<v8::Object> object)
return reinterpret_cast<NPObject*>(object->GetAlignedPointerFromInternalField(v8DOMWrapperObjectIndex));
}
-NPObject* npCreateV8ScriptObject(NPP npp, v8::Handle<v8::Object> object, DOMWindow* root, v8::Isolate* isolate)
+NPObject* npCreateV8ScriptObject(NPP npp, v8::Handle<v8::Object> object, LocalDOMWindow* root, v8::Isolate* isolate)
{
// Check to see if this object is already wrapped.
if (object->InternalFieldCount() == npObjectInternalFieldCount) {
@@ -141,10 +143,10 @@ NPObject* npCreateV8ScriptObject(NPP npp, v8::Handle<v8::Object> object, DOMWind
return reinterpret_cast<NPObject*>(v8npObject);
}
}
+ objectVector = &iter->value;
} else {
- iter = v8NPObjectMap->set(v8ObjectHash, V8NPObjectVector()).iterator;
+ objectVector = &v8NPObjectMap->set(v8ObjectHash, V8NPObjectVector()).storedValue->value;
}
- objectVector = &iter->value;
}
V8NPObject* v8npObject = reinterpret_cast<V8NPObject*>(_NPN_CreateObject(npp, &V8NPObjectClass));
@@ -230,13 +232,12 @@ bool _NPN_Invoke(NPP npp, NPObject* npObject, NPIdentifier methodName, const NPV
return _NPN_Evaluate(npp, npObject, const_cast<NPString*>(&arguments[0].value.stringValue), result);
}
- v8::HandleScope handleScope(isolate);
// FIXME: should use the plugin's owner frame as the security context.
- v8::Handle<v8::Context> context = toV8Context(npp, npObject);
- if (context.IsEmpty())
+ ScriptState* scriptState = mainWorldScriptState(isolate, npp, npObject);
+ if (!scriptState)
return false;
- v8::Context::Scope scope(context);
+ ScriptState::Scope scope(scriptState);
ExceptionCatcher exceptionCatcher;
v8::Handle<v8::Object> v8Object = v8::Local<v8::Object>::New(isolate, v8NpObject->v8Object);
@@ -250,7 +251,7 @@ bool _NPN_Invoke(NPP npp, NPObject* npObject, NPIdentifier methodName, const NPV
return false;
}
- Frame* frame = v8NpObject->rootObject->frame();
+ LocalFrame* frame = v8NpObject->rootObject->frame();
ASSERT(frame);
// Call the function object.
@@ -286,12 +287,11 @@ bool _NPN_InvokeDefault(NPP npp, NPObject* npObject, const NPVariant* arguments,
VOID_TO_NPVARIANT(*result);
- v8::HandleScope handleScope(isolate);
- v8::Handle<v8::Context> context = toV8Context(npp, npObject);
- if (context.IsEmpty())
+ ScriptState* scriptState = mainWorldScriptState(isolate, npp, npObject);
+ if (!scriptState)
return false;
- v8::Context::Scope scope(context);
+ ScriptState::Scope scope(scriptState);
ExceptionCatcher exceptionCatcher;
// Lookup the function object and call it.
@@ -302,7 +302,7 @@ bool _NPN_InvokeDefault(NPP npp, NPObject* npObject, const NPVariant* arguments,
v8::Local<v8::Value> resultObject;
v8::Handle<v8::Function> function = v8::Local<v8::Function>::Cast(functionObject);
if (!function->IsNull()) {
- Frame* frame = v8NpObject->rootObject->frame();
+ LocalFrame* frame = v8NpObject->rootObject->frame();
ASSERT(frame);
OwnPtr<v8::Handle<v8::Value>[]> argv = createValueListFromVariantArgs(arguments, argumentCount, npObject, isolate);
@@ -335,12 +335,11 @@ bool _NPN_EvaluateHelper(NPP npp, bool popupsAllowed, NPObject* npObject, NPStri
return false;
v8::Isolate* isolate = v8::Isolate::GetCurrent();
- v8::HandleScope handleScope(isolate);
- v8::Handle<v8::Context> context = toV8Context(npp, npObject);
- if (context.IsEmpty())
+ ScriptState* scriptState = mainWorldScriptState(isolate, npp, npObject);
+ if (!scriptState)
return false;
- v8::Context::Scope scope(context);
+ ScriptState::Scope scope(scriptState);
ExceptionCatcher exceptionCatcher;
// FIXME: Is this branch still needed after switching to using UserGestureIndicator?
@@ -348,13 +347,13 @@ bool _NPN_EvaluateHelper(NPP npp, bool popupsAllowed, NPObject* npObject, NPStri
if (!popupsAllowed)
filename = "npscript";
- Frame* frame = v8NpObject->rootObject->frame();
+ LocalFrame* frame = v8NpObject->rootObject->frame();
ASSERT(frame);
String script = String::fromUTF8(npScript->UTF8Characters, npScript->UTF8Length);
UserGestureIndicator gestureIndicator(popupsAllowed ? DefinitelyProcessingNewUserGesture : PossiblyProcessingUserGesture);
- v8::Local<v8::Value> v8result = frame->script().executeScriptAndReturnValue(context, ScriptSourceCode(script, KURL(ParsedURLString, filename)));
+ v8::Local<v8::Value> v8result = frame->script().executeScriptAndReturnValue(scriptState->context(), ScriptSourceCode(script, KURL(ParsedURLString, filename)));
if (v8result.IsEmpty())
return false;
@@ -371,12 +370,11 @@ bool _NPN_GetProperty(NPP npp, NPObject* npObject, NPIdentifier propertyName, NP
if (V8NPObject* object = npObjectToV8NPObject(npObject)) {
v8::Isolate* isolate = v8::Isolate::GetCurrent();
- v8::HandleScope handleScope(isolate);
- v8::Handle<v8::Context> context = toV8Context(npp, npObject);
- if (context.IsEmpty())
+ ScriptState* scriptState = mainWorldScriptState(isolate, npp, npObject);
+ if (!scriptState)
return false;
- v8::Context::Scope scope(context);
+ ScriptState::Scope scope(scriptState);
ExceptionCatcher exceptionCatcher;
v8::Handle<v8::Object> obj = v8::Local<v8::Object>::New(isolate, object->v8Object);
@@ -405,16 +403,15 @@ bool _NPN_SetProperty(NPP npp, NPObject* npObject, NPIdentifier propertyName, co
if (V8NPObject* object = npObjectToV8NPObject(npObject)) {
v8::Isolate* isolate = v8::Isolate::GetCurrent();
- v8::HandleScope handleScope(isolate);
- v8::Handle<v8::Context> context = toV8Context(npp, npObject);
- if (context.IsEmpty())
+ ScriptState* scriptState = mainWorldScriptState(isolate, npp, npObject);
+ if (!scriptState)
return false;
- v8::Context::Scope scope(context);
+ ScriptState::Scope scope(scriptState);
ExceptionCatcher exceptionCatcher;
v8::Handle<v8::Object> obj = v8::Local<v8::Object>::New(isolate, object->v8Object);
- obj->Set(npIdentifierToV8Identifier(propertyName, context->GetIsolate()), convertNPVariantToV8Object(value, object->rootObject->frame()->script().windowScriptNPObject(), context->GetIsolate()));
+ obj->Set(npIdentifierToV8Identifier(propertyName, isolate), convertNPVariantToV8Object(value, object->rootObject->frame()->script().windowScriptNPObject(), isolate));
return true;
}
@@ -434,11 +431,10 @@ bool _NPN_RemoveProperty(NPP npp, NPObject* npObject, NPIdentifier propertyName)
return false;
v8::Isolate* isolate = v8::Isolate::GetCurrent();
- v8::HandleScope handleScope(isolate);
- v8::Handle<v8::Context> context = toV8Context(npp, npObject);
- if (context.IsEmpty())
+ ScriptState* scriptState = mainWorldScriptState(isolate, npp, npObject);
+ if (!scriptState)
return false;
- v8::Context::Scope scope(context);
+ ScriptState::Scope scope(scriptState);
ExceptionCatcher exceptionCatcher;
v8::Handle<v8::Object> obj = v8::Local<v8::Object>::New(isolate, object->v8Object);
@@ -454,11 +450,10 @@ bool _NPN_HasProperty(NPP npp, NPObject* npObject, NPIdentifier propertyName)
if (V8NPObject* object = npObjectToV8NPObject(npObject)) {
v8::Isolate* isolate = v8::Isolate::GetCurrent();
- v8::HandleScope handleScope(isolate);
- v8::Handle<v8::Context> context = toV8Context(npp, npObject);
- if (context.IsEmpty())
+ ScriptState* scriptState = mainWorldScriptState(isolate, npp, npObject);
+ if (!scriptState)
return false;
- v8::Context::Scope scope(context);
+ ScriptState::Scope scope(scriptState);
ExceptionCatcher exceptionCatcher;
v8::Handle<v8::Object> obj = v8::Local<v8::Object>::New(isolate, object->v8Object);
@@ -477,11 +472,10 @@ bool _NPN_HasMethod(NPP npp, NPObject* npObject, NPIdentifier methodName)
if (V8NPObject* object = npObjectToV8NPObject(npObject)) {
v8::Isolate* isolate = v8::Isolate::GetCurrent();
- v8::HandleScope handleScope(isolate);
- v8::Handle<v8::Context> context = toV8Context(npp, npObject);
- if (context.IsEmpty())
+ ScriptState* scriptState = mainWorldScriptState(isolate, npp, npObject);
+ if (!scriptState)
return false;
- v8::Context::Scope scope(context);
+ ScriptState::Scope scope(scriptState);
ExceptionCatcher exceptionCatcher;
v8::Handle<v8::Object> obj = v8::Local<v8::Object>::New(isolate, object->v8Object);
@@ -503,15 +497,15 @@ void _NPN_SetException(NPObject* npObject, const NPUTF8 *message)
return;
}
- v8::HandleScope handleScope(v8::Isolate::GetCurrent());
- v8::Handle<v8::Context> context = toV8Context(0, npObject);
- if (context.IsEmpty())
+ v8::Isolate* isolate = v8::Isolate::GetCurrent();
+ ScriptState* scriptState = mainWorldScriptState(isolate, 0, npObject);
+ if (!scriptState)
return;
- v8::Context::Scope scope(context);
+ ScriptState::Scope scope(scriptState);
ExceptionCatcher exceptionCatcher;
- throwError(v8GeneralError, message, context->GetIsolate());
+ throwError(v8GeneralError, message, isolate);
}
bool _NPN_Enumerate(NPP npp, NPObject* npObject, NPIdentifier** identifier, uint32_t* count)
@@ -521,11 +515,10 @@ bool _NPN_Enumerate(NPP npp, NPObject* npObject, NPIdentifier** identifier, uint
if (V8NPObject* object = npObjectToV8NPObject(npObject)) {
v8::Isolate* isolate = v8::Isolate::GetCurrent();
- v8::HandleScope handleScope(isolate);
- v8::Local<v8::Context> context = toV8Context(npp, npObject);
- if (context.IsEmpty())
+ ScriptState* scriptState = mainWorldScriptState(isolate, npp, npObject);
+ if (!scriptState)
return false;
- v8::Context::Scope scope(context);
+ ScriptState::Scope scope(scriptState);
ExceptionCatcher exceptionCatcher;
v8::Handle<v8::Object> obj = v8::Local<v8::Object>::New(isolate, object->v8Object);
@@ -542,22 +535,22 @@ bool _NPN_Enumerate(NPP npp, NPObject* npObject, NPIdentifier** identifier, uint
" }"
" return props;"
"});";
- v8::Handle<v8::String> source = v8::String::NewFromUtf8(isolate, enumeratorCode);
- v8::Handle<v8::Value> result = V8ScriptRunner::compileAndRunInternalScript(source, context->GetIsolate());
+ v8::Handle<v8::String> source = v8AtomicString(isolate, enumeratorCode);
+ v8::Handle<v8::Value> result = V8ScriptRunner::compileAndRunInternalScript(source, isolate);
ASSERT(!result.IsEmpty());
ASSERT(result->IsFunction());
v8::Handle<v8::Function> enumerator = v8::Handle<v8::Function>::Cast(result);
v8::Handle<v8::Value> argv[] = { obj };
- v8::Local<v8::Value> propsObj = V8ScriptRunner::callInternalFunction(enumerator, v8::Handle<v8::Object>::Cast(result), WTF_ARRAY_LENGTH(argv), argv, context->GetIsolate());
+ v8::Local<v8::Value> propsObj = V8ScriptRunner::callInternalFunction(enumerator, v8::Handle<v8::Object>::Cast(result), WTF_ARRAY_LENGTH(argv), argv, isolate);
if (propsObj.IsEmpty())
return false;
// Convert the results into an array of NPIdentifiers.
v8::Handle<v8::Array> props = v8::Handle<v8::Array>::Cast(propsObj);
*count = props->Length();
- *identifier = static_cast<NPIdentifier*>(malloc(sizeof(NPIdentifier*) * *count));
+ *identifier = static_cast<NPIdentifier*>(calloc(*count, sizeof(NPIdentifier)));
for (uint32_t i = 0; i < *count; ++i) {
- v8::Local<v8::Value> name = props->Get(v8::Integer::New(i, context->GetIsolate()));
+ v8::Local<v8::Value> name = props->Get(v8::Integer::New(isolate, i));
(*identifier)[i] = getStringIdentifier(v8::Local<v8::String>::Cast(name));
}
return true;
@@ -577,11 +570,10 @@ bool _NPN_Construct(NPP npp, NPObject* npObject, const NPVariant* arguments, uin
v8::Isolate* isolate = v8::Isolate::GetCurrent();
if (V8NPObject* object = npObjectToV8NPObject(npObject)) {
- v8::HandleScope handleScope(isolate);
- v8::Handle<v8::Context> context = toV8Context(npp, npObject);
- if (context.IsEmpty())
+ ScriptState* scriptState = mainWorldScriptState(isolate, npp, npObject);
+ if (!scriptState)
return false;
- v8::Context::Scope scope(context);
+ ScriptState::Scope scope(scriptState);
ExceptionCatcher exceptionCatcher;
// Lookup the constructor function.
@@ -593,10 +585,10 @@ bool _NPN_Construct(NPP npp, NPObject* npObject, const NPVariant* arguments, uin
v8::Local<v8::Value> resultObject;
v8::Handle<v8::Function> ctor = v8::Handle<v8::Function>::Cast(ctorObj);
if (!ctor->IsNull()) {
- Frame* frame = object->rootObject->frame();
+ LocalFrame* frame = object->rootObject->frame();
ASSERT(frame);
OwnPtr<v8::Handle<v8::Value>[]> argv = createValueListFromVariantArgs(arguments, argumentCount, npObject, isolate);
- resultObject = V8ObjectConstructor::newInstanceInDocument(ctor, argumentCount, argv.get(), frame ? frame->document() : 0);
+ resultObject = V8ObjectConstructor::newInstanceInDocument(isolate, ctor, argumentCount, argv.get(), frame ? frame->document() : 0);
}
if (resultObject.IsEmpty())
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/NPV8Object.h b/chromium/third_party/WebKit/Source/bindings/v8/NPV8Object.h
index 435f778d151..3e7db341956 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/NPV8Object.h
+++ b/chromium/third_party/WebKit/Source/bindings/v8/NPV8Object.h
@@ -39,7 +39,7 @@
namespace WebCore {
-class DOMWindow;
+class LocalDOMWindow;
static const int npObjectInternalFieldCount = v8DefaultWrapperInternalFieldCount + 0;
@@ -53,7 +53,7 @@ struct V8NPObject {
public:
NPObject object;
v8::Persistent<v8::Object> v8Object;
- DOMWindow* rootObject;
+ LocalDOMWindow* rootObject;
};
struct PrivateIdentifier {
@@ -64,7 +64,7 @@ struct PrivateIdentifier {
bool isString;
};
-NPObject* npCreateV8ScriptObject(NPP, v8::Handle<v8::Object>, DOMWindow*, v8::Isolate*);
+NPObject* npCreateV8ScriptObject(NPP, v8::Handle<v8::Object>, LocalDOMWindow*, v8::Isolate*);
NPObject* v8ObjectToNPObject(v8::Handle<v8::Object>);
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/Nullable.h b/chromium/third_party/WebKit/Source/bindings/v8/Nullable.h
new file mode 100644
index 00000000000..0f8356c472d
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/bindings/v8/Nullable.h
@@ -0,0 +1,51 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef Nullable_h
+#define Nullable_h
+
+#include "wtf/Assertions.h"
+
+namespace WebCore {
+
+template <typename T>
+class Nullable {
+public:
+ Nullable()
+ : m_value()
+ , m_isNull(true) { }
+
+ Nullable(const T& value)
+ : m_value(value)
+ , m_isNull(false) { }
+
+ Nullable(const Nullable& other)
+ : m_value(other.m_value)
+ , m_isNull(other.m_isNull) { }
+
+ Nullable& operator=(const Nullable& other)
+ {
+ m_value = other.m_value;
+ m_isNull = other.m_isNull;
+ return *this;
+ }
+
+ T get() const { ASSERT(!m_isNull); return m_value; }
+ bool isNull() const { return m_isNull; }
+
+ operator bool() const { return !m_isNull && m_value; }
+
+ bool operator==(const Nullable& other) const
+ {
+ return (m_isNull && other.m_isNull) || (!m_isNull && !other.m_isNull && m_value == other.m_value);
+ }
+
+private:
+ T m_value;
+ bool m_isNull;
+};
+
+} // namespace WebCore
+
+#endif // Nullable_h
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/PageScriptDebugServer.cpp b/chromium/third_party/WebKit/Source/bindings/v8/PageScriptDebugServer.cpp
index 44a2b48a22c..5901fba1eaf 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/PageScriptDebugServer.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/PageScriptDebugServer.cpp
@@ -32,15 +32,20 @@
#include "bindings/v8/PageScriptDebugServer.h"
-#include "V8Window.h"
+#include "bindings/core/v8/V8Window.h"
+#include "bindings/v8/DOMWrapperWorld.h"
#include "bindings/v8/ScriptController.h"
#include "bindings/v8/ScriptSourceCode.h"
#include "bindings/v8/V8Binding.h"
#include "bindings/v8/V8ScriptRunner.h"
#include "bindings/v8/V8WindowShell.h"
+#include "core/frame/FrameConsole.h"
+#include "core/frame/FrameHost.h"
+#include "core/frame/LocalFrame.h"
+#include "core/frame/UseCounter.h"
#include "core/inspector/InspectorInstrumentation.h"
+#include "core/inspector/InspectorTraceEvents.h"
#include "core/inspector/ScriptDebugListener.h"
-#include "core/frame/Frame.h"
#include "core/page/Page.h"
#include "wtf/OwnPtr.h"
#include "wtf/PassOwnPtr.h"
@@ -50,17 +55,20 @@
namespace WebCore {
-static Frame* retrieveFrameWithGlobalObjectCheck(v8::Handle<v8::Context> context)
+static LocalFrame* retrieveFrameWithGlobalObjectCheck(v8::Handle<v8::Context> context)
{
if (context.IsEmpty())
return 0;
- // Test that context has associated global dom window object.
- v8::Handle<v8::Object> global = context->Global();
- if (global.IsEmpty())
+ // FIXME: This is a temporary hack for crbug.com/345014.
+ // Currently it's possible that V8 can trigger Debugger::ProcessDebugEvent for a context
+ // that is being initialized (i.e., inside Context::New() of the context).
+ // We should fix the V8 side so that it won't trigger the event for a half-baked context
+ // because there is no way in the embedder side to check if the context is half-baked or not.
+ if (isMainThread() && DOMWrapperWorld::windowIsBeingInitialized())
return 0;
- global = global->FindInstanceInPrototypeChain(V8Window::domTemplate(context->GetIsolate(), worldTypeInMainThread(context->GetIsolate())));
+ v8::Handle<v8::Value> global = V8Window::findInstanceInPrototypeChain(context->Global(), context->GetIsolate());
if (global.IsEmpty())
return 0;
@@ -82,31 +90,44 @@ PageScriptDebugServer& PageScriptDebugServer::shared()
return server;
}
+v8::Isolate* PageScriptDebugServer::s_mainThreadIsolate = 0;
+
+void PageScriptDebugServer::setMainThreadIsolate(v8::Isolate* isolate)
+{
+ s_mainThreadIsolate = isolate;
+}
+
PageScriptDebugServer::PageScriptDebugServer()
- : ScriptDebugServer(v8::Isolate::GetCurrent())
+ : ScriptDebugServer(s_mainThreadIsolate)
, m_pausedPage(0)
{
}
+PageScriptDebugServer::~PageScriptDebugServer()
+{
+}
+
void PageScriptDebugServer::addListener(ScriptDebugListener* listener, Page* page)
{
- ScriptController& scriptController = page->mainFrame()->script();
+ ScriptController& scriptController = page->deprecatedLocalMainFrame()->script();
if (!scriptController.canExecuteScripts(NotAboutToExecuteScript))
return;
v8::HandleScope scope(m_isolate);
- v8::Local<v8::Context> debuggerContext = v8::Debug::GetDebugContext();
- v8::Context::Scope contextScope(debuggerContext);
- v8::Local<v8::Object> debuggerScript = m_debuggerScript.newLocal(m_isolate);
if (!m_listenersMap.size()) {
+ v8::Debug::SetDebugEventListener(&PageScriptDebugServer::v8DebugEventCallback, v8::External::New(m_isolate, this));
ensureDebuggerScriptCompiled();
- ASSERT(!debuggerScript->IsUndefined());
- v8::Debug::SetDebugEventListener2(&PageScriptDebugServer::v8DebugEventCallback, v8::External::New(m_isolate, this));
}
+
+ v8::Local<v8::Context> debuggerContext = v8::Debug::GetDebugContext();
+ v8::Context::Scope contextScope(debuggerContext);
+
+ v8::Local<v8::Object> debuggerScript = m_debuggerScript.newLocal(m_isolate);
+ ASSERT(!debuggerScript->IsUndefined());
m_listenersMap.set(page, listener);
- V8WindowShell* shell = scriptController.existingWindowShell(mainThreadNormalWorld());
+ V8WindowShell* shell = scriptController.existingWindowShell(DOMWrapperWorld::mainWorld());
if (!shell || !shell->isContextInitialized())
return;
v8::Local<v8::Context> context = shell->context();
@@ -118,7 +139,7 @@ void PageScriptDebugServer::addListener(ScriptDebugListener* listener, Page* pag
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, m_isolate))));
+ dispatchDidParseSource(listener, v8::Handle<v8::Object>::Cast(scriptsArray->Get(v8::Integer::New(m_isolate, i))));
}
void PageScriptDebugServer::removeListener(ScriptDebugListener* listener, Page* page)
@@ -131,9 +152,16 @@ void PageScriptDebugServer::removeListener(ScriptDebugListener* listener, Page*
m_listenersMap.remove(page);
- if (m_listenersMap.isEmpty())
- v8::Debug::SetDebugEventListener2(0);
- // FIXME: Remove all breakpoints set by the agent.
+ if (m_listenersMap.isEmpty()) {
+ discardDebuggerScript();
+ v8::Debug::SetDebugEventListener(0);
+ // FIXME: Remove all breakpoints set by the agent.
+ }
+}
+
+void PageScriptDebugServer::interruptAndRun(PassOwnPtr<Task> task)
+{
+ ScriptDebugServer::interruptAndRun(task, s_mainThreadIsolate);
}
void PageScriptDebugServer::setClientMessageLoop(PassOwnPtr<ClientMessageLoop> clientMessageLoop)
@@ -141,11 +169,11 @@ void PageScriptDebugServer::setClientMessageLoop(PassOwnPtr<ClientMessageLoop> c
m_clientMessageLoop = clientMessageLoop;
}
-void PageScriptDebugServer::compileScript(ScriptState* state, const String& expression, const String& sourceURL, String* scriptId, String* exceptionMessage)
+void PageScriptDebugServer::compileScript(ScriptState* scriptState, const String& expression, const String& sourceURL, String* scriptId, String* exceptionDetailsText, int* lineNumber, int* columnNumber, RefPtrWillBeRawPtr<ScriptCallStack>* stackTrace)
{
- ExecutionContext* executionContext = state->executionContext();
- RefPtr<Frame> protect = toDocument(executionContext)->frame();
- ScriptDebugServer::compileScript(state, expression, sourceURL, scriptId, exceptionMessage);
+ ExecutionContext* executionContext = scriptState->executionContext();
+ RefPtr<LocalFrame> protect = toDocument(executionContext)->frame();
+ ScriptDebugServer::compileScript(scriptState, expression, sourceURL, scriptId, exceptionDetailsText, lineNumber, columnNumber, stackTrace);
if (!scriptId->isNull())
m_compiledScriptURLs.set(*scriptId, sourceURL);
}
@@ -156,27 +184,31 @@ void PageScriptDebugServer::clearCompiledScripts()
m_compiledScriptURLs.clear();
}
-void PageScriptDebugServer::runScript(ScriptState* state, const String& scriptId, ScriptValue* result, bool* wasThrown, String* exceptionMessage)
+void PageScriptDebugServer::runScript(ScriptState* scriptState, const String& scriptId, ScriptValue* result, bool* wasThrown, String* exceptionDetailsText, int* lineNumber, int* columnNumber, RefPtrWillBeRawPtr<ScriptCallStack>* stackTrace)
{
String sourceURL = m_compiledScriptURLs.take(scriptId);
- ExecutionContext* executionContext = state->executionContext();
- Frame* frame = toDocument(executionContext)->frame();
+ ExecutionContext* executionContext = scriptState->executionContext();
+ LocalFrame* frame = toDocument(executionContext)->frame();
+ TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "EvaluateScript", "data", InspectorEvaluateScriptEvent::data(frame, sourceURL, TextPosition::minimumPosition().m_line.oneBasedInt()));
+ TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline.stack"), "CallStack", "stack", InspectorCallStackEvent::currentCallStack());
+ // FIXME(361045): remove InspectorInstrumentation calls once DevTools Timeline migrates to tracing.
InspectorInstrumentationCookie cookie;
if (frame)
cookie = InspectorInstrumentation::willEvaluateScript(frame, sourceURL, TextPosition::minimumPosition().m_line.oneBasedInt());
- RefPtr<Frame> protect = frame;
- ScriptDebugServer::runScript(state, scriptId, result, wasThrown, exceptionMessage);
+ RefPtr<LocalFrame> protect = frame;
+ ScriptDebugServer::runScript(scriptState, scriptId, result, wasThrown, exceptionDetailsText, lineNumber, columnNumber, stackTrace);
if (frame)
InspectorInstrumentation::didEvaluateScript(cookie);
+ TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "UpdateCounters", "data", InspectorUpdateCountersEvent::data());
}
ScriptDebugListener* PageScriptDebugServer::getDebugListenerForContext(v8::Handle<v8::Context> context)
{
v8::HandleScope scope(m_isolate);
- Frame* frame = retrieveFrameWithGlobalObjectCheck(context);
+ LocalFrame* frame = retrieveFrameWithGlobalObjectCheck(context);
if (!frame)
return 0;
return m_listenersMap.get(frame->page());
@@ -185,7 +217,7 @@ ScriptDebugListener* PageScriptDebugServer::getDebugListenerForContext(v8::Handl
void PageScriptDebugServer::runMessageLoopOnPause(v8::Handle<v8::Context> context)
{
v8::HandleScope scope(m_isolate);
- Frame* frame = retrieveFrameWithGlobalObjectCheck(context);
+ LocalFrame* frame = retrieveFrameWithGlobalObjectCheck(context);
m_pausedPage = frame->page();
// Wait for continue or step command.
@@ -206,7 +238,7 @@ void PageScriptDebugServer::quitMessageLoopOnPause()
void PageScriptDebugServer::preprocessBeforeCompile(const v8::Debug::EventDetails& eventDetails)
{
v8::Handle<v8::Context> eventContext = eventDetails.GetEventContext();
- Frame* frame = retrieveFrameWithGlobalObjectCheck(eventContext);
+ LocalFrame* frame = retrieveFrameWithGlobalObjectCheck(eventContext);
if (!frame)
return;
@@ -236,7 +268,7 @@ void PageScriptDebugServer::preprocessBeforeCompile(const v8::Debug::EventDetail
static bool isCreatingPreprocessor = false;
-bool PageScriptDebugServer::canPreprocess(Frame* frame)
+bool PageScriptDebugServer::canPreprocess(LocalFrame* frame)
{
ASSERT(frame);
@@ -247,7 +279,7 @@ bool PageScriptDebugServer::canPreprocess(Frame* frame)
// Web page to ensure that the debugger's console initialization code has completed.
if (!m_scriptPreprocessor) {
TemporaryChange<bool> isPreprocessing(isCreatingPreprocessor, true);
- m_scriptPreprocessor = adoptPtr(new ScriptPreprocessor(*m_preprocessorSourceCode.get(), frame->script(), frame->page()->console()));
+ m_scriptPreprocessor = adoptPtr(new ScriptPreprocessor(*m_preprocessorSourceCode.get(), frame));
}
if (m_scriptPreprocessor->isValid())
@@ -260,7 +292,7 @@ bool PageScriptDebugServer::canPreprocess(Frame* frame)
}
// Source to Source processing iff debugger enabled and it has loaded a preprocessor.
-PassOwnPtr<ScriptSourceCode> PageScriptDebugServer::preprocess(Frame* frame, const ScriptSourceCode& sourceCode)
+PassOwnPtr<ScriptSourceCode> PageScriptDebugServer::preprocess(LocalFrame* frame, const ScriptSourceCode& sourceCode)
{
if (!canPreprocess(frame))
return PassOwnPtr<ScriptSourceCode>();
@@ -269,7 +301,7 @@ PassOwnPtr<ScriptSourceCode> PageScriptDebugServer::preprocess(Frame* frame, con
return adoptPtr(new ScriptSourceCode(preprocessedSource, sourceCode.url()));
}
-String PageScriptDebugServer::preprocessEventListener(Frame* frame, const String& source, const String& url, const String& functionName)
+String PageScriptDebugServer::preprocessEventListener(LocalFrame* frame, const String& source, const String& url, const String& functionName)
{
if (!canPreprocess(frame))
return source;
@@ -277,4 +309,16 @@ String PageScriptDebugServer::preprocessEventListener(Frame* frame, const String
return m_scriptPreprocessor->preprocessSourceCode(source, url, functionName);
}
+void PageScriptDebugServer::muteWarningsAndDeprecations()
+{
+ FrameConsole::mute();
+ UseCounter::muteForInspector();
+}
+
+void PageScriptDebugServer::unmuteWarningsAndDeprecations()
+{
+ FrameConsole::unmute();
+ UseCounter::unmuteForInspector();
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/PageScriptDebugServer.h b/chromium/third_party/WebKit/Source/bindings/v8/PageScriptDebugServer.h
index 78fde09e688..96f8779f223 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/PageScriptDebugServer.h
+++ b/chromium/third_party/WebKit/Source/bindings/v8/PageScriptDebugServer.h
@@ -31,11 +31,11 @@
#ifndef PageScriptDebugServer_h
#define PageScriptDebugServer_h
-
#include "bindings/v8/ScriptDebugServer.h"
#include "bindings/v8/ScriptPreprocessor.h"
#include "wtf/Forward.h"
#include "wtf/RefCounted.h"
+#include <v8.h>
namespace WebCore {
@@ -44,14 +44,18 @@ class ScriptController;
class ScriptPreprocessor;
class ScriptSourceCode;
-class PageScriptDebugServer : public ScriptDebugServer {
+class PageScriptDebugServer FINAL : public ScriptDebugServer {
WTF_MAKE_NONCOPYABLE(PageScriptDebugServer);
public:
static PageScriptDebugServer& shared();
+ static void setMainThreadIsolate(v8::Isolate*);
+
void addListener(ScriptDebugListener*, Page*);
void removeListener(ScriptDebugListener*, Page*);
+ static void interruptAndRun(PassOwnPtr<Task>);
+
class ClientMessageLoop {
public:
virtual ~ClientMessageLoop() { }
@@ -60,21 +64,24 @@ public:
};
void setClientMessageLoop(PassOwnPtr<ClientMessageLoop>);
- virtual void compileScript(ScriptState*, const String& expression, const String& sourceURL, String* scriptId, String* exceptionMessage);
- virtual void clearCompiledScripts();
- virtual void runScript(ScriptState*, const String& scriptId, ScriptValue* result, bool* wasThrown, String* exceptionMessage);
- virtual void setPreprocessorSource(const String&);
- virtual void preprocessBeforeCompile(const v8::Debug::EventDetails&);
- virtual PassOwnPtr<ScriptSourceCode> preprocess(Frame*, const ScriptSourceCode&);
- virtual String preprocessEventListener(Frame*, const String& source, const String& url, const String& functionName);
+ virtual void compileScript(ScriptState*, const String& expression, const String& sourceURL, String* scriptId, String* exceptionDetailsText, int* lineNumber, int* columnNumber, RefPtrWillBeRawPtr<ScriptCallStack>* stackTrace) OVERRIDE;
+ virtual void clearCompiledScripts() OVERRIDE;
+ virtual void runScript(ScriptState*, const String& scriptId, ScriptValue* result, bool* wasThrown, String* exceptionDetailsText, int* lineNumber, int* columnNumber, RefPtrWillBeRawPtr<ScriptCallStack>* stackTrace) OVERRIDE;
+ virtual void setPreprocessorSource(const String&) OVERRIDE;
+ virtual void preprocessBeforeCompile(const v8::Debug::EventDetails&) OVERRIDE;
+ virtual PassOwnPtr<ScriptSourceCode> preprocess(LocalFrame*, const ScriptSourceCode&) OVERRIDE;
+ virtual String preprocessEventListener(LocalFrame*, const String& source, const String& url, const String& functionName) OVERRIDE;
+
+ virtual void muteWarningsAndDeprecations() OVERRIDE;
+ virtual void unmuteWarningsAndDeprecations() OVERRIDE;
private:
PageScriptDebugServer();
- virtual ~PageScriptDebugServer() { }
+ virtual ~PageScriptDebugServer();
- virtual ScriptDebugListener* getDebugListenerForContext(v8::Handle<v8::Context>);
- virtual void runMessageLoopOnPause(v8::Handle<v8::Context>);
- virtual void quitMessageLoopOnPause();
+ virtual ScriptDebugListener* getDebugListenerForContext(v8::Handle<v8::Context>) OVERRIDE;
+ virtual void runMessageLoopOnPause(v8::Handle<v8::Context>) OVERRIDE;
+ virtual void quitMessageLoopOnPause() OVERRIDE;
typedef HashMap<Page*, ScriptDebugListener*> ListenersMap;
ListenersMap m_listenersMap;
@@ -84,7 +91,8 @@ private:
OwnPtr<ScriptSourceCode> m_preprocessorSourceCode;
OwnPtr<ScriptPreprocessor> m_scriptPreprocessor;
- bool canPreprocess(Frame*);
+ bool canPreprocess(LocalFrame*);
+ static v8::Isolate* s_mainThreadIsolate;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/RetainedDOMInfo.h b/chromium/third_party/WebKit/Source/bindings/v8/RetainedDOMInfo.h
index 52709997cfc..2138c0b9937 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/RetainedDOMInfo.h
+++ b/chromium/third_party/WebKit/Source/bindings/v8/RetainedDOMInfo.h
@@ -32,23 +32,24 @@
#define RetainedDOMInfo_h
#include "bindings/v8/RetainedObjectInfo.h"
+#include <v8-profiler.h>
namespace WebCore {
class Node;
// Implements v8::RetainedObjectInfo.
-class RetainedDOMInfo : public RetainedObjectInfo {
+class RetainedDOMInfo FINAL : public RetainedObjectInfo {
public:
explicit RetainedDOMInfo(Node* root);
virtual ~RetainedDOMInfo();
- virtual void Dispose();
- virtual bool IsEquivalent(v8::RetainedObjectInfo* other);
- virtual intptr_t GetHash();
- virtual const char* GetGroupLabel();
- virtual const char* GetLabel();
- virtual intptr_t GetElementCount();
- virtual intptr_t GetEquivalenceClass();
+ virtual void Dispose() OVERRIDE;
+ virtual bool IsEquivalent(v8::RetainedObjectInfo* other) OVERRIDE;
+ virtual intptr_t GetHash() OVERRIDE;
+ virtual const char* GetGroupLabel() OVERRIDE;
+ virtual const char* GetLabel() OVERRIDE;
+ virtual intptr_t GetElementCount() OVERRIDE;
+ virtual intptr_t GetEquivalenceClass() OVERRIDE;
private:
// V8 guarantees to keep RetainedObjectInfos alive only during a GC or heap snapshotting round, when renderer
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/ScheduledAction.cpp b/chromium/third_party/WebKit/Source/bindings/v8/ScheduledAction.cpp
index 1de2039ec15..0f669f310e8 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/ScheduledAction.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/ScheduledAction.cpp
@@ -38,41 +38,39 @@
#include "bindings/v8/V8ScriptRunner.h"
#include "core/dom/Document.h"
#include "core/dom/ExecutionContext.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
#include "core/workers/WorkerGlobalScope.h"
#include "core/workers/WorkerThread.h"
#include "platform/TraceEvent.h"
namespace WebCore {
-ScheduledAction::ScheduledAction(v8::Handle<v8::Context> context, v8::Handle<v8::Function> function, int argc, v8::Handle<v8::Value> argv[], v8::Isolate* isolate)
- : m_context(isolate, context)
+ScheduledAction::ScheduledAction(ScriptState* scriptState, v8::Handle<v8::Function> function, int argc, v8::Handle<v8::Value> argv[], v8::Isolate* isolate)
+ : m_scriptState(scriptState)
, m_function(isolate, function)
+ , m_info(isolate)
, m_code(String(), KURL(), TextPosition::belowRangePosition())
- , m_isolate(isolate)
{
- m_info.reserveCapacity(argc);
+ m_info.ReserveCapacity(argc);
for (int i = 0; i < argc; ++i)
- m_info.append(UnsafePersistent<v8::Value>(m_isolate, argv[i]));
+ m_info.Append(argv[i]);
}
-ScheduledAction::ScheduledAction(v8::Handle<v8::Context> context, const String& code, const KURL& url, v8::Isolate* isolate)
- : m_context(isolate, context)
+ScheduledAction::ScheduledAction(ScriptState* scriptState, const String& code, const KURL& url, v8::Isolate* isolate)
+ : m_scriptState(scriptState)
+ , m_info(isolate)
, m_code(code, url)
- , m_isolate(isolate)
{
}
ScheduledAction::~ScheduledAction()
{
- for (size_t i = 0; i < m_info.size(); ++i)
- m_info[i].dispose();
}
void ScheduledAction::execute(ExecutionContext* context)
{
if (context->isDocument()) {
- Frame* frame = toDocument(context)->frame();
+ LocalFrame* frame = toDocument(context)->frame();
if (!frame)
return;
if (!frame->script().canExecuteScripts(AboutToExecuteScript))
@@ -83,23 +81,19 @@ void ScheduledAction::execute(ExecutionContext* context)
}
}
-void ScheduledAction::execute(Frame* frame)
+void ScheduledAction::execute(LocalFrame* frame)
{
- v8::HandleScope handleScope(m_isolate);
-
- v8::Handle<v8::Context> context = m_context.newLocal(m_isolate);
- if (context.IsEmpty())
+ if (m_scriptState->contextIsEmpty())
return;
TRACE_EVENT0("v8", "ScheduledAction::execute");
-
+ ScriptState::Scope scope(m_scriptState.get());
if (!m_function.isEmpty()) {
- v8::Context::Scope scope(context);
Vector<v8::Handle<v8::Value> > info;
createLocalHandlesForArgs(&info);
- frame->script().callFunction(m_function.newLocal(m_isolate), context->Global(), info.size(), info.data());
+ frame->script().callFunction(m_function.newLocal(m_scriptState->isolate()), m_scriptState->context()->Global(), info.size(), info.data());
} else {
- frame->script().executeScriptAndReturnValue(context, ScriptSourceCode(m_code));
+ frame->script().executeScriptAndReturnValue(m_scriptState->context(), ScriptSourceCode(m_code));
}
// The frame might be invalid at this point because JavaScript could have released it.
@@ -108,23 +102,22 @@ void ScheduledAction::execute(Frame* frame)
void ScheduledAction::execute(WorkerGlobalScope* worker)
{
ASSERT(worker->thread()->isCurrentThread());
- v8::HandleScope handleScope(m_isolate);
- v8::Handle<v8::Context> context = m_context.newLocal(m_isolate);
- ASSERT(!context.IsEmpty());
- v8::Context::Scope scope(context);
+ ASSERT(!m_scriptState->contextIsEmpty());
if (!m_function.isEmpty()) {
+ ScriptState::Scope scope(m_scriptState.get());
Vector<v8::Handle<v8::Value> > info;
createLocalHandlesForArgs(&info);
- V8ScriptRunner::callFunction(m_function.newLocal(m_isolate), worker, context->Global(), info.size(), info.data(), m_isolate);
- } else
+ V8ScriptRunner::callFunction(m_function.newLocal(m_scriptState->isolate()), worker, m_scriptState->context()->Global(), info.size(), info.data(), m_scriptState->isolate());
+ } else {
worker->script()->evaluate(m_code);
+ }
}
void ScheduledAction::createLocalHandlesForArgs(Vector<v8::Handle<v8::Value> >* handles)
{
- handles->reserveCapacity(m_info.size());
- for (size_t i = 0; i < m_info.size(); ++i)
- handles->append(m_info[i].newLocal(m_isolate));
+ handles->reserveCapacity(m_info.Size());
+ for (size_t i = 0; i < m_info.Size(); ++i)
+ handles->append(m_info.Get(i));
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/ScheduledAction.h b/chromium/third_party/WebKit/Source/bindings/v8/ScheduledAction.h
index 9b03a027305..351ef3bed7e 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/ScheduledAction.h
+++ b/chromium/third_party/WebKit/Source/bindings/v8/ScheduledAction.h
@@ -33,36 +33,35 @@
#include "bindings/v8/ScopedPersistent.h"
#include "bindings/v8/ScriptSourceCode.h"
-#include "bindings/v8/UnsafePersistent.h"
+#include "bindings/v8/ScriptState.h"
+#include "bindings/v8/V8PersistentValueVector.h"
#include <v8.h>
#include "wtf/Forward.h"
-#include "wtf/Vector.h"
namespace WebCore {
-class Frame;
+class LocalFrame;
class ExecutionContext;
class WorkerGlobalScope;
class ScheduledAction {
WTF_MAKE_NONCOPYABLE(ScheduledAction);
public:
- ScheduledAction(v8::Handle<v8::Context>, v8::Handle<v8::Function>, int argc, v8::Handle<v8::Value> argv[], v8::Isolate*);
- ScheduledAction(v8::Handle<v8::Context>, const String&, const KURL&, v8::Isolate*);
+ ScheduledAction(ScriptState*, v8::Handle<v8::Function>, int argc, v8::Handle<v8::Value> argv[], v8::Isolate*);
+ ScheduledAction(ScriptState*, const String&, const KURL&, v8::Isolate*);
~ScheduledAction();
void execute(ExecutionContext*);
private:
- void execute(Frame*);
+ void execute(LocalFrame*);
void execute(WorkerGlobalScope*);
void createLocalHandlesForArgs(Vector<v8::Handle<v8::Value> >* handles);
- ScopedPersistent<v8::Context> m_context;
+ ScriptStateProtectingContext m_scriptState;
ScopedPersistent<v8::Function> m_function;
- Vector<UnsafePersistent<v8::Value> > m_info;
+ V8PersistentValueVector<v8::Value> m_info;
ScriptSourceCode m_code;
- v8::Isolate* m_isolate;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/ScopedPersistent.h b/chromium/third_party/WebKit/Source/bindings/v8/ScopedPersistent.h
index 84b6beea6ce..a383f780c37 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/ScopedPersistent.h
+++ b/chromium/third_party/WebKit/Source/bindings/v8/ScopedPersistent.h
@@ -64,6 +64,7 @@ public:
}
bool isEmpty() const { return m_handle.IsEmpty(); }
+ bool isWeak() const { return m_handle.IsWeak(); }
void set(v8::Isolate* isolate, v8::Handle<T> handle)
{
@@ -81,6 +82,12 @@ public:
return m_handle == other.m_handle;
}
+ template <class S>
+ bool operator==(const v8::Handle<S> other) const
+ {
+ return m_handle == other;
+ }
+
private:
// FIXME: This function does an unsafe handle access. Remove it.
friend class V8AbstractEventListener;
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/ScriptCallStackFactory.cpp b/chromium/third_party/WebKit/Source/bindings/v8/ScriptCallStackFactory.cpp
index 81dea4584c6..8c68a9ddd4a 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/ScriptCallStackFactory.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/ScriptCallStackFactory.cpp
@@ -31,10 +31,8 @@
#include "config.h"
#include "bindings/v8/ScriptCallStackFactory.h"
-#include "bindings/v8/ScriptScope.h"
#include "bindings/v8/ScriptValue.h"
#include "bindings/v8/V8Binding.h"
-#include "bindings/v8/V8Utilities.h"
#include "core/inspector/InspectorInstrumentation.h"
#include "core/inspector/ScriptArguments.h"
#include "core/inspector/ScriptCallFrame.h"
@@ -86,7 +84,7 @@ static void toScriptCallFramesVector(v8::Handle<v8::StackTrace> stackTrace, Vect
}
}
-static PassRefPtr<ScriptCallStack> createScriptCallStack(v8::Handle<v8::StackTrace> stackTrace, size_t maxStackSize, bool emptyStackIsAllowed, v8::Isolate* isolate)
+static PassRefPtrWillBeRawPtr<ScriptCallStack> createScriptCallStack(v8::Handle<v8::StackTrace> stackTrace, size_t maxStackSize, bool emptyStackIsAllowed, v8::Isolate* isolate)
{
ASSERT(isolate->InContext());
v8::HandleScope scope(isolate);
@@ -95,44 +93,38 @@ static PassRefPtr<ScriptCallStack> createScriptCallStack(v8::Handle<v8::StackTra
return ScriptCallStack::create(scriptCallFrames);
}
-PassRefPtr<ScriptCallStack> createScriptCallStack(v8::Handle<v8::StackTrace> stackTrace, size_t maxStackSize, v8::Isolate* isolate)
+PassRefPtrWillBeRawPtr<ScriptCallStack> createScriptCallStack(v8::Handle<v8::StackTrace> stackTrace, size_t maxStackSize, v8::Isolate* isolate)
{
return createScriptCallStack(stackTrace, maxStackSize, true, isolate);
}
-PassRefPtr<ScriptCallStack> createScriptCallStack(size_t maxStackSize, bool emptyStackIsAllowed)
+PassRefPtrWillBeRawPtr<ScriptCallStack> createScriptCallStack(size_t maxStackSize, bool emptyStackIsAllowed)
{
v8::Isolate* isolate = v8::Isolate::GetCurrent();
if (!isolate->InContext())
- return 0;
+ return nullptr;
v8::HandleScope handleScope(isolate);
v8::Handle<v8::StackTrace> stackTrace(v8::StackTrace::CurrentStackTrace(isolate, maxStackSize, stackTraceOptions));
return createScriptCallStack(stackTrace, maxStackSize, emptyStackIsAllowed, isolate);
}
-PassRefPtr<ScriptCallStack> createScriptCallStackForConsole(size_t maxStackSize)
+PassRefPtrWillBeRawPtr<ScriptCallStack> createScriptCallStackForConsole(ScriptState* scriptState, size_t maxStackSize)
{
size_t stackSize = 1;
if (InspectorInstrumentation::hasFrontends()) {
- ExecutionContext* executionContext = getExecutionContext();
- if (InspectorInstrumentation::consoleAgentEnabled(executionContext))
+ if (InspectorInstrumentation::consoleAgentEnabled(scriptState->executionContext()))
stackSize = maxStackSize;
}
return createScriptCallStack(stackSize);
}
-PassRefPtr<ScriptArguments> createScriptArguments(const v8::FunctionCallbackInfo<v8::Value>& v8arguments, unsigned skipArgumentCount)
+PassRefPtrWillBeRawPtr<ScriptArguments> createScriptArguments(ScriptState* scriptState, const v8::FunctionCallbackInfo<v8::Value>& v8arguments, unsigned skipArgumentCount)
{
- v8::Isolate* isolate = v8arguments.GetIsolate();
- v8::HandleScope scope(isolate);
- v8::Local<v8::Context> context = isolate->GetCurrentContext();
- ScriptState* state = ScriptState::forContext(context);
-
Vector<ScriptValue> arguments;
for (int i = skipArgumentCount; i < v8arguments.Length(); ++i)
- arguments.append(ScriptValue(v8arguments[i], isolate));
+ arguments.append(ScriptValue(scriptState, v8arguments[i]));
- return ScriptArguments::create(state, arguments);
+ return ScriptArguments::create(scriptState, arguments);
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/ScriptCallStackFactory.h b/chromium/third_party/WebKit/Source/bindings/v8/ScriptCallStackFactory.h
index ff225e30714..6654b67aab6 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/ScriptCallStackFactory.h
+++ b/chromium/third_party/WebKit/Source/bindings/v8/ScriptCallStackFactory.h
@@ -48,10 +48,10 @@ const v8::StackTrace::StackTraceOptions stackTraceOptions = static_cast<v8::Stac
| v8::StackTrace::kScriptNameOrSourceURL
| v8::StackTrace::kFunctionName);
-PassRefPtr<ScriptCallStack> createScriptCallStack(v8::Handle<v8::StackTrace>, size_t maxStackSize, v8::Isolate*);
-PassRefPtr<ScriptCallStack> createScriptCallStack(size_t maxStackSize, bool emptyStackIsAllowed = false);
-PassRefPtr<ScriptCallStack> createScriptCallStackForConsole(size_t maxStackSize = ScriptCallStack::maxCallStackSizeToCapture);
-PassRefPtr<ScriptArguments> createScriptArguments(const v8::FunctionCallbackInfo<v8::Value>& v8arguments, unsigned skipArgumentCount);
+PassRefPtrWillBeRawPtr<ScriptCallStack> createScriptCallStack(v8::Handle<v8::StackTrace>, size_t maxStackSize, v8::Isolate*);
+PassRefPtrWillBeRawPtr<ScriptCallStack> createScriptCallStack(size_t maxStackSize, bool emptyStackIsAllowed = false);
+PassRefPtrWillBeRawPtr<ScriptCallStack> createScriptCallStackForConsole(ScriptState*, size_t maxStackSize = ScriptCallStack::maxCallStackSizeToCapture);
+PassRefPtrWillBeRawPtr<ScriptArguments> createScriptArguments(ScriptState*, const v8::FunctionCallbackInfo<v8::Value>& v8arguments, unsigned skipArgumentCount);
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/ScriptController.cpp b/chromium/third_party/WebKit/Source/bindings/v8/ScriptController.cpp
index b60a5c74cca..d7049069670 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/ScriptController.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/ScriptController.cpp
@@ -32,9 +32,9 @@
#include "config.h"
#include "bindings/v8/ScriptController.h"
-#include "V8Event.h"
-#include "V8HTMLElement.h"
-#include "V8Window.h"
+#include "bindings/core/v8/V8Event.h"
+#include "bindings/core/v8/V8HTMLElement.h"
+#include "bindings/core/v8/V8Window.h"
#include "bindings/v8/BindingSecurity.h"
#include "bindings/v8/NPV8Object.h"
#include "bindings/v8/ScriptCallStackFactory.h"
@@ -42,7 +42,6 @@
#include "bindings/v8/ScriptValue.h"
#include "bindings/v8/V8Binding.h"
#include "bindings/v8/V8GCController.h"
-#include "bindings/v8/V8HiddenPropertyName.h"
#include "bindings/v8/V8NPObject.h"
#include "bindings/v8/V8PerContextData.h"
#include "bindings/v8/V8ScriptRunner.h"
@@ -54,17 +53,17 @@
#include "core/dom/ScriptableDocumentParser.h"
#include "core/events/Event.h"
#include "core/events/EventListener.h"
-#include "core/events/ThreadLocalEventNames.h"
+#include "core/frame/LocalDOMWindow.h"
+#include "core/frame/LocalFrame.h"
+#include "core/frame/Settings.h"
+#include "core/frame/csp/ContentSecurityPolicy.h"
#include "core/html/HTMLPlugInElement.h"
#include "core/inspector/InspectorInstrumentation.h"
+#include "core/inspector/InspectorTraceEvents.h"
#include "core/inspector/ScriptCallStack.h"
#include "core/loader/DocumentLoader.h"
#include "core/loader/FrameLoader.h"
#include "core/loader/FrameLoaderClient.h"
-#include "core/frame/ContentSecurityPolicy.h"
-#include "core/frame/DOMWindow.h"
-#include "core/frame/Frame.h"
-#include "core/frame/Settings.h"
#include "core/plugins/PluginView.h"
#include "platform/NotImplemented.h"
#include "platform/TraceEvent.h"
@@ -81,23 +80,27 @@
namespace WebCore {
-bool ScriptController::canAccessFromCurrentOrigin(Frame *frame)
+bool ScriptController::canAccessFromCurrentOrigin(LocalFrame *frame)
{
- return !v8::Isolate::GetCurrent()->InContext() || BindingSecurity::shouldAllowAccessToFrame(frame);
+ if (!frame)
+ return false;
+ v8::Isolate* isolate = toIsolate(frame);
+ return !isolate->InContext() || BindingSecurity::shouldAllowAccessToFrame(isolate, frame);
}
-ScriptController::ScriptController(Frame* frame)
+ScriptController::ScriptController(LocalFrame* frame)
: m_frame(frame)
, m_sourceURL(0)
, m_isolate(v8::Isolate::GetCurrent())
- , m_windowShell(V8WindowShell::create(frame, mainThreadNormalWorld(), m_isolate))
+ , m_windowShell(V8WindowShell::create(frame, DOMWrapperWorld::mainWorld(), m_isolate))
, m_windowScriptNPObject(0)
{
}
ScriptController::~ScriptController()
{
- clearForClose(true);
+ // V8WindowShell::clearForClose() must be invoked before destruction starts.
+ ASSERT(!m_windowShell->isContextInitialized());
}
void ScriptController::clearScriptObjects()
@@ -120,61 +123,39 @@ void ScriptController::clearScriptObjects()
}
}
-void ScriptController::clearForOutOfMemory()
-{
- clearForClose(true);
-}
-
-void ScriptController::clearForClose(bool destroyGlobal)
-{
- m_windowShell->clearForClose(destroyGlobal);
- for (IsolatedWorldMap::iterator iter = m_isolatedWorlds.begin(); iter != m_isolatedWorlds.end(); ++iter)
- iter->value->clearForClose(destroyGlobal);
- V8GCController::hintForCollectGarbage();
-}
-
void ScriptController::clearForClose()
{
double start = currentTime();
- clearForClose(false);
+ m_windowShell->clearForClose();
+ for (IsolatedWorldMap::iterator iter = m_isolatedWorlds.begin(); iter != m_isolatedWorlds.end(); ++iter)
+ iter->value->clearForClose();
blink::Platform::current()->histogramCustomCounts("WebCore.ScriptController.clearForClose", (currentTime() - start) * 1000, 0, 10000, 50);
}
-void ScriptController::updateSecurityOrigin()
+void ScriptController::updateSecurityOrigin(SecurityOrigin* origin)
{
- m_windowShell->updateSecurityOrigin();
+ m_windowShell->updateSecurityOrigin(origin);
}
-v8::Local<v8::Value> ScriptController::callFunction(v8::Handle<v8::Function> function, v8::Handle<v8::Object> receiver, int argc, v8::Handle<v8::Value> info[])
+v8::Local<v8::Value> ScriptController::callFunction(v8::Handle<v8::Function> function, v8::Handle<v8::Value> receiver, int argc, v8::Handle<v8::Value> info[])
{
- // Keep Frame (and therefore ScriptController) alive.
- RefPtr<Frame> protect(m_frame);
+ // Keep LocalFrame (and therefore ScriptController) alive.
+ RefPtr<LocalFrame> protect(m_frame);
return ScriptController::callFunction(m_frame->document(), function, receiver, argc, info, m_isolate);
}
-static bool resourceInfo(const v8::Handle<v8::Function> function, String& resourceName, int& lineNumber)
-{
- v8::ScriptOrigin origin = function->GetScriptOrigin();
- if (origin.ResourceName().IsEmpty()) {
- resourceName = "undefined";
- lineNumber = 1;
- } else {
- V8TRYCATCH_FOR_V8STRINGRESOURCE_RETURN(V8StringResource<>, stringResourceName, origin.ResourceName(), false);
- resourceName = stringResourceName;
- lineNumber = function->GetScriptLineNumber() + 1;
- }
- return true;
-}
-
-v8::Local<v8::Value> ScriptController::callFunction(ExecutionContext* context, v8::Handle<v8::Function> function, v8::Handle<v8::Object> receiver, int argc, v8::Handle<v8::Value> info[], v8::Isolate* isolate)
+v8::Local<v8::Value> ScriptController::callFunction(ExecutionContext* context, v8::Handle<v8::Function> function, v8::Handle<v8::Value> receiver, int argc, v8::Handle<v8::Value> info[], v8::Isolate* isolate)
{
+ TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "FunctionCall", "data", devToolsTraceEventData(context, function, isolate));
+ TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline.stack"), "CallStack", "stack", InspectorCallStackEvent::currentCallStack());
+ // FIXME(361045): remove InspectorInstrumentation calls once DevTools Timeline migrates to tracing.
InspectorInstrumentationCookie cookie;
if (InspectorInstrumentation::timelineAgentEnabled(context)) {
+ int scriptId = 0;
String resourceName;
- int lineNumber;
- if (!resourceInfo(function, resourceName, lineNumber))
- return v8::Local<v8::Value>();
- cookie = InspectorInstrumentation::willCallFunction(context, resourceName, lineNumber);
+ int lineNumber = 1;
+ GetDevToolsFunctionInfo(function, isolate, scriptId, resourceName, lineNumber);
+ cookie = InspectorInstrumentation::willCallFunction(context, scriptId, resourceName, lineNumber);
}
v8::Local<v8::Value> result = V8ScriptRunner::callFunction(function, context, receiver, argc, info, isolate);
@@ -185,9 +166,10 @@ v8::Local<v8::Value> ScriptController::callFunction(ExecutionContext* context, v
v8::Local<v8::Value> ScriptController::executeScriptAndReturnValue(v8::Handle<v8::Context> context, const ScriptSourceCode& source, AccessControlStatus corsStatus)
{
- v8::Context::Scope scope(context);
-
- InspectorInstrumentationCookie cookie = InspectorInstrumentation::willEvaluateScript(m_frame, source.url().isNull() ? String() : source.url().string(), source.startLine());
+ TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "EvaluateScript", "data", InspectorEvaluateScriptEvent::data(m_frame, source.url().string(), source.startLine()));
+ TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline.stack"), "CallStack", "stack", InspectorCallStackEvent::currentCallStack());
+ // FIXME(361045): remove InspectorInstrumentation calls once DevTools Timeline migrates to tracing.
+ InspectorInstrumentationCookie cookie = InspectorInstrumentation::willEvaluateScript(m_frame, source.url().string(), source.startLine());
v8::Local<v8::Value> result;
{
@@ -198,20 +180,16 @@ v8::Local<v8::Value> ScriptController::executeScriptAndReturnValue(v8::Handle<v8
v8::TryCatch tryCatch;
tryCatch.SetVerbose(true);
- v8::Handle<v8::String> code = v8String(m_isolate, source.source());
- OwnPtr<v8::ScriptData> scriptData = V8ScriptRunner::precompileScript(code, source.resource());
+ v8::Handle<v8::Script> script = V8ScriptRunner::compileScript(source, m_isolate, corsStatus);
- // NOTE: For compatibility with WebCore, ScriptSourceCode's line starts at
- // 1, whereas v8 starts at 0.
- v8::Handle<v8::Script> script = V8ScriptRunner::compileScript(code, source.url(), source.startPosition(), scriptData.get(), m_isolate, corsStatus);
-
- // Keep Frame (and therefore ScriptController) alive.
- RefPtr<Frame> protect(m_frame);
+ // Keep LocalFrame (and therefore ScriptController) alive.
+ RefPtr<LocalFrame> protect(m_frame);
result = V8ScriptRunner::runCompiledScript(script, m_frame->document(), m_isolate);
ASSERT(!tryCatch.HasCaught() || result.IsEmpty());
}
InspectorInstrumentation::didEvaluateScript(cookie);
+ TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "UpdateCounters", "data", InspectorUpdateCountersEvent::data());
return result;
}
@@ -220,59 +198,47 @@ bool ScriptController::initializeMainWorld()
{
if (m_windowShell->isContextInitialized())
return false;
- return windowShell(mainThreadNormalWorld())->isContextInitialized();
+ return windowShell(DOMWrapperWorld::mainWorld())->isContextInitialized();
}
-V8WindowShell* ScriptController::existingWindowShell(DOMWrapperWorld* world)
+V8WindowShell* ScriptController::existingWindowShell(DOMWrapperWorld& world)
{
- ASSERT(world);
-
- if (world->isMainWorld())
+ if (world.isMainWorld())
return m_windowShell->isContextInitialized() ? m_windowShell.get() : 0;
- // FIXME: Remove this block. See comment with existingWindowShellWorkaroundWorld().
- if (world == existingWindowShellWorkaroundWorld())
- return m_windowShell.get();
-
- IsolatedWorldMap::iterator iter = m_isolatedWorlds.find(world->worldId());
+ IsolatedWorldMap::iterator iter = m_isolatedWorlds.find(world.worldId());
if (iter == m_isolatedWorlds.end())
return 0;
return iter->value->isContextInitialized() ? iter->value.get() : 0;
}
-V8WindowShell* ScriptController::windowShell(DOMWrapperWorld* world)
+V8WindowShell* ScriptController::windowShell(DOMWrapperWorld& world)
{
- ASSERT(world);
-
V8WindowShell* shell = 0;
- if (world->isMainWorld())
+ if (world.isMainWorld())
shell = m_windowShell.get();
else {
- IsolatedWorldMap::iterator iter = m_isolatedWorlds.find(world->worldId());
+ IsolatedWorldMap::iterator iter = m_isolatedWorlds.find(world.worldId());
if (iter != m_isolatedWorlds.end())
shell = iter->value.get();
else {
OwnPtr<V8WindowShell> isolatedWorldShell = V8WindowShell::create(m_frame, world, m_isolate);
shell = isolatedWorldShell.get();
- m_isolatedWorlds.set(world->worldId(), isolatedWorldShell.release());
- }
- }
- if (!shell->isContextInitialized() && shell->initializeIfNeeded()) {
- if (world->isMainWorld()) {
- // FIXME: Remove this if clause. See comment with existingWindowShellWorkaroundWorld().
- m_frame->loader().dispatchDidClearWindowObjectInWorld(existingWindowShellWorkaroundWorld());
- } else {
- m_frame->loader().dispatchDidClearWindowObjectInWorld(world);
+ m_isolatedWorlds.set(world.worldId(), isolatedWorldShell.release());
}
}
+ if (!shell->isContextInitialized() && shell->initializeIfNeeded() && world.isMainWorld())
+ m_frame->loader().dispatchDidClearWindowObjectInMainWorld();
return shell;
}
bool ScriptController::shouldBypassMainWorldContentSecurityPolicy()
{
- if (DOMWrapperWorld* world = isolatedWorldForEnteredContext(m_isolate))
- return world->isolatedWorldHasContentSecurityPolicy();
- return false;
+ v8::Handle<v8::Context> context = m_isolate->GetCurrentContext();
+ if (context.IsEmpty() || !toDOMWindow(context))
+ return false;
+ DOMWrapperWorld& world = DOMWrapperWorld::current(m_isolate);
+ return world.isIsolatedWorld() ? world.isolatedWorldHasContentSecurityPolicy() : false;
}
TextPosition ScriptController::eventHandlerPosition() const
@@ -283,57 +249,18 @@ TextPosition ScriptController::eventHandlerPosition() const
return TextPosition::minimumPosition();
}
-static inline v8::Local<v8::Context> contextForWorld(ScriptController& scriptController, DOMWrapperWorld* world)
-{
- return scriptController.windowShell(world)->context();
-}
-
-v8::Local<v8::Context> ScriptController::currentWorldContext()
-{
- if (!isolate()->InContext())
- return contextForWorld(*this, mainThreadNormalWorld());
-
- v8::Handle<v8::Context> context = isolate()->GetEnteredContext();
- DOMWrapperWorld* isolatedWorld = DOMWrapperWorld::isolatedWorld(context);
- if (!isolatedWorld)
- return contextForWorld(*this, mainThreadNormalWorld());
-
- Frame* frame = toFrameIfNotDetached(context);
- if (m_frame == frame)
- return v8::Local<v8::Context>::New(m_isolate, context);
-
- return contextForWorld(*this, isolatedWorld);
-}
-
-v8::Local<v8::Context> ScriptController::mainWorldContext()
-{
- return contextForWorld(*this, mainThreadNormalWorld());
-}
-
-v8::Local<v8::Context> ScriptController::mainWorldContext(Frame* frame)
-{
- if (!frame)
- return v8::Local<v8::Context>();
-
- return contextForWorld(frame->script(), mainThreadNormalWorld());
-}
-
// Create a V8 object with an interceptor of NPObjectPropertyGetter.
-void ScriptController::bindToWindowObject(Frame* frame, const String& key, NPObject* object)
+void ScriptController::bindToWindowObject(LocalFrame* frame, const String& key, NPObject* object)
{
- v8::HandleScope handleScope(m_isolate);
-
- v8::Handle<v8::Context> v8Context = ScriptController::mainWorldContext(frame);
- if (v8Context.IsEmpty())
+ ScriptState* scriptState = ScriptState::forMainWorld(frame);
+ if (scriptState->contextIsEmpty())
return;
- v8::Context::Scope scope(v8Context);
-
+ ScriptState::Scope scope(scriptState);
v8::Handle<v8::Object> value = createV8ObjectForNPObject(object, 0, m_isolate);
// Attach to the global object.
- v8::Handle<v8::Object> global = v8Context->Global();
- global->Set(v8String(m_isolate, key), value);
+ scriptState->context()->Global()->Set(v8String(m_isolate, key), value);
}
void ScriptController::enableEval()
@@ -359,13 +286,13 @@ PassRefPtr<SharedPersistent<v8::Object> > ScriptController::createPluginWrapper(
ASSERT(widget);
if (!widget->isPluginView())
- return 0;
+ return nullptr;
NPObject* npObject = toPluginView(widget)->scriptableObject();
if (!npObject)
- return 0;
+ return nullptr;
- // Frame Memory Management for NPObjects
+ // LocalFrame Memory Management for NPObjects
// -------------------------------------
// NPObjects are treated differently than other objects wrapped by JS.
// NPObjects can be created either by the browser (e.g. the main
@@ -374,7 +301,7 @@ PassRefPtr<SharedPersistent<v8::Object> > ScriptController::createPluginWrapper(
// is especially careful to ensure NPObjects terminate at frame teardown because
// if a plugin leaks a reference, it could leak its objects (or the browser's objects).
//
- // The Frame maintains a list of plugin objects (m_pluginObjects)
+ // The LocalFrame maintains a list of plugin objects (m_pluginObjects)
// which it can use to quickly find the wrapped embed object.
//
// Inside the NPRuntime, we've added a few methods for registering
@@ -430,18 +357,16 @@ static NPObject* createNoScriptObject()
return 0;
}
-static NPObject* createScriptObject(Frame* frame, v8::Isolate* isolate)
+static NPObject* createScriptObject(LocalFrame* frame, v8::Isolate* isolate)
{
- v8::HandleScope handleScope(isolate);
- v8::Handle<v8::Context> v8Context = ScriptController::mainWorldContext(frame);
- if (v8Context.IsEmpty())
+ ScriptState* scriptState = ScriptState::forMainWorld(frame);
+ if (scriptState->contextIsEmpty())
return createNoScriptObject();
- v8::Context::Scope scope(v8Context);
- DOMWindow* window = frame->domWindow();
- v8::Handle<v8::Value> global = toV8(window, v8::Handle<v8::Object>(), v8Context->GetIsolate());
+ ScriptState::Scope scope(scriptState);
+ LocalDOMWindow* window = frame->domWindow();
+ v8::Handle<v8::Value> global = toV8(window, scriptState->context()->Global(), scriptState->isolate());
ASSERT(global->IsObject());
-
return npCreateV8ScriptObject(0, v8::Handle<v8::Object>::Cast(global), window, isolate);
}
@@ -470,18 +395,17 @@ NPObject* ScriptController::createScriptObjectForPluginElement(HTMLPlugInElement
if (!canExecuteScripts(NotAboutToExecuteScript))
return createNoScriptObject();
- v8::HandleScope handleScope(m_isolate);
- v8::Handle<v8::Context> v8Context = ScriptController::mainWorldContext(m_frame);
- if (v8Context.IsEmpty())
+ ScriptState* scriptState = ScriptState::forMainWorld(m_frame);
+ if (scriptState->contextIsEmpty())
return createNoScriptObject();
- v8::Context::Scope scope(v8Context);
- DOMWindow* window = m_frame->domWindow();
- v8::Handle<v8::Value> v8plugin = toV8(plugin, v8::Handle<v8::Object>(), v8Context->GetIsolate());
+ ScriptState::Scope scope(scriptState);
+ LocalDOMWindow* window = m_frame->domWindow();
+ v8::Handle<v8::Value> v8plugin = toV8(plugin, scriptState->context()->Global(), scriptState->isolate());
if (!v8plugin->IsObject())
return createNoScriptObject();
- return npCreateV8ScriptObject(0, v8::Handle<v8::Object>::Cast(v8plugin), window, v8Context->GetIsolate());
+ return npCreateV8ScriptObject(0, v8::Handle<v8::Object>::Cast(v8plugin), window, scriptState->isolate());
}
void ScriptController::clearWindowShell()
@@ -492,7 +416,7 @@ void ScriptController::clearWindowShell()
m_windowShell->clearForNavigation();
for (IsolatedWorldMap::iterator iter = m_isolatedWorlds.begin(); iter != m_isolatedWorlds.end(); ++iter)
iter->value->clearForNavigation();
- V8GCController::hintForCollectGarbage();
+ clearScriptObjects();
blink::Platform::current()->histogramCustomCounts("WebCore.ScriptController.clearWindowShell", (currentTime() - start) * 1000, 0, 10000, 50);
}
@@ -503,17 +427,14 @@ void ScriptController::setCaptureCallStackForUncaughtExceptions(bool value)
void ScriptController::collectIsolatedContexts(Vector<std::pair<ScriptState*, SecurityOrigin*> >& result)
{
- v8::HandleScope handleScope(m_isolate);
for (IsolatedWorldMap::iterator it = m_isolatedWorlds.begin(); it != m_isolatedWorlds.end(); ++it) {
V8WindowShell* isolatedWorldShell = it->value.get();
- SecurityOrigin* origin = isolatedWorldShell->world()->isolatedWorldSecurityOrigin();
+ SecurityOrigin* origin = isolatedWorldShell->world().isolatedWorldSecurityOrigin();
if (!origin)
continue;
- v8::Local<v8::Context> v8Context = isolatedWorldShell->context();
- if (v8Context.IsEmpty())
+ if (!isolatedWorldShell->isContextInitialized())
continue;
- ScriptState* scriptState = ScriptState::forContext(v8Context);
- result.append(std::pair<ScriptState*, SecurityOrigin*>(scriptState, origin));
+ result.append(std::pair<ScriptState*, SecurityOrigin*>(isolatedWorldShell->scriptState(), origin));
}
}
@@ -534,22 +455,22 @@ int ScriptController::contextDebugId(v8::Handle<v8::Context> context)
void ScriptController::updateDocument()
{
- // For an uninitialized main window shell, do not incur the cost of context initialization during FrameLoader::init().
- if ((!m_windowShell->isContextInitialized() || !m_windowShell->isGlobalInitialized()) && m_frame->loader().stateMachine()->creatingInitialEmptyDocument())
+ // For an uninitialized main window shell, do not incur the cost of context initialization.
+ if (!m_windowShell->isGlobalInitialized())
return;
if (!initializeMainWorld())
- windowShell(mainThreadNormalWorld())->updateDocument();
+ windowShell(DOMWrapperWorld::mainWorld())->updateDocument();
}
void ScriptController::namedItemAdded(HTMLDocument* doc, const AtomicString& name)
{
- windowShell(mainThreadNormalWorld())->namedItemAdded(doc, name);
+ windowShell(DOMWrapperWorld::mainWorld())->namedItemAdded(doc, name);
}
void ScriptController::namedItemRemoved(HTMLDocument* doc, const AtomicString& name)
{
- windowShell(mainThreadNormalWorld())->namedItemRemoved(doc, name);
+ windowShell(DOMWrapperWorld::mainWorld())->namedItemRemoved(doc, name);
}
bool ScriptController::canExecuteScripts(ReasonForCallingCanExecuteScripts reason)
@@ -567,7 +488,7 @@ bool ScriptController::canExecuteScripts(ReasonForCallingCanExecuteScripts reaso
}
Settings* settings = m_frame->settings();
- const bool allowed = m_frame->loader().client()->allowScript(settings && settings->isScriptEnabled());
+ const bool allowed = m_frame->loader().client()->allowScript(settings && settings->scriptEnabled());
if (!allowed && reason == AboutToExecuteScript)
m_frame->loader().client()->didNotAllowScript();
return allowed;
@@ -582,30 +503,30 @@ bool ScriptController::executeScriptIfJavaScriptURL(const KURL& url)
|| !m_frame->document()->contentSecurityPolicy()->allowJavaScriptURLs(m_frame->document()->url(), eventHandlerPosition().m_line))
return true;
- // We need to hold onto the Frame here because executing script can
+ // We need to hold onto the LocalFrame here because executing script can
// destroy the frame.
- RefPtr<Frame> protector(m_frame);
- RefPtr<Document> ownerDocument(m_frame->document());
+ RefPtr<LocalFrame> protector(m_frame);
+ RefPtrWillBeRawPtr<Document> ownerDocument(m_frame->document());
const int javascriptSchemeLength = sizeof("javascript:") - 1;
bool locationChangeBefore = m_frame->navigationScheduler().locationChangePending();
String decodedURL = decodeURLEscapeSequences(url.string());
- ScriptValue result = evaluateScriptInMainWorld(ScriptSourceCode(decodedURL.substring(javascriptSchemeLength)), NotSharableCrossOrigin, DoNotExecuteScriptWhenScriptsDisabled);
+ v8::HandleScope handleScope(m_isolate);
+ v8::Local<v8::Value> result = evaluateScriptInMainWorld(ScriptSourceCode(decodedURL.substring(javascriptSchemeLength)), NotSharableCrossOrigin, DoNotExecuteScriptWhenScriptsDisabled);
// If executing script caused this frame to be removed from the page, we
// don't want to try to replace its document!
if (!m_frame->page())
return true;
- String scriptResult;
- if (!result.getString(scriptResult))
+ if (result.IsEmpty() || !result->IsString())
return true;
+ String scriptResult = toCoreString(v8::Handle<v8::String>::Cast(result));
// We're still in a frame, so there should be a DocumentLoader.
ASSERT(m_frame->document()->loader());
-
if (!locationChangeBefore && m_frame->navigationScheduler().locationChangePending())
return true;
@@ -620,80 +541,77 @@ bool ScriptController::executeScriptIfJavaScriptURL(const KURL& url)
void ScriptController::executeScriptInMainWorld(const String& script, ExecuteScriptPolicy policy)
{
+ v8::HandleScope handleScope(m_isolate);
evaluateScriptInMainWorld(ScriptSourceCode(script), NotSharableCrossOrigin, policy);
}
void ScriptController::executeScriptInMainWorld(const ScriptSourceCode& sourceCode, AccessControlStatus corsStatus)
{
+ v8::HandleScope handleScope(m_isolate);
evaluateScriptInMainWorld(sourceCode, corsStatus, DoNotExecuteScriptWhenScriptsDisabled);
}
-ScriptValue ScriptController::executeScriptInMainWorldAndReturnValue(const ScriptSourceCode& sourceCode)
+v8::Local<v8::Value> ScriptController::executeScriptInMainWorldAndReturnValue(const ScriptSourceCode& sourceCode)
{
return evaluateScriptInMainWorld(sourceCode, NotSharableCrossOrigin, DoNotExecuteScriptWhenScriptsDisabled);
}
-ScriptValue ScriptController::evaluateScriptInMainWorld(const ScriptSourceCode& sourceCode, AccessControlStatus corsStatus, ExecuteScriptPolicy policy)
+v8::Local<v8::Value> ScriptController::evaluateScriptInMainWorld(const ScriptSourceCode& sourceCode, AccessControlStatus corsStatus, ExecuteScriptPolicy policy)
{
if (policy == DoNotExecuteScriptWhenScriptsDisabled && !canExecuteScripts(AboutToExecuteScript))
- return ScriptValue();
+ return v8::Local<v8::Value>();
String sourceURL = sourceCode.url();
const String* savedSourceURL = m_sourceURL;
m_sourceURL = &sourceURL;
- v8::HandleScope handleScope(m_isolate);
- v8::Handle<v8::Context> v8Context = ScriptController::mainWorldContext(m_frame);
- if (v8Context.IsEmpty())
- return ScriptValue();
+ ScriptState* scriptState = ScriptState::forMainWorld(m_frame);
+ if (scriptState->contextIsEmpty())
+ return v8::Local<v8::Value>();
+
+ v8::EscapableHandleScope handleScope(scriptState->isolate());
+ ScriptState::Scope scope(scriptState);
- RefPtr<Frame> protect(m_frame);
+ RefPtr<LocalFrame> protect(m_frame);
if (m_frame->loader().stateMachine()->isDisplayingInitialEmptyDocument())
m_frame->loader().didAccessInitialDocument();
OwnPtr<ScriptSourceCode> maybeProcessedSourceCode = InspectorInstrumentation::preprocess(m_frame, sourceCode);
const ScriptSourceCode& sourceCodeToCompile = maybeProcessedSourceCode ? *maybeProcessedSourceCode : sourceCode;
- v8::Local<v8::Value> object = executeScriptAndReturnValue(v8Context, sourceCodeToCompile, corsStatus);
+ v8::Local<v8::Value> object = executeScriptAndReturnValue(scriptState->context(), sourceCodeToCompile, corsStatus);
m_sourceURL = savedSourceURL;
if (object.IsEmpty())
- return ScriptValue();
+ return v8::Local<v8::Value>();
- return ScriptValue(object, m_isolate);
+ return handleScope.Escape(object);
}
-void ScriptController::executeScriptInIsolatedWorld(int worldID, const Vector<ScriptSourceCode>& sources, int extensionGroup, Vector<ScriptValue>* results)
+void ScriptController::executeScriptInIsolatedWorld(int worldID, const Vector<ScriptSourceCode>& sources, int extensionGroup, Vector<v8::Local<v8::Value> >* results)
{
ASSERT(worldID > 0);
- v8::HandleScope handleScope(m_isolate);
- v8::Local<v8::Array> v8Results;
- {
- v8::EscapableHandleScope evaluateHandleScope(m_isolate);
- RefPtr<DOMWrapperWorld> world = DOMWrapperWorld::ensureIsolatedWorld(worldID, extensionGroup);
- V8WindowShell* isolatedWorldShell = windowShell(world.get());
-
- if (!isolatedWorldShell->isContextInitialized())
- return;
-
- v8::Local<v8::Context> context = isolatedWorldShell->context();
- v8::Context::Scope contextScope(context);
- v8::Local<v8::Array> resultArray = v8::Array::New(m_isolate, sources.size());
+ RefPtr<DOMWrapperWorld> world = DOMWrapperWorld::ensureIsolatedWorld(worldID, extensionGroup);
+ V8WindowShell* isolatedWorldShell = windowShell(*world);
+ if (!isolatedWorldShell->isContextInitialized())
+ return;
- for (size_t i = 0; i < sources.size(); ++i) {
- v8::Local<v8::Value> evaluationResult = executeScriptAndReturnValue(context, sources[i]);
- if (evaluationResult.IsEmpty())
- evaluationResult = v8::Local<v8::Value>::New(m_isolate, v8::Undefined(m_isolate));
- resultArray->Set(i, evaluationResult);
- }
+ ScriptState* scriptState = isolatedWorldShell->scriptState();
+ v8::EscapableHandleScope handleScope(scriptState->isolate());
+ ScriptState::Scope scope(scriptState);
+ v8::Local<v8::Array> resultArray = v8::Array::New(m_isolate, sources.size());
- v8Results = evaluateHandleScope.Escape(resultArray);
+ for (size_t i = 0; i < sources.size(); ++i) {
+ v8::Local<v8::Value> evaluationResult = executeScriptAndReturnValue(scriptState->context(), sources[i]);
+ if (evaluationResult.IsEmpty())
+ evaluationResult = v8::Local<v8::Value>::New(m_isolate, v8::Undefined(m_isolate));
+ resultArray->Set(i, evaluationResult);
}
- if (results && !v8Results.IsEmpty()) {
- for (size_t i = 0; i < v8Results->Length(); ++i)
- results->append(ScriptValue(v8Results->Get(i), m_isolate));
+ if (results) {
+ for (size_t i = 0; i < resultArray->Length(); ++i)
+ results->append(handleScope.Escape(resultArray->Get(i)));
}
}
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/ScriptController.h b/chromium/third_party/WebKit/Source/bindings/v8/ScriptController.h
index 83793c7a96a..3da4d2c6662 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/ScriptController.h
+++ b/chromium/third_party/WebKit/Source/bindings/v8/ScriptController.h
@@ -49,12 +49,12 @@ namespace WebCore {
class DOMWrapperWorld;
class ExecutionContext;
class Event;
-class Frame;
class HTMLDocument;
class HTMLPlugInElement;
class KURL;
-class ScriptSourceCode;
+class LocalFrame;
class ScriptState;
+class ScriptSourceCode;
class SecurityOrigin;
class V8WindowShell;
class Widget;
@@ -73,17 +73,17 @@ public:
DoNotExecuteScriptWhenScriptsDisabled
};
- ScriptController(Frame*);
+ ScriptController(LocalFrame*);
~ScriptController();
bool initializeMainWorld();
- V8WindowShell* windowShell(DOMWrapperWorld*);
- V8WindowShell* existingWindowShell(DOMWrapperWorld*);
+ V8WindowShell* windowShell(DOMWrapperWorld&);
+ V8WindowShell* existingWindowShell(DOMWrapperWorld&);
// Evaluate JavaScript in the main world.
void executeScriptInMainWorld(const String&, ExecuteScriptPolicy = DoNotExecuteScriptWhenScriptsDisabled);
void executeScriptInMainWorld(const ScriptSourceCode&, AccessControlStatus = NotSharableCrossOrigin);
- ScriptValue executeScriptInMainWorldAndReturnValue(const ScriptSourceCode&);
+ v8::Local<v8::Value> executeScriptInMainWorldAndReturnValue(const ScriptSourceCode&);
v8::Local<v8::Value> executeScriptAndReturnValue(v8::Handle<v8::Context>, const ScriptSourceCode&, AccessControlStatus = NotSharableCrossOrigin);
// Executes JavaScript in an isolated world. The script gets its own global scope,
@@ -94,13 +94,13 @@ public:
// Otherwise, a new world is created.
//
// FIXME: Get rid of extensionGroup here.
- void executeScriptInIsolatedWorld(int worldID, const Vector<ScriptSourceCode>& sources, int extensionGroup, Vector<ScriptValue>* results);
+ void executeScriptInIsolatedWorld(int worldID, const Vector<ScriptSourceCode>& sources, int extensionGroup, Vector<v8::Local<v8::Value> >* results);
// Returns true if argument is a JavaScript URL.
bool executeScriptIfJavaScriptURL(const KURL&);
- v8::Local<v8::Value> callFunction(v8::Handle<v8::Function>, v8::Handle<v8::Object>, int argc, v8::Handle<v8::Value> argv[]);
- static v8::Local<v8::Value> callFunction(ExecutionContext*, v8::Handle<v8::Function>, v8::Handle<v8::Object> receiver, int argc, v8::Handle<v8::Value> info[], v8::Isolate*);
+ v8::Local<v8::Value> callFunction(v8::Handle<v8::Function>, v8::Handle<v8::Value>, int argc, v8::Handle<v8::Value> argv[]);
+ static v8::Local<v8::Value> callFunction(ExecutionContext*, v8::Handle<v8::Function>, v8::Handle<v8::Value> receiver, int argc, v8::Handle<v8::Value> info[], v8::Isolate*);
// Returns true if the current world is isolated, and has its own Content
// Security Policy. In this case, the policy of the main world should be
@@ -108,42 +108,33 @@ public:
bool shouldBypassMainWorldContentSecurityPolicy();
// Creates a property of the global object of a frame.
- void bindToWindowObject(Frame*, const String& key, NPObject*);
+ void bindToWindowObject(LocalFrame*, const String& key, NPObject*);
PassRefPtr<SharedPersistent<v8::Object> > createPluginWrapper(Widget*);
void enableEval();
void disableEval(const String& errorMessage);
- static bool canAccessFromCurrentOrigin(Frame*);
+ static bool canAccessFromCurrentOrigin(LocalFrame*);
static void setCaptureCallStackForUncaughtExceptions(bool);
void collectIsolatedContexts(Vector<std::pair<ScriptState*, SecurityOrigin*> >&);
bool canExecuteScripts(ReasonForCallingCanExecuteScripts);
- // Returns V8 Context. If none exists, creates a new context.
- // It is potentially slow and consumes memory.
- static v8::Local<v8::Context> mainWorldContext(Frame*);
- v8::Local<v8::Context> mainWorldContext();
- v8::Local<v8::Context> currentWorldContext();
-
TextPosition eventHandlerPosition() const;
- const String* sourceURL() const { return m_sourceURL; } // 0 if we are not evaluating any script.
-
void clearWindowShell();
void updateDocument();
void namedItemAdded(HTMLDocument*, const AtomicString&);
void namedItemRemoved(HTMLDocument*, const AtomicString&);
- void updateSecurityOrigin();
+ void updateSecurityOrigin(SecurityOrigin*);
void clearScriptObjects();
void cleanupScriptObjectsForPlugin(Widget*);
void clearForClose();
- void clearForOutOfMemory();
NPObject* createScriptObjectForPluginElement(HTMLPlugInElement*);
NPObject* windowScriptNPObject();
@@ -163,10 +154,9 @@ private:
typedef HashMap<int, OwnPtr<V8WindowShell> > IsolatedWorldMap;
typedef HashMap<Widget*, NPObject*> PluginObjectMap;
- ScriptValue evaluateScriptInMainWorld(const ScriptSourceCode&, AccessControlStatus, ExecuteScriptPolicy);
- void clearForClose(bool destroyGlobal);
+ v8::Local<v8::Value> evaluateScriptInMainWorld(const ScriptSourceCode&, AccessControlStatus, ExecuteScriptPolicy);
- Frame* m_frame;
+ LocalFrame* m_frame;
const String* m_sourceURL;
v8::Isolate* m_isolate;
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/ScriptDebugServer.cpp b/chromium/third_party/WebKit/Source/bindings/v8/ScriptDebugServer.cpp
index 4195a44baa2..7b100c6cffb 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/ScriptDebugServer.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/ScriptDebugServer.cpp
@@ -31,16 +31,18 @@
#include "config.h"
#include "bindings/v8/ScriptDebugServer.h"
-#include "DebuggerScriptSource.h"
-#include "V8JavaScriptCallFrame.h"
+#include "bindings/core/v8/V8JavaScriptCallFrame.h"
#include "bindings/v8/ScopedPersistent.h"
+#include "bindings/v8/ScriptCallStackFactory.h"
#include "bindings/v8/ScriptController.h"
-#include "bindings/v8/ScriptObject.h"
#include "bindings/v8/ScriptSourceCode.h"
+#include "bindings/v8/ScriptValue.h"
#include "bindings/v8/V8Binding.h"
#include "bindings/v8/V8ScriptRunner.h"
+#include "core/DebuggerScriptSource.h"
#include "core/inspector/JavaScriptCallFrame.h"
#include "core/inspector/ScriptDebugListener.h"
+#include "platform/JSONValues.h"
#include "wtf/StdLibExtras.h"
#include "wtf/Vector.h"
#include "wtf/dtoa/utils.h"
@@ -89,16 +91,16 @@ String ScriptDebugServer::setBreakpoint(const String& sourceID, const ScriptBrea
v8::Local<v8::Context> debuggerContext = v8::Debug::GetDebugContext();
v8::Context::Scope contextScope(debuggerContext);
- v8::Local<v8::Object> info = v8::Object::New();
+ v8::Local<v8::Object> info = v8::Object::New(m_isolate);
info->Set(v8AtomicString(m_isolate, "sourceID"), v8String(debuggerContext->GetIsolate(), sourceID));
- info->Set(v8AtomicString(m_isolate, "lineNumber"), v8::Integer::New(scriptBreakpoint.lineNumber, debuggerContext->GetIsolate()));
- info->Set(v8AtomicString(m_isolate, "columnNumber"), v8::Integer::New(scriptBreakpoint.columnNumber, debuggerContext->GetIsolate()));
+ info->Set(v8AtomicString(m_isolate, "lineNumber"), v8::Integer::New(debuggerContext->GetIsolate(), scriptBreakpoint.lineNumber));
+ info->Set(v8AtomicString(m_isolate, "columnNumber"), v8::Integer::New(debuggerContext->GetIsolate(), scriptBreakpoint.columnNumber));
info->Set(v8AtomicString(m_isolate, "interstatementLocation"), v8Boolean(interstatementLocation, debuggerContext->GetIsolate()));
info->Set(v8AtomicString(m_isolate, "condition"), v8String(debuggerContext->GetIsolate(), scriptBreakpoint.condition));
v8::Handle<v8::Function> setBreakpointFunction = v8::Local<v8::Function>::Cast(m_debuggerScript.newLocal(m_isolate)->Get(v8AtomicString(m_isolate, "setBreakpoint")));
v8::Handle<v8::Value> breakpointId = v8::Debug::Call(setBreakpointFunction, info);
- if (!breakpointId->IsString())
+ if (breakpointId.IsEmpty() || !breakpointId->IsString())
return "";
*actualLineNumber = info->Get(v8AtomicString(m_isolate, "lineNumber"))->Int32Value();
*actualColumnNumber = info->Get(v8AtomicString(m_isolate, "columnNumber"))->Int32Value();
@@ -111,7 +113,7 @@ void ScriptDebugServer::removeBreakpoint(const String& breakpointId)
v8::Local<v8::Context> debuggerContext = v8::Debug::GetDebugContext();
v8::Context::Scope contextScope(debuggerContext);
- v8::Local<v8::Object> info = v8::Object::New();
+ v8::Local<v8::Object> info = v8::Object::New(m_isolate);
info->Set(v8AtomicString(m_isolate, "breakpointId"), v8String(debuggerContext->GetIsolate(), breakpointId));
v8::Handle<v8::Function> removeBreakpointFunction = v8::Local<v8::Function>::Cast(m_debuggerScript.newLocal(m_isolate)->Get(v8AtomicString(m_isolate, "removeBreakpoint")));
@@ -136,7 +138,7 @@ void ScriptDebugServer::setBreakpointsActivated(bool activated)
v8::Local<v8::Context> debuggerContext = v8::Debug::GetDebugContext();
v8::Context::Scope contextScope(debuggerContext);
- v8::Local<v8::Object> info = v8::Object::New();
+ v8::Local<v8::Object> info = v8::Object::New(m_isolate);
info->Set(v8AtomicString(m_isolate, "enabled"), v8::Boolean::New(m_isolate, activated));
v8::Handle<v8::Function> setBreakpointsActivated = v8::Local<v8::Function>::Cast(m_debuggerScript.newLocal(m_isolate)->Get(v8AtomicString(m_isolate, "setBreakpointsActivated")));
v8::Debug::Call(setBreakpointsActivated, info);
@@ -161,14 +163,13 @@ void ScriptDebugServer::setPauseOnExceptionsState(PauseOnExceptionsState pauseOn
v8::HandleScope scope(m_isolate);
v8::Context::Scope contextScope(v8::Debug::GetDebugContext());
- v8::Handle<v8::Value> argv[] = { v8::Int32::New(pauseOnExceptionsState, m_isolate) };
+ v8::Handle<v8::Value> argv[] = { v8::Int32::New(m_isolate, pauseOnExceptionsState) };
callDebuggerMethod("setPauseOnExceptionsState", 1, argv);
}
void ScriptDebugServer::setPauseOnNextStatement(bool pause)
{
- if (isPaused())
- return;
+ ASSERT(!isPaused());
if (pause)
v8::Debug::DebugBreak(m_isolate);
else
@@ -179,8 +180,7 @@ bool ScriptDebugServer::canBreakProgram()
{
if (!m_breakpointsActivated)
return false;
- v8::HandleScope scope(m_isolate);
- return !m_isolate->GetCurrentContext().IsEmpty();
+ return m_isolate->InContext();
}
void ScriptDebugServer::breakProgram()
@@ -195,65 +195,56 @@ void ScriptDebugServer::breakProgram()
m_breakProgramCallbackTemplate.set(m_isolate, templ);
}
- m_pausedContext = m_isolate->GetCurrentContext();
v8::Handle<v8::Function> breakProgramFunction = m_breakProgramCallbackTemplate.newLocal(m_isolate)->GetFunction();
v8::Debug::Call(breakProgramFunction);
- m_pausedContext.Clear();
}
void ScriptDebugServer::continueProgram()
{
if (isPaused())
quitMessageLoopOnPause();
- m_executionState.clear();
+ m_pausedScriptState.clear();
+ m_executionState.Clear();
}
void ScriptDebugServer::stepIntoStatement()
{
ASSERT(isPaused());
+ ASSERT(!m_executionState.IsEmpty());
v8::HandleScope handleScope(m_isolate);
- v8::Handle<v8::Value> argv[] = { m_executionState.newLocal(m_isolate) };
+ v8::Handle<v8::Value> argv[] = { m_executionState };
callDebuggerMethod(stepIntoV8MethodName, 1, argv);
continueProgram();
}
-void ScriptDebugServer::stepCommandWithFrame(const char* functionName, const ScriptValue& frame)
+void ScriptDebugServer::stepOverStatement()
{
ASSERT(isPaused());
+ ASSERT(!m_executionState.IsEmpty());
v8::HandleScope handleScope(m_isolate);
- v8::Handle<v8::Value> callFrame;
- if (frame.hasNoValue()) {
- callFrame = v8::Undefined(m_isolate);
- } else {
- JavaScriptCallFrame* impl = V8JavaScriptCallFrame::toNative(v8::Handle<v8::Object>::Cast(frame.v8Value()));
- callFrame = impl->innerCallFrame();
- }
-
- v8::Handle<v8::Value> argv[] = {
- m_executionState.newLocal(m_isolate),
- callFrame
- };
-
- callDebuggerMethod(functionName, 2, argv);
+ v8::Handle<v8::Value> argv[] = { m_executionState };
+ callDebuggerMethod("stepOverStatement", 1, argv);
continueProgram();
}
-void ScriptDebugServer::stepOverStatement(const ScriptValue& frame)
+void ScriptDebugServer::stepOutOfFunction()
{
- stepCommandWithFrame("stepOverStatement", frame);
-}
-
-void ScriptDebugServer::stepOutOfFunction(const ScriptValue& frame)
-{
- stepCommandWithFrame(stepOutV8MethodName, frame);
+ ASSERT(isPaused());
+ ASSERT(!m_executionState.IsEmpty());
+ v8::HandleScope handleScope(m_isolate);
+ v8::Handle<v8::Value> argv[] = { m_executionState };
+ callDebuggerMethod(stepOutV8MethodName, 1, argv);
+ continueProgram();
}
-bool ScriptDebugServer::setScriptSource(const String& sourceID, const String& newContent, bool preview, String* error, RefPtr<TypeBuilder::Debugger::SetScriptSourceError>& errorData, ScriptValue* newCallFrames, ScriptObject* result)
+bool ScriptDebugServer::setScriptSource(const String& sourceID, const String& newContent, bool preview, String* error, RefPtr<TypeBuilder::Debugger::SetScriptSourceError>& errorData, ScriptValue* newCallFrames, RefPtr<JSONObject>* result)
{
class EnableLiveEditScope {
public:
- EnableLiveEditScope() { v8::Debug::SetLiveEditEnabled(true); }
- ~EnableLiveEditScope() { v8::Debug::SetLiveEditEnabled(false); }
+ explicit EnableLiveEditScope(v8::Isolate* isolate) : m_isolate(isolate) { v8::Debug::SetLiveEditEnabled(m_isolate, true); }
+ ~EnableLiveEditScope() { v8::Debug::SetLiveEditEnabled(m_isolate, false); }
+ private:
+ v8::Isolate* m_isolate;
};
ensureDebuggerScriptCompiled();
@@ -264,11 +255,11 @@ bool ScriptDebugServer::setScriptSource(const String& sourceID, const String& ne
if (!isPaused())
contextScope = adoptPtr(new v8::Context::Scope(debuggerContext));
- v8::Handle<v8::Value> argv[] = { v8String(debuggerContext->GetIsolate(), sourceID), v8String(debuggerContext->GetIsolate(), newContent), v8Boolean(preview, debuggerContext->GetIsolate()) };
+ v8::Handle<v8::Value> argv[] = { v8String(m_isolate, sourceID), v8String(m_isolate, newContent), v8Boolean(preview, m_isolate) };
v8::Local<v8::Value> v8result;
{
- EnableLiveEditScope enableLiveEditScope;
+ EnableLiveEditScope enableLiveEditScope(m_isolate);
v8::TryCatch tryCatch;
tryCatch.SetVerbose(false);
v8result = callDebuggerMethod("liveEditScriptSource", 3, argv);
@@ -288,8 +279,9 @@ bool ScriptDebugServer::setScriptSource(const String& sourceID, const String& ne
case 0:
{
v8::Local<v8::Value> normalResult = resultTuple->Get(1);
- if (normalResult->IsObject())
- *result = ScriptObject(ScriptState::current(), normalResult->ToObject());
+ RefPtr<JSONValue> jsonResult = v8ToJSONValue(m_isolate, normalResult, JSONValue::maxDepth);
+ if (jsonResult)
+ *result = jsonResult->asObject();
// Call stack may have changed after if the edited function was on the stack.
if (!preview && isPaused())
*newCallFrames = currentCallFrames();
@@ -314,40 +306,71 @@ bool ScriptDebugServer::setScriptSource(const String& sourceID, const String& ne
return false;
}
-PassRefPtr<JavaScriptCallFrame> ScriptDebugServer::wrapCallFrames(v8::Handle<v8::Object> executionState, int maximumLimit)
+int ScriptDebugServer::frameCount()
{
+ ASSERT(isPaused());
+ ASSERT(!m_executionState.IsEmpty());
+ v8::Handle<v8::Value> argv[] = { m_executionState };
+ v8::Handle<v8::Value> result = callDebuggerMethod("frameCount", WTF_ARRAY_LENGTH(argv), argv);
+ if (result->IsInt32())
+ return result->Int32Value();
+ return 0;
+}
+
+PassRefPtrWillBeRawPtr<JavaScriptCallFrame> ScriptDebugServer::wrapCallFrames(int maximumLimit, ScopeInfoDetails scopeDetails)
+{
+ const int scopeBits = 2;
+ COMPILE_ASSERT(NoScopes < (1 << scopeBits), not_enough_bits_to_encode_ScopeInfoDetails);
+
+ ASSERT(maximumLimit >= 0);
+ int data = (maximumLimit << scopeBits) | scopeDetails;
v8::Handle<v8::Value> currentCallFrameV8;
- if (executionState.IsEmpty()) {
+ if (m_executionState.IsEmpty()) {
v8::Handle<v8::Function> currentCallFrameFunction = v8::Local<v8::Function>::Cast(m_debuggerScript.newLocal(m_isolate)->Get(v8AtomicString(m_isolate, "currentCallFrame")));
- currentCallFrameV8 = v8::Debug::Call(currentCallFrameFunction, v8::Integer::New(maximumLimit, m_isolate));
+ currentCallFrameV8 = v8::Debug::Call(currentCallFrameFunction, v8::Integer::New(m_isolate, data));
} else {
- v8::Handle<v8::Value> argv[] = { executionState, v8::Integer::New(maximumLimit, m_isolate) };
- currentCallFrameV8 = callDebuggerMethod("currentCallFrame", 2, argv);
+ v8::Handle<v8::Value> argv[] = { m_executionState, v8::Integer::New(m_isolate, data) };
+ currentCallFrameV8 = callDebuggerMethod("currentCallFrame", WTF_ARRAY_LENGTH(argv), argv);
}
ASSERT(!currentCallFrameV8.IsEmpty());
if (!currentCallFrameV8->IsObject())
- return PassRefPtr<JavaScriptCallFrame>();
+ return nullptr;
return JavaScriptCallFrame::create(v8::Debug::GetDebugContext(), v8::Handle<v8::Object>::Cast(currentCallFrameV8));
}
-ScriptValue ScriptDebugServer::currentCallFrames()
+ScriptValue ScriptDebugServer::currentCallFramesInner(ScopeInfoDetails scopeDetails)
{
- v8::HandleScope scope(m_isolate);
- v8::Handle<v8::Context> pausedContext = m_pausedContext.IsEmpty() ? m_isolate->GetCurrentContext() : m_pausedContext;
- if (pausedContext.IsEmpty())
+ if (!m_isolate->InContext())
return ScriptValue();
+ v8::HandleScope handleScope(m_isolate);
- RefPtr<JavaScriptCallFrame> currentCallFrame = wrapCallFrames(m_executionState.newLocal(m_isolate), -1);
+ RefPtrWillBeRawPtr<JavaScriptCallFrame> currentCallFrame = wrapCallFrames(0, scopeDetails);
if (!currentCallFrame)
return ScriptValue();
- v8::Context::Scope contextScope(pausedContext);
- return ScriptValue(toV8(currentCallFrame.release(), v8::Handle<v8::Object>(), pausedContext->GetIsolate()), pausedContext->GetIsolate());
+ ScriptState* scriptState = m_pausedScriptState ? m_pausedScriptState.get() : ScriptState::current(m_isolate);
+ ScriptState::Scope scope(scriptState);
+ return ScriptValue(scriptState, toV8(currentCallFrame.release(), scriptState->context()->Global(), m_isolate));
+}
+
+ScriptValue ScriptDebugServer::currentCallFrames()
+{
+ return currentCallFramesInner(AllScopes);
+}
+
+ScriptValue ScriptDebugServer::currentCallFramesForAsyncStack()
+{
+ return currentCallFramesInner(FastAsyncScopes);
+}
+
+PassRefPtrWillBeRawPtr<JavaScriptCallFrame> ScriptDebugServer::topCallFrameNoScopes()
+{
+ return wrapCallFrames(1, NoScopes);
}
void ScriptDebugServer::interruptAndRun(PassOwnPtr<Task> task, v8::Isolate* isolate)
{
- v8::Debug::DebugBreakForCommand(new ClientDataImpl(task), isolate);
+ v8::Debug::DebugBreakForCommand(isolate, new ClientDataImpl(task));
}
void ScriptDebugServer::runPendingTasks()
@@ -365,18 +388,19 @@ void ScriptDebugServer::breakProgramCallback(const v8::FunctionCallbackInfo<v8::
{
ASSERT(2 == info.Length());
ScriptDebugServer* thisPtr = toScriptDebugServer(info.Data());
+ ScriptState* pausedScriptState = ScriptState::current(thisPtr->m_isolate);
v8::Handle<v8::Value> exception;
v8::Handle<v8::Array> hitBreakpoints;
- thisPtr->handleProgramBreak(v8::Handle<v8::Object>::Cast(info[0]), exception, hitBreakpoints);
+ thisPtr->handleProgramBreak(pausedScriptState, v8::Handle<v8::Object>::Cast(info[0]), exception, hitBreakpoints);
}
-void ScriptDebugServer::handleProgramBreak(v8::Handle<v8::Object> executionState, v8::Handle<v8::Value> exception, v8::Handle<v8::Array> hitBreakpointNumbers)
+void ScriptDebugServer::handleProgramBreak(ScriptState* pausedScriptState, v8::Handle<v8::Object> executionState, v8::Handle<v8::Value> exception, v8::Handle<v8::Array> hitBreakpointNumbers)
{
// Don't allow nested breaks.
if (isPaused())
return;
- ScriptDebugListener* listener = getDebugListenerForContext(m_pausedContext);
+ ScriptDebugListener* listener = getDebugListenerForContext(pausedScriptState->context());
if (!listener)
return;
@@ -390,20 +414,24 @@ void ScriptDebugServer::handleProgramBreak(v8::Handle<v8::Object> executionState
}
}
- m_executionState.set(m_isolate, executionState);
- ScriptState* currentCallFrameState = ScriptState::forContext(m_pausedContext);
- listener->didPause(currentCallFrameState, currentCallFrames(), ScriptValue(exception, currentCallFrameState->isolate()), breakpointIds);
-
- m_runningNestedMessageLoop = true;
- runMessageLoopOnPause(m_pausedContext);
- m_runningNestedMessageLoop = false;
-}
-
-void ScriptDebugServer::handleProgramBreak(const v8::Debug::EventDetails& eventDetails, v8::Handle<v8::Value> exception, v8::Handle<v8::Array> hitBreakpointNumbers)
-{
- m_pausedContext = eventDetails.GetEventContext();
- handleProgramBreak(eventDetails.GetExecutionState(), exception, hitBreakpointNumbers);
- m_pausedContext.Clear();
+ m_pausedScriptState = pausedScriptState;
+ m_executionState = executionState;
+ ScriptDebugListener::SkipPauseRequest result = listener->didPause(pausedScriptState, currentCallFrames(), ScriptValue(pausedScriptState, exception), breakpointIds);
+ if (result == ScriptDebugListener::NoSkip) {
+ m_runningNestedMessageLoop = true;
+ runMessageLoopOnPause(pausedScriptState->context());
+ m_runningNestedMessageLoop = false;
+ }
+ m_pausedScriptState.clear();
+ m_executionState.Clear();
+
+ if (result == ScriptDebugListener::StepInto) {
+ v8::Handle<v8::Value> argv[] = { executionState };
+ callDebuggerMethod(stepIntoV8MethodName, 1, argv);
+ } else if (result == ScriptDebugListener::StepOut) {
+ v8::Handle<v8::Value> argv[] = { executionState };
+ callDebuggerMethod(stepOutV8MethodName, 1, argv);
+ }
}
void ScriptDebugServer::v8DebugEventCallback(const v8::Debug::EventDetails& eventDetails)
@@ -412,22 +440,6 @@ void ScriptDebugServer::v8DebugEventCallback(const v8::Debug::EventDetails& even
thisPtr->handleV8DebugEvent(eventDetails);
}
-bool ScriptDebugServer::executeSkipPauseRequest(ScriptDebugListener::SkipPauseRequest request, v8::Handle<v8::Object> executionState)
-{
- switch (request) {
- case ScriptDebugListener::NoSkip:
- return false;
- case ScriptDebugListener::Continue:
- return true;
- case ScriptDebugListener::StepInto:
- case ScriptDebugListener::StepOut:
- break;
- }
- v8::Handle<v8::Value> argv[] = { executionState };
- callDebuggerMethod(stepIntoV8MethodName, 1, argv);
- return true;
-}
-
void ScriptDebugServer::handleV8DebugEvent(const v8::Debug::EventDetails& eventDetails)
{
v8::DebugEvent event = eventDetails.GetEvent();
@@ -463,28 +475,17 @@ void ScriptDebugServer::handleV8DebugEvent(const v8::Debug::EventDetails& eventD
// Stack trace is empty in case of syntax error. Silently continue execution in such cases.
if (!stackTrace->GetFrameCount())
return;
- RefPtr<JavaScriptCallFrame> topFrame = wrapCallFrames(eventDetails.GetExecutionState(), 1);
- if (executeSkipPauseRequest(listener->shouldSkipExceptionPause(topFrame), eventDetails.GetExecutionState()))
- return;
v8::Handle<v8::Object> eventData = eventDetails.GetEventData();
v8::Handle<v8::Value> exceptionGetterValue = eventData->Get(v8AtomicString(m_isolate, "exception"));
ASSERT(!exceptionGetterValue.IsEmpty() && exceptionGetterValue->IsFunction());
v8::Handle<v8::Value> exception = V8ScriptRunner::callInternalFunction(v8::Handle<v8::Function>::Cast(exceptionGetterValue), eventData, 0, 0, m_isolate);
- handleProgramBreak(eventDetails, exception, v8::Handle<v8::Array>());
+ handleProgramBreak(ScriptState::from(eventContext), eventDetails.GetExecutionState(), exception, v8::Handle<v8::Array>());
} else if (event == v8::Break) {
v8::Handle<v8::Function> getBreakpointNumbersFunction = v8::Local<v8::Function>::Cast(debuggerScript->Get(v8AtomicString(m_isolate, "getBreakpointNumbers")));
v8::Handle<v8::Value> argv[] = { eventDetails.GetEventData() };
v8::Handle<v8::Value> hitBreakpoints = V8ScriptRunner::callInternalFunction(getBreakpointNumbersFunction, debuggerScript, WTF_ARRAY_LENGTH(argv), argv, m_isolate);
ASSERT(hitBreakpoints->IsArray());
- RefPtr<JavaScriptCallFrame> topFrame = wrapCallFrames(eventDetails.GetExecutionState(), 1);
- ScriptDebugListener::SkipPauseRequest skipRequest;
- if (v8::Handle<v8::Array>::Cast(hitBreakpoints)->Length())
- skipRequest = listener->shouldSkipBreakpointPause(topFrame);
- else
- skipRequest = listener->shouldSkipStepPause(topFrame);
- if (executeSkipPauseRequest(skipRequest, eventDetails.GetExecutionState()))
- return;
- handleProgramBreak(eventDetails, v8::Handle<v8::Value>(), hitBreakpoints.As<v8::Array>());
+ handleProgramBreak(ScriptState::from(eventContext), eventDetails.GetExecutionState(), v8::Handle<v8::Value>(), hitBreakpoints.As<v8::Array>());
}
}
}
@@ -522,6 +523,12 @@ void ScriptDebugServer::ensureDebuggerScriptCompiled()
m_debuggerScript.set(m_isolate, v8::Handle<v8::Object>::Cast(value));
}
+void ScriptDebugServer::discardDebuggerScript()
+{
+ ASSERT(!m_debuggerScript.isEmpty());
+ m_debuggerScript.clear();
+}
+
v8::Local<v8::Value> ScriptDebugServer::functionScopes(v8::Handle<v8::Function> function)
{
ensureDebuggerScriptCompiled();
@@ -547,7 +554,7 @@ v8::Handle<v8::Value> ScriptDebugServer::setFunctionVariableValue(v8::Handle<v8:
v8::Handle<v8::Value> argv[] = {
functionValue,
- v8::Handle<v8::Value>(v8::Integer::New(scopeNumber, debuggerContext->GetIsolate())),
+ v8::Handle<v8::Value>(v8::Integer::New(debuggerContext->GetIsolate(), scopeNumber)),
v8String(debuggerContext->GetIsolate(), variableName),
newValue
};
@@ -557,30 +564,32 @@ v8::Handle<v8::Value> ScriptDebugServer::setFunctionVariableValue(v8::Handle<v8:
bool ScriptDebugServer::isPaused()
{
- return !m_executionState.isEmpty();
+ return m_pausedScriptState;
}
-void ScriptDebugServer::compileScript(ScriptState* state, const String& expression, const String& sourceURL, String* scriptId, String* exceptionMessage)
+void ScriptDebugServer::compileScript(ScriptState* scriptState, const String& expression, const String& sourceURL, String* scriptId, String* exceptionDetailsText, int* lineNumber, int* columnNumber, RefPtrWillBeRawPtr<ScriptCallStack>* stackTrace)
{
- v8::HandleScope handleScope(m_isolate);
- v8::Handle<v8::Context> context = state->context();
- if (context.IsEmpty())
+ if (scriptState->contextIsEmpty())
return;
- v8::Context::Scope contextScope(context);
+ ScriptState::Scope scope(scriptState);
v8::Handle<v8::String> source = v8String(m_isolate, expression);
v8::TryCatch tryCatch;
v8::Local<v8::Script> script = V8ScriptRunner::compileScript(source, sourceURL, TextPosition(), 0, m_isolate);
if (tryCatch.HasCaught()) {
v8::Local<v8::Message> message = tryCatch.Message();
- if (!message.IsEmpty())
- *exceptionMessage = toCoreStringWithUndefinedOrNullCheck(message->Get());
+ if (!message.IsEmpty()) {
+ *exceptionDetailsText = toCoreStringWithUndefinedOrNullCheck(message->Get());
+ *lineNumber = message->GetLineNumber();
+ *columnNumber = message->GetStartColumn();
+ *stackTrace = createScriptCallStack(message->GetStackTrace(), message->GetStackTrace()->GetFrameCount(), m_isolate);
+ }
return;
}
if (script.IsEmpty())
return;
- *scriptId = String::number(script->GetId());
+ *scriptId = String::number(script->GetUnboundScript()->GetId());
m_compiledScripts.set(*scriptId, adoptPtr(new ScopedPersistent<v8::Script>(m_isolate, script)));
}
@@ -589,7 +598,7 @@ void ScriptDebugServer::clearCompiledScripts()
m_compiledScripts.clear();
}
-void ScriptDebugServer::runScript(ScriptState* state, const String& scriptId, ScriptValue* result, bool* wasThrown, String* exceptionMessage)
+void ScriptDebugServer::runScript(ScriptState* scriptState, const String& scriptId, ScriptValue* result, bool* wasThrown, String* exceptionDetailsText, int* lineNumber, int* columnNumber, RefPtrWillBeRawPtr<ScriptCallStack>* stackTrace)
{
if (!m_compiledScripts.contains(scriptId))
return;
@@ -600,30 +609,33 @@ void ScriptDebugServer::runScript(ScriptState* state, const String& scriptId, Sc
if (script.IsEmpty())
return;
- v8::Handle<v8::Context> context = state->context();
- if (context.IsEmpty())
+ if (scriptState->contextIsEmpty())
return;
- v8::Context::Scope contextScope(context);
+ ScriptState::Scope scope(scriptState);
v8::TryCatch tryCatch;
- v8::Local<v8::Value> value = V8ScriptRunner::runCompiledScript(script, state->executionContext(), m_isolate);
+ v8::Local<v8::Value> value = V8ScriptRunner::runCompiledScript(script, scriptState->executionContext(), m_isolate);
*wasThrown = false;
if (tryCatch.HasCaught()) {
*wasThrown = true;
- *result = ScriptValue(tryCatch.Exception(), m_isolate);
+ *result = ScriptValue(scriptState, tryCatch.Exception());
v8::Local<v8::Message> message = tryCatch.Message();
- if (!message.IsEmpty())
- *exceptionMessage = toCoreStringWithUndefinedOrNullCheck(message->Get());
+ if (!message.IsEmpty()) {
+ *exceptionDetailsText = toCoreStringWithUndefinedOrNullCheck(message->Get());
+ *lineNumber = message->GetLineNumber();
+ *columnNumber = message->GetStartColumn();
+ *stackTrace = createScriptCallStack(message->GetStackTrace(), message->GetStackTrace()->GetFrameCount(), m_isolate);
+ }
} else {
- *result = ScriptValue(value, m_isolate);
+ *result = ScriptValue(scriptState, value);
}
}
-PassOwnPtr<ScriptSourceCode> ScriptDebugServer::preprocess(Frame*, const ScriptSourceCode&)
+PassOwnPtr<ScriptSourceCode> ScriptDebugServer::preprocess(LocalFrame*, const ScriptSourceCode&)
{
return PassOwnPtr<ScriptSourceCode>();
}
-String ScriptDebugServer::preprocessEventListener(Frame*, const String& source, const String& url, const String& functionName)
+String ScriptDebugServer::preprocessEventListener(LocalFrame*, const String& source, const String& url, const String& functionName)
{
return source;
}
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/ScriptDebugServer.h b/chromium/third_party/WebKit/Source/bindings/v8/ScriptDebugServer.h
index 3d0e07a954f..ea8d35f3dcd 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/ScriptDebugServer.h
+++ b/chromium/third_party/WebKit/Source/bindings/v8/ScriptDebugServer.h
@@ -31,25 +31,26 @@
#ifndef ScriptDebugServer_h
#define ScriptDebugServer_h
-#include "InspectorBackendDispatcher.h"
#include "bindings/v8/ScopedPersistent.h"
+#include "core/InspectorBackendDispatcher.h"
#include "core/inspector/ScriptBreakpoint.h"
+#include "core/inspector/ScriptCallStack.h"
#include "core/inspector/ScriptDebugListener.h"
-#include <v8-debug.h>
#include "wtf/HashMap.h"
#include "wtf/Noncopyable.h"
#include "wtf/PassOwnPtr.h"
#include "wtf/Vector.h"
#include "wtf/text/StringHash.h"
#include "wtf/text/WTFString.h"
+#include <v8-debug.h>
+#include <v8.h>
namespace WebCore {
+class ScriptState;
class ScriptController;
class ScriptDebugListener;
-class ScriptObject;
class ScriptSourceCode;
-class ScriptState;
class ScriptValue;
class JavaScriptCallFrame;
@@ -74,11 +75,14 @@ public:
void breakProgram();
void continueProgram();
void stepIntoStatement();
- void stepOverStatement(const ScriptValue& frame);
- void stepOutOfFunction(const ScriptValue& frame);
+ void stepOverStatement();
+ void stepOutOfFunction();
- bool setScriptSource(const String& sourceID, const String& newContent, bool preview, String* error, RefPtr<TypeBuilder::Debugger::SetScriptSourceError>&, ScriptValue* newCallFrames, ScriptObject* result);
+ bool setScriptSource(const String& sourceID, const String& newContent, bool preview, String* error, RefPtr<TypeBuilder::Debugger::SetScriptSourceError>&, ScriptValue* newCallFrames, RefPtr<JSONObject>* result);
ScriptValue currentCallFrames();
+ ScriptValue currentCallFramesForAsyncStack();
+ PassRefPtrWillBeRawPtr<JavaScriptCallFrame> topCallFrameNoScopes();
+ int frameCount();
class Task {
public:
@@ -96,13 +100,16 @@ public:
v8::Handle<v8::Value> setFunctionVariableValue(v8::Handle<v8::Value> functionValue, int scopeNumber, const String& variableName, v8::Handle<v8::Value> newValue);
v8::Local<v8::Value> callDebuggerMethod(const char* functionName, int argc, v8::Handle<v8::Value> argv[]);
- virtual void compileScript(ScriptState*, const String& expression, const String& sourceURL, String* scriptId, String* exceptionMessage);
+ virtual void compileScript(ScriptState*, const String& expression, const String& sourceURL, String* scriptId, String* exceptionDetailsText, int* lineNumber, int* columnNumber, RefPtrWillBeRawPtr<ScriptCallStack>* stackTrace);
virtual void clearCompiledScripts();
- virtual void runScript(ScriptState*, const String& scriptId, ScriptValue* result, bool* wasThrown, String* exceptionMessage);
+ virtual void runScript(ScriptState*, const String& scriptId, ScriptValue* result, bool* wasThrown, String* exceptionDetailsText, int* lineNumber, int* columnNumber, RefPtrWillBeRawPtr<ScriptCallStack>* stackTrace);
virtual void setPreprocessorSource(const String&) { }
virtual void preprocessBeforeCompile(const v8::Debug::EventDetails&) { }
- virtual PassOwnPtr<ScriptSourceCode> preprocess(Frame*, const ScriptSourceCode&);
- virtual String preprocessEventListener(Frame*, const String& source, const String& url, const String& functionName);
+ virtual PassOwnPtr<ScriptSourceCode> preprocess(LocalFrame*, const ScriptSourceCode&);
+ virtual String preprocessEventListener(LocalFrame*, const String& source, const String& url, const String& functionName);
+
+ virtual void muteWarningsAndDeprecations() { }
+ virtual void unmuteWarningsAndDeprecations() { }
protected:
explicit ScriptDebugServer(v8::Isolate*);
@@ -113,8 +120,7 @@ protected:
virtual void quitMessageLoopOnPause() = 0;
static void breakProgramCallback(const v8::FunctionCallbackInfo<v8::Value>&);
- void handleProgramBreak(v8::Handle<v8::Object> executionState, v8::Handle<v8::Value> exception, v8::Handle<v8::Array> hitBreakpoints);
- void handleProgramBreak(const v8::Debug::EventDetails&, v8::Handle<v8::Value> exception, v8::Handle<v8::Array> hitBreakpointNumbers);
+ void handleProgramBreak(ScriptState* pausedScriptState, v8::Handle<v8::Object> executionState, v8::Handle<v8::Value> exception, v8::Handle<v8::Array> hitBreakpoints);
static void v8DebugEventCallback(const v8::Debug::EventDetails& eventDetails);
void handleV8DebugEvent(const v8::Debug::EventDetails& eventDetails);
@@ -122,20 +128,27 @@ protected:
void dispatchDidParseSource(ScriptDebugListener* listener, v8::Handle<v8::Object> sourceObject);
void ensureDebuggerScriptCompiled();
+ void discardDebuggerScript();
PauseOnExceptionsState m_pauseOnExceptionsState;
ScopedPersistent<v8::Object> m_debuggerScript;
- ScopedPersistent<v8::Object> m_executionState;
- v8::Handle<v8::Context> m_pausedContext;
+ v8::Local<v8::Object> m_executionState;
+ RefPtr<ScriptState> m_pausedScriptState;
bool m_breakpointsActivated;
ScopedPersistent<v8::FunctionTemplate> m_breakProgramCallbackTemplate;
HashMap<String, OwnPtr<ScopedPersistent<v8::Script> > > m_compiledScripts;
v8::Isolate* m_isolate;
private:
- void stepCommandWithFrame(const char* functionName, const ScriptValue& frame);
- PassRefPtr<JavaScriptCallFrame> wrapCallFrames(v8::Handle<v8::Object> executionState, int maximumLimit);
- bool executeSkipPauseRequest(ScriptDebugListener::SkipPauseRequest, v8::Handle<v8::Object> executionState);
+ enum ScopeInfoDetails {
+ AllScopes,
+ FastAsyncScopes,
+ NoScopes // Should be the last option.
+ };
+
+ ScriptValue currentCallFramesInner(ScopeInfoDetails);
+
+ PassRefPtrWillBeRawPtr<JavaScriptCallFrame> wrapCallFrames(int maximumLimit, ScopeInfoDetails);
bool m_runningNestedMessageLoop;
};
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/ScriptEventListener.cpp b/chromium/third_party/WebKit/Source/bindings/v8/ScriptEventListener.cpp
index 8329708acc5..f720c88a021 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/ScriptEventListener.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/ScriptEventListener.cpp
@@ -32,7 +32,6 @@
#include "bindings/v8/ScriptEventListener.h"
#include "bindings/v8/ScriptController.h"
-#include "bindings/v8/ScriptScope.h"
#include "bindings/v8/ScriptState.h"
#include "bindings/v8/V8AbstractEventListener.h"
#include "bindings/v8/V8Binding.h"
@@ -40,58 +39,70 @@
#include "core/dom/Document.h"
#include "core/dom/DocumentParser.h"
#include "core/events/EventListener.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
+#include <v8.h>
namespace WebCore {
-static const AtomicString& eventParameterName(bool isSVGEvent)
-{
- DEFINE_STATIC_LOCAL(const AtomicString, eventString, ("event"));
- DEFINE_STATIC_LOCAL(const AtomicString, evtString, ("evt"));
- return isSVGEvent ? evtString : eventString;
-}
-
-PassRefPtr<V8LazyEventListener> createAttributeEventListener(Node* node, const QualifiedName& name, const AtomicString& value)
+PassRefPtr<V8LazyEventListener> createAttributeEventListener(Node* node, const QualifiedName& name, const AtomicString& value, const AtomicString& eventParameterName)
{
ASSERT(node);
if (value.isNull())
- return 0;
+ return nullptr;
// FIXME: Very strange: we initialize zero-based number with '1'.
TextPosition position(OrdinalNumber::fromZeroBasedInt(1), OrdinalNumber::first());
String sourceURL;
v8::Isolate* isolate;
- if (Frame* frame = node->document().frame()) {
+ if (LocalFrame* frame = node->document().frame()) {
isolate = toIsolate(frame);
ScriptController& scriptController = frame->script();
if (!scriptController.canExecuteScripts(AboutToExecuteScript))
- return 0;
+ return nullptr;
position = scriptController.eventHandlerPosition();
sourceURL = node->document().url().string();
} else {
isolate = v8::Isolate::GetCurrent();
}
- return V8LazyEventListener::create(name.localName(), eventParameterName(node->isSVGElement()), value, sourceURL, position, node, isolate);
+ return V8LazyEventListener::create(name.localName(), eventParameterName, value, sourceURL, position, node, isolate);
}
-PassRefPtr<V8LazyEventListener> createAttributeEventListener(Frame* frame, const QualifiedName& name, const AtomicString& value)
+PassRefPtr<V8LazyEventListener> createAttributeEventListener(LocalFrame* frame, const QualifiedName& name, const AtomicString& value, const AtomicString& eventParameterName)
{
if (!frame)
- return 0;
+ return nullptr;
if (value.isNull())
- return 0;
+ return nullptr;
ScriptController& scriptController = frame->script();
if (!scriptController.canExecuteScripts(AboutToExecuteScript))
- return 0;
+ return nullptr;
TextPosition position = scriptController.eventHandlerPosition();
String sourceURL = frame->document()->url().string();
- return V8LazyEventListener::create(name.localName(), eventParameterName(frame->document()->isSVGDocument()), value, sourceURL, position, 0, toIsolate(frame));
+ return V8LazyEventListener::create(name.localName(), eventParameterName, value, sourceURL, position, 0, toIsolate(frame));
+}
+
+static v8::Handle<v8::Function> eventListenerEffectiveFunction(v8::Isolate* isolate, v8::Handle<v8::Object> listenerObject)
+{
+ v8::Handle<v8::Function> function;
+ if (listenerObject->IsFunction()) {
+ function = v8::Handle<v8::Function>::Cast(listenerObject);
+ } else if (listenerObject->IsObject()) {
+ // Try the "handleEvent" method (EventListener interface).
+ v8::Handle<v8::Value> property = listenerObject->Get(v8AtomicString(isolate, "handleEvent"));
+ if (property.IsEmpty() || !property->IsFunction()) {
+ // Fall back to the "constructor" property.
+ property = listenerObject->Get(v8AtomicString(isolate, "constructor"));
+ }
+ if (!property.IsEmpty() && property->IsFunction())
+ function = v8::Handle<v8::Function>::Cast(property);
+ }
+ return function;
}
String eventListenerHandlerBody(Document* document, EventListener* listener)
@@ -103,11 +114,14 @@ String eventListenerHandlerBody(Document* document, EventListener* listener)
V8AbstractEventListener* v8Listener = static_cast<V8AbstractEventListener*>(listener);
v8::Handle<v8::Context> context = toV8Context(document, v8Listener->world());
v8::Context::Scope contextScope(context);
- v8::Handle<v8::Value> function = v8Listener->getListenerObject(document);
+ v8::Handle<v8::Object> object = v8Listener->getListenerObject(document);
+ if (object.IsEmpty())
+ return "";
+ v8::Handle<v8::Function> function = eventListenerEffectiveFunction(scope.GetIsolate(), object);
if (function.IsEmpty())
return "";
- V8TRYCATCH_FOR_V8STRINGRESOURCE_RETURN(V8StringResource<WithNullCheck>, functionString, function, "");
+ TOSTRING_DEFAULT(V8StringResource<WithNullCheck>, functionString, function, "");
return functionString;
}
@@ -124,17 +138,17 @@ ScriptValue eventListenerHandler(Document* document, EventListener* listener)
v8::Handle<v8::Object> function = v8Listener->getListenerObject(document);
if (function.IsEmpty())
return ScriptValue();
- return ScriptValue(function, isolate);
+ return ScriptValue(ScriptState::from(context), function);
}
-ScriptState* eventListenerHandlerScriptState(Frame* frame, EventListener* listener)
+ScriptState* eventListenerHandlerScriptState(LocalFrame* frame, EventListener* listener)
{
if (listener->type() != EventListener::JSEventListenerType)
return 0;
V8AbstractEventListener* v8Listener = static_cast<V8AbstractEventListener*>(listener);
v8::HandleScope scope(toIsolate(frame));
v8::Handle<v8::Context> v8Context = frame->script().windowShell(v8Listener->world())->context();
- return ScriptState::forContext(v8Context);
+ return ScriptState::from(v8Context);
}
bool eventListenerHandlerLocation(Document* document, EventListener* listener, String& sourceName, String& scriptId, int& lineNumber)
@@ -146,19 +160,21 @@ bool eventListenerHandlerLocation(Document* document, EventListener* listener, S
V8AbstractEventListener* v8Listener = static_cast<V8AbstractEventListener*>(listener);
v8::Handle<v8::Context> context = toV8Context(document, v8Listener->world());
v8::Context::Scope contextScope(context);
- v8::Handle<v8::Object> object = v8Listener->getListenerObject(document);
- if (object.IsEmpty() || !object->IsFunction())
+ v8::Local<v8::Object> object = v8Listener->getListenerObject(document);
+ if (object.IsEmpty())
return false;
-
- v8::Handle<v8::Function> function = v8::Handle<v8::Function>::Cast(object);
- int scriptIdValue = function->ScriptId();
+ v8::Handle<v8::Function> function = eventListenerEffectiveFunction(scope.GetIsolate(), object);
+ if (function.IsEmpty())
+ return false;
+ v8::Handle<v8::Function> originalFunction = getBoundFunction(function);
+ int scriptIdValue = originalFunction->ScriptId();
scriptId = String::number(scriptIdValue);
- v8::ScriptOrigin origin = function->GetScriptOrigin();
+ v8::ScriptOrigin origin = originalFunction->GetScriptOrigin();
if (!origin.ResourceName().IsEmpty() && origin.ResourceName()->IsString())
sourceName = toCoreString(origin.ResourceName().As<v8::String>());
else
sourceName = "";
- lineNumber = function->GetScriptLineNumber();
+ lineNumber = originalFunction->GetScriptLineNumber();
return true;
}
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/ScriptEventListener.h b/chromium/third_party/WebKit/Source/bindings/v8/ScriptEventListener.h
index bfb75ebaa03..097675defbd 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/ScriptEventListener.h
+++ b/chromium/third_party/WebKit/Source/bindings/v8/ScriptEventListener.h
@@ -33,22 +33,21 @@
#include "bindings/v8/ScriptValue.h"
#include "bindings/v8/V8LazyEventListener.h"
-
#include "wtf/PassRefPtr.h"
namespace WebCore {
class Document;
class EventListener;
- class Frame;
+ class LocalFrame;
class Node;
class QualifiedName;
- PassRefPtr<V8LazyEventListener> createAttributeEventListener(Node*, const QualifiedName&, const AtomicString& value);
- PassRefPtr<V8LazyEventListener> createAttributeEventListener(Frame*, const QualifiedName&, const AtomicString& value);
+ PassRefPtr<V8LazyEventListener> createAttributeEventListener(Node*, const QualifiedName&, const AtomicString& value, const AtomicString& eventParameterName);
+ PassRefPtr<V8LazyEventListener> createAttributeEventListener(LocalFrame*, const QualifiedName&, const AtomicString& value, const AtomicString& eventParameterName);
String eventListenerHandlerBody(Document*, EventListener*);
ScriptValue eventListenerHandler(Document*, EventListener*);
- ScriptState* eventListenerHandlerScriptState(Frame*, EventListener*);
+ ScriptState* eventListenerHandlerScriptState(LocalFrame*, EventListener*);
bool eventListenerHandlerLocation(Document*, EventListener*, String& sourceName, String& scriptId, int& lineNumber);
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/ScriptFunction.cpp b/chromium/third_party/WebKit/Source/bindings/v8/ScriptFunction.cpp
new file mode 100644
index 00000000000..18315a4b6e3
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/bindings/v8/ScriptFunction.cpp
@@ -0,0 +1,32 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "bindings/v8/ScriptFunction.h"
+
+#include "bindings/v8/V8Binding.h"
+
+namespace WebCore {
+
+void ScriptFunction::callCallback(const v8::FunctionCallbackInfo<v8::Value>& args)
+{
+ v8::Isolate* isolate = args.GetIsolate();
+ ASSERT(!args.Data().IsEmpty());
+ ScriptFunction* function = ScriptFunction::Cast(args.Data());
+ v8::Local<v8::Value> value = args.Length() > 0 ? args[0] : v8::Local<v8::Value>(v8::Undefined(isolate));
+
+ ScriptValue result = function->call(ScriptValue(ScriptState::current(isolate), value));
+
+ v8SetReturnValue(args, result.v8Value());
+}
+
+v8::Handle<v8::Function> ScriptFunction::adoptByGarbageCollector(PassOwnPtr<ScriptFunction> function)
+{
+ if (!function)
+ return v8::Handle<v8::Function>();
+ v8::Isolate* isolate = function->isolate();
+ return createClosure(&ScriptFunction::callCallback, function.leakPtr()->releaseToV8GarbageCollector(), isolate);
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8MIDIInputCustom.cpp b/chromium/third_party/WebKit/Source/bindings/v8/ScriptFunction.h
index 6ad179c447f..acb379d0f7d 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8MIDIInputCustom.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/ScriptFunction.h
@@ -28,25 +28,29 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include "config.h"
-#include "V8MIDIInput.h"
+#ifndef ScriptFunction_h
+#define ScriptFunction_h
-#include "V8MIDIAccess.h"
-#include "bindings/v8/V8HiddenPropertyName.h"
+#include "bindings/v8/ScriptValue.h"
+#include "bindings/v8/V8GarbageCollected.h"
+#include "wtf/RefCounted.h"
+#include <v8.h>
namespace WebCore {
-v8::Handle<v8::Object> wrap(MIDIInput* input, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
-{
- ASSERT(input);
- ASSERT(!DOMDataStore::containsWrapper<V8MIDIInput>(input, isolate));
+class ScriptFunction : public V8GarbageCollected<ScriptFunction> {
+public:
+ virtual ~ScriptFunction() { }
+ static v8::Handle<v8::Function> adoptByGarbageCollector(PassOwnPtr<ScriptFunction>);
- v8::Handle<v8::Object> wrapper = V8MIDIInput::createWrapper(input, creationContext, isolate);
+protected:
+ ScriptFunction(v8::Isolate* isolate) : V8GarbageCollected<ScriptFunction>(isolate) { }
- if (input->midiAccess())
- V8HiddenPropertyName::setNamedHiddenReference(wrapper, "access", toV8(input->midiAccess(), creationContext, isolate));
-
- return wrapper;
-}
+private:
+ virtual ScriptValue call(ScriptValue) = 0;
+ static void callCallback(const v8::FunctionCallbackInfo<v8::Value>& args);
+};
} // namespace WebCore
+
+#endif
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/ScriptFunctionCall.cpp b/chromium/third_party/WebKit/Source/bindings/v8/ScriptFunctionCall.cpp
index e8c618e9030..56637ded2af 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/ScriptFunctionCall.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/ScriptFunctionCall.cpp
@@ -32,19 +32,17 @@
#include "bindings/v8/ScriptFunctionCall.h"
#include "bindings/v8/ScriptController.h"
-#include "bindings/v8/ScriptScope.h"
#include "bindings/v8/ScriptState.h"
#include "bindings/v8/ScriptValue.h"
#include "bindings/v8/V8Binding.h"
#include "bindings/v8/V8ObjectConstructor.h"
#include "bindings/v8/V8ScriptRunner.h"
-#include "bindings/v8/V8Utilities.h"
#include <v8.h>
namespace WebCore {
-void ScriptCallArgumentHandler::appendArgument(const ScriptObject& argument)
+void ScriptCallArgumentHandler::appendArgument(const ScriptValue& argument)
{
if (argument.scriptState() != m_scriptState) {
ASSERT_NOT_REACHED();
@@ -53,67 +51,72 @@ void ScriptCallArgumentHandler::appendArgument(const ScriptObject& argument)
m_arguments.append(argument);
}
-void ScriptCallArgumentHandler::appendArgument(const ScriptValue& argument)
-{
- m_arguments.append(argument);
-}
-
void ScriptCallArgumentHandler::appendArgument(const String& argument)
{
v8::Isolate* isolate = m_scriptState->isolate();
- ScriptScope scope(m_scriptState);
- m_arguments.append(ScriptValue(v8String(isolate, argument), isolate));
+ ScriptState::Scope scope(m_scriptState.get());
+ m_arguments.append(ScriptValue(m_scriptState.get(), v8String(isolate, argument)));
}
void ScriptCallArgumentHandler::appendArgument(const char* argument)
{
v8::Isolate* isolate = m_scriptState->isolate();
- ScriptScope scope(m_scriptState);
- m_arguments.append(ScriptValue(v8String(isolate, argument), isolate));
+ ScriptState::Scope scope(m_scriptState.get());
+ m_arguments.append(ScriptValue(m_scriptState.get(), v8String(isolate, argument)));
}
void ScriptCallArgumentHandler::appendArgument(long argument)
{
v8::Isolate* isolate = m_scriptState->isolate();
- ScriptScope scope(m_scriptState);
- m_arguments.append(ScriptValue(v8::Number::New(isolate, argument), isolate));
+ ScriptState::Scope scope(m_scriptState.get());
+ m_arguments.append(ScriptValue(m_scriptState.get(), v8::Number::New(isolate, argument)));
}
void ScriptCallArgumentHandler::appendArgument(long long argument)
{
v8::Isolate* isolate = m_scriptState->isolate();
- ScriptScope scope(m_scriptState);
- m_arguments.append(ScriptValue(v8::Number::New(isolate, argument), isolate));
+ ScriptState::Scope scope(m_scriptState.get());
+ m_arguments.append(ScriptValue(m_scriptState.get(), v8::Number::New(isolate, argument)));
}
-void ScriptCallArgumentHandler::appendArgument(unsigned int argument)
+void ScriptCallArgumentHandler::appendArgument(unsigned argument)
{
v8::Isolate* isolate = m_scriptState->isolate();
- ScriptScope scope(m_scriptState);
- m_arguments.append(ScriptValue(v8::Number::New(isolate, argument), isolate));
+ ScriptState::Scope scope(m_scriptState.get());
+ m_arguments.append(ScriptValue(m_scriptState.get(), v8::Number::New(isolate, argument)));
}
void ScriptCallArgumentHandler::appendArgument(unsigned long argument)
{
v8::Isolate* isolate = m_scriptState->isolate();
- ScriptScope scope(m_scriptState);
- m_arguments.append(ScriptValue(v8::Number::New(isolate, argument), isolate));
+ ScriptState::Scope scope(m_scriptState.get());
+ m_arguments.append(ScriptValue(m_scriptState.get(), v8::Number::New(isolate, argument)));
}
void ScriptCallArgumentHandler::appendArgument(int argument)
{
v8::Isolate* isolate = m_scriptState->isolate();
- ScriptScope scope(m_scriptState);
- m_arguments.append(ScriptValue(v8::Number::New(isolate, argument), isolate));
+ ScriptState::Scope scope(m_scriptState.get());
+ m_arguments.append(ScriptValue(m_scriptState.get(), v8::Number::New(isolate, argument)));
}
void ScriptCallArgumentHandler::appendArgument(bool argument)
{
v8::Isolate* isolate = m_scriptState->isolate();
- m_arguments.append(ScriptValue(v8Boolean(argument, isolate), isolate));
+ m_arguments.append(ScriptValue(m_scriptState.get(), v8Boolean(argument, isolate)));
}
-ScriptFunctionCall::ScriptFunctionCall(const ScriptObject& thisObject, const String& name)
+void ScriptCallArgumentHandler::appendArgument(const Vector<ScriptValue>& argument)
+{
+ v8::Isolate* isolate = m_scriptState->isolate();
+ ScriptState::Scope scope(m_scriptState.get());
+ v8::Handle<v8::Array> result = v8::Array::New(isolate, argument.size());
+ for (size_t i = 0; i < argument.size(); ++i)
+ result->Set(v8::Integer::New(isolate, i), argument[i].v8Value());
+ m_arguments.append(ScriptValue(m_scriptState.get(), result));
+}
+
+ScriptFunctionCall::ScriptFunctionCall(const ScriptValue& thisObject, const String& name)
: ScriptCallArgumentHandler(thisObject.scriptState())
, m_thisObject(thisObject)
, m_name(name)
@@ -122,11 +125,13 @@ ScriptFunctionCall::ScriptFunctionCall(const ScriptObject& thisObject, const Str
ScriptValue ScriptFunctionCall::call(bool& hadException, bool reportExceptions)
{
- ScriptScope scope(m_scriptState, reportExceptions);
+ ScriptState::Scope scope(m_scriptState.get());
+ v8::TryCatch tryCatch;
+ tryCatch.SetVerbose(reportExceptions);
- v8::Handle<v8::Object> thisObject = m_thisObject.v8Object();
+ v8::Handle<v8::Object> thisObject = v8::Handle<v8::Object>::Cast(m_thisObject.v8Value());
v8::Local<v8::Value> value = thisObject->Get(v8String(m_scriptState->isolate(), m_name));
- if (!scope.success()) {
+ if (tryCatch.HasCaught()) {
hadException = true;
return ScriptValue();
}
@@ -140,13 +145,13 @@ ScriptValue ScriptFunctionCall::call(bool& hadException, bool reportExceptions)
ASSERT(!info[i].IsEmpty());
}
- v8::Local<v8::Value> result = V8ScriptRunner::callFunction(function, getExecutionContext(), thisObject, m_arguments.size(), info.get(), m_scriptState->isolate());
- if (!scope.success()) {
+ v8::Local<v8::Value> result = V8ScriptRunner::callFunction(function, m_scriptState->executionContext(), thisObject, m_arguments.size(), info.get(), m_scriptState->isolate());
+ if (tryCatch.HasCaught()) {
hadException = true;
return ScriptValue();
}
- return ScriptValue(result, m_scriptState->isolate());
+ return ScriptValue(m_scriptState.get(), result);
}
ScriptValue ScriptFunctionCall::call()
@@ -155,15 +160,17 @@ ScriptValue ScriptFunctionCall::call()
return call(hadException);
}
-ScriptObject ScriptFunctionCall::construct(bool& hadException, bool reportExceptions)
+ScriptValue ScriptFunctionCall::construct(bool& hadException, bool reportExceptions)
{
- ScriptScope scope(m_scriptState, reportExceptions);
+ ScriptState::Scope scope(m_scriptState.get());
+ v8::TryCatch tryCatch;
+ tryCatch.SetVerbose(reportExceptions);
- v8::Handle<v8::Object> thisObject = m_thisObject.v8Object();
+ v8::Handle<v8::Object> thisObject = v8::Handle<v8::Object>::Cast(m_thisObject.v8Value());
v8::Local<v8::Value> value = thisObject->Get(v8String(m_scriptState->isolate(), m_name));
- if (!scope.success()) {
+ if (tryCatch.HasCaught()) {
hadException = true;
- return ScriptObject();
+ return ScriptValue();
}
ASSERT(value->IsFunction());
@@ -173,39 +180,13 @@ ScriptObject ScriptFunctionCall::construct(bool& hadException, bool reportExcept
for (size_t i = 0; i < m_arguments.size(); ++i)
info[i] = m_arguments[i].v8Value();
- v8::Local<v8::Object> result = V8ObjectConstructor::newInstance(constructor, m_arguments.size(), info.get());
- if (!scope.success()) {
+ v8::Local<v8::Object> result = V8ObjectConstructor::newInstance(m_scriptState->isolate(), constructor, m_arguments.size(), info.get());
+ if (tryCatch.HasCaught()) {
hadException = true;
- return ScriptObject();
+ return ScriptValue();
}
- return ScriptObject(m_scriptState, result);
-}
-
-ScriptCallback::ScriptCallback(ScriptState* state, const ScriptValue& function)
- : ScriptCallArgumentHandler(state)
- , m_scriptState(state)
- , m_function(function)
-{
-}
-
-ScriptValue ScriptCallback::call()
-{
- v8::Isolate* isolate = v8::Isolate::GetCurrent();
- ASSERT(isolate->InContext());
- ASSERT(m_function.v8Value()->IsFunction());
-
- v8::TryCatch exceptionCatcher;
- exceptionCatcher.SetVerbose(true);
- v8::Handle<v8::Object> object = isolate->GetCurrentContext()->Global();
- v8::Handle<v8::Function> function = v8::Handle<v8::Function>::Cast(m_function.v8Value());
-
- OwnPtr<v8::Handle<v8::Value>[]> info = adoptArrayPtr(new v8::Handle<v8::Value>[m_arguments.size()]);
- for (size_t i = 0; i < m_arguments.size(); ++i)
- info[i] = m_arguments[i].v8Value();
-
- v8::Handle<v8::Value> result = ScriptController::callFunction(m_scriptState->executionContext(), function, object, m_arguments.size(), info.get(), m_scriptState->isolate());
- return ScriptValue(result, m_scriptState->isolate());
+ return ScriptValue(m_scriptState.get(), result);
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/ScriptFunctionCall.h b/chromium/third_party/WebKit/Source/bindings/v8/ScriptFunctionCall.h
index 032b6a0b0ce..f323c3f6359 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/ScriptFunctionCall.h
+++ b/chromium/third_party/WebKit/Source/bindings/v8/ScriptFunctionCall.h
@@ -31,58 +31,46 @@
#ifndef ScriptFunctionCall_h
#define ScriptFunctionCall_h
-#include "bindings/v8/ScriptObject.h"
+#include "bindings/v8/ScriptValue.h"
#include "wtf/Vector.h"
#include "wtf/text/WTFString.h"
namespace WebCore {
class ScriptValue;
- class ScriptState;
class ScriptCallArgumentHandler {
public:
ScriptCallArgumentHandler(ScriptState* scriptState) : m_scriptState(scriptState) { }
- void appendArgument(const ScriptObject&);
void appendArgument(const ScriptValue&);
void appendArgument(const String&);
void appendArgument(const char*);
void appendArgument(long);
void appendArgument(long long);
- void appendArgument(unsigned int);
+ void appendArgument(unsigned);
void appendArgument(unsigned long);
void appendArgument(int);
void appendArgument(bool);
+ void appendArgument(const Vector<ScriptValue>&);
protected:
- ScriptState* m_scriptState;
+ RefPtr<ScriptState> m_scriptState;
Vector<ScriptValue> m_arguments;
};
class ScriptFunctionCall : public ScriptCallArgumentHandler {
public:
- ScriptFunctionCall(const ScriptObject& thisObject, const String& name);
+ ScriptFunctionCall(const ScriptValue& thisObject, const String& name);
ScriptValue call(bool& hadException, bool reportExceptions = true);
ScriptValue call();
- ScriptObject construct(bool& hadException, bool reportExceptions = true);
+ ScriptValue construct(bool& hadException, bool reportExceptions = true);
protected:
- ScriptObject m_thisObject;
+ ScriptValue m_thisObject;
String m_name;
};
- class ScriptCallback : public ScriptCallArgumentHandler {
- public:
- ScriptCallback(ScriptState*, const ScriptValue&);
-
- ScriptValue call();
-
- private:
- ScriptState* m_scriptState;
- ScriptValue m_function;
- };
-
} // namespace WebCore
#endif // ScriptFunctionCall
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/ScriptGCEvent.cpp b/chromium/third_party/WebKit/Source/bindings/v8/ScriptGCEvent.cpp
index 361d8e3e965..9cc90eb4672 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/ScriptGCEvent.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/ScriptGCEvent.cpp
@@ -41,7 +41,7 @@ namespace WebCore {
static GCEventData* isolateGCEventData()
{
- V8PerIsolateData* isolateData = V8PerIsolateData::current();
+ V8PerIsolateData* isolateData = V8PerIsolateData::from(v8::Isolate::GetCurrent());
ASSERT(isolateData);
return isolateData->gcEventData();
}
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/ScriptGCEvent.h b/chromium/third_party/WebKit/Source/bindings/v8/ScriptGCEvent.h
index 3f95e7f46c7..ee042b5b8af 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/ScriptGCEvent.h
+++ b/chromium/third_party/WebKit/Source/bindings/v8/ScriptGCEvent.h
@@ -31,8 +31,8 @@
#ifndef ScriptGCEvent_h
#define ScriptGCEvent_h
-#include "v8.h"
#include "wtf/Vector.h"
+#include <v8.h>
namespace WebCore {
@@ -80,6 +80,7 @@ private:
};
+// FIXME(361045): remove ScriptGCEvent once DevTools Timeline migrates to tracing.
class ScriptGCEvent
{
public:
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/ScriptHeapSnapshot.cpp b/chromium/third_party/WebKit/Source/bindings/v8/ScriptHeapSnapshot.cpp
index 6077b57febd..b5c2c7f9e71 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/ScriptHeapSnapshot.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/ScriptHeapSnapshot.cpp
@@ -51,25 +51,15 @@ String ScriptHeapSnapshot::title() const
return toCoreString(m_snapshot->GetTitle());
}
-unsigned int ScriptHeapSnapshot::uid() const
-{
- return m_snapshot->GetUid();
-}
-
-SnapshotObjectId ScriptHeapSnapshot::maxSnapshotJSObjectId() const
-{
- return m_snapshot->GetMaxSnapshotJSObjectId();
-}
-
namespace {
-class OutputStreamAdapter : public v8::OutputStream {
+class OutputStreamAdapter FINAL : public v8::OutputStream {
public:
OutputStreamAdapter(ScriptHeapSnapshot::OutputStream* output)
: m_output(output) { }
- void EndOfStream() { m_output->Close(); }
- int GetChunkSize() { return 102400; }
- WriteResult WriteAsciiChunk(char* data, int size)
+ virtual void EndOfStream() OVERRIDE { m_output->Close(); }
+ virtual int GetChunkSize() OVERRIDE { return 102400; }
+ virtual WriteResult WriteAsciiChunk(char* data, int size) OVERRIDE
{
m_output->Write(String(data, size));
return kContinue;
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/ScriptHeapSnapshot.h b/chromium/third_party/WebKit/Source/bindings/v8/ScriptHeapSnapshot.h
index 1e168599bdb..3ca4f5e9e81 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/ScriptHeapSnapshot.h
+++ b/chromium/third_party/WebKit/Source/bindings/v8/ScriptHeapSnapshot.h
@@ -33,15 +33,10 @@
#include "wtf/RefCounted.h"
#include "wtf/text/WTFString.h"
-
-namespace v8 {
-class HeapSnapshot;
-}
+#include <v8-profiler.h>
namespace WebCore {
-typedef uint32_t SnapshotObjectId;
-
class ScriptHeapSnapshot FINAL : public RefCounted<ScriptHeapSnapshot> {
public:
class OutputStream {
@@ -58,9 +53,7 @@ public:
~ScriptHeapSnapshot();
String title() const;
- unsigned int uid() const;
void writeJSON(OutputStream* stream);
- SnapshotObjectId maxSnapshotJSObjectId() const;
private:
ScriptHeapSnapshot(const v8::HeapSnapshot* snapshot)
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/ScriptObject.h b/chromium/third_party/WebKit/Source/bindings/v8/ScriptObject.h
deleted file mode 100644
index 072313d49be..00000000000
--- a/chromium/third_party/WebKit/Source/bindings/v8/ScriptObject.h
+++ /dev/null
@@ -1,66 +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.
- */
-
-#ifndef ScriptObject_h
-#define ScriptObject_h
-
-#include "bindings/v8/ScriptValue.h"
-
-#include <v8.h>
-
-namespace WebCore {
- class InjectedScriptHost;
- class InspectorFrontendHost;
- class ScriptState;
-
- class ScriptObject : public ScriptValue {
- public:
- ScriptObject(ScriptState*, v8::Handle<v8::Object>);
- ScriptObject(ScriptState*, const ScriptValue&);
- ScriptObject() : m_scriptState(0) { };
- virtual ~ScriptObject() { }
-
- v8::Handle<v8::Object> v8Object() const;
- ScriptState* scriptState() const { return m_scriptState; }
- protected:
- ScriptState* m_scriptState;
- };
-
- class ScriptGlobalObject {
- public:
- static bool set(ScriptState*, const char* name, InspectorFrontendHost*);
- static bool get(ScriptState*, const char* name, ScriptObject&);
- private:
- ScriptGlobalObject() { }
- };
-
-}
-
-#endif // ScriptObject_h
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/ScriptPreprocessor.cpp b/chromium/third_party/WebKit/Source/bindings/v8/ScriptPreprocessor.cpp
index c9674b96c7a..3c38767e8ff 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/ScriptPreprocessor.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/ScriptPreprocessor.cpp
@@ -34,39 +34,41 @@
#include "bindings/v8/ScriptController.h"
#include "bindings/v8/ScriptSourceCode.h"
#include "bindings/v8/ScriptValue.h"
+#include "bindings/v8/V8Binding.h"
#include "bindings/v8/V8ScriptRunner.h"
-#include "core/page/PageConsole.h"
+#include "core/frame/FrameConsole.h"
+#include "core/frame/FrameHost.h"
+#include "core/frame/LocalFrame.h"
#include "wtf/TemporaryChange.h"
namespace WebCore {
-ScriptPreprocessor::ScriptPreprocessor(const ScriptSourceCode& preprocessorSourceCode, ScriptController& controller, PageConsole& console)
+ScriptPreprocessor::ScriptPreprocessor(const ScriptSourceCode& preprocessorSourceCode, LocalFrame* frame)
: m_isPreprocessing(false)
{
+ RefPtr<DOMWrapperWorld> world = DOMWrapperWorld::ensureIsolatedWorld(ScriptPreprocessorIsolatedWorldId, DOMWrapperWorld::mainWorldExtensionGroup);
+ m_scriptState = ScriptState::from(toV8Context(frame, *world));
+
+ v8::HandleScope handleScope(m_scriptState->isolate());
+ ASSERT(frame);
v8::TryCatch tryCatch;
tryCatch.SetVerbose(true);
Vector<ScriptSourceCode> sources;
sources.append(preprocessorSourceCode);
- Vector<ScriptValue> scriptResults;
- controller.executeScriptInIsolatedWorld(ScriptPreprocessorIsolatedWorldId, sources, DOMWrapperWorld::mainWorldExtensionGroup, &scriptResults);
+ Vector<v8::Local<v8::Value> > scriptResults;
+ frame->script().executeScriptInIsolatedWorld(ScriptPreprocessorIsolatedWorldId, sources, DOMWrapperWorld::mainWorldExtensionGroup, &scriptResults);
if (scriptResults.size() != 1) {
- console.addMessage(JSMessageSource, ErrorMessageLevel, "ScriptPreprocessor internal error, one ScriptSourceCode must give exactly one result.");
+ frame->console().addMessage(JSMessageSource, ErrorMessageLevel, "ScriptPreprocessor internal error, one ScriptSourceCode must give exactly one result.");
return;
}
- ScriptValue preprocessorFunction = scriptResults[0];
- if (!preprocessorFunction.isFunction()) {
- console.addMessage(JSMessageSource, ErrorMessageLevel, "The preprocessor must compile to a function.");
+ v8::Local<v8::Value> preprocessorFunction = scriptResults[0];
+ if (preprocessorFunction.IsEmpty() || !preprocessorFunction->IsFunction()) {
+ frame->console().addMessage(JSMessageSource, ErrorMessageLevel, "The preprocessor must compile to a function.");
return;
}
-
- m_world = DOMWrapperWorld::ensureIsolatedWorld(ScriptPreprocessorIsolatedWorldId, DOMWrapperWorld::mainWorldExtensionGroup);
- v8::Local<v8::Context> context = m_world->context(controller);
- m_isolate = context->GetIsolate();
-
- m_context.set(m_isolate, context);
- m_preprocessorFunction.set(m_isolate, v8::Handle<v8::Function>::Cast(preprocessorFunction.v8Value()));
+ m_preprocessorFunction.set(m_scriptState->isolate(), v8::Handle<v8::Function>::Cast(preprocessorFunction));
}
String ScriptPreprocessor::preprocessSourceCode(const String& sourceCode, const String& sourceName)
@@ -74,7 +76,7 @@ String ScriptPreprocessor::preprocessSourceCode(const String& sourceCode, const
if (!isValid())
return sourceCode;
- return preprocessSourceCode(sourceCode, sourceName, v8::Undefined(m_isolate));
+ return preprocessSourceCode(sourceCode, sourceName, v8::Undefined(m_scriptState->isolate()));
}
String ScriptPreprocessor::preprocessSourceCode(const String& sourceCode, const String& sourceName, const String& functionName)
@@ -82,7 +84,7 @@ String ScriptPreprocessor::preprocessSourceCode(const String& sourceCode, const
if (!isValid())
return sourceCode;
- v8::Handle<v8::String> functionNameString = v8String(m_isolate, functionName);
+ v8::Handle<v8::String> functionNameString = v8String(m_scriptState->isolate(), functionName);
return preprocessSourceCode(sourceCode, sourceName, functionNameString);
}
@@ -91,17 +93,17 @@ String ScriptPreprocessor::preprocessSourceCode(const String& sourceCode, const
if (!isValid())
return sourceCode;
- v8::HandleScope handleScope(m_isolate);
- v8::Context::Scope contextScope(m_context.newLocal(m_isolate));
+ v8::Isolate* isolate = m_scriptState->isolate();
+ ScriptState::Scope scope(m_scriptState.get());
- v8::Handle<v8::String> sourceCodeString = v8String(m_isolate, sourceCode);
- v8::Handle<v8::String> sourceNameString = v8String(m_isolate, sourceName);
+ v8::Handle<v8::String> sourceCodeString = v8String(isolate, sourceCode);
+ v8::Handle<v8::String> sourceNameString = v8String(isolate, sourceName);
v8::Handle<v8::Value> argv[] = { sourceCodeString, sourceNameString, functionName};
v8::TryCatch tryCatch;
tryCatch.SetVerbose(true);
TemporaryChange<bool> isPreprocessing(m_isPreprocessing, true);
- v8::Handle<v8::Value> resultValue = V8ScriptRunner::callAsFunction(m_preprocessorFunction.newLocal(m_isolate), m_context.newLocal(m_isolate)->Global(), WTF_ARRAY_LENGTH(argv), argv);
+ v8::Handle<v8::Value> resultValue = V8ScriptRunner::callAsFunction(isolate, m_preprocessorFunction.newLocal(isolate), m_scriptState->context()->Global(), WTF_ARRAY_LENGTH(argv), argv);
if (!resultValue.IsEmpty() && resultValue->IsString())
return toCoreStringWithNullCheck(resultValue.As<v8::String>());
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/ScriptPreprocessor.h b/chromium/third_party/WebKit/Source/bindings/v8/ScriptPreprocessor.h
index 823c8be95ef..20e8ac09cb9 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/ScriptPreprocessor.h
+++ b/chromium/third_party/WebKit/Source/bindings/v8/ScriptPreprocessor.h
@@ -40,12 +40,11 @@ namespace WebCore {
class ScriptController;
class ScriptSourceCode;
class ScriptDebugServer;
-class PageConsole;
class ScriptPreprocessor {
WTF_MAKE_NONCOPYABLE(ScriptPreprocessor);
public:
- ScriptPreprocessor(const ScriptSourceCode&, ScriptController&, PageConsole&);
+ ScriptPreprocessor(const ScriptSourceCode&, LocalFrame*);
String preprocessSourceCode(const String& sourceCode, const String& sourceName);
String preprocessSourceCode(const String& sourceCode, const String& sourceName, const String& functionName);
bool isPreprocessing() { return m_isPreprocessing; }
@@ -53,9 +52,7 @@ public:
private:
String preprocessSourceCode(const String& sourceCode, const String& sourceName, v8::Handle<v8::Value> functionName);
- RefPtr<DOMWrapperWorld> m_world;
- ScopedPersistent<v8::Context> m_context;
- v8::Isolate* m_isolate;
+ RefPtr<ScriptState> m_scriptState;
ScopedPersistent<v8::Function> m_preprocessorFunction;
bool m_isPreprocessing;
};
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/ScriptProfiler.cpp b/chromium/third_party/WebKit/Source/bindings/v8/ScriptProfiler.cpp
index 914a943a206..07a65f74a49 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/ScriptProfiler.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/ScriptProfiler.cpp
@@ -31,12 +31,11 @@
#include "config.h"
#include "bindings/v8/ScriptProfiler.h"
-#include "V8Node.h"
-#include "V8Window.h"
+#include "bindings/core/v8/V8Node.h"
+#include "bindings/core/v8/V8Window.h"
#include "bindings/v8/RetainedDOMInfo.h"
-#include "bindings/v8/ScriptObject.h"
+#include "bindings/v8/ScriptValue.h"
#include "bindings/v8/V8Binding.h"
-#include "bindings/v8/V8DOMWrapper.h"
#include "bindings/v8/WrapperTypeInfo.h"
#include "core/dom/Document.h"
#include "core/inspector/BindingVisitors.h"
@@ -70,19 +69,19 @@ void ScriptProfiler::start(const String& title)
if (!profiler)
return;
v8::HandleScope handleScope(isolate);
- profiler->StartCpuProfiling(v8String(isolate, title), true);
+ profiler->StartProfiling(v8String(isolate, title), true);
}
-PassRefPtr<ScriptProfile> ScriptProfiler::stop(const String& title)
+PassRefPtrWillBeRawPtr<ScriptProfile> ScriptProfiler::stop(const String& title)
{
v8::Isolate* isolate = v8::Isolate::GetCurrent();
v8::CpuProfiler* profiler = isolate->GetCpuProfiler();
if (!profiler)
- return 0;
+ return nullptr;
v8::HandleScope handleScope(isolate);
- const v8::CpuProfile* profile = profiler->StopCpuProfiling(v8String(isolate, title));
+ v8::CpuProfile* profile = profiler->StopProfiling(v8String(isolate, title));
if (!profile)
- return 0;
+ return nullptr;
String profileTitle = toCoreString(profile->GetTitle());
double idleTime = 0.0;
@@ -101,28 +100,14 @@ void ScriptProfiler::collectGarbage()
v8::V8::LowMemoryNotification();
}
-ScriptObject ScriptProfiler::objectByHeapObjectId(unsigned id)
+ScriptValue ScriptProfiler::objectByHeapObjectId(unsigned id)
{
v8::Isolate* isolate = v8::Isolate::GetCurrent();
v8::HeapProfiler* profiler = isolate->GetHeapProfiler();
- if (!profiler)
- return ScriptObject();
- // As ids are unique, it doesn't matter which HeapSnapshot owns HeapGraphNode.
- // We need to find first HeapSnapshot containing a node with the specified id.
- const v8::HeapGraphNode* node = 0;
- for (int i = 0, l = profiler->GetSnapshotCount(); i < l; ++i) {
- const v8::HeapSnapshot* snapshot = profiler->GetHeapSnapshot(i);
- node = snapshot->GetNodeById(id);
- if (node)
- break;
- }
- if (!node)
- return ScriptObject();
-
v8::HandleScope handleScope(isolate);
- v8::Handle<v8::Value> value = node->GetHeapValue();
- if (!value->IsObject())
- return ScriptObject();
+ v8::Handle<v8::Value> value = profiler->FindObjectById(id);
+ if (value.IsEmpty() || !value->IsObject())
+ return ScriptValue();
v8::Handle<v8::Object> object = value.As<v8::Object>();
@@ -131,11 +116,11 @@ ScriptObject ScriptProfiler::objectByHeapObjectId(unsigned id)
// Skip wrapper boilerplates which are like regular wrappers but don't have
// native object.
if (!wrapper.IsEmpty() && wrapper->IsUndefined())
- return ScriptObject();
+ return ScriptValue();
}
- ScriptState* scriptState = ScriptState::forContext(object->CreationContext());
- return ScriptObject(scriptState, object);
+ ScriptState* scriptState = ScriptState::from(object->CreationContext());
+ return ScriptValue(scriptState, object);
}
unsigned ScriptProfiler::getHeapObjectId(const ScriptValue& value)
@@ -146,13 +131,20 @@ unsigned ScriptProfiler::getHeapObjectId(const ScriptValue& value)
return id;
}
+void ScriptProfiler::clearHeapObjectIds()
+{
+ v8::Isolate* isolate = v8::Isolate::GetCurrent();
+ v8::HeapProfiler* profiler = isolate->GetHeapProfiler();
+ profiler->ClearObjectIds();
+}
+
namespace {
-class ActivityControlAdapter : public v8::ActivityControl {
+class ActivityControlAdapter FINAL : public v8::ActivityControl {
public:
ActivityControlAdapter(ScriptProfiler::HeapSnapshotProgress* progress)
: m_progress(progress), m_firstReport(true) { }
- ControlOption ReportProgressValue(int done, int total)
+ virtual ControlOption ReportProgressValue(int done, int total) OVERRIDE
{
ControlOption result = m_progress->isCanceled() ? kAbort : kContinue;
if (m_firstReport) {
@@ -169,19 +161,16 @@ private:
bool m_firstReport;
};
-class GlobalObjectNameResolver : public v8::HeapProfiler::ObjectNameResolver {
+class GlobalObjectNameResolver FINAL : public v8::HeapProfiler::ObjectNameResolver {
public:
- virtual const char* GetName(v8::Handle<v8::Object> object)
+ virtual const char* GetName(v8::Handle<v8::Object> object) OVERRIDE
{
- if (V8DOMWrapper::isWrapperOfType(object, &V8Window::wrapperTypeInfo)) {
- DOMWindow* window = V8Window::toNative(object);
- if (window) {
- CString url = window->document()->url().string().utf8();
- m_strings.append(url);
- return url.data();
- }
- }
- return 0;
+ LocalDOMWindow* window = toDOMWindow(object, v8::Isolate::GetCurrent());
+ if (!window)
+ return 0;
+ CString url = window->document()->url().string().utf8();
+ m_strings.append(url);
+ return url.data();
}
private:
@@ -190,9 +179,9 @@ private:
} // namespace
-void ScriptProfiler::startTrackingHeapObjects()
+void ScriptProfiler::startTrackingHeapObjects(bool trackAllocations)
{
- v8::Isolate::GetCurrent()->GetHeapProfiler()->StartTrackingHeapObjects();
+ v8::Isolate::GetCurrent()->GetHeapProfiler()->StartTrackingHeapObjects(trackAllocations);
}
namespace {
@@ -244,13 +233,13 @@ PassRefPtr<ScriptHeapSnapshot> ScriptProfiler::takeHeapSnapshot(const String& ti
v8::Isolate* isolate = v8::Isolate::GetCurrent();
v8::HeapProfiler* profiler = isolate->GetHeapProfiler();
if (!profiler)
- return 0;
+ return nullptr;
v8::HandleScope handleScope(isolate);
ASSERT(control);
ActivityControlAdapter adapter(control);
GlobalObjectNameResolver resolver;
const v8::HeapSnapshot* snapshot = profiler->TakeHeapSnapshot(v8String(isolate, title), &adapter, &resolver);
- return snapshot ? ScriptHeapSnapshot::create(snapshot) : 0;
+ return snapshot ? ScriptHeapSnapshot::create(snapshot) : nullptr;
}
static v8::RetainedObjectInfo* retainedDOMInfo(uint16_t classId, v8::Handle<v8::Value> wrapper)
@@ -292,7 +281,7 @@ void ScriptProfiler::visitNodeWrappers(WrappedNodeVisitor* visitor)
// Casting to Handle is safe here, since the Persistent cannot get
// GCd during visiting.
v8::Handle<v8::Object>* wrapper = reinterpret_cast<v8::Handle<v8::Object>*>(value);
- ASSERT_UNUSED(m_isolate, V8Node::hasInstanceInAnyWorld(*wrapper, m_isolate));
+ ASSERT_UNUSED(m_isolate, V8Node::hasInstance(*wrapper, m_isolate));
ASSERT((*wrapper)->IsObject());
m_visitor->visitNode(V8Node::toNative(*wrapper));
}
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/ScriptProfiler.h b/chromium/third_party/WebKit/Source/bindings/v8/ScriptProfiler.h
index f406c520764..167da66bf81 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/ScriptProfiler.h
+++ b/chromium/third_party/WebKit/Source/bindings/v8/ScriptProfiler.h
@@ -32,7 +32,6 @@
#define ScriptProfiler_h
#include "bindings/v8/ScriptHeapSnapshot.h"
-#include "bindings/v8/ScriptState.h"
#include "core/inspector/ScriptProfile.h"
#include "wtf/Forward.h"
@@ -41,11 +40,9 @@
namespace WebCore {
-class ExternalArrayVisitor;
class ExternalStringVisitor;
class WrappedNodeVisitor;
class Page;
-class ScriptObject;
class ScriptValue;
class WorkerGlobalScope;
@@ -68,13 +65,14 @@ public:
};
static void collectGarbage();
- static ScriptObject objectByHeapObjectId(unsigned id);
+ static ScriptValue objectByHeapObjectId(unsigned id);
static unsigned getHeapObjectId(const ScriptValue&);
+ static void clearHeapObjectIds();
static void setSamplingInterval(int intervalUs);
static void start(const String& title);
- static PassRefPtr<ScriptProfile> stop(const String& title);
+ static PassRefPtrWillBeRawPtr<ScriptProfile> stop(const String& title);
static PassRefPtr<ScriptHeapSnapshot> takeHeapSnapshot(const String& title, HeapSnapshotProgress*);
- static void startTrackingHeapObjects();
+ static void startTrackingHeapObjects(bool trackAllocations);
static void stopTrackingHeapObjects();
static unsigned requestHeapStatsUpdate(OutputStream*);
static void initialize();
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/ScriptPromise.cpp b/chromium/third_party/WebKit/Source/bindings/v8/ScriptPromise.cpp
index bdf4105edde..d6d8b317e0b 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/ScriptPromise.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/ScriptPromise.cpp
@@ -31,31 +31,105 @@
#include "config.h"
#include "bindings/v8/ScriptPromise.h"
+#include "bindings/v8/ScriptPromiseResolver.h"
#include "bindings/v8/V8Binding.h"
-#include "bindings/v8/V8DOMWrapper.h"
-#include "bindings/v8/custom/V8PromiseCustom.h"
+#include "core/dom/DOMException.h"
#include <v8.h>
namespace WebCore {
-ScriptPromise ScriptPromise::createPending(ExecutionContext* context)
+namespace {
+
+struct WithScriptState {
+ // Used by ToV8Value<WithScriptState, ScriptState*>.
+ static v8::Handle<v8::Object> getCreationContext(ScriptState* scriptState)
+ {
+ return scriptState->context()->Global();
+ }
+};
+
+} // namespace
+
+ScriptPromise::ScriptPromise(ScriptState* scriptState, v8::Handle<v8::Value> value)
+ : m_scriptState(scriptState)
+{
+ if (value.IsEmpty())
+ return;
+
+ if (!value->IsPromise()) {
+ m_promise = ScriptValue(scriptState, v8::Handle<v8::Value>());
+ V8ThrowException::throwTypeError("the given value is not a Promise", scriptState->isolate());
+ return;
+ }
+ m_promise = ScriptValue(scriptState, value);
+}
+
+ScriptPromise ScriptPromise::then(PassOwnPtr<ScriptFunction> onFulfilled, PassOwnPtr<ScriptFunction> onRejected)
+{
+ if (m_promise.isEmpty())
+ return ScriptPromise();
+
+ v8::Local<v8::Object> promise = m_promise.v8Value().As<v8::Object>();
+ v8::Local<v8::Function> v8OnFulfilled = ScriptFunction::adoptByGarbageCollector(onFulfilled);
+ v8::Local<v8::Function> v8OnRejected = ScriptFunction::adoptByGarbageCollector(onRejected);
+
+ ASSERT(promise->IsPromise());
+ // Return this Promise if no handlers are given.
+ // In fact it is not the exact bahavior of Promise.prototype.then
+ // but that is not a problem in this case.
+ v8::Local<v8::Promise> resultPromise = promise.As<v8::Promise>();
+ if (!v8OnFulfilled.IsEmpty()) {
+ resultPromise = resultPromise->Then(v8OnFulfilled);
+ if (resultPromise.IsEmpty()) {
+ // v8::Promise::Then may return an empty value, for example when
+ // the stack is exhausted.
+ return ScriptPromise();
+ }
+ }
+ if (!v8OnRejected.IsEmpty())
+ resultPromise = resultPromise->Catch(v8OnRejected);
+
+ return ScriptPromise(m_scriptState.get(), resultPromise);
+}
+
+ScriptPromise ScriptPromise::cast(ScriptState* scriptState, const ScriptValue& value)
+{
+ return ScriptPromise::cast(scriptState, value.v8Value());
+}
+
+ScriptPromise ScriptPromise::cast(ScriptState* scriptState, v8::Handle<v8::Value> value)
+{
+ if (value.IsEmpty())
+ return ScriptPromise();
+ if (value->IsPromise()) {
+ return ScriptPromise(scriptState, value);
+ }
+ RefPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver::create(scriptState);
+ ScriptPromise promise = resolver->promise();
+ resolver->resolve(value);
+ return promise;
+}
+
+ScriptPromise ScriptPromise::reject(ScriptState* scriptState, const ScriptValue& value)
+{
+ return ScriptPromise::reject(scriptState, value.v8Value());
+}
+
+ScriptPromise ScriptPromise::reject(ScriptState* scriptState, v8::Handle<v8::Value> value)
{
- ASSERT(context);
- v8::Isolate* isolate = toIsolate(context);
- ASSERT(isolate->InContext());
- v8::Handle<v8::Context> v8Context = toV8Context(context, DOMWrapperWorld::current());
- v8::Handle<v8::Object> creationContext = v8Context.IsEmpty() ? v8::Object::New() : v8Context->Global();
- v8::Handle<v8::Object> promise = V8PromiseCustom::createPromise(creationContext, isolate);
- return ScriptPromise(promise, isolate);
+ if (value.IsEmpty())
+ return ScriptPromise();
+ RefPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver::create(scriptState);
+ ScriptPromise promise = resolver->promise();
+ resolver->reject(value);
+ return promise;
}
-ScriptPromise ScriptPromise::createPending()
+ScriptPromise ScriptPromise::rejectWithDOMException(ScriptState* scriptState, PassRefPtrWillBeRawPtr<DOMException> exception)
{
- v8::Isolate* isolate = v8::Isolate::GetCurrent();
- ASSERT(isolate->InContext());
- v8::Handle<v8::Object> promise = V8PromiseCustom::createPromise(v8::Object::New(), isolate);
- return ScriptPromise(promise, isolate);
+ ASSERT(scriptState->isolate()->InContext());
+ return reject(scriptState, ToV8Value<WithScriptState, v8::Handle<v8::Object> >::toV8Value(exception, scriptState->context()->Global(), scriptState->isolate()));
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/ScriptPromise.h b/chromium/third_party/WebKit/Source/bindings/v8/ScriptPromise.h
index 0a93b10f3b4..eb79e4e3b17 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/ScriptPromise.h
+++ b/chromium/third_party/WebKit/Source/bindings/v8/ScriptPromise.h
@@ -31,14 +31,16 @@
#ifndef ScriptPromise_h
#define ScriptPromise_h
-#include "bindings/v8/ScopedPersistent.h"
+#include "bindings/v8/ScriptFunction.h"
#include "bindings/v8/ScriptValue.h"
-#include "bindings/v8/V8ScriptRunner.h"
+#include "platform/heap/Handle.h"
+#include "wtf/PassOwnPtr.h"
+#include "wtf/PassRefPtr.h"
#include <v8.h>
namespace WebCore {
-class ExecutionContext;
+class DOMException;
// ScriptPromise is the class for representing Promise values in C++ world.
// ScriptPromise holds a Promise.
@@ -48,22 +50,13 @@ class ExecutionContext;
class ScriptPromise {
public:
// Constructs an empty promise.
- ScriptPromise()
- : m_promise()
- {
- }
+ ScriptPromise() { }
- explicit ScriptPromise(const ScriptValue& promise)
- : m_promise(promise)
- {
- ASSERT(!m_promise.hasNoValue());
- }
+ // Constructs a ScriptPromise from |promise|.
+ // If |promise| is not a Promise object, throws a v8 TypeError.
+ ScriptPromise(ScriptState*, v8::Handle<v8::Value> promise);
- ScriptPromise(v8::Handle<v8::Value> promise, v8::Isolate* isolate)
- : m_promise(promise, isolate)
- {
- ASSERT(!m_promise.hasNoValue());
- }
+ ScriptPromise then(PassOwnPtr<ScriptFunction> onFulfilled, PassOwnPtr<ScriptFunction> onRejected = PassOwnPtr<ScriptFunction>());
bool isObject() const
{
@@ -90,9 +83,9 @@ public:
return m_promise.isolate();
}
- bool hasNoValue() const
+ bool isEmpty() const
{
- return m_promise.hasNoValue();
+ return m_promise.isEmpty();
}
void clear()
@@ -100,10 +93,20 @@ public:
m_promise.clear();
}
- static ScriptPromise createPending();
- static ScriptPromise createPending(ExecutionContext*);
+ // Constructs and returns a ScriptPromise from |value|.
+ // if |value| is not a Promise object, returns a Promise object
+ // resolved with |value|.
+ // Returns |value| itself if it is a Promise.
+ static ScriptPromise cast(ScriptState*, const ScriptValue& /*value*/);
+ static ScriptPromise cast(ScriptState*, v8::Handle<v8::Value> /*value*/);
+
+ static ScriptPromise reject(ScriptState*, const ScriptValue&);
+ static ScriptPromise reject(ScriptState*, v8::Handle<v8::Value>);
+
+ static ScriptPromise rejectWithDOMException(ScriptState*, PassRefPtrWillBeRawPtr<DOMException>);
private:
+ RefPtr<ScriptState> m_scriptState;
ScriptValue m_promise;
};
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/ScriptPromiseResolver.cpp b/chromium/third_party/WebKit/Source/bindings/v8/ScriptPromiseResolver.cpp
index fec672fcc15..ea7a6476b3f 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/ScriptPromiseResolver.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/ScriptPromiseResolver.cpp
@@ -31,20 +31,21 @@
#include "config.h"
#include "bindings/v8/ScriptPromiseResolver.h"
-#include "bindings/v8/ScriptState.h"
#include "bindings/v8/ScriptValue.h"
#include "bindings/v8/V8Binding.h"
#include "bindings/v8/V8DOMWrapper.h"
-#include "bindings/v8/custom/V8PromiseCustom.h"
#include <v8.h>
namespace WebCore {
-ScriptPromiseResolver::ScriptPromiseResolver(ScriptPromise promise)
- : m_isolate(promise.isolate())
- , m_promise(promise)
+ScriptPromiseResolver::ScriptPromiseResolver(ScriptState* scriptState)
+ : m_scriptState(scriptState)
{
+ v8::Isolate* isolate = m_scriptState->isolate();
+ ASSERT(!m_scriptState->contextIsEmpty());
+ ASSERT(isolate->InContext());
+ m_resolver = ScriptValue(scriptState, v8::Promise::Resolver::New(isolate));
}
ScriptPromiseResolver::~ScriptPromiseResolver()
@@ -52,61 +53,42 @@ ScriptPromiseResolver::~ScriptPromiseResolver()
// We don't call "reject" here because it requires a caller
// to be in a v8 context.
- m_promise.clear();
+ m_resolver.clear();
}
-PassRefPtr<ScriptPromiseResolver> ScriptPromiseResolver::create(ScriptPromise promise, ExecutionContext* context)
+ScriptPromise ScriptPromiseResolver::promise()
{
- ASSERT(promise.isolate()->InContext());
- ASSERT(context);
- return adoptRef(new ScriptPromiseResolver(promise));
+ ASSERT(!m_scriptState->contextIsEmpty());
+ ASSERT(m_scriptState->isolate()->InContext());
+ if (!m_resolver.isEmpty()) {
+ v8::Local<v8::Promise::Resolver> v8Resolver = m_resolver.v8Value().As<v8::Promise::Resolver>();
+ return ScriptPromise(m_scriptState.get(), v8Resolver->GetPromise());
+ }
+ return ScriptPromise();
}
-PassRefPtr<ScriptPromiseResolver> ScriptPromiseResolver::create(ScriptPromise promise)
+PassRefPtr<ScriptPromiseResolver> ScriptPromiseResolver::create(ScriptState* scriptState)
{
- ASSERT(promise.isolate()->InContext());
- return adoptRef(new ScriptPromiseResolver(promise));
-}
-
-bool ScriptPromiseResolver::isPending() const
-{
- ASSERT(m_isolate->InContext());
- if (m_promise.hasNoValue())
- return false;
- v8::Local<v8::Object> promise = m_promise.v8Value().As<v8::Object>();
- v8::Local<v8::Object> internal = V8PromiseCustom::getInternal(promise);
- V8PromiseCustom::PromiseState state = V8PromiseCustom::getState(internal);
- return state == V8PromiseCustom::Pending;
+ ASSERT(scriptState->isolate()->InContext());
+ return adoptRef(new ScriptPromiseResolver(scriptState));
}
void ScriptPromiseResolver::resolve(v8::Handle<v8::Value> value)
{
- ASSERT(m_isolate->InContext());
- if (!isPending())
- return;
- V8PromiseCustom::resolve(m_promise.v8Value().As<v8::Object>(), value, m_isolate);
- m_promise.clear();
+ ASSERT(m_scriptState->isolate()->InContext());
+ if (!m_resolver.isEmpty()) {
+ m_resolver.v8Value().As<v8::Promise::Resolver>()->Resolve(value);
+ }
+ m_resolver.clear();
}
void ScriptPromiseResolver::reject(v8::Handle<v8::Value> value)
{
- ASSERT(m_isolate->InContext());
- if (!isPending())
- return;
- V8PromiseCustom::reject(m_promise.v8Value().As<v8::Object>(), value, m_isolate);
- m_promise.clear();
-}
-
-void ScriptPromiseResolver::resolve(ScriptValue value)
-{
- ASSERT(m_isolate->InContext());
- resolve(value.v8Value());
-}
-
-void ScriptPromiseResolver::reject(ScriptValue value)
-{
- ASSERT(m_isolate->InContext());
- reject(value.v8Value());
+ ASSERT(m_scriptState->isolate()->InContext());
+ if (!m_resolver.isEmpty()) {
+ m_resolver.v8Value().As<v8::Promise::Resolver>()->Reject(value);
+ }
+ m_resolver.clear();
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/ScriptPromiseResolver.h b/chromium/third_party/WebKit/Source/bindings/v8/ScriptPromiseResolver.h
index 0379b244be5..513abab924b 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/ScriptPromiseResolver.h
+++ b/chromium/third_party/WebKit/Source/bindings/v8/ScriptPromiseResolver.h
@@ -31,9 +31,6 @@
#ifndef ScriptPromiseResolver_h
#define ScriptPromiseResolver_h
-#include "bindings/v8/DOMWrapperWorld.h"
-#include "bindings/v8/ScopedPersistent.h"
-#include "bindings/v8/ScriptObject.h"
#include "bindings/v8/ScriptPromise.h"
#include "bindings/v8/ScriptState.h"
#include "bindings/v8/ScriptValue.h"
@@ -50,25 +47,28 @@ class ExecutionContext;
// (resolve / reject) from C++ world.
// ScriptPromiseResolver holds a PromiseResolver.
// Here is a typical usage:
-// 1. Create a ScriptPromiseResolver from a ScriptPromise.
-// 2. Pass the promise object of the holder to a JavaScript program
+// 1. Create a ScriptPromiseResolver.
+// 2. Pass the associated promise object to a JavaScript program
// (such as XMLHttpRequest return value).
// 3. Call resolve or reject when the operation completes or
// the operation fails respectively.
//
// Most methods including constructors must be called within a v8 context.
// To use ScriptPromiseResolver out of a v8 context the caller must
-// enter a v8 context, for example by using ScriptScope and ScriptState.
+// enter a v8 context. Please use ScriptPromiseResolverWithContext
+// in such cases.
//
// To prevent memory leaks, you should release the reference manually
// by calling resolve or reject.
// Destroying the object will also release the reference.
-//
+// Note that ScriptPromiseResolver::promise returns an empty value when the
+// resolver is already resolved or rejected. If you want to resolve a resolver
+// immediately and return the associated promise, you should get the promise
+// before resolving.
class ScriptPromiseResolver : public RefCounted<ScriptPromiseResolver> {
WTF_MAKE_NONCOPYABLE(ScriptPromiseResolver);
public:
- static PassRefPtr<ScriptPromiseResolver> create(ScriptPromise, ExecutionContext*);
- static PassRefPtr<ScriptPromiseResolver> create(ScriptPromise);
+ static PassRefPtr<ScriptPromiseResolver> create(ScriptState*);
// A ScriptPromiseResolver should be resolved / rejected before
// its destruction.
@@ -76,90 +76,75 @@ public:
// entering a v8 context.
~ScriptPromiseResolver();
- // Return true if the promise object is in pending state.
- bool isPending() const;
+ // Returns the underlying Promise.
+ // Note that the underlying Promise is cleared when |resolve| or |reject|
+ // is called.
+ ScriptPromise promise();
- ScriptPromise promise()
+ template<typename T>
+ void resolve(const T& value, ExecutionContext* executionContext)
{
- ASSERT(m_promise.isolate()->InContext());
- return m_promise;
+ ASSERT(m_scriptState->isolate()->InContext());
+ // You should use ScriptPromiseResolverWithContext when you want
+ // to resolve a Promise in a non-original V8 context.
+ return resolve(value);
}
-
- // To use following template methods, T must be a DOM class.
-
- // This method will be implemented by the code generator.
- template<typename T>
- void resolve(T* value, v8::Handle<v8::Object> creationContext) { resolve(toV8NoInline(value, creationContext, m_isolate)); }
template<typename T>
- void reject(T* value, v8::Handle<v8::Object> creationContext) { reject(toV8NoInline(value, creationContext, m_isolate)); }
-
+ void reject(const T& value, ExecutionContext* executionContext)
+ {
+ ASSERT(m_scriptState->isolate()->InContext());
+ // You should use ScriptPromiseResolverWithContext when you want
+ // to reject a Promise in a non-original V8 context.
+ return reject(value);
+ }
template<typename T>
- void resolve(PassRefPtr<T> value, v8::Handle<v8::Object> creationContext) { resolve(value.get(), creationContext); }
+ void resolve(const T& value)
+ {
+ ASSERT(m_scriptState->isolate()->InContext());
+ resolve(toV8Value(value));
+ }
template<typename T>
- void reject(PassRefPtr<T> value, v8::Handle<v8::Object> creationContext) { reject(value.get(), creationContext); }
+ void reject(const T& value)
+ {
+ ASSERT(m_scriptState->isolate()->InContext());
+ reject(toV8Value(value));
+ }
+ template<typename T> void resolve(const T& value, v8::Handle<v8::Object> creationContext)
+ {
+ ASSERT(m_scriptState->isolate()->InContext());
+ resolve(toV8Value(value, creationContext));
+ }
+ template<typename T> void reject(const T& value, v8::Handle<v8::Object> creationContext)
+ {
+ ASSERT(m_scriptState->isolate()->InContext());
+ reject(toV8Value(value, creationContext));
+ }
- template<typename T>
- inline void resolve(T* value, ExecutionContext*);
- template<typename T>
- inline void reject(T* value, ExecutionContext*);
+ v8::Isolate* isolate() const { return m_scriptState->isolate(); }
- template<typename T>
- void resolve(PassRefPtr<T> value, ExecutionContext* context) { resolve(value.get(), context); }
- template<typename T>
- void reject(PassRefPtr<T> value, ExecutionContext* context) { reject(value.get(), context); }
+ void resolve(v8::Handle<v8::Value>);
+ void reject(v8::Handle<v8::Value>);
+private:
template<typename T>
- inline void resolve(T* value);
- template<typename T>
- inline void reject(T* value);
+ v8::Handle<v8::Value> toV8Value(const T& value, v8::Handle<v8::Object> creationContext)
+ {
+ return ToV8Value<ScriptPromiseResolver, v8::Handle<v8::Object> >::toV8Value(value, creationContext, m_scriptState->isolate());
+ }
template<typename T>
- void resolve(PassRefPtr<T> value) { resolve(value.get()); }
- template<typename T>
- void reject(PassRefPtr<T> value) { reject(value.get()); }
-
- void resolve(ScriptValue);
- void reject(ScriptValue);
+ v8::Handle<v8::Value> toV8Value(const T& value)
+ {
+ return ToV8Value<ScriptPromiseResolver, v8::Handle<v8::Object> >::toV8Value(value, m_scriptState->context()->Global(), m_scriptState->isolate());
+ }
-private:
- ScriptPromiseResolver(ScriptPromise);
- void resolve(v8::Handle<v8::Value>);
- void reject(v8::Handle<v8::Value>);
+ explicit ScriptPromiseResolver(ScriptState*);
- v8::Isolate* m_isolate;
- ScriptPromise m_promise;
+ // FIXME: Remove this once ScriptValue::scriptState() becomes available.
+ RefPtr<ScriptState> m_scriptState;
+ ScriptValue m_resolver;
};
-template<typename T>
-void ScriptPromiseResolver::resolve(T* value, ExecutionContext* context)
-{
- ASSERT(m_isolate->InContext());
- v8::Handle<v8::Context> v8Context = toV8Context(context, DOMWrapperWorld::current());
- resolve(value, v8Context->Global());
-}
-
-template<typename T>
-void ScriptPromiseResolver::reject(T* value, ExecutionContext* context)
-{
- ASSERT(m_isolate->InContext());
- v8::Handle<v8::Context> v8Context = toV8Context(context, DOMWrapperWorld::current());
- reject(value, v8Context->Global());
-}
-
-template<typename T>
-void ScriptPromiseResolver::resolve(T* value)
-{
- ASSERT(m_isolate->InContext());
- resolve(value, v8::Object::New(m_isolate));
-}
-
-template<typename T>
-void ScriptPromiseResolver::reject(T* value)
-{
- ASSERT(m_isolate->InContext());
- reject(value, v8::Object::New(m_isolate));
-}
-
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/ScriptPromiseResolverTest.cpp b/chromium/third_party/WebKit/Source/bindings/v8/ScriptPromiseResolverTest.cpp
index 26b796dd892..8a21cf7896b 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/ScriptPromiseResolverTest.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/ScriptPromiseResolverTest.cpp
@@ -33,7 +33,6 @@
#include "bindings/v8/ScriptPromise.h"
#include "bindings/v8/V8Binding.h"
-#include "bindings/v8/custom/V8PromiseCustom.h"
#include <gtest/gtest.h>
#include <v8.h>
@@ -42,132 +41,145 @@ namespace WebCore {
namespace {
-class ScriptPromiseResolverTest : public testing::Test {
+class Function : public ScriptFunction {
public:
- ScriptPromiseResolverTest()
- : m_isolate(v8::Isolate::GetCurrent())
- , m_handleScope(m_isolate)
- , m_context(m_isolate, v8::Context::New(m_isolate))
- , m_contextScope(m_context.newLocal(m_isolate))
+ static PassOwnPtr<Function> create(v8::Isolate* isolate, String* value)
{
+ return adoptPtr(new Function(isolate, value));
}
- void SetUp()
+ virtual ScriptValue call(ScriptValue value) OVERRIDE
{
- v8::Handle<v8::Context> context(m_context.newLocal(m_isolate));
- V8PerContextDataHolder::install(context);
- m_perContextData = V8PerContextData::create(context);
- m_perContextData->init();
- m_promise = ScriptPromise::createPending();
- m_resolver = ScriptPromiseResolver::create(m_promise);
+ ASSERT(!value.isEmpty());
+ *m_value = toCoreString(value.v8Value()->ToString());
+ return value;
}
- void TearDown()
- {
- m_resolver = 0;
- m_promise.clear();
- m_perContextData.clear();
- }
+private:
+ Function(v8::Isolate* isolate, String* value) : ScriptFunction(isolate), m_value(value) { }
- V8PromiseCustom::PromiseState state()
- {
- return V8PromiseCustom::getState(V8PromiseCustom::getInternal(promise()));
- }
+ String* m_value;
+};
- v8::Local<v8::Value> result()
+class ScriptPromiseResolverTest : public testing::Test {
+public:
+ ScriptPromiseResolverTest()
+ : m_scope(v8::Isolate::GetCurrent())
{
- return V8PromiseCustom::getInternal(promise())->GetInternalField(V8PromiseCustom::InternalResultIndex);
+ m_resolver = ScriptPromiseResolver::create(m_scope.scriptState());
}
- v8::Local<v8::Object> promise()
+ virtual ~ScriptPromiseResolverTest()
{
- ASSERT(!m_promise.hasNoValue());
- return m_promise.v8Value().As<v8::Object>();
+ // Run all pending microtasks here.
+ isolate()->RunMicrotasks();
}
+ v8::Isolate* isolate() { return m_scope.isolate(); }
+
protected:
- v8::Isolate* m_isolate;
- v8::HandleScope m_handleScope;
- ScopedPersistent<v8::Context> m_context;
- v8::Context::Scope m_contextScope;
RefPtr<ScriptPromiseResolver> m_resolver;
- ScriptPromise m_promise;
- OwnPtr<V8PerContextData> m_perContextData;
+ V8TestingScope m_scope;
};
TEST_F(ScriptPromiseResolverTest, initialState)
{
- EXPECT_TRUE(m_resolver->isPending());
- EXPECT_EQ(V8PromiseCustom::Pending, state());
- EXPECT_TRUE(result()->IsUndefined());
+ ScriptPromise promise = m_resolver->promise();
+ ASSERT_FALSE(promise.isEmpty());
+ String onFulfilled, onRejected;
+ promise.then(Function::create(isolate(), &onFulfilled), Function::create(isolate(), &onRejected));
+
+ EXPECT_EQ(String(), onFulfilled);
+ EXPECT_EQ(String(), onRejected);
+
+ isolate()->RunMicrotasks();
+
+ EXPECT_EQ(String(), onFulfilled);
+ EXPECT_EQ(String(), onRejected);
}
TEST_F(ScriptPromiseResolverTest, resolve)
{
- EXPECT_TRUE(m_resolver->isPending());
- EXPECT_EQ(V8PromiseCustom::Pending, state());
- EXPECT_TRUE(result()->IsUndefined());
+ ScriptPromise promise = m_resolver->promise();
+ ASSERT_FALSE(promise.isEmpty());
+ String onFulfilled, onRejected;
+ promise.then(Function::create(isolate(), &onFulfilled), Function::create(isolate(), &onRejected));
+
+ EXPECT_EQ(String(), onFulfilled);
+ EXPECT_EQ(String(), onRejected);
- m_resolver->resolve(ScriptValue(v8::Integer::New(3, m_isolate), m_isolate));
+ m_resolver->resolve("hello");
+ EXPECT_TRUE(m_resolver->promise().isEmpty());
+ isolate()->RunMicrotasks();
- EXPECT_FALSE(m_resolver->isPending());
- EXPECT_EQ(V8PromiseCustom::Fulfilled, state());
- ASSERT_TRUE(result()->IsNumber());
- EXPECT_EQ(3, result().As<v8::Integer>()->Value());
+ EXPECT_EQ("hello", onFulfilled);
+ EXPECT_EQ(String(), onRejected);
}
TEST_F(ScriptPromiseResolverTest, reject)
{
- EXPECT_TRUE(m_resolver->isPending());
- EXPECT_EQ(V8PromiseCustom::Pending, state());
- EXPECT_TRUE(result()->IsUndefined());
+ ScriptPromise promise = m_resolver->promise();
+ ASSERT_FALSE(promise.isEmpty());
+ String onFulfilled, onRejected;
+ promise.then(Function::create(isolate(), &onFulfilled), Function::create(isolate(), &onRejected));
- m_resolver->reject(ScriptValue(v8::Integer::New(3, m_isolate), m_isolate));
+ EXPECT_EQ(String(), onFulfilled);
+ EXPECT_EQ(String(), onRejected);
- EXPECT_FALSE(m_resolver->isPending());
- EXPECT_EQ(V8PromiseCustom::Rejected, state());
- ASSERT_TRUE(result()->IsNumber());
- EXPECT_EQ(3, result().As<v8::Integer>()->Value());
+ m_resolver->reject("hello");
+ EXPECT_TRUE(m_resolver->promise().isEmpty());
+ isolate()->RunMicrotasks();
+
+ EXPECT_EQ(String(), onFulfilled);
+ EXPECT_EQ("hello", onRejected);
}
TEST_F(ScriptPromiseResolverTest, resolveOverResolve)
{
- EXPECT_TRUE(m_resolver->isPending());
- EXPECT_EQ(V8PromiseCustom::Pending, state());
- EXPECT_TRUE(result()->IsUndefined());
-
- m_resolver->resolve(ScriptValue(v8::Integer::New(3, m_isolate), m_isolate));
-
- EXPECT_FALSE(m_resolver->isPending());
- EXPECT_EQ(V8PromiseCustom::Fulfilled, state());
- ASSERT_TRUE(result()->IsNumber());
- EXPECT_EQ(3, result().As<v8::Integer>()->Value());
-
- m_resolver->resolve(ScriptValue(v8::Integer::New(4, m_isolate), m_isolate));
- EXPECT_FALSE(m_resolver->isPending());
- EXPECT_EQ(V8PromiseCustom::Fulfilled, state());
- ASSERT_TRUE(result()->IsNumber());
- EXPECT_EQ(3, result().As<v8::Integer>()->Value());
+ ScriptPromise promise = m_resolver->promise();
+ ASSERT_FALSE(promise.isEmpty());
+ String onFulfilled, onRejected;
+ promise.then(Function::create(isolate(), &onFulfilled), Function::create(isolate(), &onRejected));
+
+ EXPECT_EQ(String(), onFulfilled);
+ EXPECT_EQ(String(), onRejected);
+
+ m_resolver->resolve("hello");
+ EXPECT_TRUE(m_resolver->promise().isEmpty());
+ isolate()->RunMicrotasks();
+
+ EXPECT_EQ("hello", onFulfilled);
+ EXPECT_EQ(String(), onRejected);
+
+ m_resolver->resolve("world");
+ isolate()->RunMicrotasks();
+
+ EXPECT_EQ("hello", onFulfilled);
+ EXPECT_EQ(String(), onRejected);
}
TEST_F(ScriptPromiseResolverTest, rejectOverResolve)
{
- EXPECT_TRUE(m_resolver->isPending());
- EXPECT_EQ(V8PromiseCustom::Pending, state());
- EXPECT_TRUE(result()->IsUndefined());
-
- m_resolver->resolve(ScriptValue(v8::Integer::New(3, m_isolate), m_isolate));
-
- EXPECT_FALSE(m_resolver->isPending());
- EXPECT_EQ(V8PromiseCustom::Fulfilled, state());
- ASSERT_TRUE(result()->IsNumber());
- EXPECT_EQ(3, result().As<v8::Integer>()->Value());
-
- m_resolver->reject(ScriptValue(v8::Integer::New(4, m_isolate), m_isolate));
- EXPECT_FALSE(m_resolver->isPending());
- EXPECT_EQ(V8PromiseCustom::Fulfilled, state());
- ASSERT_TRUE(result()->IsNumber());
- EXPECT_EQ(3, result().As<v8::Integer>()->Value());
+ ScriptPromise promise = m_resolver->promise();
+ ASSERT_FALSE(promise.isEmpty());
+ String onFulfilled, onRejected;
+ promise.then(Function::create(isolate(), &onFulfilled), Function::create(isolate(), &onRejected));
+
+ EXPECT_EQ(String(), onFulfilled);
+ EXPECT_EQ(String(), onRejected);
+
+ m_resolver->resolve("hello");
+ EXPECT_TRUE(m_resolver->promise().isEmpty());
+ isolate()->RunMicrotasks();
+
+ EXPECT_EQ("hello", onFulfilled);
+ EXPECT_EQ(String(), onRejected);
+
+ m_resolver->reject("world");
+ isolate()->RunMicrotasks();
+
+ EXPECT_EQ("hello", onFulfilled);
+ EXPECT_EQ(String(), onRejected);
}
} // namespace
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/ScriptPromiseResolverWithContext.cpp b/chromium/third_party/WebKit/Source/bindings/v8/ScriptPromiseResolverWithContext.cpp
new file mode 100644
index 00000000000..6cd7ab8b5ef
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/bindings/v8/ScriptPromiseResolverWithContext.cpp
@@ -0,0 +1,101 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "bindings/v8/ScriptPromiseResolverWithContext.h"
+
+#include "bindings/v8/V8RecursionScope.h"
+
+namespace WebCore {
+
+ScriptPromiseResolverWithContext::ScriptPromiseResolverWithContext(ScriptState* scriptState)
+ : ActiveDOMObject(scriptState->executionContext())
+ , m_state(Pending)
+ , m_scriptState(scriptState)
+ , m_mode(Default)
+ , m_timer(this, &ScriptPromiseResolverWithContext::onTimerFired)
+ , m_resolver(ScriptPromiseResolver::create(m_scriptState.get()))
+#if ASSERTION_ENABLED
+ , m_isPromiseCalled(false)
+#endif
+{
+ if (executionContext()->activeDOMObjectsAreStopped())
+ m_state = ResolvedOrRejected;
+}
+
+void ScriptPromiseResolverWithContext::suspend()
+{
+ m_timer.stop();
+}
+
+void ScriptPromiseResolverWithContext::resume()
+{
+ if (m_state == Resolving || m_state == Rejecting)
+ m_timer.startOneShot(0, FROM_HERE);
+}
+
+void ScriptPromiseResolverWithContext::stop()
+{
+ m_timer.stop();
+ clear();
+}
+
+void ScriptPromiseResolverWithContext::keepAliveWhilePending()
+{
+ if (m_state == ResolvedOrRejected || m_mode == KeepAliveWhilePending)
+ return;
+
+ // Keep |this| while the promise is Pending.
+ // deref() will be called in clear().
+ m_mode = KeepAliveWhilePending;
+ ref();
+}
+
+void ScriptPromiseResolverWithContext::onTimerFired(Timer<ScriptPromiseResolverWithContext>*)
+{
+ ScriptState::Scope scope(m_scriptState.get());
+ resolveOrRejectImmediately();
+}
+
+void ScriptPromiseResolverWithContext::resolveOrRejectImmediately()
+{
+ ASSERT(!executionContext()->activeDOMObjectsAreStopped());
+ ASSERT(!executionContext()->activeDOMObjectsAreSuspended());
+ {
+ // FIXME: The V8RecursionScope is only necessary to force microtask delivery for promises
+ // resolved or rejected in workers. It can be removed once worker threads run microtasks
+ // at the end of every task (rather than just the main thread).
+ V8RecursionScope scope(m_scriptState->isolate(), m_scriptState->executionContext());
+ if (m_state == Resolving) {
+ m_resolver->resolve(m_value.newLocal(m_scriptState->isolate()));
+ } else {
+ ASSERT(m_state == Rejecting);
+ m_resolver->reject(m_value.newLocal(m_scriptState->isolate()));
+ }
+ }
+ clear();
+}
+
+void ScriptPromiseResolverWithContext::clear()
+{
+ if (m_state == ResolvedOrRejected)
+ return;
+ ResolutionState state = m_state;
+ m_state = ResolvedOrRejected;
+ m_resolver.clear();
+ m_value.clear();
+ if (m_mode == KeepAliveWhilePending) {
+ // |ref| was called in |keepAliveWhilePending|.
+ deref();
+ }
+ // |this| may be deleted here, but it is safe to check |state| because
+ // it doesn't depend on |this|. When |this| is deleted, |state| can't be
+ // |Resolving| nor |Rejecting| and hence |this->deref()| can't be executed.
+ if (state == Resolving || state == Rejecting) {
+ // |ref| was called in |resolveOrReject|.
+ deref();
+ }
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/ScriptPromiseResolverWithContext.h b/chromium/third_party/WebKit/Source/bindings/v8/ScriptPromiseResolverWithContext.h
new file mode 100644
index 00000000000..729fb15beed
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/bindings/v8/ScriptPromiseResolverWithContext.h
@@ -0,0 +1,145 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef ScriptPromiseResolverWithContext_h
+#define ScriptPromiseResolverWithContext_h
+
+#include "bindings/v8/ScopedPersistent.h"
+#include "bindings/v8/ScriptPromise.h"
+#include "bindings/v8/ScriptPromiseResolver.h"
+#include "bindings/v8/ScriptState.h"
+#include "bindings/v8/V8Binding.h"
+#include "core/dom/ActiveDOMObject.h"
+#include "core/dom/ExecutionContext.h"
+#include "platform/Timer.h"
+#include "wtf/RefCounted.h"
+#include "wtf/Vector.h"
+#include <v8.h>
+
+namespace WebCore {
+
+// This class wraps ScriptPromiseResolver and provides the following
+// functionalities in addition to ScriptPromiseResolver's.
+// - A ScriptPromiseResolverWithContext retains a ScriptState. A caller
+// can call resolve or reject from outside of a V8 context.
+// - This class is an ActiveDOMObject and keeps track of the associated
+// ExecutionContext state. When the ExecutionContext is suspended,
+// resolve or reject will be delayed. When it is stopped, resolve or reject
+// will be ignored.
+class ScriptPromiseResolverWithContext : public ActiveDOMObject, public RefCounted<ScriptPromiseResolverWithContext> {
+ WTF_MAKE_NONCOPYABLE(ScriptPromiseResolverWithContext);
+
+public:
+ static PassRefPtr<ScriptPromiseResolverWithContext> create(ScriptState* scriptState)
+ {
+ RefPtr<ScriptPromiseResolverWithContext> resolver = adoptRef(new ScriptPromiseResolverWithContext(scriptState));
+ resolver->suspendIfNeeded();
+ return resolver.release();
+ }
+
+ virtual ~ScriptPromiseResolverWithContext()
+ {
+ // This assertion fails if:
+ // - promise() is called at least once and
+ // - this resolver is destructed before it is resolved, rejected or
+ // the associated ExecutionContext is stopped.
+ ASSERT(m_state == ResolvedOrRejected || !m_isPromiseCalled);
+ }
+
+ // Anything that can be passed to toV8Value can be passed to this function.
+ template <typename T>
+ void resolve(T value)
+ {
+ resolveOrReject(value, Resolving);
+ }
+
+ // Anything that can be passed to toV8Value can be passed to this function.
+ template <typename T>
+ void reject(T value)
+ {
+ resolveOrReject(value, Rejecting);
+ }
+
+ ScriptState* scriptState() { return m_scriptState.get(); }
+
+ // Note that an empty ScriptPromise will be returned after resolve or
+ // reject is called.
+ ScriptPromise promise()
+ {
+#if ASSERT_ENABLED
+ m_isPromiseCalled = true;
+#endif
+ return m_resolver ? m_resolver->promise() : ScriptPromise();
+ }
+
+ ScriptState* scriptState() const { return m_scriptState.get(); }
+
+ // ActiveDOMObject implementation.
+ virtual void suspend() OVERRIDE;
+ virtual void resume() OVERRIDE;
+ virtual void stop() OVERRIDE;
+
+ // Once this function is called this resolver stays alive while the
+ // promise is pending and the associated ExecutionContext isn't stopped.
+ void keepAliveWhilePending();
+
+protected:
+ // You need to call suspendIfNeeded after the construction because
+ // this is an ActiveDOMObject.
+ explicit ScriptPromiseResolverWithContext(ScriptState*);
+
+private:
+ enum ResolutionState {
+ Pending,
+ Resolving,
+ Rejecting,
+ ResolvedOrRejected,
+ };
+ enum LifetimeMode {
+ Default,
+ KeepAliveWhilePending,
+ };
+
+ template<typename T>
+ v8::Handle<v8::Value> toV8Value(const T& value)
+ {
+ return ToV8Value<ScriptPromiseResolverWithContext, v8::Handle<v8::Object> >::toV8Value(value, m_scriptState->context()->Global(), m_scriptState->isolate());
+ }
+
+ template <typename T>
+ void resolveOrReject(T value, ResolutionState newState)
+ {
+ if (m_state != Pending || !executionContext() || executionContext()->activeDOMObjectsAreStopped())
+ return;
+ ASSERT(newState == Resolving || newState == Rejecting);
+ m_state = newState;
+ // Retain this object until it is actually resolved or rejected.
+ // |deref| will be called in |clear|.
+ ref();
+
+ ScriptState::Scope scope(m_scriptState.get());
+ m_value.set(m_scriptState->isolate(), toV8Value(value));
+ if (!executionContext()->activeDOMObjectsAreSuspended())
+ resolveOrRejectImmediately();
+ }
+
+ void resolveOrRejectImmediately();
+ void onTimerFired(Timer<ScriptPromiseResolverWithContext>*);
+ void clear();
+
+ ResolutionState m_state;
+ const RefPtr<ScriptState> m_scriptState;
+ LifetimeMode m_mode;
+ Timer<ScriptPromiseResolverWithContext> m_timer;
+ RefPtr<ScriptPromiseResolver> m_resolver;
+ ScopedPersistent<v8::Value> m_value;
+#if ASSERT_ENABLED
+ // True if promise() is called.
+ bool m_isPromiseCalled;
+#endif
+};
+
+} // namespace WebCore
+
+#endif // #ifndef ScriptPromiseResolverWithContext_h
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/ScriptPromiseTest.cpp b/chromium/third_party/WebKit/Source/bindings/v8/ScriptPromiseTest.cpp
new file mode 100644
index 00000000000..618b38ea91b
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/bindings/v8/ScriptPromiseTest.cpp
@@ -0,0 +1,260 @@
+/*
+ * Copyright (C) 2014 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 "bindings/v8/ScriptPromise.h"
+
+#include "bindings/v8/ScriptFunction.h"
+#include "bindings/v8/ScriptPromiseResolver.h"
+#include "bindings/v8/ScriptValue.h"
+#include "bindings/v8/V8Binding.h"
+#include "core/dom/DOMException.h"
+#include "core/dom/ExceptionCode.h"
+
+#include <gtest/gtest.h>
+#include <v8.h>
+
+namespace WebCore {
+
+namespace {
+
+void callback(const v8::FunctionCallbackInfo<v8::Value>& info) { }
+
+class Function : public ScriptFunction {
+public:
+ static PassOwnPtr<Function> create(v8::Isolate* isolate, String* value)
+ {
+ return adoptPtr(new Function(isolate, value));
+ }
+
+ virtual ScriptValue call(ScriptValue value) OVERRIDE
+ {
+ ASSERT(!value.isEmpty());
+ *m_value = toCoreString(value.v8Value()->ToString());
+ return value;
+ }
+
+private:
+ Function(v8::Isolate* isolate, String* value) : ScriptFunction(isolate), m_value(value) { }
+
+ String* m_value;
+};
+
+class ScriptPromiseTest : public testing::Test {
+public:
+ ScriptPromiseTest()
+ : m_scope(v8::Isolate::GetCurrent())
+ {
+ }
+
+ ~ScriptPromiseTest()
+ {
+ // FIXME: We put this statement here to clear an exception from the isolate.
+ createClosure(callback, v8::Undefined(m_scope.isolate()), m_scope.isolate());
+
+ // Execute all pending microtasks
+ isolate()->RunMicrotasks();
+ }
+
+ ScriptState* scriptState() const { return m_scope.scriptState(); }
+ v8::Isolate* isolate() const { return m_scope.isolate(); }
+
+protected:
+ V8TestingScope m_scope;
+};
+
+TEST_F(ScriptPromiseTest, constructFromNonPromise)
+{
+ v8::TryCatch trycatch;
+ ScriptPromise promise(scriptState(), v8::Undefined(isolate()));
+ ASSERT_TRUE(trycatch.HasCaught());
+ ASSERT_TRUE(promise.isEmpty());
+}
+
+TEST_F(ScriptPromiseTest, thenResolve)
+{
+ RefPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver::create(scriptState());
+ ScriptPromise promise = resolver->promise();
+ String onFulfilled, onRejected;
+ promise.then(Function::create(isolate(), &onFulfilled), Function::create(isolate(), &onRejected));
+
+ ASSERT_FALSE(promise.isEmpty());
+ EXPECT_EQ(String(), onFulfilled);
+ EXPECT_EQ(String(), onRejected);
+
+ isolate()->RunMicrotasks();
+ resolver->resolve("hello");
+
+ EXPECT_EQ(String(), onFulfilled);
+ EXPECT_EQ(String(), onRejected);
+
+ isolate()->RunMicrotasks();
+
+ EXPECT_EQ("hello", onFulfilled);
+ EXPECT_EQ(String(), onRejected);
+}
+
+TEST_F(ScriptPromiseTest, resolveThen)
+{
+ RefPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver::create(scriptState());
+ ScriptPromise promise = resolver->promise();
+ String onFulfilled, onRejected;
+ resolver->resolve("hello");
+ promise.then(Function::create(isolate(), &onFulfilled), Function::create(isolate(), &onRejected));
+
+ ASSERT_FALSE(promise.isEmpty());
+ EXPECT_EQ(String(), onFulfilled);
+ EXPECT_EQ(String(), onRejected);
+
+ isolate()->RunMicrotasks();
+
+ EXPECT_EQ("hello", onFulfilled);
+ EXPECT_EQ(String(), onRejected);
+}
+
+TEST_F(ScriptPromiseTest, thenReject)
+{
+ RefPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver::create(scriptState());
+ ScriptPromise promise = resolver->promise();
+ String onFulfilled, onRejected;
+ promise.then(Function::create(isolate(), &onFulfilled), Function::create(isolate(), &onRejected));
+
+ ASSERT_FALSE(promise.isEmpty());
+ EXPECT_EQ(String(), onFulfilled);
+ EXPECT_EQ(String(), onRejected);
+
+ isolate()->RunMicrotasks();
+ resolver->reject("hello");
+
+ EXPECT_EQ(String(), onFulfilled);
+ EXPECT_EQ(String(), onRejected);
+
+ isolate()->RunMicrotasks();
+
+ EXPECT_EQ(String(), onFulfilled);
+ EXPECT_EQ("hello", onRejected);
+}
+
+TEST_F(ScriptPromiseTest, rejectThen)
+{
+ RefPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver::create(scriptState());
+ ScriptPromise promise = resolver->promise();
+ String onFulfilled, onRejected;
+ resolver->reject("hello");
+ promise.then(Function::create(isolate(), &onFulfilled), Function::create(isolate(), &onRejected));
+
+ ASSERT_FALSE(promise.isEmpty());
+ EXPECT_EQ(String(), onFulfilled);
+ EXPECT_EQ(String(), onRejected);
+
+ isolate()->RunMicrotasks();
+
+ EXPECT_EQ(String(), onFulfilled);
+ EXPECT_EQ("hello", onRejected);
+}
+
+TEST_F(ScriptPromiseTest, castPromise)
+{
+ ScriptPromise promise = ScriptPromiseResolver::create(scriptState())->promise();
+ ScriptPromise newPromise = ScriptPromise::cast(scriptState(), promise.v8Value());
+
+ ASSERT_FALSE(promise.isEmpty());
+ EXPECT_EQ(promise.v8Value(), newPromise.v8Value());
+}
+
+TEST_F(ScriptPromiseTest, castNonPromise)
+{
+ String onFulfilled1, onFulfilled2, onRejected1, onRejected2;
+
+ ScriptValue value = ScriptValue(scriptState(), v8String(isolate(), "hello"));
+ ScriptPromise promise1 = ScriptPromise::cast(scriptState(), ScriptValue(value));
+ ScriptPromise promise2 = ScriptPromise::cast(scriptState(), ScriptValue(value));
+ promise1.then(Function::create(isolate(), &onFulfilled1), Function::create(isolate(), &onRejected1));
+ promise2.then(Function::create(isolate(), &onFulfilled2), Function::create(isolate(), &onRejected2));
+
+ ASSERT_FALSE(promise1.isEmpty());
+ ASSERT_FALSE(promise2.isEmpty());
+ EXPECT_NE(promise1.v8Value(), promise2.v8Value());
+
+ ASSERT_TRUE(promise1.v8Value()->IsPromise());
+ ASSERT_TRUE(promise2.v8Value()->IsPromise());
+
+ EXPECT_EQ(String(), onFulfilled1);
+ EXPECT_EQ(String(), onFulfilled2);
+ EXPECT_EQ(String(), onRejected1);
+ EXPECT_EQ(String(), onRejected2);
+
+ isolate()->RunMicrotasks();
+
+ EXPECT_EQ("hello", onFulfilled1);
+ EXPECT_EQ("hello", onFulfilled2);
+ EXPECT_EQ(String(), onRejected1);
+ EXPECT_EQ(String(), onRejected2);
+}
+
+TEST_F(ScriptPromiseTest, reject)
+{
+ String onFulfilled, onRejected;
+
+ ScriptValue value = ScriptValue(scriptState(), v8String(isolate(), "hello"));
+ ScriptPromise promise = ScriptPromise::reject(scriptState(), ScriptValue(value));
+ promise.then(Function::create(isolate(), &onFulfilled), Function::create(isolate(), &onRejected));
+
+ ASSERT_FALSE(promise.isEmpty());
+ ASSERT_TRUE(promise.v8Value()->IsPromise());
+
+ EXPECT_EQ(String(), onFulfilled);
+ EXPECT_EQ(String(), onRejected);
+
+ isolate()->RunMicrotasks();
+
+ EXPECT_EQ(String(), onFulfilled);
+ EXPECT_EQ("hello", onRejected);
+}
+
+TEST_F(ScriptPromiseTest, rejectWithExceptionState)
+{
+ String onFulfilled, onRejected;
+ ScriptPromise promise = ScriptPromise::rejectWithDOMException(scriptState(), DOMException::create(SyntaxError, "some syntax error"));
+ promise.then(Function::create(isolate(), &onFulfilled), Function::create(isolate(), &onRejected));
+
+ ASSERT_FALSE(promise.isEmpty());
+ EXPECT_EQ(String(), onFulfilled);
+ EXPECT_EQ(String(), onRejected);
+
+ isolate()->RunMicrotasks();
+
+ EXPECT_EQ(String(), onFulfilled);
+ EXPECT_EQ("SyntaxError: some syntax error", onRejected);
+}
+
+} // namespace
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/ScriptRegexp.cpp b/chromium/third_party/WebKit/Source/bindings/v8/ScriptRegexp.cpp
index d0be2a1ec28..b4e25188288 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/ScriptRegexp.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/ScriptRegexp.cpp
@@ -31,7 +31,8 @@
#include "bindings/v8/V8Binding.h"
#include "bindings/v8/V8PerIsolateData.h"
-#include "bindings/v8/V8RecursionScope.h"
+#include "bindings/v8/V8ScriptRunner.h"
+#include "core/dom/ScriptForbiddenScope.h"
namespace WebCore {
@@ -39,8 +40,8 @@ ScriptRegexp::ScriptRegexp(const String& pattern, TextCaseSensitivity caseSensit
{
v8::Isolate* isolate = v8::Isolate::GetCurrent();
v8::HandleScope handleScope(isolate);
- v8::Local<v8::Context> context = V8PerIsolateData::from(isolate)->ensureRegexContext();
- v8::Context::Scope scope(context);
+ v8::Context::Scope contextScope(V8PerIsolateData::from(isolate)->ensureScriptRegexpContext());
+ v8::TryCatch tryCatch;
unsigned flags = v8::RegExp::kNone;
if (caseSensitivity == TextCaseInsensitive)
@@ -48,8 +49,7 @@ ScriptRegexp::ScriptRegexp(const String& pattern, TextCaseSensitivity caseSensit
if (multilineMode == MultilineEnabled)
flags |= v8::RegExp::kMultiline;
- v8::TryCatch tryCatch;
- v8::Local<v8::RegExp> regex = v8::RegExp::New(v8String(context->GetIsolate(), pattern), static_cast<v8::RegExp::Flags>(flags));
+ v8::Local<v8::RegExp> regex = v8::RegExp::New(v8String(isolate, pattern), static_cast<v8::RegExp::Flags>(flags));
// If the regex failed to compile we'll get an empty handle.
if (!regex.IsEmpty())
@@ -68,19 +68,20 @@ int ScriptRegexp::match(const String& string, int startFrom, int* matchLength) c
if (string.length() > INT_MAX)
return -1;
+ ScriptForbiddenScope::AllowUserAgentScript allowScript;
+
v8::Isolate* isolate = v8::Isolate::GetCurrent();
v8::HandleScope handleScope(isolate);
- v8::Local<v8::Context> context = V8PerIsolateData::current()->ensureRegexContext();
- v8::Context::Scope scope(context);
+ v8::Context::Scope contextScope(V8PerIsolateData::from(isolate)->ensureScriptRegexpContext());
v8::TryCatch tryCatch;
- V8RecursionScope::MicrotaskSuppression microtaskScope;
-
v8::Local<v8::RegExp> regex = m_regex.newLocal(isolate);
v8::Local<v8::Function> exec = regex->Get(v8AtomicString(isolate, "exec")).As<v8::Function>();
+ v8::Handle<v8::Value> argv[] = { v8String(isolate, string.substring(startFrom)) };
+ v8::Local<v8::Value> returnValue = V8ScriptRunner::callInternalFunction(exec, regex, WTF_ARRAY_LENGTH(argv), argv, isolate);
- v8::Handle<v8::Value> argv[] = { v8String(context->GetIsolate(), string.substring(startFrom)) };
- v8::Local<v8::Value> returnValue = exec->Call(regex, 1, argv);
+ if (tryCatch.HasCaught())
+ return -1;
// RegExp#exec returns null if there's no match, otherwise it returns an
// Array of strings with the first being the whole match string and others
@@ -89,12 +90,12 @@ int ScriptRegexp::match(const String& string, int startFrom, int* matchLength) c
//
// https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/RegExp/exec
+ ASSERT(!returnValue.IsEmpty());
if (!returnValue->IsArray())
return -1;
v8::Local<v8::Array> result = returnValue.As<v8::Array>();
int matchOffset = result->Get(v8AtomicString(isolate, "index"))->ToInt32()->Value();
-
if (matchLength) {
v8::Local<v8::String> match = result->Get(0).As<v8::String>();
*matchLength = match->Length();
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/ScriptScope.cpp b/chromium/third_party/WebKit/Source/bindings/v8/ScriptScope.cpp
deleted file mode 100644
index 70815114cae..00000000000
--- a/chromium/third_party/WebKit/Source/bindings/v8/ScriptScope.cpp
+++ /dev/null
@@ -1,58 +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 "bindings/v8/ScriptScope.h"
-
-#include "bindings/v8/ScriptState.h"
-#include "wtf/Assertions.h"
-
-#include <v8.h>
-
-namespace WebCore {
-
-ScriptScope::ScriptScope(ScriptState* scriptState, bool reportExceptions)
- : m_handleScope(scriptState->isolate())
- , m_context(scriptState->context())
- , m_scope(m_context)
-{
- m_exceptionCatcher.SetVerbose(reportExceptions);
- ASSERT(!m_context.IsEmpty());
-}
-
-bool ScriptScope::success()
-{
- if (!m_exceptionCatcher.HasCaught())
- return true;
- m_exceptionCatcher.Reset();
- return false;
-}
-
-} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/ScriptScope.h b/chromium/third_party/WebKit/Source/bindings/v8/ScriptScope.h
deleted file mode 100644
index ed2cf2f2e87..00000000000
--- a/chromium/third_party/WebKit/Source/bindings/v8/ScriptScope.h
+++ /dev/null
@@ -1,55 +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.
- */
-
-#ifndef ScriptScope_h
-#define ScriptScope_h
-
-#include <v8.h>
-
-namespace WebCore {
- class ScriptState;
-
- class ScriptScope {
- public:
- ScriptScope(ScriptState* scriptState, bool reportExceptions = true);
- bool success();
-
- v8::Local<v8::Object> global() const { return m_context->Global(); }
-
- private:
- v8::HandleScope m_handleScope;
- v8::Local<v8::Context> m_context;
- v8::Context::Scope m_scope;
- v8::TryCatch m_exceptionCatcher;
- };
-
-}
-
-#endif // ScriptScope_h
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/ScriptSourceCode.h b/chromium/third_party/WebKit/Source/bindings/v8/ScriptSourceCode.h
index d5ddbccd082..92944bd9064 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/ScriptSourceCode.h
+++ b/chromium/third_party/WebKit/Source/bindings/v8/ScriptSourceCode.h
@@ -38,8 +38,6 @@
#include "wtf/text/TextPosition.h"
#include "wtf/text/WTFString.h"
-#include <v8.h>
-
namespace WebCore {
class ScriptSourceCode {
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/ScriptState.cpp b/chromium/third_party/WebKit/Source/bindings/v8/ScriptState.cpp
index 0eda05f2ce6..5e17e4c6da8 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/ScriptState.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/ScriptState.cpp
@@ -1,126 +1,114 @@
-/*
- * Copyright (C) 2009, 2011 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.
- */
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "config.h"
#include "bindings/v8/ScriptState.h"
-#include "V8Window.h"
-#include "V8WorkerGlobalScope.h"
-#include "bindings/v8/ScriptController.h"
-#include "bindings/v8/V8HiddenPropertyName.h"
-#include "bindings/v8/WorkerScriptController.h"
-#include "core/frame/Frame.h"
-#include "core/workers/WorkerGlobalScope.h"
-#include <v8.h>
-#include "wtf/Assertions.h"
+#include "bindings/v8/V8Binding.h"
+#include "core/dom/ExecutionContext.h"
+#include "core/frame/LocalFrame.h"
namespace WebCore {
-ScriptState::ScriptState(v8::Handle<v8::Context> context)
- : m_context(context->GetIsolate(), context)
- , m_isolate(context->GetIsolate())
+PassRefPtr<ScriptState> ScriptState::create(v8::Handle<v8::Context> context, PassRefPtr<DOMWrapperWorld> world)
{
- m_context.setWeak(this, &setWeakCallback);
+ RefPtr<ScriptState> scriptState = adoptRef(new ScriptState(context, world));
+ // This ref() is for keeping this ScriptState alive as long as the v8::Context is alive.
+ // This is deref()ed in the weak callback of the v8::Context.
+ scriptState->ref();
+ return scriptState;
+}
+
+static void weakCallback(const v8::WeakCallbackData<v8::Context, ScriptState>& data)
+{
+ data.GetValue()->SetAlignedPointerInEmbedderData(v8ContextPerContextDataIndex, 0);
+ data.GetParameter()->clearContext();
+ data.GetParameter()->deref();
+}
+
+ScriptState::ScriptState(v8::Handle<v8::Context> context, PassRefPtr<DOMWrapperWorld> world)
+ : m_isolate(context->GetIsolate())
+ , m_context(m_isolate, context)
+ , m_world(world)
+ , m_perContextData(V8PerContextData::create(context))
+{
+ ASSERT(m_world);
+ m_context.setWeak(this, &weakCallback);
+ context->SetAlignedPointerInEmbedderData(v8ContextPerContextDataIndex, this);
}
ScriptState::~ScriptState()
{
+ ASSERT(!m_perContextData);
+ ASSERT(m_context.isEmpty());
}
-DOMWindow* ScriptState::domWindow() const
+bool ScriptState::evalEnabled() const
{
v8::HandleScope handleScope(m_isolate);
- return toDOMWindow(m_context.newLocal(m_isolate));
+ return context()->IsCodeGenerationFromStringsAllowed();
}
-ExecutionContext* ScriptState::executionContext() const
+void ScriptState::setEvalEnabled(bool enabled)
{
v8::HandleScope handleScope(m_isolate);
- return toExecutionContext(m_context.newLocal(m_isolate));
+ return context()->AllowCodeGenerationFromStrings(enabled);
}
-ScriptState* ScriptState::forContext(v8::Handle<v8::Context> context)
+ScriptValue ScriptState::getFromGlobalObject(const char* name)
{
- v8::Context::Scope contextScope(context);
-
- v8::Local<v8::Object> innerGlobal = v8::Local<v8::Object>::Cast(context->Global()->GetPrototype());
-
- v8::Local<v8::Value> scriptStateWrapper = innerGlobal->GetHiddenValue(V8HiddenPropertyName::scriptState(context->GetIsolate()));
- if (!scriptStateWrapper.IsEmpty() && scriptStateWrapper->IsExternal())
- return static_cast<ScriptState*>(v8::External::Cast(*scriptStateWrapper)->Value());
+ v8::HandleScope handleScope(m_isolate);
+ v8::Local<v8::Value> v8Value = context()->Global()->Get(v8AtomicString(isolate(), name));
+ return ScriptValue(this, v8Value);
+}
- ScriptState* scriptState = new ScriptState(context);
- innerGlobal->SetHiddenValue(V8HiddenPropertyName::scriptState(context->GetIsolate()), v8::External::New(context->GetIsolate(), scriptState));
- return scriptState;
+ExecutionContext* ScriptState::executionContext() const
+{
+ v8::HandleScope scope(m_isolate);
+ return toExecutionContext(context());
}
-ScriptState* ScriptState::current()
+void ScriptState::setExecutionContext(ExecutionContext*)
{
- v8::Isolate* isolate = v8::Isolate::GetCurrent();
- v8::HandleScope handleScope(isolate);
- v8::Local<v8::Context> context = isolate->GetCurrentContext();
- ASSERT(!context.IsEmpty());
- return ScriptState::forContext(context);
+ ASSERT_NOT_REACHED();
}
-void ScriptState::setWeakCallback(const v8::WeakCallbackData<v8::Context, ScriptState>& data)
+LocalDOMWindow* ScriptState::domWindow() const
{
- delete data.GetParameter();
+ v8::HandleScope scope(m_isolate);
+ return toDOMWindow(context());
}
-bool ScriptState::evalEnabled() const
+ScriptState* ScriptState::forMainWorld(LocalFrame* frame)
{
- v8::HandleScope handleScope(m_isolate);
- return context()->IsCodeGenerationFromStringsAllowed();
+ v8::Isolate* isolate = toIsolate(frame);
+ v8::HandleScope handleScope(isolate);
+ return ScriptState::from(toV8Context(frame, DOMWrapperWorld::mainWorld()));
}
-void ScriptState::setEvalEnabled(bool enabled)
+PassRefPtr<ScriptStateForTesting> ScriptStateForTesting::create(v8::Handle<v8::Context> context, PassRefPtr<DOMWrapperWorld> world)
{
- v8::HandleScope handleScope(m_isolate);
- return context()->AllowCodeGenerationFromStrings(enabled);
+ RefPtr<ScriptStateForTesting> scriptState = adoptRef(new ScriptStateForTesting(context, world));
+ // This ref() is for keeping this ScriptState alive as long as the v8::Context is alive.
+ // This is deref()ed in the weak callback of the v8::Context.
+ scriptState->ref();
+ return scriptState;
}
-ScriptState* mainWorldScriptState(Frame* frame)
+ScriptStateForTesting::ScriptStateForTesting(v8::Handle<v8::Context> context, PassRefPtr<DOMWrapperWorld> world)
+ : ScriptState(context, world)
{
- v8::HandleScope handleScope(toIsolate(frame));
- return ScriptState::forContext(frame->script().mainWorldContext());
}
-ScriptState* scriptStateFromWorkerGlobalScope(WorkerGlobalScope* workerGlobalScope)
+ExecutionContext* ScriptStateForTesting::executionContext() const
{
- WorkerScriptController* script = workerGlobalScope->script();
- if (!script)
- return 0;
+ return m_executionContext;
+}
- v8::HandleScope handleScope(script->isolate());
- return ScriptState::forContext(script->context());
+void ScriptStateForTesting::setExecutionContext(ExecutionContext* executionContext)
+{
+ m_executionContext = executionContext;
}
}
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/ScriptState.h b/chromium/third_party/WebKit/Source/bindings/v8/ScriptState.h
index ac93b551167..81bc5840070 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/ScriptState.h
+++ b/chromium/third_party/WebKit/Source/bindings/v8/ScriptState.h
@@ -1,130 +1,145 @@
-/*
- * Copyright (C) 2008, 2009, 2011 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.
- */
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef ScriptState_h
#define ScriptState_h
#include "bindings/v8/ScopedPersistent.h"
-#include "bindings/v8/V8Utilities.h"
+#include "bindings/v8/V8PerContextData.h"
+#include "wtf/RefCounted.h"
#include <v8.h>
-#include "wtf/Noncopyable.h"
namespace WebCore {
-class DOMWindow;
+class LocalDOMWindow;
class DOMWrapperWorld;
-class Frame;
class ExecutionContext;
-class WorkerGlobalScope;
+class LocalFrame;
+class ScriptValue;
-class ScriptState {
+// ScriptState is created when v8::Context is created.
+// ScriptState is destroyed when v8::Context is garbage-collected and
+// all V8 proxy objects that have references to the ScriptState are destructed.
+class ScriptState : public RefCounted<ScriptState> {
WTF_MAKE_NONCOPYABLE(ScriptState);
public:
- bool hadException() { return !m_exception.isEmpty(); }
- void setException(v8::Local<v8::Value> exception)
+ class Scope {
+ public:
+ // You need to make sure that scriptState->context() is not empty before creating a Scope.
+ explicit Scope(ScriptState* scriptState)
+ : m_handleScope(scriptState->isolate())
+ , m_context(scriptState->context())
+ {
+ ASSERT(!m_context.IsEmpty());
+ m_context->Enter();
+ }
+
+ ~Scope()
+ {
+ m_context->Exit();
+ }
+
+ private:
+ v8::HandleScope m_handleScope;
+ v8::Handle<v8::Context> m_context;
+ };
+
+ static PassRefPtr<ScriptState> create(v8::Handle<v8::Context>, PassRefPtr<DOMWrapperWorld>);
+ virtual ~ScriptState();
+
+ static ScriptState* current(v8::Isolate* isolate)
{
- m_exception.set(m_isolate, exception);
+ return from(isolate->GetCurrentContext());
}
- v8::Local<v8::Value> exception() { return m_exception.newLocal(m_isolate); }
- void clearException() { m_exception.clear(); }
- v8::Local<v8::Context> context() const
+ static ScriptState* from(v8::Handle<v8::Context> context)
{
- return m_context.newLocal(m_isolate);
+ ASSERT(!context.IsEmpty());
+ ScriptState* scriptState = static_cast<ScriptState*>(context->GetAlignedPointerFromEmbedderData(v8ContextPerContextDataIndex));
+ // ScriptState::from() must not be called for a context that does not have
+ // valid embedder data in the embedder field.
+ RELEASE_ASSERT_WITH_SECURITY_IMPLICATION(scriptState);
+ RELEASE_ASSERT_WITH_SECURITY_IMPLICATION(scriptState->context() == context);
+ return scriptState;
}
- v8::Isolate* isolate()
- {
- return m_isolate;
- }
+ static ScriptState* forMainWorld(LocalFrame*);
+
+ v8::Isolate* isolate() const { return m_isolate; }
+ DOMWrapperWorld& world() const { return *m_world; }
+ LocalDOMWindow* domWindow() const;
+ virtual ExecutionContext* executionContext() const;
+ virtual void setExecutionContext(ExecutionContext*);
+
+ // This can return an empty handle if the v8::Context is gone.
+ v8::Handle<v8::Context> context() const { return m_context.newLocal(m_isolate); }
+ bool contextIsEmpty() const { return m_context.isEmpty(); }
+ void clearContext() { return m_context.clear(); }
+
+ V8PerContextData* perContextData() const { return m_perContextData.get(); }
+ void disposePerContextData() { m_perContextData = nullptr; }
- DOMWindow* domWindow() const;
- ExecutionContext* executionContext() const;
bool evalEnabled() const;
void setEvalEnabled(bool);
-
- static ScriptState* forContext(v8::Handle<v8::Context>);
- static ScriptState* current();
+ ScriptValue getFromGlobalObject(const char* name);
protected:
- ScriptState()
- : m_isolate(v8::Isolate::GetCurrent())
- {
- }
-
- ~ScriptState();
+ ScriptState(v8::Handle<v8::Context>, PassRefPtr<DOMWrapperWorld>);
private:
- friend ScriptState* mainWorldScriptState(Frame*);
- explicit ScriptState(v8::Handle<v8::Context>);
+ v8::Isolate* m_isolate;
+ // This persistent handle is weak.
+ ScopedPersistent<v8::Context> m_context;
- static void setWeakCallback(const v8::WeakCallbackData<v8::Context, ScriptState>&);
+ // This RefPtr doesn't cause a cycle because all persistent handles that DOMWrapperWorld holds are weak.
+ RefPtr<DOMWrapperWorld> m_world;
- ScopedPersistent<v8::Value> m_exception;
- ScopedPersistent<v8::Context> m_context;
- v8::Isolate* m_isolate;
+ // This OwnPtr causes a cycle:
+ // V8PerContextData --(Persistent)--> v8::Context --(RefPtr)--> ScriptState --(OwnPtr)--> V8PerContextData
+ // So you must explicitly clear the OwnPtr by calling disposePerContextData()
+ // once you no longer need V8PerContextData. Otherwise, the v8::Context will leak.
+ OwnPtr<V8PerContextData> m_perContextData;
};
-class EmptyScriptState : public ScriptState {
+class ScriptStateForTesting : public ScriptState {
public:
- EmptyScriptState() : ScriptState() { }
- ~EmptyScriptState() { }
+ static PassRefPtr<ScriptStateForTesting> create(v8::Handle<v8::Context>, PassRefPtr<DOMWrapperWorld>);
+
+ virtual ExecutionContext* executionContext() const OVERRIDE;
+ virtual void setExecutionContext(ExecutionContext*) OVERRIDE;
+
+private:
+ ScriptStateForTesting(v8::Handle<v8::Context>, PassRefPtr<DOMWrapperWorld>);
+
+ ExecutionContext* m_executionContext;
};
-class ScriptStateProtectedPtr {
- WTF_MAKE_NONCOPYABLE(ScriptStateProtectedPtr);
+// ScriptStateProtectingContext keeps the context associated with the ScriptState alive.
+// You need to call clear() once you no longer need the context. Otherwise, the context will leak.
+class ScriptStateProtectingContext {
+ WTF_MAKE_NONCOPYABLE(ScriptStateProtectingContext);
public:
- ScriptStateProtectedPtr()
- : m_scriptState(0)
+ ScriptStateProtectingContext(ScriptState* scriptState)
+ : m_scriptState(scriptState)
{
+ if (m_scriptState)
+ m_context.set(m_scriptState->isolate(), m_scriptState->context());
}
- ScriptStateProtectedPtr(ScriptState* scriptState)
- : m_scriptState(scriptState)
+ ScriptState* operator->() const { return m_scriptState.get(); }
+ ScriptState* get() const { return m_scriptState.get(); }
+ void clear()
{
- v8::HandleScope handleScope(scriptState->isolate());
- // Keep the context from being GC'ed. ScriptState is guaranteed to be live while the context is live.
- m_context.set(scriptState->isolate(), scriptState->context());
+ m_scriptState = nullptr;
+ m_context.clear();
}
- ScriptState* get() const { return m_scriptState; }
-
private:
- ScriptState* m_scriptState;
+ RefPtr<ScriptState> m_scriptState;
ScopedPersistent<v8::Context> m_context;
};
-ScriptState* mainWorldScriptState(Frame*);
-
-ScriptState* scriptStateFromWorkerGlobalScope(WorkerGlobalScope*);
-
}
#endif // ScriptState_h
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/ScriptString.cpp b/chromium/third_party/WebKit/Source/bindings/v8/ScriptString.cpp
index fe1ea3ecec2..aa75fde16ad 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/ScriptString.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/ScriptString.cpp
@@ -31,26 +31,53 @@
#include "config.h"
#include "bindings/v8/ScriptString.h"
+#include "bindings/v8/V8Binding.h"
+
namespace WebCore {
+ScriptString::ScriptString()
+ : m_isolate(0)
+{
+}
+
+ScriptString::ScriptString(v8::Isolate* isolate, v8::Handle<v8::String> string)
+ : m_isolate(isolate)
+ , m_string(SharedPersistent<v8::String>::create(string, m_isolate))
+{
+}
+
+ScriptString& ScriptString::operator=(const ScriptString& string)
+{
+ if (this != &string) {
+ m_isolate = string.m_isolate;
+ m_string = string.m_string;
+ }
+ return *this;
+}
+
+v8::Handle<v8::String> ScriptString::v8Value()
+{
+ if (isEmpty())
+ return v8::Handle<v8::String>();
+ return m_string->newLocal(isolate());
+}
+
ScriptString ScriptString::concatenateWith(const String& string)
{
v8::Isolate* nonNullIsolate = isolate();
v8::HandleScope handleScope(nonNullIsolate);
- v8::Handle<v8::String> b = v8String(nonNullIsolate, string);
- if (hasNoValue())
- return ScriptString(b, nonNullIsolate);
- v8::Handle<v8::String> a = v8::Handle<v8::String>::Cast(v8Value());
- return ScriptString(v8::String::Concat(a, b), nonNullIsolate);
+ v8::Handle<v8::String> targetString = v8String(nonNullIsolate, string);
+ if (isEmpty())
+ return ScriptString(nonNullIsolate, targetString);
+ return ScriptString(nonNullIsolate, v8::String::Concat(v8Value(), targetString));
}
-String ScriptString::flattenToString() const
+String ScriptString::flattenToString()
{
- if (hasNoValue())
+ if (isEmpty())
return String();
v8::HandleScope handleScope(isolate());
- v8::Handle<v8::String> value = v8::Handle<v8::String>::Cast(v8Value());
- return v8StringToWebCoreString<String>(value, Externalize);
+ return v8StringToWebCoreString<String>(v8Value(), Externalize);
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/ScriptString.h b/chromium/third_party/WebKit/Source/bindings/v8/ScriptString.h
index ed493f8bf48..2638f44836d 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/ScriptString.h
+++ b/chromium/third_party/WebKit/Source/bindings/v8/ScriptString.h
@@ -31,19 +31,34 @@
#ifndef ScriptString_h
#define ScriptString_h
-#include "bindings/v8/ScriptValue.h"
-#include "bindings/v8/V8Binding.h"
+#include "bindings/v8/SharedPersistent.h"
+#include "wtf/RefPtr.h"
#include "wtf/text/WTFString.h"
+#include <v8.h>
namespace WebCore {
-class ScriptString : public ScriptValue {
+class ScriptString FINAL {
public:
- ScriptString() { }
- ScriptString(v8::Handle<v8::String> value, v8::Isolate* isolate) : ScriptValue(value, isolate) { }
+ ScriptString();
+ ScriptString(v8::Isolate*, v8::Handle<v8::String>);
+ ScriptString& operator=(const ScriptString&);
+ v8::Isolate* isolate()
+ {
+ if (!m_isolate)
+ m_isolate = v8::Isolate::GetCurrent();
+ return m_isolate;
+ }
+ bool isEmpty() const { return !m_string || m_string->isEmpty(); }
+ void clear() { m_string = nullptr; }
+ v8::Handle<v8::String> v8Value();
ScriptString concatenateWith(const String&);
- String flattenToString() const;
+ String flattenToString();
+
+private:
+ v8::Isolate* m_isolate;
+ RefPtr<SharedPersistent<v8::String> > m_string;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/ScriptValue.cpp b/chromium/third_party/WebKit/Source/bindings/v8/ScriptValue.cpp
index 04b2287f9c2..bdfbe082258 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/ScriptValue.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/ScriptValue.cpp
@@ -31,7 +31,6 @@
#include "config.h"
#include "bindings/v8/ScriptValue.h"
-#include "bindings/v8/ScriptScope.h"
#include "bindings/v8/ScriptState.h"
#include "bindings/v8/V8Binding.h"
#include "platform/JSONValues.h"
@@ -42,88 +41,41 @@ ScriptValue::~ScriptValue()
{
}
-bool ScriptValue::getString(String& result) const
+v8::Handle<v8::Value> ScriptValue::v8Value() const
{
- if (hasNoValue())
- return false;
+ if (isEmpty())
+ return v8::Handle<v8::Value>();
- v8::HandleScope handleScope(m_isolate);
- v8::Handle<v8::Value> string = v8Value();
- if (string.IsEmpty() || !string->IsString())
- return false;
- result = toCoreString(string.As<v8::String>());
- return true;
-}
+ ASSERT(isolate()->InContext());
-String ScriptValue::toString() const
-{
- v8::TryCatch block;
- v8::Handle<v8::String> string = v8Value()->ToString();
- if (block.HasCaught())
- return String();
- return v8StringToWebCoreString<String>(string, DoNotExternalize);
+ // This is a check to validate that you don't return a ScriptValue to a world different
+ // from the world that created the ScriptValue.
+ // Probably this could be:
+ // if (&m_scriptState->world() == &DOMWrapperWorld::current(isolate()))
+ // return v8::Handle<v8::Value>();
+ // instead of triggering RELEASE_ASSERT.
+ RELEASE_ASSERT(&m_scriptState->world() == &DOMWrapperWorld::current(isolate()));
+ return m_value->newLocal(isolate());
}
-static PassRefPtr<JSONValue> v8ToJSONValue(v8::Handle<v8::Value> value, int maxDepth, v8::Isolate* isolate)
+bool ScriptValue::toString(String& result) const
{
- if (value.IsEmpty()) {
- ASSERT_NOT_REACHED();
- return 0;
- }
-
- if (!maxDepth)
- return 0;
- maxDepth--;
+ if (isEmpty())
+ return false;
- if (value->IsNull() || value->IsUndefined())
- return JSONValue::null();
- if (value->IsBoolean())
- return JSONBasicValue::create(value->BooleanValue());
- if (value->IsNumber())
- return JSONBasicValue::create(value->NumberValue());
- if (value->IsString())
- return JSONString::create(toCoreString(value.As<v8::String>()));
- if (value->IsArray()) {
- v8::Handle<v8::Array> array = v8::Handle<v8::Array>::Cast(value);
- RefPtr<JSONArray> inspectorArray = JSONArray::create();
- uint32_t length = array->Length();
- for (uint32_t i = 0; i < length; i++) {
- v8::Local<v8::Value> value = array->Get(v8::Int32::New(i, isolate));
- RefPtr<JSONValue> element = v8ToJSONValue(value, maxDepth, isolate);
- if (!element)
- return 0;
- inspectorArray->pushValue(element);
- }
- return inspectorArray;
- }
- if (value->IsObject()) {
- RefPtr<JSONObject> jsonObject = JSONObject::create();
- v8::Handle<v8::Object> object = v8::Handle<v8::Object>::Cast(value);
- v8::Local<v8::Array> propertyNames = object->GetPropertyNames();
- uint32_t length = propertyNames->Length();
- for (uint32_t i = 0; i < length; i++) {
- v8::Local<v8::Value> name = propertyNames->Get(v8::Int32::New(i, isolate));
- // FIXME(yurys): v8::Object should support GetOwnPropertyNames
- if (name->IsString() && !object->HasRealNamedProperty(v8::Handle<v8::String>::Cast(name)))
- continue;
- RefPtr<JSONValue> propertyValue = v8ToJSONValue(object->Get(name), maxDepth, isolate);
- if (!propertyValue)
- return 0;
- V8TRYCATCH_FOR_V8STRINGRESOURCE_RETURN(V8StringResource<WithNullCheck>, nameString, name, 0);
- jsonObject->setValue(nameString, propertyValue);
- }
- return jsonObject;
- }
- ASSERT_NOT_REACHED();
- return 0;
+ ScriptState::Scope scope(m_scriptState.get());
+ v8::Handle<v8::Value> string = v8Value();
+ if (string.IsEmpty() || !string->IsString())
+ return false;
+ result = toCoreString(v8::Handle<v8::String>::Cast(string));
+ return true;
}
PassRefPtr<JSONValue> ScriptValue::toJSONValue(ScriptState* scriptState) const
{
- v8::HandleScope handleScope(scriptState->isolate());
- // v8::Object::GetPropertyNames() expects current context to be not null.
- v8::Context::Scope contextScope(scriptState->context());
- return v8ToJSONValue(v8Value(), JSONValue::maxDepth, scriptState->isolate());
+ ASSERT(!scriptState->contextIsEmpty());
+ ScriptState::Scope scope(scriptState);
+ return v8ToJSONValue(scriptState->isolate(), v8Value(), JSONValue::maxDepth);
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/ScriptValue.h b/chromium/third_party/WebKit/Source/bindings/v8/ScriptValue.h
index 42b5fe7962b..41c76847987 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/ScriptValue.h
+++ b/chromium/third_party/WebKit/Source/bindings/v8/ScriptValue.h
@@ -31,6 +31,7 @@
#ifndef ScriptValue_h
#define ScriptValue_h
+#include "bindings/v8/ScriptState.h"
#include "bindings/v8/SharedPersistent.h"
#include "wtf/PassRefPtr.h"
#include "wtf/RefPtr.h"
@@ -40,26 +41,36 @@
namespace WebCore {
class JSONValue;
-class ScriptState;
class ScriptValue {
public:
ScriptValue()
: m_isolate(0)
- { }
+ , m_scriptState(nullptr)
+ {
+ }
virtual ~ScriptValue();
- ScriptValue(v8::Handle<v8::Value> value, v8::Isolate* isolate)
- : m_isolate(isolate)
- , m_value(value.IsEmpty() ? 0 : SharedPersistent<v8::Value>::create(value, isolate))
+ ScriptValue(ScriptState* scriptState, v8::Handle<v8::Value> value)
+ : m_isolate(scriptState->isolate())
+ , m_scriptState(scriptState)
+ , m_value(value.IsEmpty() ? nullptr : SharedPersistent<v8::Value>::create(value, scriptState->isolate()))
{
+ ASSERT(isEmpty() || m_scriptState);
}
ScriptValue(const ScriptValue& value)
: m_isolate(value.m_isolate)
+ , m_scriptState(value.m_scriptState)
, m_value(value.m_value)
{
+ ASSERT(isEmpty() || m_scriptState);
+ }
+
+ ScriptState* scriptState() const
+ {
+ return m_scriptState.get();
}
v8::Isolate* isolate() const
@@ -69,108 +80,80 @@ public:
return m_isolate;
}
- static ScriptValue createUndefined(v8::Isolate* isolate)
- {
- return ScriptValue(v8::Undefined(isolate), isolate);
- }
-
- static ScriptValue createNull()
- {
- v8::Isolate* isolate = v8::Isolate::GetCurrent();
- return ScriptValue(v8::Null(isolate), isolate);
- }
- static ScriptValue createBoolean(bool b)
- {
- v8::Isolate* isolate = v8::Isolate::GetCurrent();
- return ScriptValue(b ? v8::True(isolate) : v8::False(isolate), isolate);
- }
-
ScriptValue& operator=(const ScriptValue& value)
{
if (this != &value) {
- m_value = value.m_value;
m_isolate = value.m_isolate;
+ m_scriptState = value.m_scriptState;
+ m_value = value.m_value;
}
return *this;
}
bool operator==(const ScriptValue& value) const
{
- if (hasNoValue())
- return value.hasNoValue();
- if (value.hasNoValue())
+ if (isEmpty())
+ return value.isEmpty();
+ if (value.isEmpty())
return false;
return *m_value == *value.m_value;
}
- bool isEqual(ScriptState*, const ScriptValue& value) const
+ bool operator!=(const ScriptValue& value) const
{
- return operator==(value);
+ return !operator==(value);
}
- // Note: This creates a new local Handle; not to be used in cases where is
- // is an efficiency problem.
+ // This creates a new local Handle; Don't use this in performance-sensitive places.
bool isFunction() const
{
- ASSERT(!hasNoValue());
+ ASSERT(!isEmpty());
v8::Handle<v8::Value> value = v8Value();
return !value.IsEmpty() && value->IsFunction();
}
- bool operator!=(const ScriptValue& value) const
- {
- return !operator==(value);
- }
-
- // Note: This creates a new local Handle; not to be used in cases where is
- // is an efficiency problem.
+ // This creates a new local Handle; Don't use this in performance-sensitive places.
bool isNull() const
{
- ASSERT(!hasNoValue());
+ ASSERT(!isEmpty());
v8::Handle<v8::Value> value = v8Value();
return !value.IsEmpty() && value->IsNull();
}
- // Note: This creates a new local Handle; not to be used in cases where is
- // is an efficiency problem.
+ // This creates a new local Handle; Don't use this in performance-sensitive places.
bool isUndefined() const
{
- ASSERT(!hasNoValue());
+ ASSERT(!isEmpty());
v8::Handle<v8::Value> value = v8Value();
return !value.IsEmpty() && value->IsUndefined();
}
- // Note: This creates a new local Handle; not to be used in cases where is
- // is an efficiency problem.
+ // This creates a new local Handle; Don't use this in performance-sensitive places.
bool isObject() const
{
- ASSERT(!hasNoValue());
+ ASSERT(!isEmpty());
v8::Handle<v8::Value> value = v8Value();
return !value.IsEmpty() && value->IsObject();
}
- bool hasNoValue() const
+ bool isEmpty() const
{
return !m_value.get() || m_value->isEmpty();
}
void clear()
{
- m_value = 0;
- }
-
- v8::Handle<v8::Value> v8Value() const
- {
- return m_value.get() ? m_value->newLocal(m_isolate) : v8::Handle<v8::Value>();
+ m_value = nullptr;
}
- bool getString(String& result) const;
- String toString() const;
+ v8::Handle<v8::Value> v8Value() const;
+ bool toString(String&) const;
PassRefPtr<JSONValue> toJSONValue(ScriptState*) const;
private:
mutable v8::Isolate* m_isolate;
+ mutable RefPtr<ScriptState> m_scriptState;
RefPtr<SharedPersistent<v8::Value> > m_value;
};
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/ScriptWrappable.h b/chromium/third_party/WebKit/Source/bindings/v8/ScriptWrappable.h
index 72ab761ee4f..c81fda0e6e1 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/ScriptWrappable.h
+++ b/chromium/third_party/WebKit/Source/bindings/v8/ScriptWrappable.h
@@ -31,9 +31,8 @@
#ifndef ScriptWrappable_h
#define ScriptWrappable_h
-#include "bindings/v8/UnsafePersistent.h"
-#include "bindings/v8/V8Utilities.h"
#include "bindings/v8/WrapperTypeInfo.h"
+#include "platform/heap/Handle.h"
#include <v8.h>
// Helper to call webCoreInitializeScriptWrappableForInterface in the global namespace.
@@ -45,6 +44,35 @@ template <class C> inline void initializeScriptWrappableHelper(C* object)
namespace WebCore {
+/**
+ * ScriptWrappable wraps a V8 object and its WrapperTypeInfo.
+ *
+ * ScriptWrappable acts much like a v8::Persistent<> in that it keeps a
+ * V8 object alive. Under the hood, however, it keeps either a TypeInfo
+ * object or an actual v8 persistent (or is empty).
+ *
+ * The physical state space of ScriptWrappable is:
+ * - uintptr_t m_wrapperOrTypeInfo;
+ * - if 0: the ScriptWrappable is uninitialized/empty.
+ * - if even: a pointer to WebCore::TypeInfo
+ * - if odd: a pointer to v8::Persistent<v8::Object> + 1.
+ *
+ * In other words, one integer represents one of two object pointers,
+ * depending on its least signficiant bit, plus an uninitialized state.
+ * This class is meant to mask the logistics behind this.
+ *
+ * typeInfo() and newLocalWrapper will return appropriate values (possibly
+ * 0/empty) in all physical states.
+ *
+ * The state transitions are:
+ * - new: an empty and invalid ScriptWrappable.
+ * - init (to be called by all subclasses in their constructor):
+ * needs to call setTypeInfo
+ * - setTypeInfo: install a WrapperTypeInfo
+ * - setWrapper: install a v8::Persistent (or empty)
+ * - disposeWrapper (via setWeakCallback, triggered by V8 garbage collecter):
+ * remove v8::Persistent and install a TypeInfo of the previous value.
+ */
class ScriptWrappable {
public:
ScriptWrappable() : m_wrapperOrTypeInfo(0) { }
@@ -77,7 +105,9 @@ public:
v8::Local<v8::Object> newLocalWrapper(v8::Isolate* isolate) const
{
- return unsafePersistent().newLocal(isolate);
+ v8::Persistent<v8::Object> persistent;
+ getPersistent(&persistent);
+ return v8::Local<v8::Object>::New(isolate, persistent);
}
const WrapperTypeInfo* typeInfo()
@@ -85,102 +115,134 @@ public:
if (containsTypeInfo())
return reinterpret_cast<const WrapperTypeInfo*>(m_wrapperOrTypeInfo);
- if (containsWrapper())
- return toWrapperTypeInfo(*(unsafePersistent().persistent()));
+ if (containsWrapper()) {
+ v8::Persistent<v8::Object> persistent;
+ getPersistent(&persistent);
+ return toWrapperTypeInfo(persistent);
+ }
return 0;
}
- void setTypeInfo(const WrapperTypeInfo* info)
+ void setTypeInfo(const WrapperTypeInfo* typeInfo)
{
- m_wrapperOrTypeInfo = reinterpret_cast<uintptr_t>(info);
+ m_wrapperOrTypeInfo = reinterpret_cast<uintptr_t>(typeInfo);
ASSERT(containsTypeInfo());
}
+ bool isEqualTo(const v8::Local<v8::Object>& other) const
+ {
+ v8::Persistent<v8::Object> persistent;
+ getPersistent(&persistent);
+ return persistent == other;
+ }
+
static bool wrapperCanBeStoredInObject(const void*) { return false; }
static bool wrapperCanBeStoredInObject(const ScriptWrappable*) { return true; }
- static void setWrapperInObject(void*, v8::Handle<v8::Object>, v8::Isolate*, const WrapperConfiguration&)
+ static ScriptWrappable* fromObject(const void*)
{
ASSERT_NOT_REACHED();
+ return 0;
}
- static void setWrapperInObject(ScriptWrappable* object, v8::Handle<v8::Object> wrapper, v8::Isolate* isolate, const WrapperConfiguration& configuration)
+ static ScriptWrappable* fromObject(ScriptWrappable* object)
{
- object->setWrapper(wrapper, isolate, configuration);
+ return object;
}
- static const WrapperTypeInfo* getTypeInfoFromObject(void* object)
+ bool setReturnValue(v8::ReturnValue<v8::Value> returnValue)
{
- ASSERT_NOT_REACHED();
- return 0;
+ v8::Persistent<v8::Object> persistent;
+ getPersistent(&persistent);
+ returnValue.Set(persistent);
+ return containsWrapper();
}
- static const WrapperTypeInfo* getTypeInfoFromObject(ScriptWrappable* object)
+ void markAsDependentGroup(ScriptWrappable* groupRoot, v8::Isolate* isolate)
{
- return object->typeInfo();
+ ASSERT(containsWrapper());
+ ASSERT(groupRoot && groupRoot->containsWrapper());
+
+ v8::UniqueId groupId(groupRoot->m_wrapperOrTypeInfo);
+ v8::Persistent<v8::Object> wrapper;
+ getPersistent(&wrapper);
+ wrapper.MarkPartiallyDependent();
+ isolate->SetObjectGroupId(v8::Persistent<v8::Value>::Cast(wrapper), groupId);
}
- static void setTypeInfoInObject(void* object, const WrapperTypeInfo* info)
+ void setReference(const v8::Persistent<v8::Object>& parent, v8::Isolate* isolate)
{
- ASSERT_NOT_REACHED();
+ v8::Persistent<v8::Object> persistent;
+ getPersistent(&persistent);
+ isolate->SetReference(parent, persistent);
}
- static void setTypeInfoInObject(ScriptWrappable* object, const WrapperTypeInfo* info)
+ template<typename V8T, typename T>
+ static void assertWrapperSanity(v8::Local<v8::Object> object, T* objectAsT)
{
- object->setTypeInfo(info);
+ ASSERT(objectAsT);
+ RELEASE_ASSERT_WITH_SECURITY_IMPLICATION(object.IsEmpty()
+ || object->GetAlignedPointerFromInternalField(v8DOMWrapperObjectIndex) == V8T::toInternalPointer(objectAsT));
}
template<typename V8T, typename T>
- static bool setReturnValueWithSecurityCheck(v8::ReturnValue<v8::Value> returnValue, T* object)
+ static void assertWrapperSanity(void* object, T* objectAsT)
{
- return ScriptWrappable::getUnsafeWrapperFromObject(object).template setReturnValueWithSecurityCheck<V8T>(returnValue, object);
+ ASSERT_NOT_REACHED();
}
- template<typename T>
- static bool setReturnValue(v8::ReturnValue<v8::Value> returnValue, T* object)
+ template<typename V8T, typename T>
+ static void assertWrapperSanity(ScriptWrappable* object, T* objectAsT)
{
- return ScriptWrappable::getUnsafeWrapperFromObject(object).setReturnValue(returnValue);
+ ASSERT(object);
+ ASSERT(objectAsT);
+ v8::Object* value = object->getRawValue();
+ RELEASE_ASSERT_WITH_SECURITY_IMPLICATION(value == 0
+ || value->GetAlignedPointerFromInternalField(v8DOMWrapperObjectIndex) == V8T::toInternalPointer(objectAsT));
}
+ inline bool containsWrapper() const { return (m_wrapperOrTypeInfo & 1); }
+ inline bool containsTypeInfo() const { return m_wrapperOrTypeInfo && !(m_wrapperOrTypeInfo & 1); }
+
protected:
~ScriptWrappable()
{
- ASSERT(m_wrapperOrTypeInfo); // Assert initialization via init() even if not subsequently wrapped.
- m_wrapperOrTypeInfo = 0; // Break UAF attempts to wrap.
+ // We must not get deleted as long as we contain a wrapper. If this happens, we screwed up ref
+ // counting somewhere. Crash here instead of crashing during a later gc cycle.
+ RELEASE_ASSERT_WITH_SECURITY_IMPLICATION(!containsWrapper());
+ ASSERT(m_wrapperOrTypeInfo); // Assert initialization via init() even if not subsequently wrapped.
+ m_wrapperOrTypeInfo = 0; // Break UAF attempts to wrap.
}
private:
- // For calling unsafePersistent and getWrapperFromObject.
- friend class MinorGCWrapperVisitor;
- friend class DOMDataStore;
-
- UnsafePersistent<v8::Object> unsafePersistent() const
+ void getPersistent(v8::Persistent<v8::Object>* persistent) const
{
- v8::Object* object = containsWrapper() ? reinterpret_cast<v8::Object*>(m_wrapperOrTypeInfo & ~1) : 0;
- return UnsafePersistent<v8::Object>(object);
- }
+ ASSERT(persistent);
- static UnsafePersistent<v8::Object> getUnsafeWrapperFromObject(void*)
- {
- ASSERT_NOT_REACHED();
- return UnsafePersistent<v8::Object>();
+ // Horrible and super unsafe: Cast the Persistent to an Object*, so
+ // that we can inject the wrapped value. This only works because
+ // we previously 'stole' the object pointer from a Persistent in
+ // the setWrapper() method.
+ *reinterpret_cast<v8::Object**>(persistent) = getRawValue();
}
- static UnsafePersistent<v8::Object> getUnsafeWrapperFromObject(ScriptWrappable* object)
+ inline v8::Object* getRawValue() const
{
- return object->unsafePersistent();
+ v8::Object* object = containsWrapper() ? reinterpret_cast<v8::Object*>(m_wrapperOrTypeInfo & ~1) : 0;
+ return object;
}
- inline bool containsWrapper() const { return (m_wrapperOrTypeInfo & 1) == 1; }
- inline bool containsTypeInfo() const { return m_wrapperOrTypeInfo && (m_wrapperOrTypeInfo & 1) == 0; }
-
- inline void disposeWrapper(v8::Local<v8::Object> value, const WrapperTypeInfo* info)
+ inline void disposeWrapper(v8::Local<v8::Object> wrapper)
{
ASSERT(containsWrapper());
- ASSERT(value == *unsafePersistent().persistent());
- unsafePersistent().dispose();
- setTypeInfo(info);
+
+ v8::Persistent<v8::Object> persistent;
+ getPersistent(&persistent);
+
+ ASSERT(wrapper == persistent);
+ persistent.Reset();
+ setTypeInfo(toWrapperTypeInfo(wrapper));
}
// If zero, then this contains nothing, otherwise:
@@ -190,18 +252,15 @@ private:
static void setWeakCallback(const v8::WeakCallbackData<v8::Object, ScriptWrappable>& data)
{
- ASSERT(*data.GetParameter()->unsafePersistent().persistent() == data.GetValue());
-
- // Note: |object| might not be equal to |data|.GetParameter(), e.g., if ScriptWrappable isn't a left-most base class.
- void* object = toNative(data.GetValue());
- const WrapperTypeInfo* info = toWrapperTypeInfo(data.GetValue());
- ASSERT(info->derefObjectFunction);
+ v8::Persistent<v8::Object> persistent;
+ data.GetParameter()->getPersistent(&persistent);
+ ASSERT(persistent == data.GetValue());
+ data.GetParameter()->disposeWrapper(data.GetValue());
- data.GetParameter()->disposeWrapper(data.GetValue(), info);
// FIXME: I noticed that 50%~ of minor GC cycle times can be consumed
// inside data.GetParameter()->deref(), which causes Node destructions. We should
// make Node destructions incremental.
- info->derefObject(object);
+ releaseObject(data.GetValue());
}
};
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/SerializedScriptValue.cpp b/chromium/third_party/WebKit/Source/bindings/v8/SerializedScriptValue.cpp
index 72f35602748..8da614f47cc 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/SerializedScriptValue.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/SerializedScriptValue.cpp
@@ -31,16 +31,16 @@
#include "config.h"
#include "bindings/v8/SerializedScriptValue.h"
-#include "V8Blob.h"
-#include "V8DOMFileSystem.h"
-#include "V8File.h"
-#include "V8FileList.h"
-#include "V8ImageData.h"
-#include "V8MessagePort.h"
-#include "bindings/v8/ScriptScope.h"
-#include "bindings/v8/ScriptState.h"
+#include "bindings/core/v8/V8Blob.h"
+#include "bindings/core/v8/V8File.h"
+#include "bindings/core/v8/V8FileList.h"
+#include "bindings/core/v8/V8ImageData.h"
+#include "bindings/core/v8/V8MessagePort.h"
+#include "bindings/modules/v8/V8DOMFileSystem.h"
+#include "bindings/modules/v8/V8Key.h"
+#include "bindings/v8/ExceptionState.h"
#include "bindings/v8/V8Binding.h"
-#include "bindings/v8/V8Utilities.h"
+#include "bindings/v8/WorkerScriptController.h"
#include "bindings/v8/custom/V8ArrayBufferCustom.h"
#include "bindings/v8/custom/V8ArrayBufferViewCustom.h"
#include "bindings/v8/custom/V8DataViewCustom.h"
@@ -61,6 +61,12 @@
#include "core/html/ImageData.h"
#include "core/html/canvas/DataView.h"
#include "platform/SharedBuffer.h"
+#include "platform/heap/Handle.h"
+#include "public/platform/Platform.h"
+#include "public/platform/WebBlobInfo.h"
+#include "public/platform/WebCrypto.h"
+#include "public/platform/WebCryptoKey.h"
+#include "public/platform/WebCryptoKeyAlgorithm.h"
#include "wtf/ArrayBuffer.h"
#include "wtf/ArrayBufferContents.h"
#include "wtf/ArrayBufferView.h"
@@ -133,6 +139,12 @@ private:
// need to rehash after every garbage collection because a key object may have been moved.
template<typename G>
struct V8HandlePtrHash {
+ static v8::Handle<G> unsafeHandleFromRawValue(const G* value)
+ {
+ const v8::Handle<G>* handle = reinterpret_cast<const v8::Handle<G>*>(&value);
+ return *handle;
+ }
+
static unsigned hash(const G* key)
{
return static_cast<unsigned>(unsafeHandleFromRawValue(key)->GetIdentityHash());
@@ -186,10 +198,13 @@ enum SerializationTag {
DateTag = 'D', // value:double -> Date (ref)
MessagePortTag = 'M', // index:int -> MessagePort. Fills the result with transferred MessagePort.
NumberTag = 'N', // value:double -> Number
- BlobTag = 'b', // url:WebCoreString, type:WebCoreString, size:uint64_t -> Blob (ref)
+ BlobTag = 'b', // uuid:WebCoreString, type:WebCoreString, size:uint64_t -> Blob (ref)
+ BlobIndexTag = 'i', // index:int32_t -> Blob (ref)
FileTag = 'f', // file:RawFile -> File (ref)
- DOMFileSystemTag = 'd', // type:int32_t, name:WebCoreString, url:WebCoreString -> FileSystem (ref)
+ FileIndexTag = 'e', // index:int32_t -> File (ref)
+ DOMFileSystemTag = 'd', // type:int32_t, name:WebCoreString, uuid:WebCoreString -> FileSystem (ref)
FileListTag = 'l', // length:uint32_t, files:RawFile[length] -> FileList (ref)
+ FileListIndexTag = 'L', // length:uint32_t, files:int32_t[length] -> FileList (ref)
ImageDataTag = '#', // width:uint32_t, height:uint32_t, pixelDataLength:uint32_t, data:byte[pixelDataLength] -> ImageData (ref)
ObjectTag = '{', // numProperties:uint32_t -> pops the last object from the open stack;
// fills it with the last numProperties name,value pairs pushed onto the deserialization stack
@@ -201,6 +216,13 @@ enum SerializationTag {
ArrayBufferTag = 'B', // byteLength:uint32_t, data:byte[byteLength] -> ArrayBuffer (ref)
ArrayBufferTransferTag = 't', // index:uint32_t -> ArrayBuffer. For ArrayBuffer transfer
ArrayBufferViewTag = 'V', // subtag:byte, byteOffset:uint32_t, byteLength:uint32_t -> ArrayBufferView (ref). Consumes an ArrayBuffer from the top of the deserialization stack.
+ CryptoKeyTag = 'K', // subtag:byte, props, usages:uint32_t, keyDataLength:uint32_t, keyData:byte[keyDataLength]
+ // If subtag=AesKeyTag:
+ // props = keyLengthBytes:uint32_t, algorithmId:uint32_t
+ // If subtag=HmacKeyTag:
+ // props = keyLengthBytes:uint32_t, hashId:uint32_t
+ // If subtag=RsaHashedKeyTag:
+ // props = algorithmId:uint32_t, type:uint32_t, modulusLengthBits:uint32_t, publicExponentLength:uint32_t, publicExponent:byte[publicExponentLength], hashId:uint32_t
ObjectReferenceTag = '^', // ref:uint32_t -> reference table[ref]
GenerateFreshObjectTag = 'o', // -> empty object allocated an object ID and pushed onto the open stack (ref)
GenerateFreshSparseArrayTag = 'a', // length:uint32_t -> empty array[length] allocated an object ID and pushed onto the open stack (ref)
@@ -226,6 +248,52 @@ enum ArrayBufferViewSubTag {
DataViewTag = '?'
};
+enum CryptoKeySubTag {
+ AesKeyTag = 1,
+ HmacKeyTag = 2,
+ // ID 3 was used by RsaKeyTag, while still behind experimental flag.
+ RsaHashedKeyTag = 4,
+ // Maximum allowed value is 255
+};
+
+enum AssymetricCryptoKeyType {
+ PublicKeyType = 1,
+ PrivateKeyType = 2,
+ // Maximum allowed value is 2^32-1
+};
+
+enum CryptoKeyAlgorithmTag {
+ AesCbcTag = 1,
+ HmacTag = 2,
+ RsaSsaPkcs1v1_5Tag = 3,
+ // ID 4 was used by RsaEs, while still behind experimental flag.
+ Sha1Tag = 5,
+ Sha256Tag = 6,
+ Sha384Tag = 7,
+ Sha512Tag = 8,
+ AesGcmTag = 9,
+ RsaOaepTag = 10,
+ AesCtrTag = 11,
+ AesKwTag = 12,
+ // Maximum allowed value is 2^32-1
+};
+
+enum CryptoKeyUsage {
+ // Extractability is not a "usage" in the WebCryptoKeyUsages sense, however
+ // it fits conveniently into this bitfield.
+ ExtractableUsage = 1 << 0,
+
+ EncryptUsage = 1 << 1,
+ DecryptUsage = 1 << 2,
+ SignUsage = 1 << 3,
+ VerifyUsage = 1 << 4,
+ DeriveKeyUsage = 1 << 5,
+ WrapKeyUsage = 1 << 6,
+ UnwrapKeyUsage = 1 << 7,
+ DeriveBitsUsage = 1 << 8,
+ // Maximum allowed value is 1 << 31
+};
+
static bool shouldCheckForCycles(int depth)
{
ASSERT(depth >= 0);
@@ -272,9 +340,8 @@ private:
class Writer {
WTF_MAKE_NONCOPYABLE(Writer);
public:
- explicit Writer(v8::Isolate* isolate)
+ Writer()
: m_position(0)
- , m_isolate(isolate)
{
}
@@ -392,6 +459,13 @@ public:
doWriteUint64(size);
}
+ void writeBlobIndex(int blobIndex)
+ {
+ ASSERT(blobIndex >= 0);
+ append(BlobIndexTag);
+ doWriteUint32(blobIndex);
+ }
+
void writeDOMFileSystem(int type, const String& name, const String& url)
{
append(DOMFileSystemTag);
@@ -406,6 +480,12 @@ public:
doWriteFile(file);
}
+ void writeFileIndex(int blobIndex)
+ {
+ append(FileIndexTag);
+ doWriteUint32(blobIndex);
+ }
+
void writeFileList(const FileList& fileList)
{
append(FileListTag);
@@ -415,6 +495,45 @@ public:
doWriteFile(*fileList.item(i));
}
+ void writeFileListIndex(const Vector<int>& blobIndices)
+ {
+ append(FileListIndexTag);
+ uint32_t length = blobIndices.size();
+ doWriteUint32(length);
+ for (unsigned i = 0; i < length; ++i)
+ doWriteUint32(blobIndices[i]);
+ }
+
+ bool writeCryptoKey(const blink::WebCryptoKey& key)
+ {
+ append(static_cast<uint8_t>(CryptoKeyTag));
+
+ switch (key.algorithm().paramsType()) {
+ case blink::WebCryptoKeyAlgorithmParamsTypeAes:
+ doWriteAesKey(key);
+ break;
+ case blink::WebCryptoKeyAlgorithmParamsTypeHmac:
+ doWriteHmacKey(key);
+ break;
+ case blink::WebCryptoKeyAlgorithmParamsTypeRsaHashed:
+ doWriteRsaHashedKey(key);
+ break;
+ case blink::WebCryptoKeyAlgorithmParamsTypeNone:
+ ASSERT_NOT_REACHED();
+ return false;
+ }
+
+ doWriteKeyUsages(key.usages(), key.extractable());
+
+ blink::WebVector<uint8_t> keyData;
+ if (!blink::Platform::current()->crypto()->serializeKeyForClone(key, keyData))
+ return false;
+
+ doWriteUint32(keyData.size());
+ append(keyData.data(), keyData.size());
+ return true;
+ }
+
void writeArrayBuffer(const ArrayBuffer& arrayBuffer)
{
append(ArrayBufferTag);
@@ -429,7 +548,7 @@ public:
ASSERT(static_cast<const uint8_t*>(arrayBuffer.data()) + arrayBufferView.byteOffset() ==
static_cast<const uint8_t*>(arrayBufferView.baseAddress()));
#endif
- ArrayBufferView::ViewType type = arrayBufferView.getType();
+ ArrayBufferView::ViewType type = arrayBufferView.type();
if (type == ArrayBufferView::TypeInt8)
append(ByteArrayTag);
@@ -544,8 +663,6 @@ public:
doWriteUint32(length);
}
- v8::Isolate* getIsolate() { return m_isolate; }
-
private:
void doWriteFile(const File& file)
{
@@ -588,6 +705,112 @@ private:
doWriteString(stringUTF8.data(), stringUTF8.length());
}
+ void doWriteHmacKey(const blink::WebCryptoKey& key)
+ {
+ ASSERT(key.algorithm().paramsType() == blink::WebCryptoKeyAlgorithmParamsTypeHmac);
+
+ append(static_cast<uint8_t>(HmacKeyTag));
+ ASSERT(!(key.algorithm().hmacParams()->lengthBits() % 8));
+ doWriteUint32(key.algorithm().hmacParams()->lengthBits() / 8);
+ doWriteAlgorithmId(key.algorithm().hmacParams()->hash().id());
+ }
+
+ void doWriteAesKey(const blink::WebCryptoKey& key)
+ {
+ ASSERT(key.algorithm().paramsType() == blink::WebCryptoKeyAlgorithmParamsTypeAes);
+
+ append(static_cast<uint8_t>(AesKeyTag));
+ doWriteAlgorithmId(key.algorithm().id());
+ // Converting the key length from bits to bytes is lossless and makes
+ // it fit in 1 byte.
+ ASSERT(!(key.algorithm().aesParams()->lengthBits() % 8));
+ doWriteUint32(key.algorithm().aesParams()->lengthBits() / 8);
+ }
+
+ void doWriteRsaHashedKey(const blink::WebCryptoKey& key)
+ {
+ ASSERT(key.algorithm().rsaHashedParams());
+ append(static_cast<uint8_t>(RsaHashedKeyTag));
+
+ doWriteAlgorithmId(key.algorithm().id());
+
+ switch (key.type()) {
+ case blink::WebCryptoKeyTypePublic:
+ doWriteUint32(PublicKeyType);
+ break;
+ case blink::WebCryptoKeyTypePrivate:
+ doWriteUint32(PrivateKeyType);
+ break;
+ case blink::WebCryptoKeyTypeSecret:
+ ASSERT_NOT_REACHED();
+ }
+
+ const blink::WebCryptoRsaHashedKeyAlgorithmParams* params = key.algorithm().rsaHashedParams();
+ doWriteUint32(params->modulusLengthBits());
+ doWriteUint32(params->publicExponent().size());
+ append(params->publicExponent().data(), params->publicExponent().size());
+ doWriteAlgorithmId(key.algorithm().rsaHashedParams()->hash().id());
+ }
+
+ void doWriteAlgorithmId(blink::WebCryptoAlgorithmId id)
+ {
+ switch (id) {
+ case blink::WebCryptoAlgorithmIdAesCbc:
+ return doWriteUint32(AesCbcTag);
+ case blink::WebCryptoAlgorithmIdHmac:
+ return doWriteUint32(HmacTag);
+ case blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5:
+ return doWriteUint32(RsaSsaPkcs1v1_5Tag);
+ case blink::WebCryptoAlgorithmIdSha1:
+ return doWriteUint32(Sha1Tag);
+ case blink::WebCryptoAlgorithmIdSha256:
+ return doWriteUint32(Sha256Tag);
+ case blink::WebCryptoAlgorithmIdSha384:
+ return doWriteUint32(Sha384Tag);
+ case blink::WebCryptoAlgorithmIdSha512:
+ return doWriteUint32(Sha512Tag);
+ case blink::WebCryptoAlgorithmIdAesGcm:
+ return doWriteUint32(AesGcmTag);
+ case blink::WebCryptoAlgorithmIdRsaOaep:
+ return doWriteUint32(RsaOaepTag);
+ case blink::WebCryptoAlgorithmIdAesCtr:
+ return doWriteUint32(AesCtrTag);
+ case blink::WebCryptoAlgorithmIdAesKw:
+ return doWriteUint32(AesKwTag);
+ }
+ ASSERT_NOT_REACHED();
+ }
+
+ void doWriteKeyUsages(const blink::WebCryptoKeyUsageMask usages, bool extractable)
+ {
+ // Reminder to update this when adding new key usages.
+ COMPILE_ASSERT(blink::EndOfWebCryptoKeyUsage == (1 << 7) + 1, UpdateMe);
+
+ uint32_t value = 0;
+
+ if (extractable)
+ value |= ExtractableUsage;
+
+ if (usages & blink::WebCryptoKeyUsageEncrypt)
+ value |= EncryptUsage;
+ if (usages & blink::WebCryptoKeyUsageDecrypt)
+ value |= DecryptUsage;
+ if (usages & blink::WebCryptoKeyUsageSign)
+ value |= SignUsage;
+ if (usages & blink::WebCryptoKeyUsageVerify)
+ value |= VerifyUsage;
+ if (usages & blink::WebCryptoKeyUsageDeriveKey)
+ value |= DeriveKeyUsage;
+ if (usages & blink::WebCryptoKeyUsageWrapKey)
+ value |= WrapKeyUsage;
+ if (usages & blink::WebCryptoKeyUsageUnwrapKey)
+ value |= UnwrapKeyUsage;
+ if (usages & blink::WebCryptoKeyUsageDeriveBits)
+ value |= DeriveBitsUsage;
+
+ doWriteUint32(value);
+ }
+
int bytesNeededToWireEncode(uint32_t value)
{
int bytes = 1;
@@ -675,23 +898,22 @@ private:
Vector<BufferValueType> m_buffer;
unsigned m_position;
- v8::Isolate* m_isolate;
};
-static v8::Handle<v8::Object> toV8Object(MessagePort* impl, v8::Isolate* isolate)
+static v8::Handle<v8::Object> toV8Object(MessagePort* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
{
if (!impl)
return v8::Handle<v8::Object>();
- v8::Handle<v8::Value> wrapper = toV8(impl, v8::Handle<v8::Object>(), isolate);
+ v8::Handle<v8::Value> wrapper = toV8(impl, creationContext, isolate);
ASSERT(wrapper->IsObject());
return wrapper.As<v8::Object>();
}
-static v8::Handle<v8::ArrayBuffer> toV8Object(ArrayBuffer* impl, v8::Isolate* isolate)
+static v8::Handle<v8::ArrayBuffer> toV8Object(ArrayBuffer* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
{
if (!impl)
return v8::Handle<v8::ArrayBuffer>();
- v8::Handle<v8::Value> wrapper = toV8(impl, v8::Handle<v8::Object>(), isolate);
+ v8::Handle<v8::Value> wrapper = toV8(impl, creationContext, isolate);
ASSERT(wrapper->IsArrayBuffer());
return wrapper.As<v8::ArrayBuffer>();
}
@@ -703,28 +925,28 @@ public:
Success,
InputError,
DataCloneError,
- InvalidStateError,
- JSException,
- JSFailure
+ JSException
};
- Serializer(Writer& writer, MessagePortArray* messagePorts, ArrayBufferArray* arrayBuffers, BlobDataHandleMap& blobDataHandles, v8::TryCatch& tryCatch, v8::Isolate* isolate)
- : m_writer(writer)
+ Serializer(Writer& writer, MessagePortArray* messagePorts, ArrayBufferArray* arrayBuffers, WebBlobInfoArray* blobInfo, BlobDataHandleMap& blobDataHandles, v8::TryCatch& tryCatch, ScriptState* scriptState)
+ : m_scriptState(scriptState)
+ , m_writer(writer)
, m_tryCatch(tryCatch)
, m_depth(0)
, m_status(Success)
, m_nextObjectReference(0)
+ , m_blobInfo(blobInfo)
, m_blobDataHandles(blobDataHandles)
- , m_isolate(isolate)
{
ASSERT(!tryCatch.HasCaught());
+ v8::Handle<v8::Object> creationContext = m_scriptState->context()->Global();
if (messagePorts) {
for (size_t i = 0; i < messagePorts->size(); i++)
- m_transferredMessagePorts.set(toV8Object(messagePorts->at(i).get(), m_writer.getIsolate()), i);
+ m_transferredMessagePorts.set(toV8Object(messagePorts->at(i).get(), creationContext, isolate()), i);
}
if (arrayBuffers) {
for (size_t i = 0; i < arrayBuffers->size(); i++) {
- v8::Handle<v8::Object> v8ArrayBuffer = toV8Object(arrayBuffers->at(i).get(), m_writer.getIsolate());
+ v8::Handle<v8::Object> v8ArrayBuffer = toV8Object(arrayBuffers->at(i).get(), creationContext, isolate());
// Coalesce multiple occurences of the same buffer to the first index.
if (!m_transferredArrayBuffers.contains(v8ArrayBuffer))
m_transferredArrayBuffers.set(v8ArrayBuffer, i);
@@ -732,9 +954,11 @@ public:
}
}
+ v8::Isolate* isolate() { return m_scriptState->isolate(); }
+
Status serialize(v8::Handle<v8::Value> value)
{
- v8::HandleScope scope(m_isolate);
+ v8::HandleScope scope(isolate());
m_writer.writeVersion();
StateBase* state = doSerialize(value, 0);
while (state)
@@ -742,6 +966,8 @@ public:
return m_status;
}
+ String errorMessage() { return m_errorMessage; }
+
// Functions used by serialization states.
StateBase* doSerialize(v8::Handle<v8::Value>, StateBase* next);
@@ -752,12 +978,7 @@ public:
StateBase* checkException(StateBase* state)
{
- return m_tryCatch.HasCaught() ? handleError(JSException, state) : 0;
- }
-
- StateBase* reportFailure(StateBase* state)
- {
- return handleError(JSFailure, state);
+ return m_tryCatch.HasCaught() ? handleError(JSException, "", state) : 0;
}
StateBase* writeObject(uint32_t numProperties, StateBase* state)
@@ -796,10 +1017,6 @@ private:
// state.
virtual StateBase* advance(Serializer&) = 0;
- // Returns 1 if this state is currently serializing a property
- // via an accessor and 0 otherwise.
- virtual uint32_t execDepth() const { return 0; }
-
protected:
StateBase(v8::Handle<v8::Value> composite, StateBase* next)
: m_composite(composite)
@@ -813,14 +1030,14 @@ private:
};
// Dummy state that is used to signal serialization errors.
- class ErrorState : public StateBase {
+ class ErrorState FINAL : public StateBase {
public:
ErrorState()
: StateBase(v8Undefined(), 0)
{
}
- virtual StateBase* advance(Serializer&)
+ virtual StateBase* advance(Serializer&) OVERRIDE
{
delete this;
return 0;
@@ -860,7 +1077,7 @@ private:
if (StateBase* newState = serializer.checkException(this))
return newState;
if (propertyName.IsEmpty())
- return serializer.reportFailure(this);
+ return serializer.handleError(InputError, "Empty property names cannot be cloned.", this);
bool hasStringProperty = propertyName->IsString() && composite()->HasRealNamedProperty(propertyName.As<v8::String>());
if (StateBase* newState = serializer.checkException(this))
return newState;
@@ -905,33 +1122,33 @@ private:
bool m_nameDone;
};
- class ObjectState : public AbstractObjectState {
+ class ObjectState FINAL : public AbstractObjectState {
public:
ObjectState(v8::Handle<v8::Object> object, StateBase* next)
: AbstractObjectState(object, next)
{
}
- virtual StateBase* advance(Serializer& serializer)
+ virtual StateBase* advance(Serializer& serializer) OVERRIDE
{
if (m_propertyNames.IsEmpty()) {
m_propertyNames = composite()->GetPropertyNames();
if (StateBase* newState = serializer.checkException(this))
return newState;
if (m_propertyNames.IsEmpty())
- return serializer.reportFailure(this);
+ return serializer.handleError(InputError, "Empty property names cannot be cloned.", nextState());
}
return serializeProperties(false, serializer);
}
protected:
- virtual StateBase* objectDone(unsigned numProperties, Serializer& serializer)
+ virtual StateBase* objectDone(unsigned numProperties, Serializer& serializer) OVERRIDE
{
return serializer.writeObject(numProperties, this);
}
};
- class DenseArrayState : public AbstractObjectState {
+ class DenseArrayState FINAL : public AbstractObjectState {
public:
DenseArrayState(v8::Handle<v8::Array> array, v8::Handle<v8::Array> propertyNames, StateBase* next, v8::Isolate* isolate)
: AbstractObjectState(array, next)
@@ -941,7 +1158,7 @@ private:
m_propertyNames = v8::Local<v8::Array>::New(isolate, propertyNames);
}
- virtual StateBase* advance(Serializer& serializer)
+ virtual StateBase* advance(Serializer& serializer) OVERRIDE
{
while (m_arrayIndex < m_arrayLength) {
v8::Handle<v8::Value> value = composite().As<v8::Array>()->Get(m_arrayIndex);
@@ -955,7 +1172,7 @@ private:
}
protected:
- virtual StateBase* objectDone(unsigned numProperties, Serializer& serializer)
+ virtual StateBase* objectDone(unsigned numProperties, Serializer& serializer) OVERRIDE
{
return serializer.writeDenseArray(numProperties, m_arrayLength, this);
}
@@ -965,7 +1182,7 @@ private:
uint32_t m_arrayLength;
};
- class SparseArrayState : public AbstractObjectState {
+ class SparseArrayState FINAL : public AbstractObjectState {
public:
SparseArrayState(v8::Handle<v8::Array> array, v8::Handle<v8::Array> propertyNames, StateBase* next, v8::Isolate* isolate)
: AbstractObjectState(array, next)
@@ -973,13 +1190,13 @@ private:
m_propertyNames = v8::Local<v8::Array>::New(isolate, propertyNames);
}
- virtual StateBase* advance(Serializer& serializer)
+ virtual StateBase* advance(Serializer& serializer) OVERRIDE
{
return serializeProperties(false, serializer);
}
protected:
- virtual StateBase* objectDone(unsigned numProperties, Serializer& serializer)
+ virtual StateBase* objectDone(unsigned numProperties, Serializer& serializer) OVERRIDE
{
return serializer.writeSparseArray(numProperties, composite().As<v8::Array>()->Length(), this);
}
@@ -989,7 +1206,7 @@ private:
{
ASSERT(state);
++m_depth;
- return checkComposite(state) ? state : handleError(InputError, state);
+ return checkComposite(state) ? state : handleError(InputError, "Value being cloned is either cyclic or too deeply nested.", state);
}
StateBase* pop(StateBase* state)
@@ -1001,10 +1218,11 @@ private:
return next;
}
- StateBase* handleError(Status errorStatus, StateBase* state)
+ StateBase* handleError(Status errorStatus, const String& message, StateBase* state)
{
ASSERT(errorStatus != Success);
m_status = errorStatus;
+ m_errorMessage = message;
while (state) {
StateBase* tmp = state->nextState();
delete state;
@@ -1056,13 +1274,20 @@ private:
m_writer.writeBooleanObject(booleanObject->ValueOf());
}
- void writeBlob(v8::Handle<v8::Value> value)
+ StateBase* writeBlob(v8::Handle<v8::Value> value, StateBase* next)
{
Blob* blob = V8Blob::toNative(value.As<v8::Object>());
if (!blob)
- return;
- m_writer.writeBlob(blob->uuid(), blob->type(), blob->size());
- m_blobDataHandles.add(blob->uuid(), blob->blobDataHandle());
+ return 0;
+ if (blob->hasBeenClosed())
+ return handleError(DataCloneError, "A Blob object has been closed, and could therefore not be cloned.", next);
+ int blobIndex = -1;
+ m_blobDataHandles.set(blob->uuid(), blob->blobDataHandle());
+ if (appendBlobInfo(blob->uuid(), blob->type(), blob->size(), &blobIndex))
+ m_writer.writeBlobIndex(blobIndex);
+ else
+ m_writer.writeBlob(blob->uuid(), blob->type(), blob->size());
+ return 0;
}
StateBase* writeDOMFileSystem(v8::Handle<v8::Value> value, StateBase* next)
@@ -1071,29 +1296,61 @@ private:
if (!fs)
return 0;
if (!fs->clonable())
- return handleError(DataCloneError, next);
+ return handleError(DataCloneError, "A FileSystem object could not be cloned.", next);
m_writer.writeDOMFileSystem(fs->type(), fs->name(), fs->rootURL().string());
return 0;
}
- void writeFile(v8::Handle<v8::Value> value)
+ StateBase* writeFile(v8::Handle<v8::Value> value, StateBase* next)
{
File* file = V8File::toNative(value.As<v8::Object>());
if (!file)
- return;
- m_writer.writeFile(*file);
- m_blobDataHandles.add(file->uuid(), file->blobDataHandle());
+ return 0;
+ if (file->hasBeenClosed())
+ return handleError(DataCloneError, "A File object has been closed, and could therefore not be cloned.", next);
+ int blobIndex = -1;
+ m_blobDataHandles.set(file->uuid(), file->blobDataHandle());
+ if (appendFileInfo(file, &blobIndex)) {
+ ASSERT(blobIndex >= 0);
+ m_writer.writeFileIndex(blobIndex);
+ } else {
+ m_writer.writeFile(*file);
+ }
+ return 0;
}
- void writeFileList(v8::Handle<v8::Value> value)
+ StateBase* writeFileList(v8::Handle<v8::Value> value, StateBase* next)
{
FileList* fileList = V8FileList::toNative(value.As<v8::Object>());
if (!fileList)
- return;
- m_writer.writeFileList(*fileList);
+ return 0;
unsigned length = fileList->length();
- for (unsigned i = 0; i < length; ++i)
- m_blobDataHandles.add(fileList->item(i)->uuid(), fileList->item(i)->blobDataHandle());
+ Vector<int> blobIndices;
+ for (unsigned i = 0; i < length; ++i) {
+ int blobIndex = -1;
+ const File* file = fileList->item(i);
+ if (file->hasBeenClosed())
+ return handleError(DataCloneError, "A File object has been closed, and could therefore not be cloned.", next);
+ m_blobDataHandles.set(file->uuid(), file->blobDataHandle());
+ if (appendFileInfo(file, &blobIndex)) {
+ ASSERT(!i || blobIndex > 0);
+ ASSERT(blobIndex >= 0);
+ blobIndices.append(blobIndex);
+ }
+ }
+ if (!blobIndices.isEmpty())
+ m_writer.writeFileListIndex(blobIndices);
+ else
+ m_writer.writeFileList(*fileList);
+ return 0;
+ }
+
+ bool writeCryptoKey(v8::Handle<v8::Value> value)
+ {
+ Key* key = V8Key::toNative(value.As<v8::Object>());
+ if (!key)
+ return false;
+ return m_writer.writeCryptoKey(key->key());
}
void writeImageData(v8::Handle<v8::Value> value)
@@ -1118,10 +1375,10 @@ private:
if (!arrayBufferView)
return 0;
if (!arrayBufferView->buffer())
- return handleError(DataCloneError, next);
- v8::Handle<v8::Value> underlyingBuffer = toV8(arrayBufferView->buffer(), v8::Handle<v8::Object>(), m_writer.getIsolate());
+ return handleError(DataCloneError, "An ArrayBuffer could not be cloned.", next);
+ v8::Handle<v8::Value> underlyingBuffer = toV8(arrayBufferView->buffer(), m_scriptState->context()->Global(), isolate());
if (underlyingBuffer.IsEmpty())
- return handleError(DataCloneError, next);
+ return handleError(DataCloneError, "An ArrayBuffer could not be cloned.", next);
StateBase* stateOut = doSerializeArrayBuffer(underlyingBuffer, next);
if (stateOut)
return stateOut;
@@ -1146,7 +1403,7 @@ private:
if (!arrayBuffer)
return 0;
if (arrayBuffer->isNeutered())
- return handleError(InvalidStateError, next);
+ return handleError(DataCloneError, "An ArrayBuffer is neutered and could not be cloned.", next);
ASSERT(!m_transferredArrayBuffers.contains(value.As<v8::Object>()));
m_writer.writeArrayBuffer(*arrayBuffer);
return 0;
@@ -1158,7 +1415,7 @@ private:
if (!arrayBuffer)
return 0;
if (arrayBuffer->isNeutered())
- return handleError(DataCloneError, next);
+ return handleError(DataCloneError, "An ArrayBuffer is neutered and could not be cloned.", next);
m_writer.writeTransferredArrayBuffer(index);
return 0;
}
@@ -1181,11 +1438,11 @@ private:
if (shouldSerializeDensely(length, propertyNames->Length())) {
m_writer.writeGenerateFreshDenseArray(length);
- return push(new DenseArrayState(array, propertyNames, next, m_isolate));
+ return push(new DenseArrayState(array, propertyNames, next, isolate()));
}
m_writer.writeGenerateFreshSparseArray(length);
- return push(new SparseArrayState(array, propertyNames, next, m_isolate));
+ return push(new SparseArrayState(array, propertyNames, next, isolate()));
}
StateBase* startObjectState(v8::Handle<v8::Object> object, StateBase* next)
@@ -1204,34 +1461,68 @@ private:
m_objectPool.set(object, objectReference);
}
+ bool appendBlobInfo(const String& uuid, const String& type, unsigned long long size, int* index)
+ {
+ if (!m_blobInfo)
+ return false;
+ *index = m_blobInfo->size();
+ m_blobInfo->append(blink::WebBlobInfo(uuid, type, size));
+ return true;
+ }
+
+ bool appendFileInfo(const File* file, int* index)
+ {
+ if (!m_blobInfo)
+ return false;
+
+ long long size = -1;
+ double lastModified = invalidFileTime();
+ file->captureSnapshot(size, lastModified);
+ *index = m_blobInfo->size();
+ m_blobInfo->append(blink::WebBlobInfo(file->uuid(), file->path(), file->name(), file->type(), lastModified, size));
+ return true;
+ }
+
+ RefPtr<ScriptState> m_scriptState;
Writer& m_writer;
v8::TryCatch& m_tryCatch;
int m_depth;
Status m_status;
+ String m_errorMessage;
typedef V8ObjectMap<v8::Object, uint32_t> ObjectPool;
ObjectPool m_objectPool;
ObjectPool m_transferredMessagePorts;
ObjectPool m_transferredArrayBuffers;
uint32_t m_nextObjectReference;
+ WebBlobInfoArray* m_blobInfo;
BlobDataHandleMap& m_blobDataHandles;
- v8::Isolate* m_isolate;
};
+// Returns true if the provided object is to be considered a 'host object', as used in the
+// HTML5 structured clone algorithm.
+static bool isHostObject(v8::Handle<v8::Object> object)
+{
+ // If the object has any internal fields, then we won't be able to serialize or deserialize
+ // them; conveniently, this is also a quick way to detect DOM wrapper objects, because
+ // the mechanism for these relies on data stored in these fields. We should
+ // catch external array data as a special case.
+ return object->InternalFieldCount() || object->HasIndexedPropertiesInExternalArrayData();
+}
+
Serializer::StateBase* Serializer::doSerialize(v8::Handle<v8::Value> value, StateBase* next)
{
m_writer.writeReferenceCount(m_nextObjectReference);
uint32_t objectReference;
uint32_t arrayBufferIndex;
- WrapperWorldType currentWorldType = worldType(m_isolate);
if ((value->IsObject() || value->IsDate() || value->IsRegExp())
&& m_objectPool.tryGet(value.As<v8::Object>(), &objectReference)) {
// Note that IsObject() also detects wrappers (eg, it will catch the things
// that we grey and write below).
ASSERT(!value->IsString());
m_writer.writeObjectReference(objectReference);
- } else if (value.IsEmpty())
- return reportFailure(next);
- else if (value->IsUndefined())
+ } else if (value.IsEmpty()) {
+ return handleError(InputError, "The empty property name cannot be cloned.", next);
+ } else if (value->IsUndefined())
m_writer.writeUndefined();
else if (value->IsNull())
m_writer.writeNull();
@@ -1245,22 +1536,22 @@ Serializer::StateBase* Serializer::doSerialize(v8::Handle<v8::Value> value, Stat
m_writer.writeUint32(value->Uint32Value());
else if (value->IsNumber())
m_writer.writeNumber(value.As<v8::Number>()->Value());
- else if (V8ArrayBufferView::hasInstance(value, m_isolate, currentWorldType))
+ else if (V8ArrayBufferView::hasInstance(value, isolate()))
return writeAndGreyArrayBufferView(value.As<v8::Object>(), next);
else if (value->IsString())
writeString(value);
- else if (V8MessagePort::hasInstance(value, m_isolate, currentWorldType)) {
+ else if (V8MessagePort::hasInstance(value, isolate())) {
uint32_t messagePortIndex;
if (m_transferredMessagePorts.tryGet(value.As<v8::Object>(), &messagePortIndex))
m_writer.writeTransferredMessagePort(messagePortIndex);
else
- return handleError(DataCloneError, next);
- } else if (V8ArrayBuffer::hasInstance(value, m_isolate, currentWorldType) && m_transferredArrayBuffers.tryGet(value.As<v8::Object>(), &arrayBufferIndex))
+ return handleError(DataCloneError, "A MessagePort could not be cloned.", next);
+ } else if (V8ArrayBuffer::hasInstance(value, isolate()) && m_transferredArrayBuffers.tryGet(value.As<v8::Object>(), &arrayBufferIndex))
return writeTransferredArrayBuffer(value, arrayBufferIndex, next);
else {
v8::Handle<v8::Object> jsObject = value.As<v8::Object>();
if (jsObject.IsEmpty())
- return handleError(DataCloneError, next);
+ return handleError(DataCloneError, "An object could not be cloned.", next);
greyObject(jsObject);
if (value->IsDate())
m_writer.writeDate(value->NumberValue());
@@ -1272,26 +1563,29 @@ Serializer::StateBase* Serializer::doSerialize(v8::Handle<v8::Value> value, Stat
writeBooleanObject(value);
else if (value->IsArray()) {
return startArrayState(value.As<v8::Array>(), next);
- } else if (V8File::hasInstance(value, m_isolate, currentWorldType))
- writeFile(value);
- else if (V8Blob::hasInstance(value, m_isolate, currentWorldType))
- writeBlob(value);
- else if (V8DOMFileSystem::hasInstance(value, m_isolate, currentWorldType))
+ } else if (V8File::hasInstance(value, isolate()))
+ return writeFile(value, next);
+ else if (V8Blob::hasInstance(value, isolate()))
+ return writeBlob(value, next);
+ else if (V8DOMFileSystem::hasInstance(value, isolate()))
return writeDOMFileSystem(value, next);
- else if (V8FileList::hasInstance(value, m_isolate, currentWorldType))
- writeFileList(value);
- else if (V8ImageData::hasInstance(value, m_isolate, currentWorldType))
+ else if (V8FileList::hasInstance(value, isolate()))
+ return writeFileList(value, next);
+ else if (V8Key::hasInstance(value, isolate())) {
+ if (!writeCryptoKey(value))
+ return handleError(DataCloneError, "Couldn't serialize key data", next);
+ } else if (V8ImageData::hasInstance(value, isolate()))
writeImageData(value);
else if (value->IsRegExp())
writeRegExp(value);
- else if (V8ArrayBuffer::hasInstance(value, m_isolate, currentWorldType))
+ else if (V8ArrayBuffer::hasInstance(value, isolate()))
return writeArrayBuffer(value, next);
else if (value->IsObject()) {
if (isHostObject(jsObject) || jsObject->IsCallable() || value->IsNativeError())
- return handleError(DataCloneError, next);
+ return handleError(DataCloneError, "An object could not be cloned.", next);
return startObjectState(jsObject, next);
} else
- return handleError(DataCloneError, next);
+ return handleError(DataCloneError, "A value could not be cloned.", next);
}
return 0;
}
@@ -1319,12 +1613,13 @@ public:
// restoring information about saved objects of composite types.
class Reader {
public:
- Reader(const uint8_t* buffer, int length, v8::Isolate* isolate, const BlobDataHandleMap& blobDataHandles)
- : m_buffer(buffer)
+ Reader(const uint8_t* buffer, int length, const WebBlobInfoArray* blobInfo, BlobDataHandleMap& blobDataHandles, ScriptState* scriptState)
+ : m_scriptState(scriptState)
+ , m_buffer(buffer)
, m_length(length)
, m_position(0)
, m_version(0)
- , m_isolate(isolate)
+ , m_blobInfo(blobInfo)
, m_blobDataHandles(blobDataHandles)
{
ASSERT(!(reinterpret_cast<size_t>(buffer) & 1));
@@ -1333,8 +1628,12 @@ public:
bool isEof() const { return m_position >= m_length; }
- v8::Isolate* isolate() const { return m_isolate; }
+ ScriptState* scriptState() const { return m_scriptState.get(); }
+
+private:
+ v8::Isolate* isolate() const { return m_scriptState->isolate(); }
+public:
bool read(v8::Handle<v8::Value>* value, CompositeCreator& creator)
{
SerializationTag tag;
@@ -1342,7 +1641,7 @@ public:
return false;
switch (tag) {
case ReferenceCountTag: {
- if (m_version <= 0)
+ if (!m_version)
return false;
uint32_t referenceTableSize;
if (!doReadUint32(&referenceTableSize))
@@ -1359,16 +1658,16 @@ public:
case PaddingTag:
return true;
case UndefinedTag:
- *value = v8::Undefined(m_isolate);
+ *value = v8::Undefined(isolate());
break;
case NullTag:
- *value = v8::Null(m_isolate);
+ *value = v8::Null(isolate());
break;
case TrueTag:
- *value = v8BooleanWithCheck(true, m_isolate);
+ *value = v8Boolean(true, isolate());
break;
case FalseTag:
- *value = v8BooleanWithCheck(false, m_isolate);
+ *value = v8Boolean(false, isolate());
break;
case TrueObjectTag:
*value = v8::BooleanObject::New(true);
@@ -1414,12 +1713,14 @@ public:
creator.pushObjectReference(*value);
break;
case BlobTag:
- if (!readBlob(value))
+ case BlobIndexTag:
+ if (!readBlob(value, tag == BlobIndexTag))
return false;
creator.pushObjectReference(*value);
break;
case FileTag:
- if (!readFile(value))
+ case FileIndexTag:
+ if (!readFile(value, tag == FileIndexTag))
return false;
creator.pushObjectReference(*value);
break;
@@ -1429,7 +1730,13 @@ public:
creator.pushObjectReference(*value);
break;
case FileListTag:
- if (!readFileList(value))
+ case FileListIndexTag:
+ if (!readFileList(value, tag == FileListIndexTag))
+ return false;
+ creator.pushObjectReference(*value);
+ break;
+ case CryptoKeyTag:
+ if (!readCryptoKey(value))
return false;
creator.pushObjectReference(*value);
break;
@@ -1475,7 +1782,7 @@ public:
break;
}
case ArrayBufferViewTag: {
- if (m_version <= 0)
+ if (!m_version)
return false;
if (!readArrayBufferView(value, creator))
return false;
@@ -1483,7 +1790,7 @@ public:
break;
}
case ArrayBufferTag: {
- if (m_version <= 0)
+ if (!m_version)
return false;
if (!readArrayBuffer(value))
return false;
@@ -1491,14 +1798,14 @@ public:
break;
}
case GenerateFreshObjectTag: {
- if (m_version <= 0)
+ if (!m_version)
return false;
if (!creator.newObject())
return false;
return true;
}
case GenerateFreshSparseArrayTag: {
- if (m_version <= 0)
+ if (!m_version)
return false;
uint32_t length;
if (!doReadUint32(&length))
@@ -1508,7 +1815,7 @@ public:
return true;
}
case GenerateFreshDenseArrayTag: {
- if (m_version <= 0)
+ if (!m_version)
return false;
uint32_t length;
if (!doReadUint32(&length))
@@ -1518,7 +1825,7 @@ public:
return true;
}
case MessagePortTag: {
- if (m_version <= 0)
+ if (!m_version)
return false;
uint32_t index;
if (!doReadUint32(&index))
@@ -1528,7 +1835,7 @@ public:
break;
}
case ArrayBufferTransferTag: {
- if (m_version <= 0)
+ if (!m_version)
return false;
uint32_t index;
if (!doReadUint32(&index))
@@ -1538,7 +1845,7 @@ public:
break;
}
case ObjectReferenceTag: {
- if (m_version <= 0)
+ if (!m_version)
return false;
uint32_t reference;
if (!doReadUint32(&reference))
@@ -1577,8 +1884,6 @@ public:
m_version = version;
}
- v8::Isolate* getIsolate() { return m_isolate; }
-
private:
bool readTag(SerializationTag* tag)
{
@@ -1609,7 +1914,7 @@ private:
return false;
if (m_position + length > m_length)
return false;
- *value = v8::String::NewFromUtf8(m_isolate, reinterpret_cast<const char*>(m_buffer + m_position), v8::String::kNormalString, length);
+ *value = v8::String::NewFromUtf8(isolate(), reinterpret_cast<const char*>(m_buffer + m_position), v8::String::kNormalString, length);
m_position += length;
return true;
}
@@ -1622,7 +1927,7 @@ private:
if (m_position + length > m_length)
return false;
ASSERT(!(m_position & 1));
- *value = v8::String::NewFromTwoByte(m_isolate, reinterpret_cast<const uint16_t*>(m_buffer + m_position), v8::String::kNormalString, length / sizeof(UChar));
+ *value = v8::String::NewFromTwoByte(isolate(), reinterpret_cast<const uint16_t*>(m_buffer + m_position), v8::String::kNormalString, length / sizeof(UChar));
m_position += length;
return true;
}
@@ -1653,7 +1958,7 @@ private:
uint32_t rawValue;
if (!doReadUint32(&rawValue))
return false;
- *value = v8::Integer::New(static_cast<int32_t>(ZigZag::decode(rawValue)), m_isolate);
+ *value = v8::Integer::New(isolate(), static_cast<int32_t>(ZigZag::decode(rawValue)));
return true;
}
@@ -1662,7 +1967,7 @@ private:
uint32_t rawValue;
if (!doReadUint32(&rawValue))
return false;
- *value = v8::Integer::NewFromUnsigned(rawValue, m_isolate);
+ *value = v8::Integer::NewFromUnsigned(isolate(), rawValue);
return true;
}
@@ -1671,7 +1976,7 @@ private:
double numberValue;
if (!doReadNumber(&numberValue))
return false;
- *value = v8DateOrNull(numberValue, m_isolate);
+ *value = v8DateOrNaN(numberValue, isolate());
return true;
}
@@ -1680,7 +1985,7 @@ private:
double number;
if (!doReadNumber(&number))
return false;
- *value = v8::Number::New(m_isolate, number);
+ *value = v8::Number::New(isolate(), number);
return true;
}
@@ -1689,7 +1994,7 @@ private:
double number;
if (!doReadNumber(&number))
return false;
- *value = v8::NumberObject::New(m_isolate, number);
+ *value = v8::NumberObject::New(isolate(), number);
return true;
}
@@ -1706,13 +2011,13 @@ private:
return false;
if (m_position + pixelDataLength > m_length)
return false;
- RefPtr<ImageData> imageData = ImageData::create(IntSize(width, height));
+ RefPtrWillBeRawPtr<ImageData> imageData = ImageData::create(IntSize(width, height));
Uint8ClampedArray* pixelArray = imageData->data();
ASSERT(pixelArray);
ASSERT(pixelArray->length() >= pixelDataLength);
memcpy(pixelArray->data(), m_buffer + m_position, pixelDataLength);
m_position += pixelDataLength;
- *value = toV8(imageData.release(), v8::Handle<v8::Object>(), m_isolate);
+ *value = toV8(imageData.release(), m_scriptState->context()->Global(), isolate());
return true;
}
@@ -1720,9 +2025,9 @@ private:
{
uint32_t byteLength;
if (!doReadUint32(&byteLength))
- return 0;
+ return nullptr;
if (m_position + byteLength > m_length)
- return 0;
+ return nullptr;
const void* bufferStart = m_buffer + m_position;
RefPtr<ArrayBuffer> arrayBuffer = ArrayBuffer::create(bufferStart, byteLength);
arrayBuffer->setDeallocationObserver(V8ArrayBufferDeallocationObserver::instanceTemplate());
@@ -1735,7 +2040,7 @@ private:
RefPtr<ArrayBuffer> arrayBuffer = doReadArrayBuffer();
if (!arrayBuffer)
return false;
- *value = toV8(arrayBuffer.release(), v8::Handle<v8::Object>(), m_isolate);
+ *value = toV8(arrayBuffer.release(), m_scriptState->context()->Global(), isolate());
return true;
}
@@ -1759,60 +2064,62 @@ private:
arrayBuffer = V8ArrayBuffer::toNative(arrayBufferV8Value.As<v8::Object>());
if (!arrayBuffer)
return false;
+
+ v8::Handle<v8::Object> creationContext = m_scriptState->context()->Global();
switch (subTag) {
case ByteArrayTag:
- *value = toV8(Int8Array::create(arrayBuffer.release(), byteOffset, byteLength), v8::Handle<v8::Object>(), m_isolate);
+ *value = toV8(Int8Array::create(arrayBuffer.release(), byteOffset, byteLength), creationContext, isolate());
break;
case UnsignedByteArrayTag:
- *value = toV8(Uint8Array::create(arrayBuffer.release(), byteOffset, byteLength), v8::Handle<v8::Object>(), m_isolate);
+ *value = toV8(Uint8Array::create(arrayBuffer.release(), byteOffset, byteLength), creationContext, isolate());
break;
case UnsignedByteClampedArrayTag:
- *value = toV8(Uint8ClampedArray::create(arrayBuffer.release(), byteOffset, byteLength), v8::Handle<v8::Object>(), m_isolate);
+ *value = toV8(Uint8ClampedArray::create(arrayBuffer.release(), byteOffset, byteLength), creationContext, isolate());
break;
case ShortArrayTag: {
uint32_t shortLength = byteLength / sizeof(int16_t);
if (shortLength * sizeof(int16_t) != byteLength)
return false;
- *value = toV8(Int16Array::create(arrayBuffer.release(), byteOffset, shortLength), v8::Handle<v8::Object>(), m_isolate);
+ *value = toV8(Int16Array::create(arrayBuffer.release(), byteOffset, shortLength), creationContext, isolate());
break;
}
case UnsignedShortArrayTag: {
uint32_t shortLength = byteLength / sizeof(uint16_t);
if (shortLength * sizeof(uint16_t) != byteLength)
return false;
- *value = toV8(Uint16Array::create(arrayBuffer.release(), byteOffset, shortLength), v8::Handle<v8::Object>(), m_isolate);
+ *value = toV8(Uint16Array::create(arrayBuffer.release(), byteOffset, shortLength), creationContext, isolate());
break;
}
case IntArrayTag: {
uint32_t intLength = byteLength / sizeof(int32_t);
if (intLength * sizeof(int32_t) != byteLength)
return false;
- *value = toV8(Int32Array::create(arrayBuffer.release(), byteOffset, intLength), v8::Handle<v8::Object>(), m_isolate);
+ *value = toV8(Int32Array::create(arrayBuffer.release(), byteOffset, intLength), creationContext, isolate());
break;
}
case UnsignedIntArrayTag: {
uint32_t intLength = byteLength / sizeof(uint32_t);
if (intLength * sizeof(uint32_t) != byteLength)
return false;
- *value = toV8(Uint32Array::create(arrayBuffer.release(), byteOffset, intLength), v8::Handle<v8::Object>(), m_isolate);
+ *value = toV8(Uint32Array::create(arrayBuffer.release(), byteOffset, intLength), creationContext, isolate());
break;
}
case FloatArrayTag: {
uint32_t floatLength = byteLength / sizeof(float);
if (floatLength * sizeof(float) != byteLength)
return false;
- *value = toV8(Float32Array::create(arrayBuffer.release(), byteOffset, floatLength), v8::Handle<v8::Object>(), m_isolate);
+ *value = toV8(Float32Array::create(arrayBuffer.release(), byteOffset, floatLength), creationContext, isolate());
break;
}
case DoubleArrayTag: {
uint32_t floatLength = byteLength / sizeof(double);
if (floatLength * sizeof(double) != byteLength)
return false;
- *value = toV8(Float64Array::create(arrayBuffer.release(), byteOffset, floatLength), v8::Handle<v8::Object>(), m_isolate);
+ *value = toV8(Float64Array::create(arrayBuffer.release(), byteOffset, floatLength), creationContext, isolate());
break;
}
case DataViewTag:
- *value = toV8(DataView::create(arrayBuffer.release(), byteOffset, byteLength), v8::Handle<v8::Object>(), m_isolate);
+ *value = toV8(DataView::create(arrayBuffer.release(), byteOffset, byteLength), creationContext, isolate());
break;
default:
return false;
@@ -1835,21 +2142,35 @@ private:
return true;
}
- bool readBlob(v8::Handle<v8::Value>* value)
+ bool readBlob(v8::Handle<v8::Value>* value, bool isIndexed)
{
if (m_version < 3)
return false;
- String uuid;
- String type;
- uint64_t size;
- if (!readWebCoreString(&uuid))
- return false;
- if (!readWebCoreString(&type))
- return false;
- if (!doReadUint64(&size))
- return false;
- RefPtr<Blob> blob = Blob::create(getOrCreateBlobDataHandle(uuid, type, size));
- *value = toV8(blob.release(), v8::Handle<v8::Object>(), m_isolate);
+ RefPtrWillBeRawPtr<Blob> blob;
+ if (isIndexed) {
+ if (m_version < 6)
+ return false;
+ ASSERT(m_blobInfo);
+ uint32_t index;
+ if (!doReadUint32(&index) || index >= m_blobInfo->size())
+ return false;
+ const blink::WebBlobInfo& info = (*m_blobInfo)[index];
+ blob = Blob::create(getOrCreateBlobDataHandle(info.uuid(), info.type(), info.size()));
+ } else {
+ ASSERT(!m_blobInfo);
+ String uuid;
+ String type;
+ uint64_t size;
+ ASSERT(!m_blobInfo);
+ if (!readWebCoreString(&uuid))
+ return false;
+ if (!readWebCoreString(&type))
+ return false;
+ if (!doReadUint64(&size))
+ return false;
+ blob = Blob::create(getOrCreateBlobDataHandle(uuid, type, size));
+ }
+ *value = toV8(blob.release(), m_scriptState->context()->Global(), isolate());
return true;
}
@@ -1864,42 +2185,108 @@ private:
return false;
if (!readWebCoreString(&url))
return false;
- RefPtr<DOMFileSystem> fs = DOMFileSystem::create(getExecutionContext(), name, static_cast<WebCore::FileSystemType>(type), KURL(ParsedURLString, url));
- *value = toV8(fs.release(), v8::Handle<v8::Object>(), m_isolate);
+ DOMFileSystem* fs = DOMFileSystem::create(m_scriptState->executionContext(), name, static_cast<WebCore::FileSystemType>(type), KURL(ParsedURLString, url));
+ *value = toV8(fs, m_scriptState->context()->Global(), isolate());
return true;
}
- bool readFile(v8::Handle<v8::Value>* value)
+ bool readFile(v8::Handle<v8::Value>* value, bool isIndexed)
{
- RefPtr<File> file = doReadFileHelper();
+ RefPtrWillBeRawPtr<File> file;
+ if (isIndexed) {
+ if (m_version < 6)
+ return false;
+ file = readFileIndexHelper();
+ } else {
+ file = readFileHelper();
+ }
if (!file)
return false;
- *value = toV8(file.release(), v8::Handle<v8::Object>(), m_isolate);
+ *value = toV8(file.release(), m_scriptState->context()->Global(), isolate());
return true;
}
- bool readFileList(v8::Handle<v8::Value>* value)
+ bool readFileList(v8::Handle<v8::Value>* value, bool isIndexed)
{
if (m_version < 3)
return false;
uint32_t length;
if (!doReadUint32(&length))
return false;
- RefPtr<FileList> fileList = FileList::create();
+ RefPtrWillBeRawPtr<FileList> fileList = FileList::create();
for (unsigned i = 0; i < length; ++i) {
- RefPtr<File> file = doReadFileHelper();
+ RefPtrWillBeRawPtr<File> file;
+ if (isIndexed) {
+ if (m_version < 6)
+ return false;
+ file = readFileIndexHelper();
+ } else {
+ file = readFileHelper();
+ }
if (!file)
return false;
fileList->append(file.release());
}
- *value = toV8(fileList.release(), v8::Handle<v8::Object>(), m_isolate);
+ *value = toV8(fileList.release(), m_scriptState->context()->Global(), isolate());
return true;
}
- PassRefPtr<File> doReadFileHelper()
+ bool readCryptoKey(v8::Handle<v8::Value>* value)
+ {
+ uint32_t rawKeyType;
+ if (!doReadUint32(&rawKeyType))
+ return false;
+
+ blink::WebCryptoKeyAlgorithm algorithm;
+ blink::WebCryptoKeyType type = blink::WebCryptoKeyTypeSecret;
+
+ switch (static_cast<CryptoKeySubTag>(rawKeyType)) {
+ case AesKeyTag:
+ if (!doReadAesKey(algorithm, type))
+ return false;
+ break;
+ case HmacKeyTag:
+ if (!doReadHmacKey(algorithm, type))
+ return false;
+ break;
+ case RsaHashedKeyTag:
+ if (!doReadRsaHashedKey(algorithm, type))
+ return false;
+ break;
+ default:
+ return false;
+ }
+
+ blink::WebCryptoKeyUsageMask usages;
+ bool extractable;
+ if (!doReadKeyUsages(usages, extractable))
+ return false;
+
+ uint32_t keyDataLength;
+ if (!doReadUint32(&keyDataLength))
+ return false;
+
+ if (m_position + keyDataLength > m_length)
+ return false;
+
+ const uint8_t* keyData = m_buffer + m_position;
+ m_position += keyDataLength;
+
+ blink::WebCryptoKey key = blink::WebCryptoKey::createNull();
+ if (!blink::Platform::current()->crypto()->deserializeKeyForClone(
+ algorithm, type, extractable, usages, keyData, keyDataLength, key)) {
+ return false;
+ }
+
+ *value = toV8(Key::create(key), m_scriptState->context()->Global(), isolate());
+ return true;
+ }
+
+ PassRefPtrWillBeRawPtr<File> readFileHelper()
{
if (m_version < 3)
- return 0;
+ return nullptr;
+ ASSERT(!m_blobInfo);
String path;
String name;
String relativePath;
@@ -1909,26 +2296,38 @@ private:
uint64_t size = 0;
double lastModified = 0;
if (!readWebCoreString(&path))
- return 0;
+ return nullptr;
if (m_version >= 4 && !readWebCoreString(&name))
- return 0;
+ return nullptr;
if (m_version >= 4 && !readWebCoreString(&relativePath))
- return 0;
+ return nullptr;
if (!readWebCoreString(&uuid))
- return 0;
+ return nullptr;
if (!readWebCoreString(&type))
- return 0;
+ return nullptr;
if (m_version >= 4 && !doReadUint32(&hasSnapshot))
- return 0;
+ return nullptr;
if (hasSnapshot) {
if (!doReadUint64(&size))
- return 0;
+ return nullptr;
if (!doReadNumber(&lastModified))
- return 0;
+ return nullptr;
}
return File::create(path, name, relativePath, hasSnapshot > 0, size, lastModified, getOrCreateBlobDataHandle(uuid, type));
}
+ PassRefPtrWillBeRawPtr<File> readFileIndexHelper()
+ {
+ if (m_version < 3)
+ return nullptr;
+ ASSERT(m_blobInfo);
+ uint32_t index;
+ if (!doReadUint32(&index) || index >= m_blobInfo->size())
+ return nullptr;
+ const blink::WebBlobInfo& info = (*m_blobInfo)[index];
+ return File::create(info.filePath(), info.fileName(), info.size(), info.lastModified(), getOrCreateBlobDataHandle(info.uuid(), info.type(), info.size()));
+ }
+
template<class T>
bool doReadUintHelper(T* value)
{
@@ -1976,7 +2375,7 @@ private:
// the collection of BDH's for blobs to work, which would encourage lifetimes to be considered
// when passing ssv's around cross process. At present, we get 'lucky' in some cases because
// the blob in the src process happens to still exist at the time the dest process is deserializing.
- // For example in sharedWorker.postMesssage(...).
+ // For example in sharedWorker.postMessage(...).
BlobDataHandleMap::const_iterator it = m_blobDataHandles.find(uuid);
if (it != m_blobDataHandles.end()) {
// make assertions about type and size?
@@ -1985,18 +2384,171 @@ private:
return BlobDataHandle::create(uuid, type, size);
}
+ bool doReadHmacKey(blink::WebCryptoKeyAlgorithm& algorithm, blink::WebCryptoKeyType& type)
+ {
+ uint32_t lengthBytes;
+ if (!doReadUint32(&lengthBytes))
+ return false;
+ blink::WebCryptoAlgorithmId hash;
+ if (!doReadAlgorithmId(hash))
+ return false;
+ algorithm = blink::WebCryptoKeyAlgorithm::createHmac(hash, lengthBytes * 8);
+ type = blink::WebCryptoKeyTypeSecret;
+ return !algorithm.isNull();
+ }
+
+ bool doReadAesKey(blink::WebCryptoKeyAlgorithm& algorithm, blink::WebCryptoKeyType& type)
+ {
+ blink::WebCryptoAlgorithmId id;
+ if (!doReadAlgorithmId(id))
+ return false;
+ uint32_t lengthBytes;
+ if (!doReadUint32(&lengthBytes))
+ return false;
+ algorithm = blink::WebCryptoKeyAlgorithm::createAes(id, lengthBytes * 8);
+ type = blink::WebCryptoKeyTypeSecret;
+ return !algorithm.isNull();
+ }
+
+ bool doReadRsaHashedKey(blink::WebCryptoKeyAlgorithm& algorithm, blink::WebCryptoKeyType& type)
+ {
+ blink::WebCryptoAlgorithmId id;
+ if (!doReadAlgorithmId(id))
+ return false;
+
+ uint32_t rawType;
+ if (!doReadUint32(&rawType))
+ return false;
+
+ switch (static_cast<AssymetricCryptoKeyType>(rawType)) {
+ case PublicKeyType:
+ type = blink::WebCryptoKeyTypePublic;
+ break;
+ case PrivateKeyType:
+ type = blink::WebCryptoKeyTypePrivate;
+ break;
+ default:
+ return false;
+ }
+
+ uint32_t modulusLengthBits;
+ if (!doReadUint32(&modulusLengthBits))
+ return false;
+
+ uint32_t publicExponentSize;
+ if (!doReadUint32(&publicExponentSize))
+ return false;
+
+ if (m_position + publicExponentSize > m_length)
+ return false;
+
+ const uint8_t* publicExponent = m_buffer + m_position;
+ m_position += publicExponentSize;
+
+ blink::WebCryptoAlgorithmId hash;
+ if (!doReadAlgorithmId(hash))
+ return false;
+ algorithm = blink::WebCryptoKeyAlgorithm::createRsaHashed(id, modulusLengthBits, publicExponent, publicExponentSize, hash);
+
+ return !algorithm.isNull();
+ }
+
+ bool doReadAlgorithmId(blink::WebCryptoAlgorithmId& id)
+ {
+ uint32_t rawId;
+ if (!doReadUint32(&rawId))
+ return false;
+
+ switch (static_cast<CryptoKeyAlgorithmTag>(rawId)) {
+ case AesCbcTag:
+ id = blink::WebCryptoAlgorithmIdAesCbc;
+ return true;
+ case HmacTag:
+ id = blink::WebCryptoAlgorithmIdHmac;
+ return true;
+ case RsaSsaPkcs1v1_5Tag:
+ id = blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5;
+ return true;
+ case Sha1Tag:
+ id = blink::WebCryptoAlgorithmIdSha1;
+ return true;
+ case Sha256Tag:
+ id = blink::WebCryptoAlgorithmIdSha256;
+ return true;
+ case Sha384Tag:
+ id = blink::WebCryptoAlgorithmIdSha384;
+ return true;
+ case Sha512Tag:
+ id = blink::WebCryptoAlgorithmIdSha512;
+ return true;
+ case AesGcmTag:
+ id = blink::WebCryptoAlgorithmIdAesGcm;
+ return true;
+ case RsaOaepTag:
+ id = blink::WebCryptoAlgorithmIdRsaOaep;
+ return true;
+ case AesCtrTag:
+ id = blink::WebCryptoAlgorithmIdAesCtr;
+ return true;
+ case AesKwTag:
+ id = blink::WebCryptoAlgorithmIdAesKw;
+ return true;
+ }
+
+ return false;
+ }
+
+ bool doReadKeyUsages(blink::WebCryptoKeyUsageMask& usages, bool& extractable)
+ {
+ // Reminder to update this when adding new key usages.
+ COMPILE_ASSERT(blink::EndOfWebCryptoKeyUsage == (1 << 7) + 1, UpdateMe);
+ const uint32_t allPossibleUsages = ExtractableUsage | EncryptUsage | DecryptUsage | SignUsage | VerifyUsage | DeriveKeyUsage | WrapKeyUsage | UnwrapKeyUsage | DeriveBitsUsage;
+
+ uint32_t rawUsages;
+ if (!doReadUint32(&rawUsages))
+ return false;
+
+ // Make sure it doesn't contain an unrecognized usage value.
+ if (rawUsages & ~allPossibleUsages)
+ return false;
+
+ usages = 0;
+
+ extractable = rawUsages & ExtractableUsage;
+
+ if (rawUsages & EncryptUsage)
+ usages |= blink::WebCryptoKeyUsageEncrypt;
+ if (rawUsages & DecryptUsage)
+ usages |= blink::WebCryptoKeyUsageDecrypt;
+ if (rawUsages & SignUsage)
+ usages |= blink::WebCryptoKeyUsageSign;
+ if (rawUsages & VerifyUsage)
+ usages |= blink::WebCryptoKeyUsageVerify;
+ if (rawUsages & DeriveKeyUsage)
+ usages |= blink::WebCryptoKeyUsageDeriveKey;
+ if (rawUsages & WrapKeyUsage)
+ usages |= blink::WebCryptoKeyUsageWrapKey;
+ if (rawUsages & UnwrapKeyUsage)
+ usages |= blink::WebCryptoKeyUsageUnwrapKey;
+ if (rawUsages & DeriveBitsUsage)
+ usages |= blink::WebCryptoKeyUsageDeriveBits;
+
+ return true;
+ }
+
+ RefPtr<ScriptState> m_scriptState;
const uint8_t* m_buffer;
const unsigned m_length;
unsigned m_position;
uint32_t m_version;
- v8::Isolate* m_isolate;
+ const WebBlobInfoArray* m_blobInfo;
const BlobDataHandleMap& m_blobDataHandles;
};
typedef Vector<WTF::ArrayBufferContents, 1> ArrayBufferContentsArray;
-class Deserializer : public CompositeCreator {
+class Deserializer FINAL : public CompositeCreator {
public:
Deserializer(Reader& reader, MessagePortArray* messagePorts, ArrayBufferContentsArray* arrayBufferContents)
: m_reader(reader)
@@ -2009,35 +2561,36 @@ public:
v8::Handle<v8::Value> deserialize()
{
+ v8::Isolate* isolate = m_reader.scriptState()->isolate();
if (!m_reader.readVersion(m_version) || m_version > SerializedScriptValue::wireFormatVersion)
- return v8::Null(m_reader.getIsolate());
+ return v8::Null(isolate);
m_reader.setVersion(m_version);
- v8::EscapableHandleScope scope(m_reader.getIsolate());
+ v8::EscapableHandleScope scope(isolate);
while (!m_reader.isEof()) {
if (!doDeserialize())
- return v8::Null(m_reader.getIsolate());
+ return v8::Null(isolate);
}
if (stackDepth() != 1 || m_openCompositeReferenceStack.size())
- return v8::Null(m_reader.getIsolate());
+ return v8::Null(isolate);
v8::Handle<v8::Value> result = scope.Escape(element(0));
return result;
}
- virtual bool newSparseArray(uint32_t)
+ virtual bool newSparseArray(uint32_t) OVERRIDE
{
- v8::Local<v8::Array> array = v8::Array::New(m_reader.isolate(), 0);
+ v8::Local<v8::Array> array = v8::Array::New(m_reader.scriptState()->isolate(), 0);
openComposite(array);
return true;
}
- virtual bool newDenseArray(uint32_t length)
+ virtual bool newDenseArray(uint32_t length) OVERRIDE
{
- v8::Local<v8::Array> array = v8::Array::New(m_reader.isolate(), length);
+ v8::Local<v8::Array> array = v8::Array::New(m_reader.scriptState()->isolate(), length);
openComposite(array);
return true;
}
- virtual bool consumeTopOfStack(v8::Handle<v8::Value>* object)
+ virtual bool consumeTopOfStack(v8::Handle<v8::Value>* object) OVERRIDE
{
if (stackDepth() < 1)
return false;
@@ -2046,40 +2599,16 @@ public:
return true;
}
- virtual bool completeArray(uint32_t length, v8::Handle<v8::Value>* value)
- {
- if (length > stackDepth())
- return false;
- v8::Local<v8::Array> array;
- if (m_version > 0) {
- v8::Local<v8::Value> composite;
- if (!closeComposite(&composite))
- return false;
- array = composite.As<v8::Array>();
- } else {
- array = v8::Array::New(m_reader.isolate(), length);
- }
- if (array.IsEmpty())
- return false;
- const int depth = stackDepth() - length;
- // The V8 API ensures space exists for any index argument to Set; it will (eg) resize arrays as necessary.
- for (unsigned i = 0; i < length; ++i)
- array->Set(i, element(depth + i));
- pop(length);
- *value = array;
- return true;
- }
-
- virtual bool newObject()
+ virtual bool newObject() OVERRIDE
{
- v8::Local<v8::Object> object = v8::Object::New();
+ v8::Local<v8::Object> object = v8::Object::New(m_reader.scriptState()->isolate());
if (object.IsEmpty())
return false;
openComposite(object);
return true;
}
- virtual bool completeObject(uint32_t numProperties, v8::Handle<v8::Value>* value)
+ virtual bool completeObject(uint32_t numProperties, v8::Handle<v8::Value>* value) OVERRIDE
{
v8::Local<v8::Object> object;
if (m_version > 0) {
@@ -2087,14 +2616,15 @@ public:
if (!closeComposite(&composite))
return false;
object = composite.As<v8::Object>();
- } else
- object = v8::Object::New();
+ } else {
+ object = v8::Object::New(m_reader.scriptState()->isolate());
+ }
if (object.IsEmpty())
return false;
return initializeObject(object, numProperties, value);
}
- virtual bool completeSparseArray(uint32_t numProperties, uint32_t length, v8::Handle<v8::Value>* value)
+ virtual bool completeSparseArray(uint32_t numProperties, uint32_t length, v8::Handle<v8::Value>* value) OVERRIDE
{
v8::Local<v8::Array> array;
if (m_version > 0) {
@@ -2103,14 +2633,14 @@ public:
return false;
array = composite.As<v8::Array>();
} else {
- array = v8::Array::New(m_reader.isolate());
+ array = v8::Array::New(m_reader.scriptState()->isolate());
}
if (array.IsEmpty())
return false;
return initializeObject(array, numProperties, value);
}
- virtual bool completeDenseArray(uint32_t numProperties, uint32_t length, v8::Handle<v8::Value>* value)
+ virtual bool completeDenseArray(uint32_t numProperties, uint32_t length, v8::Handle<v8::Value>* value) OVERRIDE
{
v8::Local<v8::Array> array;
if (m_version > 0) {
@@ -2134,22 +2664,23 @@ public:
return true;
}
- virtual void pushObjectReference(const v8::Handle<v8::Value>& object)
+ virtual void pushObjectReference(const v8::Handle<v8::Value>& object) OVERRIDE
{
m_objectPool.append(object);
}
- virtual bool tryGetTransferredMessagePort(uint32_t index, v8::Handle<v8::Value>* object)
+ virtual bool tryGetTransferredMessagePort(uint32_t index, v8::Handle<v8::Value>* object) OVERRIDE
{
if (!m_transferredMessagePorts)
return false;
if (index >= m_transferredMessagePorts->size())
return false;
- *object = toV8(m_transferredMessagePorts->at(index).get(), v8::Handle<v8::Object>(), m_reader.getIsolate());
+ v8::Handle<v8::Object> creationContext = m_reader.scriptState()->context()->Global();
+ *object = toV8(m_transferredMessagePorts->at(index).get(), creationContext, m_reader.scriptState()->isolate());
return true;
}
- virtual bool tryGetTransferredArrayBuffer(uint32_t index, v8::Handle<v8::Value>* object)
+ virtual bool tryGetTransferredArrayBuffer(uint32_t index, v8::Handle<v8::Value>* object) OVERRIDE
{
if (!m_arrayBufferContents)
return false;
@@ -2159,15 +2690,17 @@ public:
if (result.IsEmpty()) {
RefPtr<ArrayBuffer> buffer = ArrayBuffer::create(m_arrayBufferContents->at(index));
buffer->setDeallocationObserver(V8ArrayBufferDeallocationObserver::instanceTemplate());
- m_reader.isolate()->AdjustAmountOfExternalAllocatedMemory(buffer->byteLength());
- result = toV8Object(buffer.get(), m_reader.getIsolate());
+ v8::Isolate* isolate = m_reader.scriptState()->isolate();
+ v8::Handle<v8::Object> creationContext = m_reader.scriptState()->context()->Global();
+ isolate->AdjustAmountOfExternalAllocatedMemory(buffer->byteLength());
+ result = toV8Object(buffer.get(), creationContext, isolate);
m_arrayBuffers[index] = result;
}
*object = result;
return true;
}
- virtual bool tryGetObjectFromObjectReference(uint32_t reference, v8::Handle<v8::Value>* object)
+ virtual bool tryGetObjectFromObjectReference(uint32_t reference, v8::Handle<v8::Value>* object) OVERRIDE
{
if (reference >= m_objectPool.size())
return false;
@@ -2175,7 +2708,7 @@ public:
return object;
}
- virtual uint32_t objectReferenceCount()
+ virtual uint32_t objectReferenceCount() OVERRIDE
{
return m_objectPool.size();
}
@@ -2253,21 +2786,21 @@ private:
} // namespace
-PassRefPtr<SerializedScriptValue> SerializedScriptValue::create(v8::Handle<v8::Value> value, MessagePortArray* messagePorts, ArrayBufferArray* arrayBuffers, bool& didThrow, v8::Isolate* isolate)
+PassRefPtr<SerializedScriptValue> SerializedScriptValue::create(v8::Handle<v8::Value> value, MessagePortArray* messagePorts, ArrayBufferArray* arrayBuffers, ExceptionState& exceptionState, v8::Isolate* isolate)
{
- return adoptRef(new SerializedScriptValue(value, messagePorts, arrayBuffers, didThrow, isolate));
+ return adoptRef(new SerializedScriptValue(value, messagePorts, arrayBuffers, 0, exceptionState, isolate));
}
PassRefPtr<SerializedScriptValue> SerializedScriptValue::createAndSwallowExceptions(v8::Handle<v8::Value> value, v8::Isolate* isolate)
{
- bool didThrow;
- return adoptRef(new SerializedScriptValue(value, 0, 0, didThrow, isolate, DoNotThrowExceptions));
+ TrackExceptionState exceptionState;
+ return adoptRef(new SerializedScriptValue(value, 0, 0, 0, exceptionState, isolate));
}
-PassRefPtr<SerializedScriptValue> SerializedScriptValue::create(const ScriptValue& value, bool& didThrow, ScriptState* state)
+PassRefPtr<SerializedScriptValue> SerializedScriptValue::create(const ScriptValue& value, WebBlobInfoArray* blobInfo, ExceptionState& exceptionState, v8::Isolate* isolate)
{
- ScriptScope scope(state);
- return adoptRef(new SerializedScriptValue(value.v8Value(), 0, 0, didThrow, state->isolate()));
+ ASSERT(isolate->InContext());
+ return adoptRef(new SerializedScriptValue(value.v8Value(), 0, 0, blobInfo, exceptionState, isolate));
}
PassRefPtr<SerializedScriptValue> SerializedScriptValue::createFromWire(const String& data)
@@ -2296,7 +2829,7 @@ PassRefPtr<SerializedScriptValue> SerializedScriptValue::create(const String& da
PassRefPtr<SerializedScriptValue> SerializedScriptValue::create(const String& data, v8::Isolate* isolate)
{
- Writer writer(isolate);
+ Writer writer;
writer.writeWebCoreString(data);
String wireData = writer.takeWireString();
return adoptRef(new SerializedScriptValue(wireData));
@@ -2309,12 +2842,7 @@ PassRefPtr<SerializedScriptValue> SerializedScriptValue::create()
PassRefPtr<SerializedScriptValue> SerializedScriptValue::nullValue()
{
- return nullValue(v8::Isolate::GetCurrent());
-}
-
-PassRefPtr<SerializedScriptValue> SerializedScriptValue::nullValue(v8::Isolate* isolate)
-{
- Writer writer(isolate);
+ Writer writer;
writer.writeNull();
String wireData = writer.takeWireString();
return adoptRef(new SerializedScriptValue(wireData));
@@ -2344,12 +2872,21 @@ SerializedScriptValue::SerializedScriptValue()
{
}
-inline void neuterBinding(ArrayBuffer* object)
+static void neuterArrayBufferInAllWorlds(ArrayBuffer* object)
{
v8::Isolate* isolate = v8::Isolate::GetCurrent();
- Vector<DOMDataStore*>& allStores = V8PerIsolateData::from(isolate)->allStores();
- for (size_t i = 0; i < allStores.size(); i++) {
- v8::Handle<v8::Object> wrapper = allStores[i]->get<V8ArrayBuffer>(object, isolate);
+ if (isMainThread()) {
+ Vector<RefPtr<DOMWrapperWorld> > worlds;
+ DOMWrapperWorld::allWorldsInMainThread(worlds);
+ for (size_t i = 0; i < worlds.size(); i++) {
+ v8::Handle<v8::Object> wrapper = worlds[i]->domDataStore().get<V8ArrayBuffer>(object, isolate);
+ if (!wrapper.IsEmpty()) {
+ ASSERT(wrapper->IsArrayBuffer());
+ v8::Handle<v8::ArrayBuffer>::Cast(wrapper)->Neuter();
+ }
+ }
+ } else {
+ v8::Handle<v8::Object> wrapper = DOMWrapperWorld::current(isolate).domDataStore().get<V8ArrayBuffer>(object, isolate);
if (!wrapper.IsEmpty()) {
ASSERT(wrapper->IsArrayBuffer());
v8::Handle<v8::ArrayBuffer>::Cast(wrapper)->Neuter();
@@ -2357,25 +2894,13 @@ inline void neuterBinding(ArrayBuffer* object)
}
}
-inline void neuterBinding(ArrayBufferView* object)
-{
- v8::Isolate* isolate = v8::Isolate::GetCurrent();
- Vector<DOMDataStore*>& allStores = V8PerIsolateData::from(isolate)->allStores();
- for (size_t i = 0; i < allStores.size(); i++) {
- v8::Handle<v8::Object> wrapper = allStores[i]->get<V8ArrayBufferView>(object, isolate);
- if (!wrapper.IsEmpty())
- wrapper->SetIndexedPropertiesToExternalArrayData(0, v8::kExternalByteArray, 0);
- }
-}
-
-PassOwnPtr<SerializedScriptValue::ArrayBufferContentsArray> SerializedScriptValue::transferArrayBuffers(ArrayBufferArray& arrayBuffers, bool& didThrow, v8::Isolate* isolate)
+PassOwnPtr<SerializedScriptValue::ArrayBufferContentsArray> SerializedScriptValue::transferArrayBuffers(ArrayBufferArray& arrayBuffers, ExceptionState& exceptionState, v8::Isolate* isolate)
{
ASSERT(arrayBuffers.size());
for (size_t i = 0; i < arrayBuffers.size(); i++) {
if (arrayBuffers[i]->isNeutered()) {
- setDOMException(InvalidStateError, isolate);
- didThrow = true;
+ exceptionState.throwDOMException(DataCloneError, "ArrayBuffer at index " + String::number(i) + " is already neutered.");
return nullptr;
}
}
@@ -2384,72 +2909,51 @@ PassOwnPtr<SerializedScriptValue::ArrayBufferContentsArray> SerializedScriptValu
HashSet<ArrayBuffer*> visited;
for (size_t i = 0; i < arrayBuffers.size(); i++) {
- Vector<RefPtr<ArrayBufferView> > neuteredViews;
-
if (visited.contains(arrayBuffers[i].get()))
continue;
visited.add(arrayBuffers[i].get());
- bool result = arrayBuffers[i]->transfer(contents->at(i), neuteredViews);
+ bool result = arrayBuffers[i]->transfer(contents->at(i));
if (!result) {
- setDOMException(InvalidStateError, isolate);
- didThrow = true;
+ exceptionState.throwDOMException(DataCloneError, "ArrayBuffer at index " + String::number(i) + " could not be transferred.");
return nullptr;
}
- neuterBinding(arrayBuffers[i].get());
- for (size_t j = 0; j < neuteredViews.size(); j++)
- neuterBinding(neuteredViews[j].get());
+ neuterArrayBufferInAllWorlds(arrayBuffers[i].get());
}
return contents.release();
}
-SerializedScriptValue::SerializedScriptValue(v8::Handle<v8::Value> value, MessagePortArray* messagePorts, ArrayBufferArray* arrayBuffers, bool& didThrow, v8::Isolate* isolate, ExceptionPolicy policy)
+SerializedScriptValue::SerializedScriptValue(v8::Handle<v8::Value> value, MessagePortArray* messagePorts, ArrayBufferArray* arrayBuffers, WebBlobInfoArray* blobInfo, ExceptionState& exceptionState, v8::Isolate* isolate)
: m_externallyAllocatedMemory(0)
{
- didThrow = false;
- Writer writer(isolate);
+ Writer writer;
Serializer::Status status;
+ String errorMessage;
{
v8::TryCatch tryCatch;
- Serializer serializer(writer, messagePorts, arrayBuffers, m_blobDataHandles, tryCatch, isolate);
+ Serializer serializer(writer, messagePorts, arrayBuffers, blobInfo, m_blobDataHandles, tryCatch, ScriptState::current(isolate));
status = serializer.serialize(value);
if (status == Serializer::JSException) {
- didThrow = true;
// If there was a JS exception thrown, re-throw it.
- if (policy == ThrowExceptions)
- tryCatch.ReThrow();
+ exceptionState.rethrowV8Exception(tryCatch.Exception());
return;
}
+ errorMessage = serializer.errorMessage();
}
switch (status) {
case Serializer::InputError:
case Serializer::DataCloneError:
- // If there was an input error, throw a new exception outside
- // of the TryCatch scope.
- didThrow = true;
- if (policy == ThrowExceptions)
- setDOMException(DataCloneError, isolate);
- return;
- case Serializer::InvalidStateError:
- didThrow = true;
- if (policy == ThrowExceptions)
- setDOMException(InvalidStateError, isolate);
- return;
- case Serializer::JSFailure:
- // If there was a JS failure (but no exception), there's not
- // much we can do except for unwinding the C++ stack by
- // pretending there was a JS exception.
- didThrow = true;
+ exceptionState.throwDOMException(DataCloneError, errorMessage);
return;
case Serializer::Success:
m_data = writer.takeWireString();
ASSERT(m_data.impl()->hasOneRef());
if (arrayBuffers && arrayBuffers->size())
- m_arrayBufferContentsArray = transferArrayBuffers(*arrayBuffers, didThrow, isolate);
+ m_arrayBufferContentsArray = transferArrayBuffers(*arrayBuffers, exceptionState, isolate);
return;
case Serializer::JSException:
- // We should never get here because this case was handled above.
+ ASSERT_NOT_REACHED();
break;
}
ASSERT_NOT_REACHED();
@@ -2463,10 +2967,10 @@ SerializedScriptValue::SerializedScriptValue(const String& wireData)
v8::Handle<v8::Value> SerializedScriptValue::deserialize(MessagePortArray* messagePorts)
{
- return deserialize(v8::Isolate::GetCurrent(), messagePorts);
+ return deserialize(v8::Isolate::GetCurrent(), messagePorts, 0);
}
-v8::Handle<v8::Value> SerializedScriptValue::deserialize(v8::Isolate* isolate, MessagePortArray* messagePorts)
+v8::Handle<v8::Value> SerializedScriptValue::deserialize(v8::Isolate* isolate, MessagePortArray* messagePorts, const WebBlobInfoArray* blobInfo)
{
if (!m_data.impl())
return v8::Null(isolate);
@@ -2476,7 +2980,7 @@ v8::Handle<v8::Value> SerializedScriptValue::deserialize(v8::Isolate* isolate, M
// storage. Instead, it should use SharedBuffer or Vector<uint8_t>. The
// information stored in m_data isn't even encoded in UTF-16. Instead,
// unicode characters are encoded as UTF-8 with two code units per UChar.
- Reader reader(reinterpret_cast<const uint8_t*>(m_data.impl()->characters16()), 2 * m_data.length(), isolate, m_blobDataHandles);
+ Reader reader(reinterpret_cast<const uint8_t*>(m_data.impl()->characters16()), 2 * m_data.length(), blobInfo, m_blobDataHandles, ScriptState::current(isolate));
Deserializer deserializer(reader, messagePorts, m_arrayBufferContentsArray.get());
// deserialize() can run arbitrary script (e.g., setters), which could result in |this| being destroyed.
@@ -2485,6 +2989,57 @@ v8::Handle<v8::Value> SerializedScriptValue::deserialize(v8::Isolate* isolate, M
return deserializer.deserialize();
}
+bool SerializedScriptValue::extractTransferables(v8::Local<v8::Value> value, int argumentIndex, MessagePortArray& ports, ArrayBufferArray& arrayBuffers, ExceptionState& exceptionState, v8::Isolate* isolate)
+{
+ if (isUndefinedOrNull(value)) {
+ ports.resize(0);
+ arrayBuffers.resize(0);
+ return true;
+ }
+
+ uint32_t length = 0;
+ if (value->IsArray()) {
+ v8::Local<v8::Array> array = v8::Local<v8::Array>::Cast(value);
+ length = array->Length();
+ } else if (toV8Sequence(value, length, isolate).IsEmpty()) {
+ exceptionState.throwTypeError(ExceptionMessages::notAnArrayTypeArgumentOrValue(argumentIndex + 1));
+ return false;
+ }
+
+ v8::Local<v8::Object> transferrables = v8::Local<v8::Object>::Cast(value);
+
+ // Validate the passed array of transferrables.
+ for (unsigned i = 0; i < length; ++i) {
+ v8::Local<v8::Value> transferrable = transferrables->Get(i);
+ // Validation of non-null objects, per HTML5 spec 10.3.3.
+ if (isUndefinedOrNull(transferrable)) {
+ exceptionState.throwDOMException(DataCloneError, "Value at index " + String::number(i) + " is an untransferable " + (transferrable->IsUndefined() ? "'undefined'" : "'null'") + " value.");
+ return false;
+ }
+ // Validation of Objects implementing an interface, per WebIDL spec 4.1.15.
+ if (V8MessagePort::hasInstance(transferrable, isolate)) {
+ RefPtr<MessagePort> port = V8MessagePort::toNative(v8::Handle<v8::Object>::Cast(transferrable));
+ // Check for duplicate MessagePorts.
+ if (ports.contains(port)) {
+ exceptionState.throwDOMException(DataCloneError, "Message port at index " + String::number(i) + " is a duplicate of an earlier port.");
+ return false;
+ }
+ ports.append(port.release());
+ } else if (V8ArrayBuffer::hasInstance(transferrable, isolate)) {
+ RefPtr<ArrayBuffer> arrayBuffer = V8ArrayBuffer::toNative(v8::Handle<v8::Object>::Cast(transferrable));
+ if (arrayBuffers.contains(arrayBuffer)) {
+ exceptionState.throwDOMException(DataCloneError, "ArrayBuffer at index " + String::number(i) + " is a duplicate of an earlier ArrayBuffer.");
+ return false;
+ }
+ arrayBuffers.append(arrayBuffer.release());
+ } else {
+ exceptionState.throwDOMException(DataCloneError, "Value at index " + String::number(i) + " does not have a transferable type.");
+ return false;
+ }
+ }
+ return true;
+}
+
void SerializedScriptValue::registerMemoryAllocatedWithCurrentScriptContext()
{
if (m_externallyAllocatedMemory)
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/SerializedScriptValue.h b/chromium/third_party/WebKit/Source/bindings/v8/SerializedScriptValue.h
index 97a73aa04ab..b1064206698 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/SerializedScriptValue.h
+++ b/chromium/third_party/WebKit/Source/bindings/v8/SerializedScriptValue.h
@@ -32,11 +32,16 @@
#define SerializedScriptValue_h
#include "bindings/v8/ScriptValue.h"
-
#include "wtf/HashMap.h"
#include "wtf/ThreadSafeRefCounted.h"
#include <v8.h>
+namespace blink {
+
+class WebBlobInfo;
+
+}
+
namespace WTF {
class ArrayBuffer;
@@ -47,11 +52,13 @@ class ArrayBufferContents;
namespace WebCore {
class BlobDataHandle;
+class ExceptionState;
class MessagePort;
typedef Vector<RefPtr<MessagePort>, 1> MessagePortArray;
typedef Vector<RefPtr<WTF::ArrayBuffer>, 1> ArrayBufferArray;
typedef HashMap<String, RefPtr<BlobDataHandle> > BlobDataHandleMap;
+typedef Vector<blink::WebBlobInfo> WebBlobInfoArray;
class SerializedScriptValue FINAL : public ThreadSafeRefCounted<SerializedScriptValue> {
public:
@@ -59,7 +66,9 @@ public:
// Version 2: Added StringUCharTag for UChar v8 strings.
// Version 3: Switched to using uuids as blob data identifiers.
// Version 4: Extended File serialization to be complete.
- static const uint32_t wireFormatVersion = 4;
+ // Version 5: Added CryptoKeyTag for Key objects.
+ // Version 6: Added indexed serialization for File, Blob, and FileList.
+ static const uint32_t wireFormatVersion = 6;
~SerializedScriptValue();
@@ -68,20 +77,18 @@ public:
// 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>, MessagePortArray*, ArrayBufferArray*, bool& didThrow, v8::Isolate*);
+ static PassRefPtr<SerializedScriptValue> create(v8::Handle<v8::Value>, MessagePortArray*, ArrayBufferArray*, ExceptionState&, v8::Isolate*);
static PassRefPtr<SerializedScriptValue> createFromWire(const String&);
static PassRefPtr<SerializedScriptValue> createFromWireBytes(const Vector<uint8_t>&);
static PassRefPtr<SerializedScriptValue> create(const String&);
static PassRefPtr<SerializedScriptValue> create(const String&, v8::Isolate*);
static PassRefPtr<SerializedScriptValue> create();
-
- static PassRefPtr<SerializedScriptValue> create(const ScriptValue&, bool& didThrow, ScriptState*);
+ static PassRefPtr<SerializedScriptValue> create(const ScriptValue&, WebBlobInfoArray*, ExceptionState&, v8::Isolate*);
// Never throws exceptions.
static PassRefPtr<SerializedScriptValue> createAndSwallowExceptions(v8::Handle<v8::Value>, v8::Isolate*);
static PassRefPtr<SerializedScriptValue> nullValue();
- static PassRefPtr<SerializedScriptValue> nullValue(v8::Isolate*);
String toWireString() const { return m_data; }
void toWireBytes(Vector<char>&) const;
@@ -89,11 +96,13 @@ public:
// Deserializes the value (in the current context). Returns a null value in
// case of failure.
v8::Handle<v8::Value> deserialize(MessagePortArray* = 0);
- v8::Handle<v8::Value> deserialize(v8::Isolate*, MessagePortArray* = 0);
+ v8::Handle<v8::Value> deserialize(v8::Isolate*, MessagePortArray* = 0, const WebBlobInfoArray* = 0);
- // Only reflects the truth if the SSV was created by walking a v8 value, not reliable
- // if the SSV was created createdFromWire(data).
- bool containsBlobs() const { return !m_blobDataHandles.isEmpty(); }
+ // Helper function which pulls the values out of a JS sequence and into a MessagePortArray.
+ // Also validates the elements per sections 4.1.13 and 4.1.15 of the WebIDL spec and section 8.3.3
+ // of the HTML5 spec and generates exceptions as appropriate.
+ // Returns true if the array was filled, or false if the passed value was not of an appropriate type.
+ static bool extractTransferables(v8::Local<v8::Value>, int, MessagePortArray&, ArrayBufferArray&, ExceptionState&, v8::Isolate*);
// Informs the V8 about external memory allocated and owned by this object. Large values should contribute
// to GC counters to eventually trigger a GC, otherwise flood of postMessage() can cause OOM.
@@ -106,17 +115,13 @@ private:
StringValue,
WireData
};
- enum ExceptionPolicy {
- ThrowExceptions,
- DoNotThrowExceptions
- };
typedef Vector<WTF::ArrayBufferContents, 1> ArrayBufferContentsArray;
SerializedScriptValue();
- SerializedScriptValue(v8::Handle<v8::Value>, MessagePortArray*, ArrayBufferArray*, bool& didThrow, v8::Isolate*, ExceptionPolicy = ThrowExceptions);
+ SerializedScriptValue(v8::Handle<v8::Value>, MessagePortArray*, ArrayBufferArray*, WebBlobInfoArray*, ExceptionState&, v8::Isolate*);
explicit SerializedScriptValue(const String& wireData);
- static PassOwnPtr<ArrayBufferContentsArray> transferArrayBuffers(ArrayBufferArray&, bool& didThrow, v8::Isolate*);
+ static PassOwnPtr<ArrayBufferContentsArray> transferArrayBuffers(ArrayBufferArray&, ExceptionState&, v8::Isolate*);
String m_data;
OwnPtr<ArrayBufferContentsArray> m_arrayBufferContentsArray;
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/UnsafePersistent.h b/chromium/third_party/WebKit/Source/bindings/v8/UnsafePersistent.h
deleted file mode 100644
index 4a889c27430..00000000000
--- a/chromium/third_party/WebKit/Source/bindings/v8/UnsafePersistent.h
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * Copyright (C) 2013 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 UnsafePersistent_h
-#define UnsafePersistent_h
-
-#include "bindings/v8/WrapperTypeInfo.h"
-
-#include <v8.h>
-
-namespace WebCore {
-
-template<class KeyType> class DOMWrapperMap;
-
-// An unsafe way to pass Persistent handles around. Do not use unless you know
-// what you're doing. UnsafePersistent is only safe to use when we know that the
-// memory pointed by the it is not going away: 1) When GC cannot happen while
-// the UnsafePersistent is alive or 2) when there is a strong Persistent keeping
-// the memory alive while the UnsafePersistent is alive.
-template<typename T> class UnsafePersistent {
-public:
- UnsafePersistent() : m_value(0) { }
- explicit UnsafePersistent(T* value) : m_value(value) { }
- explicit UnsafePersistent(v8::Persistent<T>& handle)
- {
- m_value = handle.ClearAndLeak();
- }
-
- UnsafePersistent(v8::Isolate* isolate, v8::Handle<T>& handle)
- {
- v8::Persistent<T> persistent(isolate, handle);
- m_value = persistent.ClearAndLeak();
- }
-
- T* value() const
- {
- return m_value;
- }
-
- template<typename V8T, typename U>
- inline bool setReturnValueWithSecurityCheck(v8::ReturnValue<v8::Value> returnValue, U* object)
- {
- v8::Handle<v8::Object> result = deprecatedHandle();
- // Security: always guard against malicious tampering.
- RELEASE_ASSERT_WITH_SECURITY_IMPLICATION(result.IsEmpty() || result->GetAlignedPointerFromInternalField(v8DOMWrapperObjectIndex) == V8T::toInternalPointer(object));
- returnValue.Set(result);
- return !result.IsEmpty();
- }
-
- inline bool setReturnValue(v8::ReturnValue<v8::Value> returnValue)
- {
- returnValue.Set(deprecatedHandle());
- return !isEmpty();
- }
-
- // This is incredibly unsafe: the handle is valid only when this
- // UnsafePersistent is alive and valid (see class level comment).
- v8::Persistent<T>* persistent()
- {
- v8::Persistent<T>* handle = reinterpret_cast<v8::Persistent<T>*>(&m_value);
- return handle;
- }
-
- void setReferenceFrom(const v8::Persistent<v8::Object>& parent, v8::Isolate* isolate)
- {
- isolate->SetReference(parent, *persistent());
- }
-
- void dispose()
- {
- persistent()->Reset();
- m_value = 0;
- }
-
- void clear()
- {
- m_value = 0;
- }
-
- v8::Local<T> newLocal(v8::Isolate* isolate)
- {
- return v8::Local<T>::New(isolate, *persistent());
- }
-
- bool isEmpty() const
- {
- return !m_value;
- }
-
-private:
- v8::Handle<T> deprecatedHandle()
- {
- v8::Handle<T>* handle = reinterpret_cast<v8::Handle<T>*>(&m_value);
- return *handle;
- }
-
- T* m_value;
-};
-
-} // namespace WebCore
-
-#endif // UnsafePersistent_h
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/V8AbstractEventListener.cpp b/chromium/third_party/WebKit/Source/bindings/v8/V8AbstractEventListener.cpp
index 5324a0d59c2..12f78db5563 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/V8AbstractEventListener.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/V8AbstractEventListener.cpp
@@ -31,23 +31,32 @@
#include "config.h"
#include "bindings/v8/V8AbstractEventListener.h"
-#include "V8Event.h"
-#include "V8EventTarget.h"
+#include "bindings/core/v8/V8Event.h"
+#include "bindings/core/v8/V8EventTarget.h"
#include "bindings/v8/V8Binding.h"
#include "bindings/v8/V8EventListenerList.h"
-#include "bindings/v8/V8HiddenPropertyName.h"
+#include "bindings/v8/V8HiddenValue.h"
#include "core/events/BeforeUnloadEvent.h"
#include "core/events/Event.h"
-#include "core/events/ThreadLocalEventNames.h"
#include "core/inspector/InspectorCounters.h"
#include "core/workers/WorkerGlobalScope.h"
namespace WebCore {
-V8AbstractEventListener::V8AbstractEventListener(bool isAttribute, PassRefPtr<DOMWrapperWorld> world, v8::Isolate* isolate)
+V8AbstractEventListener::V8AbstractEventListener(bool isAttribute, ScriptState* scriptState)
: EventListener(JSEventListenerType)
, m_isAttribute(isAttribute)
- , m_world(world)
+ , m_scriptState(scriptState)
+ , m_isolate(scriptState->isolate())
+{
+ if (isMainThread())
+ InspectorCounters::incrementCounter(InspectorCounters::JSEventListenerCounter);
+}
+
+V8AbstractEventListener::V8AbstractEventListener(bool isAttribute, v8::Isolate* isolate)
+ : EventListener(JSEventListenerType)
+ , m_isAttribute(isAttribute)
+ , m_scriptState(nullptr)
, m_isolate(isolate)
{
if (isMainThread())
@@ -58,16 +67,16 @@ V8AbstractEventListener::~V8AbstractEventListener()
{
if (!m_listener.isEmpty()) {
v8::HandleScope scope(m_isolate);
- V8EventListenerList::clearWrapper(m_listener.newLocal(m_isolate), m_isAttribute, m_isolate);
+ V8EventListenerList::clearWrapper(m_listener.newLocal(isolate()), m_isAttribute, isolate());
}
if (isMainThread())
InspectorCounters::decrementCounter(InspectorCounters::JSEventListenerCounter);
}
-void V8AbstractEventListener::handleEvent(ExecutionContext* context, Event* event)
+void V8AbstractEventListener::handleEvent(ExecutionContext*, Event* event)
{
// Don't reenter V8 if execution was terminated in this instance of V8.
- if (context->isJSExecutionForbidden())
+ if (scriptState()->executionContext()->isJSExecutionForbidden())
return;
ASSERT(event);
@@ -76,82 +85,68 @@ void V8AbstractEventListener::handleEvent(ExecutionContext* context, Event* even
// See issue 889829.
RefPtr<V8AbstractEventListener> protect(this);
- v8::HandleScope handleScope(m_isolate);
-
- v8::Local<v8::Context> v8Context = toV8Context(context, world());
- if (v8Context.IsEmpty())
+ if (scriptState()->contextIsEmpty())
return;
-
- // Enter the V8 context in which to perform the event handling.
- v8::Context::Scope scope(v8Context);
+ ScriptState::Scope scope(scriptState());
// Get the V8 wrapper for the event object.
- v8::Isolate* isolate = v8Context->GetIsolate();
- v8::Handle<v8::Value> jsEvent = toV8(event, v8::Handle<v8::Object>(), isolate);
+ v8::Handle<v8::Value> jsEvent = toV8(event, scriptState()->context()->Global(), isolate());
if (jsEvent.IsEmpty())
return;
- invokeEventHandler(context, event, v8::Local<v8::Value>::New(isolate, jsEvent));
+ invokeEventHandler(event, v8::Local<v8::Value>::New(isolate(), jsEvent));
}
void V8AbstractEventListener::setListenerObject(v8::Handle<v8::Object> listener)
{
- m_listener.set(m_isolate, listener);
+ m_listener.set(isolate(), listener);
m_listener.setWeak(this, &setWeakCallback);
}
-void V8AbstractEventListener::invokeEventHandler(ExecutionContext* context, Event* event, v8::Local<v8::Value> jsEvent)
+void V8AbstractEventListener::invokeEventHandler(Event* event, v8::Local<v8::Value> jsEvent)
{
// If jsEvent is empty, attempt to set it as a hidden value would crash v8.
if (jsEvent.IsEmpty())
return;
- v8::Local<v8::Context> v8Context = toV8Context(context, world());
- if (v8Context.IsEmpty())
- return;
-
- // We push the event being processed into the global object, so that it can be exposed by DOMWindow's bindings.
- v8::Handle<v8::String> eventSymbol = V8HiddenPropertyName::event(v8Context->GetIsolate());
+ ASSERT(!scriptState()->contextIsEmpty());
v8::Local<v8::Value> returnValue;
-
{
// Catch exceptions thrown in the event handler so they do not propagate to javascript code that caused the event to fire.
v8::TryCatch tryCatch;
tryCatch.SetVerbose(true);
// Save the old 'event' property so we can restore it later.
- v8::Local<v8::Value> savedEvent = v8Context->Global()->GetHiddenValue(eventSymbol);
+ v8::Local<v8::Value> savedEvent = V8HiddenValue::getHiddenValue(isolate(), scriptState()->context()->Global(), V8HiddenValue::event(isolate()));
tryCatch.Reset();
- // Make the event available in the global object, so DOMWindow can expose it.
- v8Context->Global()->SetHiddenValue(eventSymbol, jsEvent);
+ // Make the event available in the global object, so LocalDOMWindow can expose it.
+ V8HiddenValue::setHiddenValue(isolate(), scriptState()->context()->Global(), V8HiddenValue::event(isolate()), jsEvent);
tryCatch.Reset();
- returnValue = callListenerFunction(context, jsEvent, event);
+ returnValue = callListenerFunction(jsEvent, event);
if (tryCatch.HasCaught())
event->target()->uncaughtExceptionInEventHandler();
if (!tryCatch.CanContinue()) { // Result of TerminateExecution().
- if (context->isWorkerGlobalScope())
- toWorkerGlobalScope(context)->script()->forbidExecution();
+ if (scriptState()->executionContext()->isWorkerGlobalScope())
+ toWorkerGlobalScope(scriptState()->executionContext())->script()->forbidExecution();
return;
}
tryCatch.Reset();
// Restore the old event. This must be done for all exit paths through this method.
if (savedEvent.IsEmpty())
- v8Context->Global()->SetHiddenValue(eventSymbol, v8::Undefined(v8Context->GetIsolate()));
+ V8HiddenValue::setHiddenValue(isolate(), scriptState()->context()->Global(), V8HiddenValue::event(isolate()), v8::Undefined(isolate()));
else
- v8Context->Global()->SetHiddenValue(eventSymbol, savedEvent);
+ V8HiddenValue::setHiddenValue(isolate(), scriptState()->context()->Global(), V8HiddenValue::event(isolate()), savedEvent);
tryCatch.Reset();
}
- ASSERT(!handleOutOfMemory() || returnValue.IsEmpty());
-
if (returnValue.IsEmpty())
return;
- if (!returnValue->IsNull() && !returnValue->IsUndefined() && event->isBeforeUnloadEvent()) {
- V8TRYCATCH_FOR_V8STRINGRESOURCE_VOID(V8StringResource<>, stringReturnValue, returnValue);
+ if (m_isAttribute && !returnValue->IsNull() && !returnValue->IsUndefined() && event->isBeforeUnloadEvent()) {
+ TOSTRING_VOID(V8StringResource<>, stringReturnValue, returnValue);
toBeforeUnloadEvent(event)->setReturnValue(stringReturnValue);
}
@@ -166,18 +161,22 @@ bool V8AbstractEventListener::shouldPreventDefault(v8::Local<v8::Value> returnVa
return returnValue->IsBoolean() && !returnValue->BooleanValue();
}
-v8::Local<v8::Object> V8AbstractEventListener::getReceiverObject(ExecutionContext* context, Event* event)
+v8::Local<v8::Object> V8AbstractEventListener::getReceiverObject(Event* event)
{
- v8::Isolate* isolate = toV8Context(context, world())->GetIsolate();
- v8::Local<v8::Object> listener = m_listener.newLocal(isolate);
+ v8::Local<v8::Object> listener = m_listener.newLocal(isolate());
if (!m_listener.isEmpty() && !listener->IsFunction())
return listener;
EventTarget* target = event->currentTarget();
- v8::Handle<v8::Value> value = toV8(target, v8::Handle<v8::Object>(), isolate);
+ v8::Handle<v8::Value> value = toV8(target, scriptState()->context()->Global(), isolate());
if (value.IsEmpty())
return v8::Local<v8::Object>();
- return v8::Local<v8::Object>::New(isolate, v8::Handle<v8::Object>::Cast(value));
+ return v8::Local<v8::Object>::New(isolate(), v8::Handle<v8::Object>::Cast(value));
+}
+
+bool V8AbstractEventListener::belongsToTheCurrentWorld() const
+{
+ return isolate()->InContext() && &world() == &DOMWrapperWorld::current(isolate());
}
void V8AbstractEventListener::setWeakCallback(const v8::WeakCallbackData<v8::Object, V8AbstractEventListener> &data)
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/V8AbstractEventListener.h b/chromium/third_party/WebKit/Source/bindings/v8/V8AbstractEventListener.h
index c605821ea67..469050c4207 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/V8AbstractEventListener.h
+++ b/chromium/third_party/WebKit/Source/bindings/v8/V8AbstractEventListener.h
@@ -33,7 +33,6 @@
#include "bindings/v8/DOMWrapperWorld.h"
#include "bindings/v8/ScopedPersistent.h"
-#include "bindings/v8/V8Utilities.h"
#include "core/events/EventListener.h"
#include <v8.h>
#include "wtf/PassRefPtr.h"
@@ -69,9 +68,9 @@ namespace WebCore {
// Implementation of EventListener interface.
- virtual bool operator==(const EventListener& other) { return this == &other; }
+ virtual bool operator==(const EventListener& other) OVERRIDE { return this == &other; }
- virtual void handleEvent(ExecutionContext*, Event*);
+ virtual void handleEvent(ExecutionContext*, Event*) OVERRIDE;
virtual bool isLazy() const { return false; }
@@ -109,26 +108,34 @@ namespace WebCore {
m_listener.clear();
}
- virtual DOMWrapperWorld* world() const OVERRIDE FINAL { return m_world.get(); }
+ virtual bool belongsToTheCurrentWorld() const OVERRIDE FINAL;
v8::Isolate* isolate() const { return m_isolate; }
+ virtual DOMWrapperWorld& world() const { return scriptState()->world(); }
+ ScriptState* scriptState() const
+ {
+ ASSERT(m_scriptState);
+ return m_scriptState.get();
+ }
+ void setScriptState(ScriptState* scriptState) { m_scriptState = scriptState; }
protected:
- V8AbstractEventListener(bool isAttribute, PassRefPtr<DOMWrapperWorld>, v8::Isolate*);
+ V8AbstractEventListener(bool isAttribute, ScriptState*);
+ V8AbstractEventListener(bool isAttribute, v8::Isolate*);
virtual void prepareListenerObject(ExecutionContext*) { }
void setListenerObject(v8::Handle<v8::Object> listener);
- void invokeEventHandler(ExecutionContext*, Event*, v8::Local<v8::Value> jsEvent);
+ void invokeEventHandler(Event*, v8::Local<v8::Value> jsEvent);
// Get the receiver object to use for event listener call.
- v8::Local<v8::Object> getReceiverObject(ExecutionContext*, Event*);
+ v8::Local<v8::Object> getReceiverObject(Event*);
private:
// Implementation of EventListener function.
- virtual bool virtualisAttribute() const { return m_isAttribute; }
+ virtual bool virtualisAttribute() const OVERRIDE { return m_isAttribute; }
- virtual v8::Local<v8::Value> callListenerFunction(ExecutionContext*, v8::Handle<v8::Value> jsevent, Event*) = 0;
+ virtual v8::Local<v8::Value> callListenerFunction(v8::Handle<v8::Value> jsevent, Event*) = 0;
virtual bool shouldPreventDefault(v8::Local<v8::Value> returnValue);
@@ -139,7 +146,10 @@ namespace WebCore {
// Indicates if this is an HTML type listener.
bool m_isAttribute;
- RefPtr<DOMWrapperWorld> m_world;
+ // For V8LazyEventListener, m_scriptState can be 0 until V8LazyEventListener is actually used.
+ // m_scriptState is set lazily because V8LazyEventListener doesn't know the associated frame
+ // until the listener is actually used.
+ RefPtr<ScriptState> m_scriptState;
v8::Isolate* m_isolate;
};
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/V8Binding.cpp b/chromium/third_party/WebKit/Source/bindings/v8/V8Binding.cpp
index 2d8da03d149..639784e3f56 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/V8Binding.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/V8Binding.cpp
@@ -31,12 +31,14 @@
#include "config.h"
#include "bindings/v8/V8Binding.h"
-#include "V8Element.h"
-#include "V8NodeFilter.h"
-#include "V8Window.h"
-#include "V8WorkerGlobalScope.h"
-#include "V8XPathNSResolver.h"
+#include "bindings/core/v8/V8Element.h"
+#include "bindings/core/v8/V8NodeFilter.h"
+#include "bindings/core/v8/V8Window.h"
+#include "bindings/core/v8/V8WorkerGlobalScope.h"
+#include "bindings/core/v8/V8XPathNSResolver.h"
#include "bindings/v8/ScriptController.h"
+#include "bindings/v8/V8AbstractEventListener.h"
+#include "bindings/v8/V8BindingMacros.h"
#include "bindings/v8/V8NodeFilterCondition.h"
#include "bindings/v8/V8ObjectConstructor.h"
#include "bindings/v8/V8WindowShell.h"
@@ -45,14 +47,16 @@
#include "core/dom/Element.h"
#include "core/dom/NodeFilter.h"
#include "core/dom/QualifiedName.h"
+#include "core/frame/LocalFrame.h"
+#include "core/frame/Settings.h"
#include "core/inspector/BindingVisitors.h"
+#include "core/inspector/InspectorTraceEvents.h"
#include "core/loader/FrameLoader.h"
#include "core/loader/FrameLoaderClient.h"
-#include "core/frame/Frame.h"
-#include "core/frame/Settings.h"
#include "core/workers/WorkerGlobalScope.h"
#include "core/xml/XPathNSResolver.h"
-#include "gin/public/isolate_holder.h"
+#include "platform/EventTracer.h"
+#include "platform/JSONValues.h"
#include "wtf/ArrayBufferContents.h"
#include "wtf/MainThread.h"
#include "wtf/MathExtras.h"
@@ -63,38 +67,56 @@
#include "wtf/text/StringBuffer.h"
#include "wtf/text/StringHash.h"
#include "wtf/text/WTFString.h"
+#include "wtf/unicode/CharacterNames.h"
+#include "wtf/unicode/Unicode.h"
namespace WebCore {
-v8::Handle<v8::Value> setDOMException(int exceptionCode, v8::Isolate* isolate)
+v8::Handle<v8::Value> throwError(V8ErrorType errorType, const String& message, v8::Isolate* isolate)
{
- // FIXME: pass in an ExceptionState instead for better creationContext.
- return V8ThrowException::throwDOMException(exceptionCode, v8::Handle<v8::Object>(), isolate);
+ return V8ThrowException::throwError(errorType, message, isolate);
}
-v8::Handle<v8::Value> setDOMException(int exceptionCode, const String& message, v8::Isolate* isolate)
+v8::Handle<v8::Value> throwError(v8::Handle<v8::Value> exception, v8::Isolate* isolate)
{
- return V8ThrowException::throwDOMException(exceptionCode, message, v8::Handle<v8::Object>(), isolate);
+ return V8ThrowException::throwError(exception, isolate);
}
-v8::Handle<v8::Value> throwError(V8ErrorType errorType, const String& message, v8::Isolate* isolate)
+v8::Handle<v8::Value> throwTypeError(const String& message, v8::Isolate* isolate)
{
- return V8ThrowException::throwError(errorType, message, isolate);
+ return V8ThrowException::throwTypeError(message, isolate);
}
-v8::Handle<v8::Value> throwError(v8::Handle<v8::Value> exception, v8::Isolate* isolate)
+void throwArityTypeErrorForMethod(const char* method, const char* type, const char* valid, unsigned provided, v8::Isolate* isolate)
{
- return V8ThrowException::throwError(exception, isolate);
+ throwTypeError(ExceptionMessages::failedToExecute(method, type, ExceptionMessages::invalidArity(valid, provided)), isolate);
}
-v8::Handle<v8::Value> throwUninformativeAndGenericTypeError(v8::Isolate* isolate)
+void throwArityTypeErrorForConstructor(const char* type, const char* valid, unsigned provided, v8::Isolate* isolate)
{
- return V8ThrowException::throwTypeError(String(), isolate);
+ throwTypeError(ExceptionMessages::failedToConstruct(type, ExceptionMessages::invalidArity(valid, provided)), isolate);
}
-v8::Handle<v8::Value> throwTypeError(const String& message, v8::Isolate* isolate)
+void throwArityTypeError(ExceptionState& exceptionState, const char* valid, unsigned provided)
{
- return V8ThrowException::throwTypeError(message, isolate);
+ exceptionState.throwTypeError(ExceptionMessages::invalidArity(valid, provided));
+ exceptionState.throwIfNeeded();
+}
+
+void throwMinimumArityTypeErrorForMethod(const char* method, const char* type, unsigned expected, unsigned providedLeastNumMandatoryParams, v8::Isolate* isolate)
+{
+ throwTypeError(ExceptionMessages::failedToExecute(method, type, ExceptionMessages::notEnoughArguments(expected, providedLeastNumMandatoryParams)), isolate);
+}
+
+void throwMinimumArityTypeErrorForConstructor(const char* type, unsigned expected, unsigned providedLeastNumMandatoryParams, v8::Isolate* isolate)
+{
+ throwTypeError(ExceptionMessages::failedToConstruct(type, ExceptionMessages::notEnoughArguments(expected, providedLeastNumMandatoryParams)), isolate);
+}
+
+void throwMinimumArityTypeError(ExceptionState& exceptionState, unsigned expected, unsigned providedLeastNumMandatoryParams)
+{
+ exceptionState.throwTypeError(ExceptionMessages::notEnoughArguments(expected, providedLeastNumMandatoryParams));
+ exceptionState.throwIfNeeded();
}
class ArrayBufferAllocator : public v8::ArrayBuffer::Allocator {
@@ -124,14 +146,13 @@ v8::ArrayBuffer::Allocator* v8ArrayBufferAllocator()
return &arrayBufferAllocator;
}
-PassRefPtr<NodeFilter> toNodeFilter(v8::Handle<v8::Value> callback, v8::Isolate* isolate)
+PassRefPtrWillBeRawPtr<NodeFilter> toNodeFilter(v8::Handle<v8::Value> callback, v8::Handle<v8::Object> creationContext, ScriptState* scriptState)
{
- RefPtr<NodeFilter> filter = NodeFilter::create();
+ RefPtrWillBeRawPtr<NodeFilter> filter = NodeFilter::create();
- // FIXME: Should pass in appropriate creationContext
- v8::Handle<v8::Object> filterWrapper = toV8(filter, v8::Handle<v8::Object>(), isolate).As<v8::Object>();
+ v8::Handle<v8::Object> filterWrapper = toV8(filter, creationContext, scriptState->isolate()).As<v8::Object>();
- RefPtr<NodeFilterCondition> condition = V8NodeFilterCondition::create(callback, filterWrapper, isolate);
+ RefPtrWillBeRawPtr<NodeFilterCondition> condition = V8NodeFilterCondition::create(callback, filterWrapper, scriptState);
filter->setCondition(condition.release());
return filter.release();
@@ -140,17 +161,17 @@ PassRefPtr<NodeFilter> toNodeFilter(v8::Handle<v8::Value> callback, v8::Isolate*
const int32_t kMaxInt32 = 0x7fffffff;
const int32_t kMinInt32 = -kMaxInt32 - 1;
const uint32_t kMaxUInt32 = 0xffffffff;
-const int64_t kJSMaxInteger = 0x20000000000000LL - 1; // 2^53 - 1, maximum integer exactly representable in ECMAScript.
+const int64_t kJSMaxInteger = 0x20000000000000LL - 1; // 2^53 - 1, maximum uniquely representable integer in ECMAScript.
-static double enforceRange(double x, double minimum, double maximum, bool& ok)
+static double enforceRange(double x, double minimum, double maximum, const char* typeName, ExceptionState& exceptionState)
{
if (std::isnan(x) || std::isinf(x)) {
- ok = false;
+ exceptionState.throwTypeError("Value is" + String(std::isinf(x) ? " infinite and" : "") + " not of type '" + String(typeName) + "'.");
return 0;
}
x = trunc(x);
if (x < minimum || x > maximum) {
- ok = false;
+ exceptionState.throwTypeError("Value is outside the '" + String(typeName) + "' value range.");
return 0;
}
return x;
@@ -187,10 +208,9 @@ struct IntTypeLimits<uint16_t> {
};
template <typename T>
-static inline T toSmallerInt(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, bool& ok)
+static inline T toSmallerInt(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, const char* typeName, ExceptionState& exceptionState)
{
typedef IntTypeLimits<T> LimitsTrait;
- ok = true;
// Fast case. The value is already a 32-bit integer in the right range.
if (value->IsInt32()) {
@@ -198,7 +218,7 @@ static inline T toSmallerInt(v8::Handle<v8::Value> value, IntegerConversionConfi
if (result >= LimitsTrait::minValue && result <= LimitsTrait::maxValue)
return static_cast<T>(result);
if (configuration == EnforceRange) {
- ok = false;
+ exceptionState.throwTypeError("Value is outside the '" + String(typeName) + "' value range.");
return 0;
}
result %= LimitsTrait::numberOfValues;
@@ -206,14 +226,14 @@ static inline T toSmallerInt(v8::Handle<v8::Value> value, IntegerConversionConfi
}
// Can the value be converted to a number?
- v8::Local<v8::Number> numberObject = value->ToNumber();
+ TONATIVE_DEFAULT_EXCEPTIONSTATE(v8::Local<v8::Number>, numberObject, value->ToNumber(), exceptionState, 0);
if (numberObject.IsEmpty()) {
- ok = false;
+ exceptionState.throwTypeError("Not convertible to a number value (of type '" + String(typeName) + "'.");
return 0;
}
if (configuration == EnforceRange)
- return enforceRange(numberObject->Value(), LimitsTrait::minValue, LimitsTrait::maxValue, ok);
+ return enforceRange(numberObject->Value(), LimitsTrait::minValue, LimitsTrait::maxValue, typeName, exceptionState);
double numberValue = numberObject->Value();
if (std::isnan(numberValue) || std::isinf(numberValue) || !numberValue)
@@ -226,10 +246,9 @@ static inline T toSmallerInt(v8::Handle<v8::Value> value, IntegerConversionConfi
}
template <typename T>
-static inline T toSmallerUInt(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, bool& ok)
+static inline T toSmallerUInt(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, const char* typeName, ExceptionState& exceptionState)
{
typedef IntTypeLimits<T> LimitsTrait;
- ok = true;
// Fast case. The value is a 32-bit signed integer - possibly positive?
if (value->IsInt32()) {
@@ -237,21 +256,21 @@ static inline T toSmallerUInt(v8::Handle<v8::Value> value, IntegerConversionConf
if (result >= 0 && result <= LimitsTrait::maxValue)
return static_cast<T>(result);
if (configuration == EnforceRange) {
- ok = false;
+ exceptionState.throwTypeError("Value is outside the '" + String(typeName) + "' value range.");
return 0;
}
return static_cast<T>(result);
}
// Can the value be converted to a number?
- v8::Local<v8::Number> numberObject = value->ToNumber();
+ TONATIVE_DEFAULT_EXCEPTIONSTATE(v8::Local<v8::Number>, numberObject, value->ToNumber(), exceptionState, 0);
if (numberObject.IsEmpty()) {
- ok = false;
+ exceptionState.throwTypeError("Not convertible to a number value (of type '" + String(typeName) + "'.");
return 0;
}
if (configuration == EnforceRange)
- return enforceRange(numberObject->Value(), 0, LimitsTrait::maxValue, ok);
+ return enforceRange(numberObject->Value(), 0, LimitsTrait::maxValue, typeName, exceptionState);
// Does the value convert to nan or to an infinity?
double numberValue = numberObject->Value();
@@ -265,44 +284,65 @@ static inline T toSmallerUInt(v8::Handle<v8::Value> value, IntegerConversionConf
return static_cast<T>(fmod(numberValue, LimitsTrait::numberOfValues));
}
-int8_t toInt8(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, bool& ok)
+int8_t toInt8(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, ExceptionState& exceptionState)
+{
+ return toSmallerInt<int8_t>(value, configuration, "byte", exceptionState);
+}
+
+int8_t toInt8(v8::Handle<v8::Value> value)
+{
+ NonThrowableExceptionState exceptionState;
+ return toInt8(value, NormalConversion, exceptionState);
+}
+
+uint8_t toUInt8(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, ExceptionState& exceptionState)
{
- return toSmallerInt<int8_t>(value, configuration, ok);
+ return toSmallerUInt<uint8_t>(value, configuration, "octet", exceptionState);
}
-uint8_t toUInt8(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, bool& ok)
+uint8_t toUInt8(v8::Handle<v8::Value> value)
{
- return toSmallerUInt<uint8_t>(value, configuration, ok);
+ NonThrowableExceptionState exceptionState;
+ return toUInt8(value, NormalConversion, exceptionState);
}
-int16_t toInt16(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, bool& ok)
+int16_t toInt16(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, ExceptionState& exceptionState)
{
- return toSmallerInt<int16_t>(value, configuration, ok);
+ return toSmallerInt<int16_t>(value, configuration, "short", exceptionState);
}
-uint16_t toUInt16(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, bool& ok)
+int16_t toInt16(v8::Handle<v8::Value> value)
{
- return toSmallerUInt<uint16_t>(value, configuration, ok);
+ NonThrowableExceptionState exceptionState;
+ return toInt16(value, NormalConversion, exceptionState);
}
-int32_t toInt32(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, bool& ok)
+uint16_t toUInt16(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, ExceptionState& exceptionState)
{
- ok = true;
+ return toSmallerUInt<uint16_t>(value, configuration, "unsigned short", exceptionState);
+}
+uint16_t toUInt16(v8::Handle<v8::Value> value)
+{
+ NonThrowableExceptionState exceptionState;
+ return toUInt16(value, NormalConversion, exceptionState);
+}
+
+int32_t toInt32(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, ExceptionState& exceptionState)
+{
// Fast case. The value is already a 32-bit integer.
if (value->IsInt32())
return value->Int32Value();
// Can the value be converted to a number?
- ok = false;
- V8TRYCATCH_RETURN(v8::Local<v8::Number>, numberObject, value->ToNumber(), 0);
+ TONATIVE_DEFAULT_EXCEPTIONSTATE(v8::Local<v8::Number>, numberObject, value->ToNumber(), exceptionState, 0);
if (numberObject.IsEmpty()) {
+ exceptionState.throwTypeError("Not convertible to a number value (of type 'long'.)");
return 0;
}
- ok = true;
if (configuration == EnforceRange)
- return enforceRange(numberObject->Value(), kMinInt32, kMaxInt32, ok);
+ return enforceRange(numberObject->Value(), kMinInt32, kMaxInt32, "long", exceptionState);
// Does the value convert to nan or to an infinity?
double numberValue = numberObject->Value();
@@ -312,14 +352,18 @@ int32_t toInt32(v8::Handle<v8::Value> value, IntegerConversionConfiguration conf
if (configuration == Clamp)
return clampTo<int32_t>(numberObject->Value());
- V8TRYCATCH_RETURN(int32_t, result, numberObject->Int32Value(), 0);
+ TONATIVE_DEFAULT_EXCEPTIONSTATE(int32_t, result, numberObject->Int32Value(), exceptionState, 0);
return result;
}
-uint32_t toUInt32(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, bool& ok)
+int32_t toInt32(v8::Handle<v8::Value> value)
{
- ok = true;
+ NonThrowableExceptionState exceptionState;
+ return toInt32(value, NormalConversion, exceptionState);
+}
+uint32_t toUInt32(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, ExceptionState& exceptionState)
+{
// Fast case. The value is already a 32-bit unsigned integer.
if (value->IsUint32())
return value->Uint32Value();
@@ -330,22 +374,21 @@ uint32_t toUInt32(v8::Handle<v8::Value> value, IntegerConversionConfiguration co
if (result >= 0)
return result;
if (configuration == EnforceRange) {
- ok = false;
+ exceptionState.throwTypeError("Value is outside the 'unsigned long' value range.");
return 0;
}
return result;
}
// Can the value be converted to a number?
- ok = false;
- V8TRYCATCH_RETURN(v8::Local<v8::Number>, numberObject, value->ToNumber(), 0);
+ TONATIVE_DEFAULT_EXCEPTIONSTATE(v8::Local<v8::Number>, numberObject, value->ToNumber(), exceptionState, 0);
if (numberObject.IsEmpty()) {
+ exceptionState.throwTypeError("Not convertible to a number value (of type 'unsigned long'.)");
return 0;
}
- ok = true;
if (configuration == EnforceRange)
- return enforceRange(numberObject->Value(), 0, kMaxUInt32, ok);
+ return enforceRange(numberObject->Value(), 0, kMaxUInt32, "unsigned long", exceptionState);
// Does the value convert to nan or to an infinity?
double numberValue = numberObject->Value();
@@ -355,29 +398,33 @@ uint32_t toUInt32(v8::Handle<v8::Value> value, IntegerConversionConfiguration co
if (configuration == Clamp)
return clampTo<uint32_t>(numberObject->Value());
- V8TRYCATCH_RETURN(uint32_t, result, numberObject->Uint32Value(), 0);
+ TONATIVE_DEFAULT(uint32_t, result, numberObject->Uint32Value(), 0);
return result;
}
-int64_t toInt64(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, bool& ok)
+uint32_t toUInt32(v8::Handle<v8::Value> value)
{
- ok = true;
+ NonThrowableExceptionState exceptionState;
+ return toUInt32(value, NormalConversion, exceptionState);
+}
+int64_t toInt64(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, ExceptionState& exceptionState)
+{
// Fast case. The value is a 32-bit integer.
if (value->IsInt32())
return value->Int32Value();
// Can the value be converted to a number?
- v8::Local<v8::Number> numberObject = value->ToNumber();
+ TONATIVE_DEFAULT_EXCEPTIONSTATE(v8::Local<v8::Number>, numberObject, value->ToNumber(), exceptionState, 0);
if (numberObject.IsEmpty()) {
- ok = false;
+ exceptionState.throwTypeError("Not convertible to a number value (of type 'long long'.)");
return 0;
}
double x = numberObject->Value();
if (configuration == EnforceRange)
- return enforceRange(x, -kJSMaxInteger, kJSMaxInteger, ok);
+ return enforceRange(x, -kJSMaxInteger, kJSMaxInteger, "long long", exceptionState);
// Does the value convert to nan or to an infinity?
if (std::isnan(x) || std::isinf(x))
@@ -389,10 +436,14 @@ int64_t toInt64(v8::Handle<v8::Value> value, IntegerConversionConfiguration conf
return integer;
}
-uint64_t toUInt64(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, bool& ok)
+int64_t toInt64(v8::Handle<v8::Value> value)
{
- ok = true;
+ NonThrowableExceptionState exceptionState;
+ return toInt64(value, NormalConversion, exceptionState);
+}
+uint64_t toUInt64(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, ExceptionState& exceptionState)
+{
// Fast case. The value is a 32-bit unsigned integer.
if (value->IsUint32())
return value->Uint32Value();
@@ -403,23 +454,23 @@ uint64_t toUInt64(v8::Handle<v8::Value> value, IntegerConversionConfiguration co
if (result >= 0)
return result;
if (configuration == EnforceRange) {
- ok = false;
+ exceptionState.throwTypeError("Value is outside the 'unsigned long long' value range.");
return 0;
}
return result;
}
// Can the value be converted to a number?
- v8::Local<v8::Number> numberObject = value->ToNumber();
+ TONATIVE_DEFAULT_EXCEPTIONSTATE(v8::Local<v8::Number>, numberObject, value->ToNumber(), exceptionState, 0);
if (numberObject.IsEmpty()) {
- ok = false;
+ exceptionState.throwTypeError("Not convertible to a number value (of type 'unsigned long long'.)");
return 0;
}
double x = numberObject->Value();
if (configuration == EnforceRange)
- return enforceRange(x, 0, kJSMaxInteger, ok);
+ return enforceRange(x, 0, kJSMaxInteger, "unsigned long long", exceptionState);
// Does the value convert to nan or to an infinity?
if (std::isnan(x) || std::isinf(x))
@@ -431,134 +482,283 @@ uint64_t toUInt64(v8::Handle<v8::Value> value, IntegerConversionConfiguration co
return integer;
}
-v8::Handle<v8::FunctionTemplate> createRawTemplate(v8::Isolate* isolate)
+uint64_t toUInt64(v8::Handle<v8::Value> value)
+{
+ NonThrowableExceptionState exceptionState;
+ return toUInt64(value, NormalConversion, exceptionState);
+}
+
+float toFloat(v8::Handle<v8::Value> value, ExceptionState& exceptionState)
+{
+ TONATIVE_DEFAULT_EXCEPTIONSTATE(v8::Local<v8::Number>, numberObject, value->ToNumber(), exceptionState, 0);
+ return numberObject->NumberValue();
+}
+
+String toByteString(v8::Handle<v8::Value> value, ExceptionState& exceptionState)
+{
+ // Handle null default value.
+ if (value.IsEmpty())
+ return String();
+
+ // From the Web IDL spec: http://heycam.github.io/webidl/#es-ByteString
+ if (value.IsEmpty())
+ return String();
+
+ // 1. Let x be ToString(v)
+ TONATIVE_DEFAULT_EXCEPTIONSTATE(v8::Local<v8::String>, stringObject, value->ToString(), exceptionState, String());
+ String x = toCoreString(stringObject);
+
+ // 2. If the value of any element of x is greater than 255, then throw a TypeError.
+ if (!x.containsOnlyLatin1()) {
+ exceptionState.throwTypeError("Value is not a valid ByteString.");
+ return String();
+ }
+
+ // 3. Return an IDL ByteString value whose length is the length of x, and where the
+ // value of each element is the value of the corresponding element of x.
+ // Blink: A ByteString is simply a String with a range constrained per the above, so
+ // this is the identity operation.
+ return x;
+}
+
+static bool hasUnmatchedSurrogates(const String& string)
+{
+ // By definition, 8-bit strings are confined to the Latin-1 code page and
+ // have no surrogates, matched or otherwise.
+ if (string.is8Bit())
+ return false;
+
+ const UChar* characters = string.characters16();
+ const unsigned length = string.length();
+
+ for (unsigned i = 0; i < length; ++i) {
+ UChar c = characters[i];
+ if (U16_IS_SINGLE(c))
+ continue;
+ if (U16_IS_TRAIL(c))
+ return true;
+ ASSERT(U16_IS_LEAD(c));
+ if (i == length - 1)
+ return true;
+ UChar d = characters[i + 1];
+ if (!U16_IS_TRAIL(d))
+ return true;
+ ++i;
+ }
+ return false;
+}
+
+// Replace unmatched surrogates with REPLACEMENT CHARACTER U+FFFD.
+static String replaceUnmatchedSurrogates(const String& string)
+{
+ // This roughly implements http://heycam.github.io/webidl/#dfn-obtain-unicode
+ // but since Blink strings are 16-bits internally, the output is simply
+ // re-encoded to UTF-16.
+
+ // The concept of surrogate pairs is explained at:
+ // http://www.unicode.org/versions/Unicode6.2.0/ch03.pdf#G2630
+
+ // Blink-specific optimization to avoid making an unnecessary copy.
+ if (!hasUnmatchedSurrogates(string))
+ return string;
+ ASSERT(!string.is8Bit());
+
+ // 1. Let S be the DOMString value.
+ const UChar* s = string.characters16();
+
+ // 2. Let n be the length of S.
+ const unsigned n = string.length();
+
+ // 3. Initialize i to 0.
+ unsigned i = 0;
+
+ // 4. Initialize U to be an empty sequence of Unicode characters.
+ StringBuilder u;
+ u.reserveCapacity(n);
+
+ // 5. While i < n:
+ while (i < n) {
+ // 1. Let c be the code unit in S at index i.
+ UChar c = s[i];
+ // 2. Depending on the value of c:
+ if (U16_IS_SINGLE(c)) {
+ // c < 0xD800 or c > 0xDFFF
+ // Append to U the Unicode character with code point c.
+ u.append(c);
+ } else if (U16_IS_TRAIL(c)) {
+ // 0xDC00 <= c <= 0xDFFF
+ // Append to U a U+FFFD REPLACEMENT CHARACTER.
+ u.append(WTF::Unicode::replacementCharacter);
+ } else {
+ // 0xD800 <= c <= 0xDBFF
+ ASSERT(U16_IS_LEAD(c));
+ if (i == n - 1) {
+ // 1. If i = n−1, then append to U a U+FFFD REPLACEMENT CHARACTER.
+ u.append(WTF::Unicode::replacementCharacter);
+ } else {
+ // 2. Otherwise, i < n−1:
+ ASSERT(i < n - 1);
+ // ....1. Let d be the code unit in S at index i+1.
+ UChar d = s[i + 1];
+ if (U16_IS_TRAIL(d)) {
+ // 2. If 0xDC00 <= d <= 0xDFFF, then:
+ // ..1. Let a be c & 0x3FF.
+ // ..2. Let b be d & 0x3FF.
+ // ..3. Append to U the Unicode character with code point 2^16+2^10*a+b.
+ u.append(U16_GET_SUPPLEMENTARY(c, d));
+ // Blink: This is equivalent to u.append(c); u.append(d);
+ ++i;
+ } else {
+ // 3. Otherwise, d < 0xDC00 or d > 0xDFFF. Append to U a U+FFFD REPLACEMENT CHARACTER.
+ u.append(WTF::Unicode::replacementCharacter);
+ }
+ }
+ }
+ // 3. Set i to i+1.
+ ++i;
+ }
+
+ // 6. Return U.
+ ASSERT(u.length() == string.length());
+ return u.toString();
+}
+
+String toScalarValueString(v8::Handle<v8::Value> value, ExceptionState& exceptionState)
{
- v8::EscapableHandleScope scope(isolate);
- v8::Local<v8::FunctionTemplate> result = v8::FunctionTemplate::New(isolate, V8ObjectConstructor::isValidConstructorMode);
- return scope.Escape(result);
+ // From the Encoding standard (with a TODO to move to Web IDL):
+ // http://encoding.spec.whatwg.org/#type-scalarvaluestring
+ if (value.IsEmpty())
+ return String();
+ TONATIVE_DEFAULT_EXCEPTIONSTATE(v8::Local<v8::String>, stringObject, value->ToString(), exceptionState, String());
+
+ // ScalarValueString is identical to DOMString except that "convert a
+ // DOMString to a sequence of Unicode characters" is used subsequently
+ // when converting to an IDL value
+ String x = toCoreString(stringObject);
+ return replaceUnmatchedSurrogates(x);
}
-PassRefPtr<XPathNSResolver> toXPathNSResolver(v8::Handle<v8::Value> value, v8::Isolate* isolate)
+PassRefPtrWillBeRawPtr<XPathNSResolver> toXPathNSResolver(v8::Handle<v8::Value> value, v8::Isolate* isolate)
{
- RefPtr<XPathNSResolver> resolver;
- if (V8XPathNSResolver::hasInstance(value, isolate, worldType(isolate)))
+ RefPtrWillBeRawPtr<XPathNSResolver> resolver = nullptr;
+ if (V8XPathNSResolver::hasInstance(value, isolate))
resolver = V8XPathNSResolver::toNative(v8::Handle<v8::Object>::Cast(value));
else if (value->IsObject())
resolver = V8CustomXPathNSResolver::create(value->ToObject(), isolate);
return resolver;
}
-v8::Handle<v8::Object> toInnerGlobalObject(v8::Handle<v8::Context> context)
+LocalDOMWindow* toDOMWindow(v8::Handle<v8::Value> value, v8::Isolate* isolate)
{
- return v8::Handle<v8::Object>::Cast(context->Global()->GetPrototype());
+ if (value.IsEmpty() || !value->IsObject())
+ return 0;
+
+ v8::Handle<v8::Object> windowWrapper = V8Window::findInstanceInPrototypeChain(v8::Handle<v8::Object>::Cast(value), isolate);
+ if (!windowWrapper.IsEmpty())
+ return V8Window::toNative(windowWrapper);
+ return 0;
}
-DOMWindow* toDOMWindow(v8::Handle<v8::Context> context)
+LocalDOMWindow* toDOMWindow(v8::Handle<v8::Context> context)
{
- v8::Handle<v8::Object> global = context->Global();
- ASSERT(!global.IsEmpty());
- v8::Handle<v8::Object> window = global->FindInstanceInPrototypeChain(V8Window::domTemplate(context->GetIsolate(), MainWorld));
- if (!window.IsEmpty())
- return V8Window::toNative(window);
- window = global->FindInstanceInPrototypeChain(V8Window::domTemplate(context->GetIsolate(), IsolatedWorld));
- ASSERT(!window.IsEmpty());
- return V8Window::toNative(window);
+ if (context.IsEmpty())
+ return 0;
+ return toDOMWindow(context->Global(), context->GetIsolate());
+}
+
+LocalDOMWindow* enteredDOMWindow(v8::Isolate* isolate)
+{
+ LocalDOMWindow* window = toDOMWindow(isolate->GetEnteredContext());
+ if (!window) {
+ // We don't always have an entered DOM window, for example during microtask callbacks from V8
+ // (where the entered context may be the DOM-in-JS context). In that case, we fall back
+ // to the current context.
+ window = currentDOMWindow(isolate);
+ ASSERT(window);
+ }
+ return window;
+}
+
+LocalDOMWindow* currentDOMWindow(v8::Isolate* isolate)
+{
+ return toDOMWindow(isolate->GetCurrentContext());
+}
+
+LocalDOMWindow* callingDOMWindow(v8::Isolate* isolate)
+{
+ v8::Handle<v8::Context> context = isolate->GetCallingContext();
+ if (context.IsEmpty()) {
+ // Unfortunately, when processing script from a plug-in, we might not
+ // have a calling context. In those cases, we fall back to the
+ // entered context.
+ context = isolate->GetEnteredContext();
+ }
+ return toDOMWindow(context);
}
ExecutionContext* toExecutionContext(v8::Handle<v8::Context> context)
{
v8::Handle<v8::Object> global = context->Global();
- v8::Handle<v8::Object> windowWrapper = global->FindInstanceInPrototypeChain(V8Window::domTemplate(context->GetIsolate(), MainWorld));
- if (!windowWrapper.IsEmpty())
- return V8Window::toNative(windowWrapper)->executionContext();
- windowWrapper = global->FindInstanceInPrototypeChain(V8Window::domTemplate(context->GetIsolate(), IsolatedWorld));
+ v8::Handle<v8::Object> windowWrapper = V8Window::findInstanceInPrototypeChain(global, context->GetIsolate());
if (!windowWrapper.IsEmpty())
return V8Window::toNative(windowWrapper)->executionContext();
- v8::Handle<v8::Object> workerWrapper = global->FindInstanceInPrototypeChain(V8WorkerGlobalScope::domTemplate(context->GetIsolate(), WorkerWorld));
+ v8::Handle<v8::Object> workerWrapper = V8WorkerGlobalScope::findInstanceInPrototypeChain(global, context->GetIsolate());
if (!workerWrapper.IsEmpty())
return V8WorkerGlobalScope::toNative(workerWrapper)->executionContext();
// FIXME: Is this line of code reachable?
return 0;
}
-DOMWindow* activeDOMWindow()
+ExecutionContext* currentExecutionContext(v8::Isolate* isolate)
{
- v8::Handle<v8::Context> context = v8::Isolate::GetCurrent()->GetCallingContext();
- if (context.IsEmpty()) {
- // Unfortunately, when processing script from a plug-in, we might not
- // have a calling context. In those cases, we fall back to the
- // entered context.
- context = v8::Isolate::GetCurrent()->GetEnteredContext();
- }
- return toDOMWindow(context);
+ return toExecutionContext(isolate->GetCurrentContext());
}
-ExecutionContext* activeExecutionContext()
+ExecutionContext* callingExecutionContext(v8::Isolate* isolate)
{
- v8::Handle<v8::Context> context = v8::Isolate::GetCurrent()->GetCallingContext();
+ v8::Handle<v8::Context> context = isolate->GetCallingContext();
if (context.IsEmpty()) {
// Unfortunately, when processing script from a plug-in, we might not
// have a calling context. In those cases, we fall back to the
// entered context.
- context = v8::Isolate::GetCurrent()->GetEnteredContext();
+ context = isolate->GetEnteredContext();
}
return toExecutionContext(context);
}
-DOMWindow* firstDOMWindow()
-{
- return toDOMWindow(v8::Isolate::GetCurrent()->GetEnteredContext());
-}
-
-Document* currentDocument()
-{
- return toDOMWindow(v8::Isolate::GetCurrent()->GetCurrentContext())->document();
-}
-
-Frame* toFrameIfNotDetached(v8::Handle<v8::Context> context)
+LocalFrame* toFrameIfNotDetached(v8::Handle<v8::Context> context)
{
- DOMWindow* window = toDOMWindow(context);
- if (window->isCurrentlyDisplayedInFrame())
+ LocalDOMWindow* window = toDOMWindow(context);
+ if (window && window->isCurrentlyDisplayedInFrame())
return window->frame();
- // We return 0 here because |context| is detached from the Frame. If we
+ // We return 0 here because |context| is detached from the LocalFrame. If we
// did return |frame| we could get in trouble because the frame could be
// navigated to another security origin.
return 0;
}
-v8::Local<v8::Context> toV8Context(ExecutionContext* context, DOMWrapperWorld* world)
+v8::Local<v8::Context> toV8Context(ExecutionContext* context, DOMWrapperWorld& world)
{
+ ASSERT(context);
if (context->isDocument()) {
- ASSERT(world);
- if (Frame* frame = toDocument(context)->frame())
+ if (LocalFrame* frame = toDocument(context)->frame())
return frame->script().windowShell(world)->context();
} else if (context->isWorkerGlobalScope()) {
- ASSERT(!world);
if (WorkerScriptController* script = toWorkerGlobalScope(context)->script())
return script->context();
}
return v8::Local<v8::Context>();
}
-bool handleOutOfMemory()
+v8::Local<v8::Context> toV8Context(LocalFrame* frame, DOMWrapperWorld& world)
{
- v8::Local<v8::Context> context = v8::Isolate::GetCurrent()->GetCurrentContext();
-
- if (!context->HasOutOfMemoryException())
- return false;
-
- // Warning, error, disable JS for this frame?
- Frame* frame = toFrameIfNotDetached(context);
if (!frame)
- return true;
-
- frame->script().clearForOutOfMemory();
- frame->loader().client()->didExhaustMemoryAvailableForScript();
-
- if (Settings* settings = frame->settings())
- settings->setScriptEnabled(false);
-
- return true;
+ return v8::Local<v8::Context>();
+ v8::Local<v8::Context> context = frame->script().windowShell(world)->context();
+ if (context.IsEmpty())
+ return v8::Local<v8::Context>();
+ LocalFrame* attachedFrame= toFrameIfNotDetached(context);
+ return frame == attachedFrame ? context : v8::Local<v8::Context>();
}
v8::Local<v8::Value> handleMaxRecursionDepthExceeded(v8::Isolate* isolate)
@@ -576,73 +776,165 @@ void crashIfV8IsDead()
}
}
-WrapperWorldType worldType(v8::Isolate* isolate)
+v8::Handle<v8::Function> getBoundFunction(v8::Handle<v8::Function> function)
{
- V8PerIsolateData* data = V8PerIsolateData::from(isolate);
- if (!data->workerDOMDataStore())
- return worldTypeInMainThread(isolate);
- return WorkerWorld;
+ v8::Handle<v8::Value> boundFunction = function->GetBoundFunction();
+ return boundFunction->IsFunction() ? v8::Handle<v8::Function>::Cast(boundFunction) : function;
}
-WrapperWorldType worldTypeInMainThread(v8::Isolate* isolate)
+void addHiddenValueToArray(v8::Handle<v8::Object> object, v8::Local<v8::Value> value, int arrayIndex, v8::Isolate* isolate)
{
- if (!DOMWrapperWorld::isolatedWorldsExist())
- return MainWorld;
- ASSERT(!isolate->GetEnteredContext().IsEmpty());
- DOMWrapperWorld* isolatedWorld = DOMWrapperWorld::isolatedWorld(isolate->GetEnteredContext());
- if (isolatedWorld)
- return IsolatedWorld;
- return MainWorld;
+ v8::Local<v8::Value> arrayValue = object->GetInternalField(arrayIndex);
+ if (arrayValue->IsNull() || arrayValue->IsUndefined()) {
+ arrayValue = v8::Array::New(isolate);
+ object->SetInternalField(arrayIndex, arrayValue);
+ }
+
+ v8::Local<v8::Array> array = v8::Local<v8::Array>::Cast(arrayValue);
+ array->Set(v8::Integer::New(isolate, array->Length()), value);
}
-DOMWrapperWorld* isolatedWorldForIsolate(v8::Isolate* isolate)
+void removeHiddenValueFromArray(v8::Handle<v8::Object> object, v8::Local<v8::Value> value, int arrayIndex, v8::Isolate* isolate)
{
- V8PerIsolateData* data = V8PerIsolateData::from(isolate);
- if (data->workerDOMDataStore())
- return 0;
- if (!DOMWrapperWorld::isolatedWorldsExist())
- return 0;
- ASSERT(isolate->InContext());
- return DOMWrapperWorld::isolatedWorld(isolate->GetCurrentContext());
+ v8::Local<v8::Value> arrayValue = object->GetInternalField(arrayIndex);
+ if (!arrayValue->IsArray())
+ return;
+ v8::Local<v8::Array> array = v8::Local<v8::Array>::Cast(arrayValue);
+ for (int i = array->Length() - 1; i >= 0; --i) {
+ v8::Local<v8::Value> item = array->Get(v8::Integer::New(isolate, i));
+ if (item->StrictEquals(value)) {
+ array->Delete(i);
+ return;
+ }
+ }
}
-v8::Local<v8::Value> getHiddenValueFromMainWorldWrapper(v8::Isolate* isolate, ScriptWrappable* wrappable, v8::Handle<v8::String> key)
+void moveEventListenerToNewWrapper(v8::Handle<v8::Object> object, EventListener* oldValue, v8::Local<v8::Value> newValue, int arrayIndex, v8::Isolate* isolate)
{
- v8::Local<v8::Object> wrapper = wrappable->newLocalWrapper(isolate);
- return wrapper.IsEmpty() ? v8::Local<v8::Value>() : wrapper->GetHiddenValue(key);
+ if (oldValue) {
+ V8AbstractEventListener* oldListener = V8AbstractEventListener::cast(oldValue);
+ if (oldListener) {
+ v8::Local<v8::Object> oldListenerObject = oldListener->getExistingListenerObject();
+ if (!oldListenerObject.IsEmpty())
+ removeHiddenValueFromArray(object, oldListenerObject, arrayIndex, isolate);
+ }
+ }
+ // Non-callable input is treated as null and ignored
+ if (newValue->IsFunction())
+ addHiddenValueToArray(object, newValue, arrayIndex, isolate);
}
-static gin::IsolateHolder* mainIsolateHolder = 0;
+v8::Isolate* toIsolate(ExecutionContext* context)
+{
+ if (context && context->isDocument())
+ return V8PerIsolateData::mainThreadIsolate();
+ return v8::Isolate::GetCurrent();
+}
-v8::Isolate* mainThreadIsolate()
+v8::Isolate* toIsolate(LocalFrame* frame)
{
- ASSERT(mainIsolateHolder);
- ASSERT(isMainThread());
- return mainIsolateHolder->isolate();
+ ASSERT(frame);
+ return frame->script().isolate();
}
-void setMainThreadIsolate(v8::Isolate* isolate)
+PassRefPtr<JSONValue> v8ToJSONValue(v8::Isolate* isolate, v8::Handle<v8::Value> value, int maxDepth)
{
- ASSERT(!mainIsolateHolder || !isolate);
- ASSERT(isMainThread());
- if (isolate) {
- mainIsolateHolder = new gin::IsolateHolder(isolate);
- } else {
- delete mainIsolateHolder;
- mainIsolateHolder = 0;
+ if (value.IsEmpty()) {
+ ASSERT_NOT_REACHED();
+ return nullptr;
+ }
+
+ if (!maxDepth)
+ return nullptr;
+ maxDepth--;
+
+ if (value->IsNull() || value->IsUndefined())
+ return JSONValue::null();
+ if (value->IsBoolean())
+ return JSONBasicValue::create(value->BooleanValue());
+ if (value->IsNumber())
+ return JSONBasicValue::create(value->NumberValue());
+ if (value->IsString())
+ return JSONString::create(toCoreString(value.As<v8::String>()));
+ if (value->IsArray()) {
+ v8::Handle<v8::Array> array = v8::Handle<v8::Array>::Cast(value);
+ RefPtr<JSONArray> inspectorArray = JSONArray::create();
+ uint32_t length = array->Length();
+ for (uint32_t i = 0; i < length; i++) {
+ v8::Local<v8::Value> value = array->Get(v8::Int32::New(isolate, i));
+ RefPtr<JSONValue> element = v8ToJSONValue(isolate, value, maxDepth);
+ if (!element)
+ return nullptr;
+ inspectorArray->pushValue(element);
+ }
+ return inspectorArray;
+ }
+ if (value->IsObject()) {
+ RefPtr<JSONObject> jsonObject = JSONObject::create();
+ v8::Handle<v8::Object> object = v8::Handle<v8::Object>::Cast(value);
+ v8::Local<v8::Array> propertyNames = object->GetPropertyNames();
+ uint32_t length = propertyNames->Length();
+ for (uint32_t i = 0; i < length; i++) {
+ v8::Local<v8::Value> name = propertyNames->Get(v8::Int32::New(isolate, i));
+ // FIXME(yurys): v8::Object should support GetOwnPropertyNames
+ if (name->IsString() && !object->HasRealNamedProperty(v8::Handle<v8::String>::Cast(name)))
+ continue;
+ RefPtr<JSONValue> propertyValue = v8ToJSONValue(isolate, object->Get(name), maxDepth);
+ if (!propertyValue)
+ return nullptr;
+ TOSTRING_DEFAULT(V8StringResource<WithNullCheck>, nameString, name, nullptr);
+ jsonObject->setValue(nameString, propertyValue);
+ }
+ return jsonObject;
}
+ ASSERT_NOT_REACHED();
+ return nullptr;
}
-v8::Isolate* toIsolate(ExecutionContext* context)
+V8TestingScope::V8TestingScope(v8::Isolate* isolate)
+ : m_handleScope(isolate)
+ , m_contextScope(v8::Context::New(isolate))
+ , m_scriptState(ScriptStateForTesting::create(isolate->GetCurrentContext(), DOMWrapperWorld::create()))
{
- if (context && context->isDocument())
- return mainThreadIsolate();
- return v8::Isolate::GetCurrent();
}
-v8::Isolate* toIsolate(Frame* frame)
+V8TestingScope::~V8TestingScope()
{
- return frame->script().isolate();
+ m_scriptState->disposePerContextData();
+}
+
+ScriptState* V8TestingScope::scriptState() const
+{
+ return m_scriptState.get();
+}
+
+v8::Isolate* V8TestingScope::isolate() const
+{
+ return m_scriptState->isolate();
+}
+
+void GetDevToolsFunctionInfo(v8::Handle<v8::Function> function, v8::Isolate* isolate, int& scriptId, String& resourceName, int& lineNumber)
+{
+ v8::Handle<v8::Function> originalFunction = getBoundFunction(function);
+ scriptId = originalFunction->ScriptId();
+ v8::ScriptOrigin origin = originalFunction->GetScriptOrigin();
+ if (!origin.ResourceName().IsEmpty()) {
+ resourceName = NativeValueTraits<String>::nativeValue(origin.ResourceName(), isolate);
+ lineNumber = originalFunction->GetScriptLineNumber() + 1;
+ }
+ if (resourceName.isEmpty()) {
+ resourceName = "undefined";
+ lineNumber = 1;
+ }
+}
+
+PassRefPtr<TraceEvent::ConvertableToTraceFormat> devToolsTraceEventData(ExecutionContext* context, v8::Handle<v8::Function> function, v8::Isolate* isolate)
+{
+ int scriptId = 0;
+ String resourceName;
+ int lineNumber = 1;
+ GetDevToolsFunctionInfo(function, isolate, scriptId, resourceName, lineNumber);
+ return InspectorFunctionCallEvent::data(context, scriptId, resourceName, lineNumber);
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/V8Binding.h b/chromium/third_party/WebKit/Source/bindings/v8/V8Binding.h
index 48200a2fdd0..7fb8e727b57 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/V8Binding.h
+++ b/chromium/third_party/WebKit/Source/bindings/v8/V8Binding.h
@@ -34,668 +34,942 @@
#include "bindings/v8/DOMWrapperWorld.h"
#include "bindings/v8/ExceptionMessages.h"
+#include "bindings/v8/ScriptValue.h"
#include "bindings/v8/V8BindingMacros.h"
#include "bindings/v8/V8PerIsolateData.h"
#include "bindings/v8/V8StringResource.h"
#include "bindings/v8/V8ThrowException.h"
#include "bindings/v8/V8ValueCache.h"
+#include "platform/heap/Heap.h"
#include "wtf/MathExtras.h"
#include "wtf/text/AtomicString.h"
#include <v8.h>
namespace WebCore {
- class DOMWindow;
- class Document;
- class Frame;
- class NodeFilter;
- class ExecutionContext;
- class ScriptWrappable;
- class XPathNSResolver;
+class LocalDOMWindow;
+class Document;
+class EventListener;
+class ExecutionContext;
+class ExceptionState;
+class LocalFrame;
+class NodeFilter;
+class ScriptWrappable;
+class XPathNSResolver;
+
+namespace TraceEvent {
+class ConvertableToTraceFormat;
+}
+
+const int kMaxRecursionDepth = 22;
+
+// Schedule a JavaScript error to be thrown.
+v8::Handle<v8::Value> throwError(V8ErrorType, const String&, v8::Isolate*);
+
+// Schedule a JavaScript error to be thrown.
+v8::Handle<v8::Value> throwError(v8::Handle<v8::Value>, v8::Isolate*);
+
+// A helper for throwing JavaScript TypeError.
+v8::Handle<v8::Value> throwTypeError(const String&, v8::Isolate*);
+
+// Helpers for throwing JavaScript TypeErrors for arity mismatches.
+void throwArityTypeErrorForMethod(const char* method, const char* type, const char* valid, unsigned provided, v8::Isolate*);
+void throwArityTypeErrorForConstructor(const char* type, const char* valid, unsigned provided, v8::Isolate*);
+void throwArityTypeError(ExceptionState&, const char* valid, unsigned provided);
+void throwMinimumArityTypeErrorForMethod(const char* method, const char* type, unsigned expected, unsigned providedLeastNumMandatoryParams, v8::Isolate*);
+void throwMinimumArityTypeErrorForConstructor(const char* type, unsigned expected, unsigned providedLeastNumMandatoryParams, v8::Isolate*);
+void throwMinimumArityTypeError(ExceptionState&, unsigned expected, unsigned providedLeastNumMandatoryParams);
+
+v8::ArrayBuffer::Allocator* v8ArrayBufferAllocator();
+
+inline v8::Handle<v8::Value> argumentOrNull(const v8::FunctionCallbackInfo<v8::Value>& info, int index)
+{
+ return index >= info.Length() ? v8::Local<v8::Value>() : info[index];
+}
+
+template<typename CallbackInfo, typename V>
+inline void v8SetReturnValue(const CallbackInfo& info, V v)
+{
+ info.GetReturnValue().Set(v);
+}
+
+template<typename CallbackInfo>
+inline void v8SetReturnValueBool(const CallbackInfo& info, bool v)
+{
+ info.GetReturnValue().Set(v);
+}
+
+template<typename CallbackInfo>
+inline void v8SetReturnValueInt(const CallbackInfo& info, int v)
+{
+ info.GetReturnValue().Set(v);
+}
+
+template<typename CallbackInfo>
+inline void v8SetReturnValueUnsigned(const CallbackInfo& info, unsigned v)
+{
+ info.GetReturnValue().Set(v);
+}
+
+template<typename CallbackInfo>
+inline void v8SetReturnValueNull(const CallbackInfo& info)
+{
+ info.GetReturnValue().SetNull();
+}
+
+template<typename CallbackInfo>
+inline void v8SetReturnValueUndefined(const CallbackInfo& info)
+{
+ info.GetReturnValue().SetUndefined();
+}
+
+template<typename CallbackInfo>
+inline void v8SetReturnValueEmptyString(const CallbackInfo& info)
+{
+ info.GetReturnValue().SetEmptyString();
+}
+
+template <class CallbackInfo>
+inline void v8SetReturnValueString(const CallbackInfo& info, const String& string, v8::Isolate* isolate)
+{
+ if (string.isNull()) {
+ v8SetReturnValueEmptyString(info);
+ return;
+ }
+ V8PerIsolateData::from(isolate)->stringCache()->setReturnValueFromString(info.GetReturnValue(), string.impl());
+}
+
+template <class CallbackInfo>
+inline void v8SetReturnValueStringOrNull(const CallbackInfo& info, const String& string, v8::Isolate* isolate)
+{
+ if (string.isNull()) {
+ v8SetReturnValueNull(info);
+ return;
+ }
+ V8PerIsolateData::from(isolate)->stringCache()->setReturnValueFromString(info.GetReturnValue(), string.impl());
+}
+
+template <class CallbackInfo>
+inline void v8SetReturnValueStringOrUndefined(const CallbackInfo& info, const String& string, v8::Isolate* isolate)
+{
+ if (string.isNull()) {
+ v8SetReturnValueUndefined(info);
+ return;
+ }
+ V8PerIsolateData::from(isolate)->stringCache()->setReturnValueFromString(info.GetReturnValue(), string.impl());
+}
+
+// Convert v8::String to a WTF::String. If the V8 string is not already
+// an external string then it is transformed into an external string at this
+// point to avoid repeated conversions.
+inline String toCoreString(v8::Handle<v8::String> value)
+{
+ return v8StringToWebCoreString<String>(value, Externalize);
+}
+
+inline String toCoreStringWithNullCheck(v8::Handle<v8::String> value)
+{
+ if (value.IsEmpty() || value->IsNull())
+ return String();
+ return toCoreString(value);
+}
+
+inline String toCoreStringWithUndefinedOrNullCheck(v8::Handle<v8::String> value)
+{
+ if (value.IsEmpty() || value->IsNull() || value->IsUndefined())
+ return String();
+ return toCoreString(value);
+}
+
+inline AtomicString toCoreAtomicString(v8::Handle<v8::String> value)
+{
+ return v8StringToWebCoreString<AtomicString>(value, Externalize);
+}
+
+// This method will return a null String if the v8::Value does not contain a v8::String.
+// It will not call ToString() on the v8::Value. If you want ToString() to be called,
+// please use the TONATIVE_FOR_V8STRINGRESOURCE_*() macros instead.
+inline String toCoreStringWithUndefinedOrNullCheck(v8::Handle<v8::Value> value)
+{
+ if (value.IsEmpty() || !value->IsString())
+ return String();
+ return toCoreString(value.As<v8::String>());
+}
+
+// Convert a string to a V8 string.
+// Return a V8 external string that shares the underlying buffer with the given
+// WebCore string. The reference counting mechanism is used to keep the
+// underlying buffer alive while the string is still live in the V8 engine.
+inline v8::Handle<v8::String> v8String(v8::Isolate* isolate, const String& string)
+{
+ if (string.isNull())
+ return v8::String::Empty(isolate);
+ return V8PerIsolateData::from(isolate)->stringCache()->v8ExternalString(string.impl(), isolate);
+}
+
+inline v8::Handle<v8::String> v8AtomicString(v8::Isolate* isolate, const char* str)
+{
+ ASSERT(isolate);
+ return v8::String::NewFromUtf8(isolate, str, v8::String::kInternalizedString, strlen(str));
+}
- const int kMaxRecursionDepth = 22;
+inline v8::Handle<v8::String> v8AtomicString(v8::Isolate* isolate, const char* str, size_t length)
+{
+ ASSERT(isolate);
+ return v8::String::NewFromUtf8(isolate, str, v8::String::kInternalizedString, length);
+}
- // Schedule a DOM exception to be thrown, if the exception code is different
- // from zero.
- v8::Handle<v8::Value> setDOMException(int, v8::Isolate*);
- v8::Handle<v8::Value> setDOMException(int, const String&, v8::Isolate*);
+inline v8::Handle<v8::Value> v8Undefined()
+{
+ return v8::Handle<v8::Value>();
+}
- // Schedule a JavaScript error to be thrown.
- v8::Handle<v8::Value> throwError(V8ErrorType, const String&, v8::Isolate*);
-
- // Schedule a JavaScript error to be thrown.
- v8::Handle<v8::Value> throwError(v8::Handle<v8::Value>, v8::Isolate*);
-
- // A helper for throwing JavaScript TypeError.
- v8::Handle<v8::Value> throwTypeError(const String&, v8::Isolate*);
-
- // FIXME: Remove this once we kill its callers.
- v8::Handle<v8::Value> throwUninformativeAndGenericTypeError(v8::Isolate*);
-
- v8::ArrayBuffer::Allocator* v8ArrayBufferAllocator();
-
- v8::Handle<v8::Value> toV8Sequence(v8::Handle<v8::Value>, uint32_t& length, v8::Isolate*);
-
- inline v8::Handle<v8::Value> argumentOrNull(const v8::FunctionCallbackInfo<v8::Value>& info, int index)
+template <class T>
+struct V8ValueTraits {
+ // FIXME: This function requires the associated generated header to be
+ // included. Also, this function does not match with other V8ValueTraits
+ // classes. Remove this V8ValueTraits if possible.
+ static inline v8::Handle<v8::Value> toV8Value(const T& value, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
{
- return index >= info.Length() ? v8::Local<v8::Value>() : info[index];
+ return toV8(WTF::getPtr(value), creationContext, isolate);
}
+};
- template<typename CallbackInfo, typename V>
- inline void v8SetReturnValue(const CallbackInfo& info, V v)
+template<>
+struct V8ValueTraits<String> {
+ static inline v8::Handle<v8::Value> toV8Value(const String& value, v8::Handle<v8::Object>, v8::Isolate* isolate)
{
- info.GetReturnValue().Set(v);
+ return v8String(isolate, value);
}
+};
- template<typename CallbackInfo>
- inline void v8SetReturnValueBool(const CallbackInfo& info, bool v)
+template<>
+struct V8ValueTraits<AtomicString> {
+ static inline v8::Handle<v8::Value> toV8Value(const AtomicString& value, v8::Handle<v8::Object>, v8::Isolate* isolate)
{
- info.GetReturnValue().Set(v);
+ return v8String(isolate, value);
}
+};
- template<typename CallbackInfo>
- inline void v8SetReturnValueInt(const CallbackInfo& info, int v)
+template<size_t n>
+struct V8ValueTraits<char[n]> {
+ static inline v8::Handle<v8::Value> toV8Value(char const (&value)[n], v8::Handle<v8::Object>, v8::Isolate* isolate)
{
- info.GetReturnValue().Set(v);
+ return v8String(isolate, value);
}
+};
- template<typename CallbackInfo>
- inline void v8SetReturnValueUnsigned(const CallbackInfo& info, unsigned v)
+template<>
+struct V8ValueTraits<const char*> {
+ static inline v8::Handle<v8::Value> toV8Value(const char* const& value, v8::Handle<v8::Object>, v8::Isolate* isolate)
{
- info.GetReturnValue().Set(v);
+ return v8String(isolate, value);
}
+};
- template<typename CallbackInfo>
- inline void v8SetReturnValueNull(const CallbackInfo& info)
+template<>
+struct V8ValueTraits<int> {
+ static inline v8::Handle<v8::Value> toV8Value(const int& value, v8::Handle<v8::Object>, v8::Isolate* isolate)
{
- info.GetReturnValue().SetNull();
+ return v8::Integer::New(isolate, value);
}
+};
- template<typename CallbackInfo>
- inline void v8SetReturnValueUndefined(const CallbackInfo& info)
+template<>
+struct V8ValueTraits<long> {
+ static inline v8::Handle<v8::Value> toV8Value(const long& value, v8::Handle<v8::Object>, v8::Isolate* isolate)
{
- info.GetReturnValue().SetUndefined();
+ return v8::Integer::New(isolate, value);
}
+};
- template<typename CallbackInfo>
- inline void v8SetReturnValueEmptyString(const CallbackInfo& info)
+template<>
+struct V8ValueTraits<unsigned> {
+ static inline v8::Handle<v8::Value> toV8Value(const unsigned& value, v8::Handle<v8::Object>, v8::Isolate* isolate)
{
- info.GetReturnValue().SetEmptyString();
+ return v8::Integer::NewFromUnsigned(isolate, value);
}
+};
- template <class CallbackInfo>
- inline void v8SetReturnValueString(const CallbackInfo& info, const String& string, v8::Isolate* isolate)
+template<>
+struct V8ValueTraits<unsigned long> {
+ static inline v8::Handle<v8::Value> toV8Value(const unsigned long& value, v8::Handle<v8::Object>, v8::Isolate* isolate)
{
- if (string.isNull()) {
- v8SetReturnValueEmptyString(info);
- return;
- }
- V8PerIsolateData::from(isolate)->stringCache()->setReturnValueFromString(info.GetReturnValue(), string.impl());
+ return v8::Integer::NewFromUnsigned(isolate, value);
}
+};
- template <class CallbackInfo>
- inline void v8SetReturnValueStringOrNull(const CallbackInfo& info, const String& string, v8::Isolate* isolate)
+template<>
+struct V8ValueTraits<float> {
+ static inline v8::Handle<v8::Value> toV8Value(const float& value, v8::Handle<v8::Object>, v8::Isolate* isolate)
{
- if (string.isNull()) {
- v8SetReturnValueNull(info);
- return;
- }
- V8PerIsolateData::from(isolate)->stringCache()->setReturnValueFromString(info.GetReturnValue(), string.impl());
+ return v8::Number::New(isolate, value);
}
+};
- template <class CallbackInfo>
- inline void v8SetReturnValueStringOrUndefined(const CallbackInfo& info, const String& string, v8::Isolate* isolate)
+template<>
+struct V8ValueTraits<double> {
+ static inline v8::Handle<v8::Value> toV8Value(const double& value, v8::Handle<v8::Object>, v8::Isolate* isolate)
{
- if (string.isNull()) {
- v8SetReturnValueUndefined(info);
- return;
- }
- V8PerIsolateData::from(isolate)->stringCache()->setReturnValueFromString(info.GetReturnValue(), string.impl());
+ return v8::Number::New(isolate, value);
}
+};
- // Convert v8::String to a WTF::String. If the V8 string is not already
- // an external string then it is transformed into an external string at this
- // point to avoid repeated conversions.
- inline String toCoreString(v8::Handle<v8::String> value)
+template<>
+struct V8ValueTraits<bool> {
+ static inline v8::Handle<v8::Value> toV8Value(const bool& value, v8::Handle<v8::Object>, v8::Isolate* isolate)
{
- return v8StringToWebCoreString<String>(value, Externalize);
+ return v8::Boolean::New(isolate, value);
}
+};
- inline String toCoreStringWithNullCheck(v8::Handle<v8::String> value)
- {
- if (value.IsEmpty() || value->IsNull())
- return String();
- return toCoreString(value);
- }
+// V8NullType and V8UndefinedType are used only for the value conversion.
+class V8NullType { };
+class V8UndefinedType { };
- inline String toCoreStringWithUndefinedOrNullCheck(v8::Handle<v8::String> value)
+template<>
+struct V8ValueTraits<V8NullType> {
+ static inline v8::Handle<v8::Value> toV8Value(const V8NullType&, v8::Handle<v8::Object>, v8::Isolate* isolate)
{
- if (value.IsEmpty() || value->IsNull() || value->IsUndefined())
- return String();
- return toCoreString(value);
+ return v8::Null(isolate);
}
+};
- inline AtomicString toCoreAtomicString(v8::Handle<v8::String> value)
+template<>
+struct V8ValueTraits<V8UndefinedType> {
+ static inline v8::Handle<v8::Value> toV8Value(const V8UndefinedType&, v8::Handle<v8::Object>, v8::Isolate* isolate)
{
- return v8StringToWebCoreString<AtomicString>(value, Externalize);
+ return v8::Undefined(isolate);
}
+};
- // This method will return a null String if the v8::Value does not contain a v8::String.
- // It will not call ToString() on the v8::Value. If you want ToString() to be called,
- // please use the V8TRYCATCH_FOR_V8STRINGRESOURCE_*() macros instead.
- inline String toCoreStringWithUndefinedOrNullCheck(v8::Handle<v8::Value> value)
+template<>
+struct V8ValueTraits<ScriptValue> {
+ static inline v8::Handle<v8::Value> toV8Value(const ScriptValue& value, v8::Handle<v8::Object>, v8::Isolate*)
{
- if (value.IsEmpty() || !value->IsString())
- return String();
-
- return toCoreString(value.As<v8::String>());
+ return value.v8Value();
}
+};
- // Convert a string to a V8 string.
- // Return a V8 external string that shares the underlying buffer with the given
- // WebCore string. The reference counting mechanism is used to keep the
- // underlying buffer alive while the string is still live in the V8 engine.
- inline v8::Handle<v8::String> v8String(v8::Isolate* isolate, const String& string)
+template<>
+struct V8ValueTraits<v8::Handle<v8::Value> > {
+ static inline v8::Handle<v8::Value> toV8Value(const v8::Handle<v8::Value>& value, v8::Handle<v8::Object>, v8::Isolate*)
{
- if (string.isNull())
- return v8::String::Empty(isolate);
- return V8PerIsolateData::from(isolate)->stringCache()->v8ExternalString(string.impl(), isolate);
+ return value;
}
+};
- inline v8::Handle<v8::Value> v8Undefined()
+template<>
+struct V8ValueTraits<v8::Local<v8::Value> > {
+ static inline v8::Handle<v8::Value> toV8Value(const v8::Local<v8::Value>& value, v8::Handle<v8::Object>, v8::Isolate*)
{
- return v8::Handle<v8::Value>();
+ return value;
}
+};
- template <class T>
- struct V8ValueTraits {
- static inline v8::Handle<v8::Value> arrayV8Value(const T& value, v8::Isolate* isolate)
- {
- return toV8(WTF::getPtr(value), v8::Handle<v8::Object>(), isolate);
- }
- };
-
- template<>
- struct V8ValueTraits<String> {
- static inline v8::Handle<v8::Value> arrayV8Value(const String& value, v8::Isolate* isolate)
- {
- return v8String(isolate, value);
- }
- };
-
- template<>
- struct V8ValueTraits<unsigned> {
- static inline v8::Handle<v8::Value> arrayV8Value(const unsigned& value, v8::Isolate* isolate)
- {
- return v8::Integer::NewFromUnsigned(value, isolate);
- }
- };
-
- template<>
- struct V8ValueTraits<unsigned long> {
- static inline v8::Handle<v8::Value> arrayV8Value(const unsigned long& value, v8::Isolate* isolate)
- {
- return v8::Integer::NewFromUnsigned(value, isolate);
- }
- };
-
- template<>
- struct V8ValueTraits<float> {
- static inline v8::Handle<v8::Value> arrayV8Value(const float& value, v8::Isolate* isolate)
- {
- return v8::Number::New(isolate, value);
- }
- };
-
- template<>
- struct V8ValueTraits<double> {
- static inline v8::Handle<v8::Value> arrayV8Value(const double& value, v8::Isolate* isolate)
- {
- return v8::Number::New(isolate, value);
- }
- };
-
- template<typename T, size_t inlineCapacity>
- v8::Handle<v8::Value> v8Array(const Vector<T, inlineCapacity>& iterator, v8::Isolate* isolate)
+template<typename T, size_t inlineCapacity>
+v8::Handle<v8::Value> v8Array(const Vector<T, inlineCapacity>& iterator, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
+{
+ v8::Local<v8::Array> result = v8::Array::New(isolate, iterator.size());
+ int index = 0;
+ typename Vector<T, inlineCapacity>::const_iterator end = iterator.end();
+ typedef V8ValueTraits<T> TraitsType;
+ for (typename Vector<T, inlineCapacity>::const_iterator iter = iterator.begin(); iter != end; ++iter)
+ result->Set(v8::Integer::New(isolate, index++), TraitsType::toV8Value(*iter, creationContext, isolate));
+ return result;
+}
+
+template<typename T, size_t inlineCapacity>
+v8::Handle<v8::Value> v8Array(const HeapVector<T, inlineCapacity>& iterator, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
+{
+ v8::Local<v8::Array> result = v8::Array::New(isolate, iterator.size());
+ int index = 0;
+ typename HeapVector<T, inlineCapacity>::const_iterator end = iterator.end();
+ typedef V8ValueTraits<T> TraitsType;
+ for (typename HeapVector<T, inlineCapacity>::const_iterator iter = iterator.begin(); iter != end; ++iter)
+ result->Set(v8::Integer::New(isolate, index++), TraitsType::toV8Value(*iter, creationContext, isolate));
+ return result;
+}
+
+template<typename T, size_t inlineCapacity>
+v8::Handle<v8::Value> v8ArrayNoInline(const Vector<T, inlineCapacity>& iterator, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
+{
+ v8::Local<v8::Array> result = v8::Array::New(isolate, iterator.size());
+ int index = 0;
+ typename Vector<T, inlineCapacity>::const_iterator end = iterator.end();
+ for (typename Vector<T, inlineCapacity>::const_iterator iter = iterator.begin(); iter != end; ++iter)
+ result->Set(v8::Integer::New(isolate, index++), toV8NoInline(WTF::getPtr(*iter), creationContext, isolate));
+ return result;
+}
+
+template<typename T, size_t inlineCapacity>
+v8::Handle<v8::Value> v8ArrayNoInline(const HeapVector<T, inlineCapacity>& iterator, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
+{
+ v8::Local<v8::Array> result = v8::Array::New(isolate, iterator.size());
+ int index = 0;
+ typename HeapVector<T, inlineCapacity>::const_iterator end = iterator.end();
+ for (typename HeapVector<T, inlineCapacity>::const_iterator iter = iterator.begin(); iter != end; ++iter)
+ result->Set(v8::Integer::New(isolate, index++), toV8NoInline(WTF::getPtr(*iter), creationContext, isolate));
+ return result;
+}
+
+// Conversion flags, used in toIntXX/toUIntXX.
+enum IntegerConversionConfiguration {
+ NormalConversion,
+ EnforceRange,
+ Clamp
+};
+
+// Convert a value to a 8-bit signed integer. The conversion fails if the
+// value cannot be converted to a number or the range violated per WebIDL:
+// http://www.w3.org/TR/WebIDL/#es-byte
+int8_t toInt8(v8::Handle<v8::Value>, IntegerConversionConfiguration, ExceptionState&);
+inline int8_t toInt8(v8::Handle<v8::Value> value, ExceptionState& exceptionState)
+{
+ return toInt8(value, NormalConversion, exceptionState);
+}
+
+// Convert a value to a 8-bit integer assuming the conversion cannot fail.
+int8_t toInt8(v8::Handle<v8::Value>);
+
+// Convert a value to a 8-bit unsigned integer. The conversion fails if the
+// value cannot be converted to a number or the range violated per WebIDL:
+// http://www.w3.org/TR/WebIDL/#es-octet
+uint8_t toUInt8(v8::Handle<v8::Value>, IntegerConversionConfiguration, ExceptionState&);
+inline uint8_t toUInt8(v8::Handle<v8::Value> value, ExceptionState& exceptionState)
+{
+ return toUInt8(value, NormalConversion, exceptionState);
+}
+
+// Convert a value to a 8-bit unsigned integer assuming the conversion cannot fail.
+uint8_t toUInt8(v8::Handle<v8::Value>);
+
+// Convert a value to a 16-bit signed integer. The conversion fails if the
+// value cannot be converted to a number or the range violated per WebIDL:
+// http://www.w3.org/TR/WebIDL/#es-short
+int16_t toInt16(v8::Handle<v8::Value>, IntegerConversionConfiguration, ExceptionState&);
+inline int16_t toInt16(v8::Handle<v8::Value> value, ExceptionState& exceptionState)
+{
+ return toInt16(value, NormalConversion, exceptionState);
+}
+
+// Convert a value to a 16-bit integer assuming the conversion cannot fail.
+int16_t toInt16(v8::Handle<v8::Value>);
+
+// Convert a value to a 16-bit unsigned integer. The conversion fails if the
+// value cannot be converted to a number or the range violated per WebIDL:
+// http://www.w3.org/TR/WebIDL/#es-unsigned-short
+uint16_t toUInt16(v8::Handle<v8::Value>, IntegerConversionConfiguration, ExceptionState&);
+inline uint16_t toUInt16(v8::Handle<v8::Value> value, ExceptionState& exceptionState)
+{
+ return toUInt16(value, NormalConversion, exceptionState);
+}
+
+// Convert a value to a 16-bit unsigned integer assuming the conversion cannot fail.
+uint16_t toUInt16(v8::Handle<v8::Value>);
+
+// Convert a value to a 32-bit signed integer. The conversion fails if the
+// value cannot be converted to a number or the range violated per WebIDL:
+// http://www.w3.org/TR/WebIDL/#es-long
+int32_t toInt32(v8::Handle<v8::Value>, IntegerConversionConfiguration, ExceptionState&);
+inline int32_t toInt32(v8::Handle<v8::Value> value, ExceptionState& exceptionState)
+{
+ return toInt32(value, NormalConversion, exceptionState);
+}
+
+// Convert a value to a 32-bit integer assuming the conversion cannot fail.
+int32_t toInt32(v8::Handle<v8::Value>);
+
+// Convert a value to a 32-bit unsigned integer. The conversion fails if the
+// value cannot be converted to a number or the range violated per WebIDL:
+// http://www.w3.org/TR/WebIDL/#es-unsigned-long
+uint32_t toUInt32(v8::Handle<v8::Value>, IntegerConversionConfiguration, ExceptionState&);
+inline uint32_t toUInt32(v8::Handle<v8::Value> value, ExceptionState& exceptionState)
+{
+ return toUInt32(value, NormalConversion, exceptionState);
+}
+
+// Convert a value to a 32-bit unsigned integer assuming the conversion cannot fail.
+uint32_t toUInt32(v8::Handle<v8::Value>);
+
+// Convert a value to a 64-bit signed integer. The conversion fails if the
+// value cannot be converted to a number or the range violated per WebIDL:
+// http://www.w3.org/TR/WebIDL/#es-long-long
+int64_t toInt64(v8::Handle<v8::Value>, IntegerConversionConfiguration, ExceptionState&);
+inline int64_t toInt64(v8::Handle<v8::Value> value, ExceptionState& exceptionState)
+{
+ return toInt64(value, NormalConversion, exceptionState);
+}
+
+// Convert a value to a 64-bit integer assuming the conversion cannot fail.
+int64_t toInt64(v8::Handle<v8::Value>);
+
+// Convert a value to a 64-bit unsigned integer. The conversion fails if the
+// value cannot be converted to a number or the range violated per WebIDL:
+// http://www.w3.org/TR/WebIDL/#es-unsigned-long-long
+uint64_t toUInt64(v8::Handle<v8::Value>, IntegerConversionConfiguration, ExceptionState&);
+inline uint64_t toUInt64(v8::Handle<v8::Value> value, ExceptionState& exceptionState)
+{
+ return toUInt64(value, NormalConversion, exceptionState);
+}
+
+// Convert a value to a 64-bit unsigned integer assuming the conversion cannot fail.
+uint64_t toUInt64(v8::Handle<v8::Value>);
+
+// Convert a value to a single precision float, which might fail.
+float toFloat(v8::Handle<v8::Value>, ExceptionState&);
+
+// Convert a value to a single precision float assuming the conversion cannot fail.
+inline float toFloat(v8::Local<v8::Value> value)
+{
+ return static_cast<float>(value->NumberValue());
+}
+
+// Converts a value to a String, throwing if any code unit is outside 0-255.
+String toByteString(v8::Handle<v8::Value>, ExceptionState&);
+
+// Converts a value to a String, replacing unmatched UTF-16 surrogates with replacement characters.
+String toScalarValueString(v8::Handle<v8::Value>, ExceptionState&);
+
+inline v8::Handle<v8::Boolean> v8Boolean(bool value, v8::Isolate* isolate)
+{
+ return value ? v8::True(isolate) : v8::False(isolate);
+}
+
+inline double toCoreDate(v8::Handle<v8::Value> object)
+{
+ if (object->IsDate())
+ return v8::Handle<v8::Date>::Cast(object)->ValueOf();
+ if (object->IsNumber())
+ return object->NumberValue();
+ return std::numeric_limits<double>::quiet_NaN();
+}
+
+inline v8::Handle<v8::Value> v8DateOrNaN(double value, v8::Isolate* isolate)
+{
+ ASSERT(isolate);
+ return v8::Date::New(isolate, std::isfinite(value) ? value : std::numeric_limits<double>::quiet_NaN());
+}
+
+// FIXME: Remove the special casing for NodeFilter and XPathNSResolver.
+PassRefPtrWillBeRawPtr<NodeFilter> toNodeFilter(v8::Handle<v8::Value>, v8::Handle<v8::Object>, ScriptState*);
+PassRefPtrWillBeRawPtr<XPathNSResolver> toXPathNSResolver(v8::Handle<v8::Value>, v8::Isolate*);
+
+template<class T> struct NativeValueTraits;
+
+template<>
+struct NativeValueTraits<String> {
+ static inline String nativeValue(const v8::Handle<v8::Value>& value, v8::Isolate* isolate)
+ {
+ TOSTRING_DEFAULT(V8StringResource<>, stringValue, value, String());
+ return stringValue;
+ }
+};
+
+template<>
+struct NativeValueTraits<unsigned> {
+ static inline unsigned nativeValue(const v8::Handle<v8::Value>& value, v8::Isolate* isolate)
+ {
+ return toUInt32(value);
+ }
+};
+
+template<>
+struct NativeValueTraits<float> {
+ static inline float nativeValue(const v8::Handle<v8::Value>& value, v8::Isolate* isolate)
{
- v8::Local<v8::Array> result = v8::Array::New(isolate, iterator.size());
- int index = 0;
- typename Vector<T, inlineCapacity>::const_iterator end = iterator.end();
- typedef V8ValueTraits<T> TraitsType;
- for (typename Vector<T, inlineCapacity>::const_iterator iter = iterator.begin(); iter != end; ++iter)
- result->Set(v8::Integer::New(index++, isolate), TraitsType::arrayV8Value(*iter, isolate));
- return result;
+ return static_cast<float>(value->NumberValue());
}
+};
- // Conversion flags, used in toIntXX/toUIntXX.
- enum IntegerConversionConfiguration {
- NormalConversion,
- EnforceRange,
- Clamp
- };
-
- // Convert a value to a 8-bit signed integer. The conversion fails if the
- // value cannot be converted to a number or the range violated per WebIDL:
- // http://www.w3.org/TR/WebIDL/#es-byte
- int8_t toInt8(v8::Handle<v8::Value>, IntegerConversionConfiguration, bool& ok);
- inline int8_t toInt8(v8::Handle<v8::Value> value, bool& ok) { return toInt8(value, NormalConversion, ok); }
-
- // Convert a value to a 8-bit integer assuming the conversion cannot fail.
- inline int8_t toInt8(v8::Handle<v8::Value> value)
+template<>
+struct NativeValueTraits<double> {
+ static inline double nativeValue(const v8::Handle<v8::Value>& value, v8::Isolate* isolate)
{
- bool ok;
- return toInt8(value, NormalConversion, ok);
+ return static_cast<double>(value->NumberValue());
}
+};
- // Convert a value to a 8-bit unsigned integer. The conversion fails if the
- // value cannot be converted to a number or the range violated per WebIDL:
- // http://www.w3.org/TR/WebIDL/#es-octet
- uint8_t toUInt8(v8::Handle<v8::Value>, IntegerConversionConfiguration, bool& ok);
- inline uint8_t toUInt8(v8::Handle<v8::Value> value, bool& ok) { return toUInt8(value, NormalConversion, ok); }
-
- // Convert a value to a 8-bit unsigned integer assuming the conversion cannot fail.
- inline uint8_t toUInt8(v8::Handle<v8::Value> value)
+template<>
+struct NativeValueTraits<v8::Handle<v8::Value> > {
+ static inline v8::Handle<v8::Value> nativeValue(const v8::Handle<v8::Value>& value, v8::Isolate* isolate)
{
- bool ok;
- return toUInt8(value, NormalConversion, ok);
+ return value;
}
+};
- // Convert a value to a 16-bit signed integer. The conversion fails if the
- // value cannot be converted to a number or the range violated per WebIDL:
- // http://www.w3.org/TR/WebIDL/#es-short
- int16_t toInt16(v8::Handle<v8::Value>, IntegerConversionConfiguration, bool& ok);
- inline int16_t toInt16(v8::Handle<v8::Value> value, bool& ok) { return toInt16(value, NormalConversion, ok); }
+v8::Handle<v8::Value> toV8Sequence(v8::Handle<v8::Value>, uint32_t& length, v8::Isolate*);
- // Convert a value to a 16-bit integer assuming the conversion cannot fail.
- inline int16_t toInt16(v8::Handle<v8::Value> value)
- {
- bool ok;
- return toInt16(value, NormalConversion, ok);
+// Converts a JavaScript value to an array as per the Web IDL specification:
+// http://www.w3.org/TR/2012/CR-WebIDL-20120419/#es-array
+template <class T, class V8T>
+Vector<RefPtr<T> > toRefPtrNativeArrayUnchecked(v8::Local<v8::Value> v8Value, uint32_t length, v8::Isolate* isolate, bool* success = 0)
+{
+ Vector<RefPtr<T> > result;
+ result.reserveInitialCapacity(length);
+ v8::Local<v8::Object> object = v8::Local<v8::Object>::Cast(v8Value);
+ for (uint32_t i = 0; i < length; ++i) {
+ v8::Handle<v8::Value> element = object->Get(i);
+ if (V8T::hasInstance(element, isolate)) {
+ v8::Handle<v8::Object> elementObject = v8::Handle<v8::Object>::Cast(element);
+ result.uncheckedAppend(V8T::toNative(elementObject));
+ } else {
+ if (success)
+ *success = false;
+ throwTypeError("Invalid Array element type", isolate);
+ return Vector<RefPtr<T> >();
+ }
}
-
- // Convert a value to a 16-bit unsigned integer. The conversion fails if the
- // value cannot be converted to a number or the range violated per WebIDL:
- // http://www.w3.org/TR/WebIDL/#es-unsigned-short
- uint16_t toUInt16(v8::Handle<v8::Value>, IntegerConversionConfiguration, bool& ok);
- inline uint16_t toUInt16(v8::Handle<v8::Value> value, bool& ok) { return toUInt16(value, NormalConversion, ok); }
-
- // Convert a value to a 16-bit unsigned integer assuming the conversion cannot fail.
- inline uint16_t toUInt16(v8::Handle<v8::Value> value)
- {
- bool ok;
- return toUInt16(value, NormalConversion, ok);
+ return result;
+}
+
+template <class T, class V8T>
+Vector<RefPtr<T> > toRefPtrNativeArray(v8::Handle<v8::Value> value, int argumentIndex, v8::Isolate* isolate, bool* success = 0)
+{
+ if (success)
+ *success = true;
+
+ v8::Local<v8::Value> v8Value(v8::Local<v8::Value>::New(isolate, value));
+ uint32_t length = 0;
+ if (value->IsArray()) {
+ length = v8::Local<v8::Array>::Cast(v8Value)->Length();
+ } else if (toV8Sequence(value, length, isolate).IsEmpty()) {
+ throwTypeError(ExceptionMessages::notAnArrayTypeArgumentOrValue(argumentIndex), isolate);
+ return Vector<RefPtr<T> >();
+ }
+ return toRefPtrNativeArrayUnchecked<T, V8T>(v8Value, length, isolate, success);
+}
+
+template <class T, class V8T>
+Vector<RefPtr<T> > toRefPtrNativeArray(v8::Handle<v8::Value> value, const String& propertyName, v8::Isolate* isolate, bool* success = 0)
+{
+ if (success)
+ *success = true;
+
+ v8::Local<v8::Value> v8Value(v8::Local<v8::Value>::New(isolate, value));
+ uint32_t length = 0;
+ if (value->IsArray()) {
+ length = v8::Local<v8::Array>::Cast(v8Value)->Length();
+ } else if (toV8Sequence(value, length, isolate).IsEmpty()) {
+ throwTypeError(ExceptionMessages::notASequenceTypeProperty(propertyName), isolate);
+ return Vector<RefPtr<T> >();
+ }
+ return toRefPtrNativeArrayUnchecked<T, V8T>(v8Value, length, isolate, success);
+}
+
+template <class T, class V8T>
+WillBeHeapVector<RefPtrWillBeMember<T> > toRefPtrWillBeMemberNativeArray(v8::Handle<v8::Value> value, int argumentIndex, v8::Isolate* isolate, bool* success = 0)
+{
+ if (success)
+ *success = true;
+
+ v8::Local<v8::Value> v8Value(v8::Local<v8::Value>::New(isolate, value));
+ uint32_t length = 0;
+ if (value->IsArray()) {
+ length = v8::Local<v8::Array>::Cast(v8Value)->Length();
+ } else if (toV8Sequence(value, length, isolate).IsEmpty()) {
+ throwTypeError(ExceptionMessages::notAnArrayTypeArgumentOrValue(argumentIndex), isolate);
+ return WillBeHeapVector<RefPtrWillBeMember<T> >();
+ }
+
+ WillBeHeapVector<RefPtrWillBeMember<T> > result;
+ result.reserveInitialCapacity(length);
+ v8::Local<v8::Object> object = v8::Local<v8::Object>::Cast(v8Value);
+ for (uint32_t i = 0; i < length; ++i) {
+ v8::Handle<v8::Value> element = object->Get(i);
+ if (V8T::hasInstance(element, isolate)) {
+ v8::Handle<v8::Object> elementObject = v8::Handle<v8::Object>::Cast(element);
+ result.uncheckedAppend(V8T::toNative(elementObject));
+ } else {
+ if (success)
+ *success = false;
+ throwTypeError("Invalid Array element type", isolate);
+ return WillBeHeapVector<RefPtrWillBeMember<T> >();
+ }
}
-
- // Convert a value to a 32-bit signed integer. The conversion fails if the
- // value cannot be converted to a number or the range violated per WebIDL:
- // http://www.w3.org/TR/WebIDL/#es-long
- int32_t toInt32(v8::Handle<v8::Value>, IntegerConversionConfiguration, bool& ok);
- inline int32_t toInt32(v8::Handle<v8::Value> value, bool& ok) { return toInt32(value, NormalConversion, ok); }
-
- // Convert a value to a 32-bit integer assuming the conversion cannot fail.
- inline int32_t toInt32(v8::Handle<v8::Value> value)
+ return result;
+}
+
+// Converts a JavaScript value to an array as per the Web IDL specification:
+// http://www.w3.org/TR/2012/CR-WebIDL-20120419/#es-array
+template <class T>
+Vector<T> toNativeArray(v8::Handle<v8::Value> value, int argumentIndex, v8::Isolate* isolate)
+{
+ v8::Local<v8::Value> v8Value(v8::Local<v8::Value>::New(isolate, value));
+ uint32_t length = 0;
+ if (value->IsArray()) {
+ length = v8::Local<v8::Array>::Cast(v8Value)->Length();
+ } else if (toV8Sequence(value, length, isolate).IsEmpty()) {
+ throwTypeError(ExceptionMessages::notAnArrayTypeArgumentOrValue(argumentIndex), isolate);
+ return Vector<T>();
+ }
+
+ Vector<T> result;
+ result.reserveInitialCapacity(length);
+ typedef NativeValueTraits<T> TraitsType;
+ v8::Local<v8::Object> object = v8::Local<v8::Object>::Cast(v8Value);
+ for (uint32_t i = 0; i < length; ++i)
+ result.uncheckedAppend(TraitsType::nativeValue(object->Get(i), isolate));
+ return result;
+}
+
+template <class T>
+Vector<T> toNativeArguments(const v8::FunctionCallbackInfo<v8::Value>& info, int startIndex)
+{
+ ASSERT(startIndex <= info.Length());
+ Vector<T> result;
+ typedef NativeValueTraits<T> TraitsType;
+ int length = info.Length();
+ result.reserveInitialCapacity(length);
+ for (int i = startIndex; i < length; ++i)
+ result.uncheckedAppend(TraitsType::nativeValue(info[i], info.GetIsolate()));
+ return result;
+}
+
+// Validates that the passed object is a sequence type per WebIDL spec
+// http://www.w3.org/TR/2012/CR-WebIDL-20120419/#es-sequence
+inline v8::Handle<v8::Value> toV8Sequence(v8::Handle<v8::Value> value, uint32_t& length, v8::Isolate* isolate)
+{
+ // Attempt converting to a sequence if the value is not already an array but is
+ // any kind of object except for a native Date object or a native RegExp object.
+ ASSERT(!value->IsArray());
+ // FIXME: Do we really need to special case Date and RegExp object?
+ // https://www.w3.org/Bugs/Public/show_bug.cgi?id=22806
+ if (!value->IsObject() || value->IsDate() || value->IsRegExp()) {
+ // The caller is responsible for reporting a TypeError.
+ return v8Undefined();
+ }
+
+ v8::Local<v8::Value> v8Value(v8::Local<v8::Value>::New(isolate, value));
+ v8::Local<v8::Object> object = v8::Local<v8::Object>::Cast(v8Value);
+ v8::Local<v8::String> lengthSymbol = v8AtomicString(isolate, "length");
+
+ // FIXME: The specification states that the length property should be used as fallback, if value
+ // is not a platform object that supports indexed properties. If it supports indexed properties,
+ // length should actually be one greater than value’s maximum indexed property index.
+ TONATIVE_EXCEPTION(v8::Local<v8::Value>, lengthValue, object->Get(lengthSymbol));
+
+ if (lengthValue->IsUndefined() || lengthValue->IsNull()) {
+ // The caller is responsible for reporting a TypeError.
+ return v8Undefined();
+ }
+
+ TONATIVE_EXCEPTION(uint32_t, sequenceLength, lengthValue->Int32Value());
+ length = sequenceLength;
+ return v8Value;
+}
+
+v8::Isolate* toIsolate(ExecutionContext*);
+v8::Isolate* toIsolate(LocalFrame*);
+
+LocalDOMWindow* toDOMWindow(v8::Handle<v8::Value>, v8::Isolate*);
+LocalDOMWindow* toDOMWindow(v8::Handle<v8::Context>);
+LocalDOMWindow* enteredDOMWindow(v8::Isolate*);
+LocalDOMWindow* currentDOMWindow(v8::Isolate*);
+LocalDOMWindow* callingDOMWindow(v8::Isolate*);
+ExecutionContext* toExecutionContext(v8::Handle<v8::Context>);
+ExecutionContext* currentExecutionContext(v8::Isolate*);
+ExecutionContext* callingExecutionContext(v8::Isolate*);
+
+// Returns a V8 context associated with a ExecutionContext and a DOMWrapperWorld.
+// This method returns an empty context if there is no frame or the frame is already detached.
+v8::Local<v8::Context> toV8Context(ExecutionContext*, DOMWrapperWorld&);
+// Returns a V8 context associated with a LocalFrame and a DOMWrapperWorld.
+// This method returns an empty context if the frame is already detached.
+v8::Local<v8::Context> toV8Context(LocalFrame*, DOMWrapperWorld&);
+
+// Returns the frame object of the window object associated with
+// a context, if the window is currently being displayed in the LocalFrame.
+LocalFrame* toFrameIfNotDetached(v8::Handle<v8::Context>);
+
+// If the current context causes out of memory, JavaScript setting
+// is disabled and it returns true.
+bool handleOutOfMemory();
+v8::Local<v8::Value> handleMaxRecursionDepthExceeded(v8::Isolate*);
+void crashIfV8IsDead();
+
+inline bool isUndefinedOrNull(v8::Handle<v8::Value> value)
+{
+ return value->IsNull() || value->IsUndefined();
+}
+v8::Handle<v8::Function> getBoundFunction(v8::Handle<v8::Function>);
+
+// Attaches |environment| to |function| and returns it.
+inline v8::Local<v8::Function> createClosure(v8::FunctionCallback function, v8::Handle<v8::Value> environment, v8::Isolate* isolate)
+{
+ return v8::Function::New(isolate, function, environment);
+}
+
+// FIXME: This will be soon embedded in the generated code.
+template<class Collection> static void indexedPropertyEnumerator(const v8::PropertyCallbackInfo<v8::Array>& info)
+{
+ Collection* collection = reinterpret_cast<Collection*>(info.Holder()->GetAlignedPointerFromInternalField(v8DOMWrapperObjectIndex));
+ int length = collection->length();
+ v8::Handle<v8::Array> properties = v8::Array::New(info.GetIsolate(), length);
+ for (int i = 0; i < length; ++i) {
+ // FIXME: Do we need to check that the item function returns a non-null value for this index?
+ v8::Handle<v8::Integer> integer = v8::Integer::New(info.GetIsolate(), i);
+ properties->Set(integer, integer);
+ }
+ v8SetReturnValue(info, properties);
+}
+
+// These methods store hidden values into an array that is stored in the internal field of a DOM wrapper.
+void addHiddenValueToArray(v8::Handle<v8::Object>, v8::Local<v8::Value>, int cacheIndex, v8::Isolate*);
+void removeHiddenValueFromArray(v8::Handle<v8::Object>, v8::Local<v8::Value>, int cacheIndex, v8::Isolate*);
+void moveEventListenerToNewWrapper(v8::Handle<v8::Object>, EventListener* oldValue, v8::Local<v8::Value> newValue, int cacheIndex, v8::Isolate*);
+
+PassRefPtr<JSONValue> v8ToJSONValue(v8::Isolate*, v8::Handle<v8::Value>, int);
+
+// Converts a DOM object to a v8 value.
+// This is a no-inline version of toV8(). If you want to call toV8()
+// without creating #include cycles, you can use this function instead.
+// Each specialized implementation will be generated.
+template<typename T>
+v8::Handle<v8::Value> toV8NoInline(T* impl, v8::Handle<v8::Object> creationContext, v8::Isolate*);
+
+// ToV8Value<U, Context> is a class that converts a C++ object to a
+// v8 value. U has to be a class having a static method getCreationContext
+// which returns an object created from a target context.
+template<typename U, typename Context>
+class ToV8Value {
+public:
+ template<typename T>
+ static v8::Handle<v8::Value> toV8Value(const T& value, Context context, v8::Isolate* isolate)
{
- bool ok;
- return toInt32(value, NormalConversion, ok);
+ // Default implementaion: for types that don't need the context.
+ return V8ValueTraits<T>::toV8Value(value, context, isolate);
}
- // Convert a value to a 32-bit unsigned integer. The conversion fails if the
- // value cannot be converted to a number or the range violated per WebIDL:
- // http://www.w3.org/TR/WebIDL/#es-unsigned-long
- uint32_t toUInt32(v8::Handle<v8::Value>, IntegerConversionConfiguration, bool& ok);
- inline uint32_t toUInt32(v8::Handle<v8::Value> value, bool& ok) { return toUInt32(value, NormalConversion, ok); }
-
- // Convert a value to a 32-bit unsigned integer assuming the conversion cannot fail.
- inline uint32_t toUInt32(v8::Handle<v8::Value> value)
+ // Pointer specializations.
+ template<typename T>
+ static v8::Handle<v8::Value> toV8Value(T* const& value, Context context, v8::Isolate* isolate)
{
- bool ok;
- return toUInt32(value, NormalConversion, ok);
+ return toV8NoInline(value, context, isolate);
}
-
- // Convert a value to a 64-bit signed integer. The conversion fails if the
- // value cannot be converted to a number or the range violated per WebIDL:
- // http://www.w3.org/TR/WebIDL/#es-long-long
- int64_t toInt64(v8::Handle<v8::Value>, IntegerConversionConfiguration, bool& ok);
-
- // Convert a value to a 64-bit integer assuming the conversion cannot fail.
- inline int64_t toInt64(v8::Handle<v8::Value> value)
+ template<typename T>
+ static v8::Handle<v8::Value> toV8Value(const RefPtr<T>& value, Context context, v8::Isolate* isolate)
{
- bool ok;
- return toInt64(value, NormalConversion, ok);
+ return toV8Value(value.get(), context, isolate);
}
-
- // Convert a value to a 64-bit unsigned integer. The conversion fails if the
- // value cannot be converted to a number or the range violated per WebIDL:
- // http://www.w3.org/TR/WebIDL/#es-unsigned-long-long
- uint64_t toUInt64(v8::Handle<v8::Value>, IntegerConversionConfiguration, bool& ok);
-
- // Convert a value to a 64-bit unsigned integer assuming the conversion cannot fail.
- inline uint64_t toUInt64(v8::Handle<v8::Value> value)
+ template<typename T>
+ static v8::Handle<v8::Value> toV8Value(const PassRefPtr<T>& value, Context context, v8::Isolate* isolate)
{
- bool ok;
- return toUInt64(value, NormalConversion, ok);
+ return toV8Value(value.get(), context, isolate);
}
-
- inline float toFloat(v8::Local<v8::Value> value)
+ template<typename T>
+ static v8::Handle<v8::Value> toV8Value(const OwnPtr<T>& value, Context context, v8::Isolate* isolate)
{
- return static_cast<float>(value->NumberValue());
- }
-
- WrapperWorldType worldType(v8::Isolate*);
- WrapperWorldType worldTypeInMainThread(v8::Isolate*);
-
- DOMWrapperWorld* isolatedWorldForIsolate(v8::Isolate*);
-
- template<class T> struct NativeValueTraits;
-
- template<>
- struct NativeValueTraits<String> {
- static inline String nativeValue(const v8::Handle<v8::Value>& value, v8::Isolate* isolate)
- {
- V8TRYCATCH_FOR_V8STRINGRESOURCE_RETURN(V8StringResource<>, stringValue, value, String());
- return stringValue;
- }
- };
-
- template<>
- struct NativeValueTraits<unsigned> {
- static inline unsigned nativeValue(const v8::Handle<v8::Value>& value, v8::Isolate* isolate)
- {
- return toUInt32(value);
- }
- };
-
- template<>
- struct NativeValueTraits<float> {
- static inline float nativeValue(const v8::Handle<v8::Value>& value, v8::Isolate* isolate)
- {
- return static_cast<float>(value->NumberValue());
- }
- };
-
- template<>
- struct NativeValueTraits<double> {
- static inline double nativeValue(const v8::Handle<v8::Value>& value, v8::Isolate* isolate)
- {
- return static_cast<double>(value->NumberValue());
- }
- };
-
- template<>
- struct NativeValueTraits<v8::Handle<v8::Value> > {
- static inline v8::Handle<v8::Value> nativeValue(const v8::Handle<v8::Value>& value, v8::Isolate* isolate)
- {
- return value;
- }
- };
-
- // Converts a JavaScript value to an array as per the Web IDL specification:
- // http://www.w3.org/TR/2012/CR-WebIDL-20120419/#es-array
- template <class T, class V8T>
- Vector<RefPtr<T> > toRefPtrNativeArrayUnchecked(v8::Local<v8::Value> v8Value, uint32_t length, v8::Isolate* isolate, bool* success = 0)
- {
- Vector<RefPtr<T> > result;
- result.reserveInitialCapacity(length);
- v8::Local<v8::Object> object = v8::Local<v8::Object>::Cast(v8Value);
- for (uint32_t i = 0; i < length; ++i) {
- v8::Handle<v8::Value> element = object->Get(i);
-
- if (V8T::hasInstance(element, isolate, worldType(isolate))) {
- v8::Handle<v8::Object> elementObject = v8::Handle<v8::Object>::Cast(element);
- result.uncheckedAppend(V8T::toNative(elementObject));
- } else {
- if (success)
- *success = false;
- throwTypeError("Invalid Array element type", isolate);
- return Vector<RefPtr<T> >();
- }
- }
- return result;
+ return toV8Value(value.get(), context, isolate);
}
-
- template <class T, class V8T>
- Vector<RefPtr<T> > toRefPtrNativeArray(v8::Handle<v8::Value> value, int argumentIndex, v8::Isolate* isolate, bool* success = 0)
+ template<typename T>
+ static v8::Handle<v8::Value> toV8Value(const PassOwnPtr<T>& value, Context context, v8::Isolate* isolate)
{
- if (success)
- *success = true;
-
- v8::Local<v8::Value> v8Value(v8::Local<v8::Value>::New(isolate, value));
- uint32_t length = 0;
- if (value->IsArray()) {
- length = v8::Local<v8::Array>::Cast(v8Value)->Length();
- } else if (toV8Sequence(value, length, isolate).IsEmpty()) {
- throwTypeError(ExceptionMessages::notAnArrayTypeArgumentOrValue(argumentIndex), isolate);
- return Vector<RefPtr<T> >();
- }
-
- return toRefPtrNativeArrayUnchecked<T, V8T>(v8Value, length, isolate, success);
+ return toV8Value(value.get(), context, isolate);
}
-
- template <class T, class V8T>
- Vector<RefPtr<T> > toRefPtrNativeArray(v8::Handle<v8::Value> value, const String& propertyName, v8::Isolate* isolate, bool* success = 0)
+ template<typename T>
+ static v8::Handle<v8::Value> toV8Value(const RawPtr<T>& value, Context context, v8::Isolate* isolate)
{
- if (success)
- *success = true;
-
- v8::Local<v8::Value> v8Value(v8::Local<v8::Value>::New(isolate, value));
- uint32_t length = 0;
- if (value->IsArray()) {
- length = v8::Local<v8::Array>::Cast(v8Value)->Length();
- } else if (toV8Sequence(value, length, isolate).IsEmpty()) {
- throwTypeError(ExceptionMessages::notASequenceTypeProperty(propertyName), isolate);
- return Vector<RefPtr<T> >();
- }
-
- return toRefPtrNativeArrayUnchecked<T, V8T>(v8Value, length, isolate, success);
+ return toV8Value(value.get(), context, isolate);
}
- // Converts a JavaScript value to an array as per the Web IDL specification:
- // http://www.w3.org/TR/2012/CR-WebIDL-20120419/#es-array
- template <class T>
- Vector<T> toNativeArray(v8::Handle<v8::Value> value, int argumentIndex, v8::Isolate* isolate)
+ // const char* should use V8ValueTraits.
+ static v8::Handle<v8::Value> toV8Value(const char* const& value, Context context, v8::Isolate* isolate)
{
- v8::Local<v8::Value> v8Value(v8::Local<v8::Value>::New(isolate, value));
- uint32_t length = 0;
- if (value->IsArray()) {
- length = v8::Local<v8::Array>::Cast(v8Value)->Length();
- } else if (toV8Sequence(value, length, isolate).IsEmpty()) {
- throwTypeError(ExceptionMessages::notAnArrayTypeArgumentOrValue(argumentIndex), isolate);
- return Vector<T>();
- }
-
- Vector<T> result;
- result.reserveInitialCapacity(length);
- typedef NativeValueTraits<T> TraitsType;
- v8::Local<v8::Object> object = v8::Local<v8::Object>::Cast(v8Value);
- for (uint32_t i = 0; i < length; ++i)
- result.uncheckedAppend(TraitsType::nativeValue(object->Get(i), isolate));
- return result;
- }
-
- template <class T>
- Vector<T> toNativeArguments(const v8::FunctionCallbackInfo<v8::Value>& info, int startIndex)
- {
- ASSERT(startIndex <= info.Length());
- Vector<T> result;
- typedef NativeValueTraits<T> TraitsType;
- int length = info.Length();
- result.reserveInitialCapacity(length);
- for (int i = startIndex; i < length; ++i)
- result.uncheckedAppend(TraitsType::nativeValue(info[i], info.GetIsolate()));
- return result;
- }
-
- // Validates that the passed object is a sequence type per WebIDL spec
- // http://www.w3.org/TR/2012/CR-WebIDL-20120419/#es-sequence
- inline v8::Handle<v8::Value> toV8Sequence(v8::Handle<v8::Value> value, uint32_t& length, v8::Isolate* isolate)
- {
- // Attempt converting to a sequence if the value is not already an array but is
- // any kind of object except for a native Date object or a native RegExp object.
- ASSERT(!value->IsArray());
- // FIXME: Do we really need to special case Date and RegExp object?
- // https://www.w3.org/Bugs/Public/show_bug.cgi?id=22806
- if (!value->IsObject() || value->IsDate() || value->IsRegExp()) {
- // The caller is responsible for reporting a TypeError.
- return v8Undefined();
- }
-
- v8::Local<v8::Value> v8Value(v8::Local<v8::Value>::New(isolate, value));
- v8::Local<v8::Object> object = v8::Local<v8::Object>::Cast(v8Value);
- v8::Local<v8::String> lengthSymbol = v8::String::NewFromUtf8(isolate, "length", v8::String::kInternalizedString, 6);
-
- // FIXME: The specification states that the length property should be used as fallback, if value
- // is not a platform object that supports indexed properties. If it supports indexed properties,
- // length should actually be one greater than value’s maximum indexed property index.
- V8TRYCATCH(v8::Local<v8::Value>, lengthValue, object->Get(lengthSymbol));
-
- if (lengthValue->IsUndefined() || lengthValue->IsNull()) {
- // The caller is responsible for reporting a TypeError.
- return v8Undefined();
- }
-
- V8TRYCATCH(uint32_t, sequenceLength, lengthValue->Int32Value());
- length = sequenceLength;
-
- return v8Value;
+ return V8ValueTraits<const char*>::toV8Value(value, context, isolate);
}
- PassRefPtr<NodeFilter> toNodeFilter(v8::Handle<v8::Value>, v8::Isolate*);
-
- inline bool isUndefinedOrNull(v8::Handle<v8::Value> value)
+ template<typename T, size_t inlineCapacity>
+ static v8::Handle<v8::Value> toV8Value(const Vector<T, inlineCapacity>& value, Context context, v8::Isolate* isolate)
{
- return value->IsNull() || value->IsUndefined();
+ return v8ArrayNoInline(value, context, isolate);
}
- // Returns true if the provided object is to be considered a 'host object', as used in the
- // HTML5 structured clone algorithm.
- inline bool isHostObject(v8::Handle<v8::Object> object)
+ template<typename T, size_t inlineCapacity>
+ static v8::Handle<v8::Value> toV8Value(const HeapVector<T, inlineCapacity>& value, Context context, v8::Isolate* isolate)
{
- // If the object has any internal fields, then we won't be able to serialize or deserialize
- // them; conveniently, this is also a quick way to detect DOM wrapper objects, because
- // the mechanism for these relies on data stored in these fields. We should
- // catch external array data as a special case.
- return object->InternalFieldCount() || object->HasIndexedPropertiesInExternalArrayData();
+ return v8ArrayNoInline(value, context, isolate);
}
- inline v8::Handle<v8::Boolean> v8Boolean(bool value, v8::Isolate* isolate)
+ template<typename T, size_t inlineCapacity>
+ static v8::Handle<v8::Value> toV8Value(const PersistentHeapVector<T, inlineCapacity>& value, Context context, v8::Isolate* isolate)
{
- return value ? v8::True(isolate) : v8::False(isolate);
+ return v8ArrayNoInline(static_cast<HeapVector<T, inlineCapacity> >(value), context, isolate);
}
+};
- // Since v8Boolean(value, isolate) crashes if we pass a null isolate,
- // we need to use v8BooleanWithCheck(value, isolate) if an isolate can be null.
- //
- // FIXME: Remove all null isolates from V8 bindings, and remove v8BooleanWithCheck(value, isolate).
- inline v8::Handle<v8::Boolean> v8BooleanWithCheck(bool value, v8::Isolate* isolate)
- {
- return isolate ? v8Boolean(value, isolate) : v8Boolean(value, v8::Isolate::GetCurrent());
- }
+// Result values for platform object 'deleter' methods,
+// http://www.w3.org/TR/WebIDL/#delete
+enum DeleteResult {
+ DeleteSuccess,
+ DeleteReject,
+ DeleteUnknownProperty
+};
- inline double toWebCoreDate(v8::Handle<v8::Value> object)
- {
- if (object->IsDate())
- return v8::Handle<v8::Date>::Cast(object)->ValueOf();
- if (object->IsNumber())
- return object->NumberValue();
- return std::numeric_limits<double>::quiet_NaN();
- }
+class V8IsolateInterruptor : public ThreadState::Interruptor {
+public:
+ explicit V8IsolateInterruptor(v8::Isolate* isolate) : m_isolate(isolate) { }
- inline v8::Handle<v8::Value> v8DateOrNull(double value, v8::Isolate* isolate)
+ static void onInterruptCallback(v8::Isolate* isolate, void* data)
{
- ASSERT(isolate);
- return std::isfinite(value) ? v8::Date::New(isolate, value) : v8::Handle<v8::Value>::Cast(v8::Null(isolate));
+ reinterpret_cast<V8IsolateInterruptor*>(data)->onInterrupted();
}
- inline v8::Handle<v8::String> v8AtomicString(v8::Isolate* isolate, const char* str)
+ virtual void requestInterrupt() OVERRIDE
{
- ASSERT(isolate);
- return v8::String::NewFromUtf8(isolate, str, v8::String::kInternalizedString, strlen(str));
+ m_isolate->RequestInterrupt(&onInterruptCallback, this);
}
- inline v8::Handle<v8::String> v8AtomicString(v8::Isolate* isolate, const char* str, size_t length)
+ virtual void clearInterrupt() OVERRIDE
{
- ASSERT(isolate);
- return v8::String::NewFromUtf8(isolate, str, v8::String::kInternalizedString, length);
+ m_isolate->ClearInterrupt();
}
+private:
+ v8::Isolate* m_isolate;
+};
- v8::Handle<v8::FunctionTemplate> createRawTemplate(v8::Isolate*);
-
- PassRefPtr<XPathNSResolver> toXPathNSResolver(v8::Handle<v8::Value>, v8::Isolate*);
+class V8TestingScope {
+public:
+ explicit V8TestingScope(v8::Isolate*);
+ ScriptState* scriptState() const;
+ v8::Isolate* isolate() const;
+ ~V8TestingScope();
- v8::Handle<v8::Object> toInnerGlobalObject(v8::Handle<v8::Context>);
- DOMWindow* toDOMWindow(v8::Handle<v8::Context>);
- ExecutionContext* toExecutionContext(v8::Handle<v8::Context>);
+private:
+ v8::HandleScope m_handleScope;
+ v8::Context::Scope m_contextScope;
+ RefPtr<ScriptState> m_scriptState;
+};
- DOMWindow* activeDOMWindow();
- ExecutionContext* activeExecutionContext();
- DOMWindow* firstDOMWindow();
- Document* currentDocument();
+void GetDevToolsFunctionInfo(v8::Handle<v8::Function>, v8::Isolate*, int& scriptId, String& resourceName, int& lineNumber);
+PassRefPtr<TraceEvent::ConvertableToTraceFormat> devToolsTraceEventData(ExecutionContext*, v8::Handle<v8::Function>, v8::Isolate*);
- // Returns the context associated with a ExecutionContext.
- v8::Local<v8::Context> toV8Context(ExecutionContext*, DOMWrapperWorld*);
-
- // Returns the frame object of the window object associated with
- // a context, if the window is currently being displayed in the Frame.
- Frame* toFrameIfNotDetached(v8::Handle<v8::Context>);
-
- inline DOMWrapperWorld* isolatedWorldForEnteredContext(v8::Isolate* isolate)
+class V8RethrowTryCatchScope FINAL {
+public:
+ explicit V8RethrowTryCatchScope(v8::TryCatch& block) : m_block(block) { }
+ ~V8RethrowTryCatchScope()
{
- v8::Handle<v8::Context> context = isolate->GetEnteredContext();
- if (context.IsEmpty())
- return 0;
- return DOMWrapperWorld::isolatedWorld(context);
+ // ReThrow() is a no-op if no exception has been caught, so always call.
+ m_block.ReThrow();
}
- // FIXME: This will be soon embedded in the generated code.
- template<class Collection> static void indexedPropertyEnumerator(const v8::PropertyCallbackInfo<v8::Array>& info)
- {
- Collection* collection = reinterpret_cast<Collection*>(info.Holder()->GetAlignedPointerFromInternalField(v8DOMWrapperObjectIndex));
- int length = collection->length();
- v8::Handle<v8::Array> properties = v8::Array::New(info.GetIsolate(), length);
- for (int i = 0; i < length; ++i) {
- // FIXME: Do we need to check that the item function returns a non-null value for this index?
- v8::Handle<v8::Integer> integer = v8::Integer::New(i, info.GetIsolate());
- properties->Set(integer, integer);
- }
- v8SetReturnValue(info, properties);
- }
-
- // If the current context causes out of memory, JavaScript setting
- // is disabled and it returns true.
- bool handleOutOfMemory();
- v8::Local<v8::Value> handleMaxRecursionDepthExceeded(v8::Isolate*);
-
- void crashIfV8IsDead();
+private:
+ v8::TryCatch& m_block;
+};
- template <class T>
- v8::Handle<T> unsafeHandleFromRawValue(const T* value)
+class V8ResetTryCatchScope FINAL {
+public:
+ explicit V8ResetTryCatchScope(v8::TryCatch& block) : m_block(block) { }
+ ~V8ResetTryCatchScope()
{
- const v8::Handle<T>* handle = reinterpret_cast<const v8::Handle<T>*>(&value);
- return *handle;
+ m_block.Reset();
}
- // Attaches |environment| to |function| and returns it.
- inline v8::Local<v8::Function> createClosure(v8::FunctionCallback function, v8::Handle<v8::Value> environment, v8::Isolate* isolate)
- {
- return v8::Function::New(isolate, function, environment);
- }
-
- v8::Local<v8::Value> getHiddenValueFromMainWorldWrapper(v8::Isolate*, ScriptWrappable*, v8::Handle<v8::String> key);
+private:
+ v8::TryCatch& m_block;
+};
- v8::Isolate* mainThreadIsolate();
- v8::Isolate* toIsolate(ExecutionContext*);
- v8::Isolate* toIsolate(Frame*);
-
- // Can only be called by blink::initialize
- void setMainThreadIsolate(v8::Isolate*);
-
- // Converts a DOM object to a v8 value.
- // This is a no-inline version of toV8(). If you want to call toV8()
- // without creating #include cycles, you can use this function instead.
- // Each specialized implementation will be generated.
- template<typename T>
- v8::Handle<v8::Value> toV8NoInline(T* impl, v8::Handle<v8::Object> creationContext, v8::Isolate*);
} // namespace WebCore
#endif // V8Binding_h
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/V8BindingMacros.h b/chromium/third_party/WebKit/Source/bindings/v8/V8BindingMacros.h
index 8098652e209..1abb3233b80 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/V8BindingMacros.h
+++ b/chromium/third_party/WebKit/Source/bindings/v8/V8BindingMacros.h
@@ -33,65 +33,84 @@
namespace WebCore {
-#define V8TRYCATCH(type, var, value) \
- type var; \
- { \
- v8::TryCatch block; \
- var = (value); \
- if (block.HasCaught()) \
- return block.ReThrow(); \
+// Naming scheme:
+// TO*_RETURNTYPE[_ARGTYPE]...
+// ...using _DEFAULT instead of _ANY..._ANY when returing a default value.
+
+#define TONATIVE_EXCEPTION(type, var, value) \
+ type var; \
+ { \
+ v8::TryCatch block; \
+ var = (value); \
+ if (UNLIKELY(block.HasCaught())) \
+ return block.ReThrow(); \
}
-#define V8TRYCATCH_RETURN(type, var, value, retVal) \
- type var; \
- { \
- v8::TryCatch block; \
- var = (value); \
- if (block.HasCaught()) { \
- block.ReThrow(); \
- return retVal; \
- } \
+#define TONATIVE_VOID_INTERNAL(var, value) \
+ var = (value); \
+ if (UNLIKELY(block.HasCaught())) \
+ return;
+
+#define TONATIVE_VOID(type, var, value) \
+ type var; \
+ { \
+ v8::TryCatch block; \
+ V8RethrowTryCatchScope rethrow(block); \
+ TONATIVE_VOID_INTERNAL(var, value); \
}
-#define V8TRYCATCH_VOID(type, var, value) \
- type var; \
- { \
- v8::TryCatch block; \
- var = (value); \
- if (block.HasCaught()) { \
- block.ReThrow(); \
- return; \
- } \
+#define TONATIVE_DEFAULT(type, var, value, retVal) \
+ type var; \
+ { \
+ v8::TryCatch block; \
+ var = (value); \
+ if (UNLIKELY(block.HasCaught())) { \
+ block.ReThrow(); \
+ return retVal; \
+ } \
}
-#define V8TRYCATCH_WITH_TYPECHECK_VOID(type, var, value, isolate) \
- type var; \
- { \
- bool ok = true; \
- { \
- v8::TryCatch block; \
- var = (value); \
- if (block.HasCaught()) { \
- block.ReThrow(); \
- return; \
- } \
- } \
- if (UNLIKELY(!ok)) { \
- throwUninformativeAndGenericTypeError(isolate); \
- return; \
- } \
+#define TONATIVE_VOID_EXCEPTIONSTATE_INTERNAL(var, value, exceptionState) \
+ var = (value); \
+ if (UNLIKELY(block.HasCaught() || exceptionState.throwIfNeeded())) \
+ return; \
+
+#define TONATIVE_VOID_EXCEPTIONSTATE(type, var, value, exceptionState) \
+ type var; \
+ { \
+ v8::TryCatch block; \
+ V8RethrowTryCatchScope rethrow(block); \
+ TONATIVE_VOID_EXCEPTIONSTATE_INTERNAL(var, value, exceptionState); \
}
-#define V8TRYCATCH_FOR_V8STRINGRESOURCE_RETURN(type, var, value, retVal) \
- type var(value); \
- if (!var.prepare()) \
- return retVal;
+#define TONATIVE_DEFAULT_EXCEPTIONSTATE(type, var, value, exceptionState, retVal) \
+ type var; \
+ { \
+ v8::TryCatch block; \
+ V8RethrowTryCatchScope rethrow(block); \
+ var = (value); \
+ if (UNLIKELY(block.HasCaught() || exceptionState.throwIfNeeded())) \
+ return retVal; \
+ }
+
+// type is an instance of class template V8StringResource<>,
+// but Mode argument varies; using type (not Mode) for consistency
+// with other macros and ease of code generation
+#define TOSTRING_VOID(type, var, value) \
+ type var(value); \
+ if (UNLIKELY(!var.prepare())) \
+ return;
-#define V8TRYCATCH_FOR_V8STRINGRESOURCE_VOID(type, var, value) \
- type var(value); \
- if (!var.prepare()) \
+#define TOSTRING_VOID_INTERNAL(var, value) \
+ var = (value); \
+ if (UNLIKELY(!var.prepare())) \
return;
+#define TOSTRING_DEFAULT(type, var, value, retVal) \
+ type var(value); \
+ if (UNLIKELY(!var.prepare())) \
+ return retVal;
+
} // namespace WebCore
#endif // V8BindingMacros_h
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/V8Callback.cpp b/chromium/third_party/WebKit/Source/bindings/v8/V8Callback.cpp
index ef56f45fcbc..b47b3daf58a 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/V8Callback.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/V8Callback.cpp
@@ -36,16 +36,16 @@
namespace WebCore {
-bool invokeCallback(v8::Local<v8::Function> callback, int argc, v8::Handle<v8::Value> argv[], ExecutionContext* executionContext, v8::Isolate* isolate)
+bool invokeCallback(ScriptState* scriptState, v8::Local<v8::Function> callback, int argc, v8::Handle<v8::Value> argv[])
{
- return invokeCallback(callback, isolate->GetCurrentContext()->Global(), argc, argv, executionContext, isolate);
+ return invokeCallback(scriptState, callback, scriptState->context()->Global(), argc, argv);
}
-bool invokeCallback(v8::Local<v8::Function> callback, v8::Handle<v8::Object> thisObject, int argc, v8::Handle<v8::Value> argv[], ExecutionContext* executionContext, v8::Isolate* isolate)
+bool invokeCallback(ScriptState* scriptState, v8::Local<v8::Function> callback, v8::Handle<v8::Value> thisValue, int argc, v8::Handle<v8::Value> argv[])
{
v8::TryCatch exceptionCatcher;
exceptionCatcher.SetVerbose(true);
- ScriptController::callFunction(executionContext, callback, thisObject, argc, argv, isolate);
+ ScriptController::callFunction(scriptState->executionContext(), callback, thisValue, argc, argv, scriptState->isolate());
return !exceptionCatcher.HasCaught();
}
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/V8Callback.h b/chromium/third_party/WebKit/Source/bindings/v8/V8Callback.h
index 6fad1b5c503..f6126243f27 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/V8Callback.h
+++ b/chromium/third_party/WebKit/Source/bindings/v8/V8Callback.h
@@ -31,8 +31,8 @@
#ifndef V8Callback_h
#define V8Callback_h
+#include "bindings/v8/ExceptionState.h"
#include "bindings/v8/V8Binding.h"
-#include "bindings/v8/V8Utilities.h"
#include "core/dom/ExceptionCode.h"
#include <v8.h>
@@ -41,9 +41,10 @@ namespace WebCore {
class ExecutionContext;
// Returns false if the callback threw an exception, true otherwise.
-bool invokeCallback(v8::Local<v8::Function> callback, int argc, v8::Handle<v8::Value> argv[], ExecutionContext*, v8::Isolate*);
-bool invokeCallback(v8::Local<v8::Function> callback, v8::Handle<v8::Object> thisObject, int argc, v8::Handle<v8::Value> argv[], ExecutionContext*, v8::Isolate*);
+bool invokeCallback(ScriptState*, v8::Local<v8::Function> callback, int argc, v8::Handle<v8::Value> argv[]);
+bool invokeCallback(ScriptState*, v8::Local<v8::Function> callback, v8::Handle<v8::Value> thisValue, int argc, v8::Handle<v8::Value> argv[]);
+// FIXME: This file is used only by V8GeolocationCustom.cpp. Remove the custom binding and this file.
enum CallbackAllowedValueFlag {
CallbackAllowUndefined = 1,
CallbackAllowNull = 1 << 1
@@ -53,7 +54,7 @@ typedef unsigned CallbackAllowedValueFlags;
// 'FunctionOnly' is assumed for the created callback.
template <typename V8CallbackType>
-PassOwnPtr<V8CallbackType> createFunctionOnlyCallback(v8::Local<v8::Value> value, bool& succeeded, v8::Isolate* isolate, CallbackAllowedValueFlags acceptedValues = 0)
+PassOwnPtr<V8CallbackType> createFunctionOnlyCallback(v8::Local<v8::Value> value, unsigned index, bool& succeeded, v8::Isolate* isolate, ExceptionState& exceptionState, CallbackAllowedValueFlags acceptedValues = 0)
{
succeeded = true;
@@ -65,11 +66,12 @@ PassOwnPtr<V8CallbackType> createFunctionOnlyCallback(v8::Local<v8::Value> value
if (!value->IsFunction()) {
succeeded = false;
- setDOMException(TypeMismatchError, isolate);
+ exceptionState.throwDOMException(TypeMismatchError, ExceptionMessages::argumentNullOrIncorrectType(index, "Function"));
+ exceptionState.throwIfNeeded();
return nullptr;
}
- return V8CallbackType::create(v8::Handle<v8::Function>::Cast(value), getExecutionContext());
+ return V8CallbackType::create(v8::Handle<v8::Function>::Cast(value), ScriptState::current(isolate));
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/V8CustomElementLifecycleCallbacks.cpp b/chromium/third_party/WebKit/Source/bindings/v8/V8CustomElementLifecycleCallbacks.cpp
index 29e1bc093de..aa03363d7d9 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/V8CustomElementLifecycleCallbacks.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/V8CustomElementLifecycleCallbacks.cpp
@@ -31,14 +31,15 @@
#include "config.h"
#include "bindings/v8/V8CustomElementLifecycleCallbacks.h"
-#include "V8Element.h"
+#include "bindings/core/v8/V8Element.h"
#include "bindings/v8/CustomElementBinding.h"
#include "bindings/v8/DOMDataStore.h"
#include "bindings/v8/ScriptController.h"
#include "bindings/v8/V8Binding.h"
-#include "bindings/v8/V8HiddenPropertyName.h"
+#include "bindings/v8/V8HiddenValue.h"
#include "bindings/v8/V8PerContextData.h"
#include "core/dom/ExecutionContext.h"
+#include "core/inspector/InspectorInstrumentation.h"
#include "wtf/PassOwnPtr.h"
namespace WebCore {
@@ -49,20 +50,20 @@ namespace WebCore {
V(detached, Detached) \
V(attributeChanged, AttributeChanged)
-PassRefPtr<V8CustomElementLifecycleCallbacks> V8CustomElementLifecycleCallbacks::create(ExecutionContext* executionContext, v8::Handle<v8::Object> prototype, v8::Handle<v8::Function> created, v8::Handle<v8::Function> attached, v8::Handle<v8::Function> detached, v8::Handle<v8::Function> attributeChanged)
+PassRefPtr<V8CustomElementLifecycleCallbacks> V8CustomElementLifecycleCallbacks::create(ScriptState* scriptState, v8::Handle<v8::Object> prototype, v8::Handle<v8::Function> created, v8::Handle<v8::Function> attached, v8::Handle<v8::Function> detached, v8::Handle<v8::Function> attributeChanged)
{
- v8::Isolate* isolate = toIsolate(executionContext);
+ v8::Isolate* isolate = scriptState->isolate();
// A given object can only be used as a Custom Element prototype
// once; see customElementIsInterfacePrototypeObject
-#define SET_HIDDEN_PROPERTY(Value, Name) \
- ASSERT(prototype->GetHiddenValue(V8HiddenPropertyName::customElement##Name(isolate)).IsEmpty()); \
+#define SET_HIDDEN_VALUE(Value, Name) \
+ ASSERT(V8HiddenValue::getHiddenValue(isolate, prototype, V8HiddenValue::customElement##Name(isolate)).IsEmpty()); \
if (!Value.IsEmpty()) \
- prototype->SetHiddenValue(V8HiddenPropertyName::customElement##Name(isolate), Value);
+ V8HiddenValue::setHiddenValue(isolate, prototype, V8HiddenValue::customElement##Name(isolate), Value);
- CALLBACK_LIST(SET_HIDDEN_PROPERTY)
-#undef SET_HIDDEN_PROPERTY
+ CALLBACK_LIST(SET_HIDDEN_VALUE)
+#undef SET_HIDDEN_VALUE
- return adoptRef(new V8CustomElementLifecycleCallbacks(executionContext, prototype, created, attached, detached, attributeChanged));
+ return adoptRef(new V8CustomElementLifecycleCallbacks(scriptState, prototype, created, attached, detached, attributeChanged));
}
static CustomElementLifecycleCallbacks::CallbackType flagSet(v8::Handle<v8::Function> attached, v8::Handle<v8::Function> detached, v8::Handle<v8::Function> attributeChanged)
@@ -88,16 +89,16 @@ static void weakCallback(const v8::WeakCallbackData<T, ScopedPersistent<T> >& da
data.GetParameter()->clear();
}
-V8CustomElementLifecycleCallbacks::V8CustomElementLifecycleCallbacks(ExecutionContext* executionContext, v8::Handle<v8::Object> prototype, v8::Handle<v8::Function> created, v8::Handle<v8::Function> attached, v8::Handle<v8::Function> detached, v8::Handle<v8::Function> attributeChanged)
+V8CustomElementLifecycleCallbacks::V8CustomElementLifecycleCallbacks(ScriptState* scriptState, v8::Handle<v8::Object> prototype, v8::Handle<v8::Function> created, v8::Handle<v8::Function> attached, v8::Handle<v8::Function> detached, v8::Handle<v8::Function> attributeChanged)
: CustomElementLifecycleCallbacks(flagSet(attached, detached, attributeChanged))
- , ActiveDOMCallback(executionContext)
+ , ContextLifecycleObserver(scriptState->executionContext())
, m_owner(0)
- , m_world(DOMWrapperWorld::current())
- , m_prototype(toIsolate(executionContext), prototype)
- , m_created(toIsolate(executionContext), created)
- , m_attached(toIsolate(executionContext), attached)
- , m_detached(toIsolate(executionContext), detached)
- , m_attributeChanged(toIsolate(executionContext), attributeChanged)
+ , m_scriptState(scriptState)
+ , m_prototype(scriptState->isolate(), prototype)
+ , m_created(scriptState->isolate(), created)
+ , m_attached(scriptState->isolate(), attached)
+ , m_detached(scriptState->isolate(), detached)
+ , m_attributeChanged(scriptState->isolate(), attributeChanged)
{
m_prototype.setWeak(&m_prototype, weakCallback<v8::Object>);
@@ -114,7 +115,7 @@ V8PerContextData* V8CustomElementLifecycleCallbacks::creationContextData()
if (!executionContext())
return 0;
- v8::Handle<v8::Context> context = toV8Context(executionContext(), m_world.get());
+ v8::Handle<v8::Context> context = m_scriptState->context();
if (context.IsEmpty())
return 0;
@@ -126,7 +127,7 @@ V8CustomElementLifecycleCallbacks::~V8CustomElementLifecycleCallbacks()
if (!m_owner)
return;
- v8::HandleScope handleScope(toIsolate(executionContext()));
+ v8::HandleScope handleScope(m_scriptState->isolate());
if (V8PerContextData* perContextData = creationContextData())
perContextData->clearCustomElementBinding(m_owner);
}
@@ -149,20 +150,20 @@ bool V8CustomElementLifecycleCallbacks::setBinding(CustomElementDefinition* owne
void V8CustomElementLifecycleCallbacks::created(Element* element)
{
- if (!canInvokeCallback())
+ // FIXME: callbacks while paused should be queued up for execution to
+ // continue then be delivered in order rather than delivered immediately.
+ // Bug 329665 tracks similar behavior for other synchronous events.
+ if (!executionContext() || executionContext()->activeDOMObjectsAreStopped())
return;
element->setCustomElementState(Element::Upgraded);
- v8::Isolate* isolate = toIsolate(executionContext());
- v8::HandleScope handleScope(isolate);
- v8::Handle<v8::Context> context = toV8Context(executionContext(), m_world.get());
- if (context.IsEmpty())
+ if (m_scriptState->contextIsEmpty())
return;
-
- v8::Context::Scope scope(context);
-
- v8::Handle<v8::Object> receiver = DOMDataStore::current(isolate).get<V8Element>(element, isolate);
+ ScriptState::Scope scope(m_scriptState.get());
+ v8::Isolate* isolate = m_scriptState->isolate();
+ v8::Handle<v8::Context> context = m_scriptState->context();
+ v8::Handle<v8::Object> receiver = m_scriptState->world().domDataStore().get<V8Element>(element, isolate);
if (!receiver.IsEmpty()) {
// Swizzle the prototype of the existing wrapper. We don't need to
// worry about non-existent wrappers; they will get the right
@@ -182,6 +183,8 @@ void V8CustomElementLifecycleCallbacks::created(Element* element)
ASSERT(!receiver.IsEmpty());
+ InspectorInstrumentation::willExecuteCustomElementCallback(element);
+
v8::TryCatch exceptionCatcher;
exceptionCatcher.SetVerbose(true);
ScriptController::callFunction(executionContext(), callback, receiver, 0, 0, isolate);
@@ -199,17 +202,17 @@ void V8CustomElementLifecycleCallbacks::detached(Element* element)
void V8CustomElementLifecycleCallbacks::attributeChanged(Element* element, const AtomicString& name, const AtomicString& oldValue, const AtomicString& newValue)
{
- if (!canInvokeCallback())
+ // FIXME: callbacks while paused should be queued up for execution to
+ // continue then be delivered in order rather than delivered immediately.
+ // Bug 329665 tracks similar behavior for other synchronous events.
+ if (!executionContext() || executionContext()->activeDOMObjectsAreStopped())
return;
- v8::Isolate* isolate = toIsolate(executionContext());
- v8::HandleScope handleScope(isolate);
- v8::Handle<v8::Context> context = toV8Context(executionContext(), m_world.get());
- if (context.IsEmpty())
+ if (m_scriptState->contextIsEmpty())
return;
-
- v8::Context::Scope scope(context);
-
+ ScriptState::Scope scope(m_scriptState.get());
+ v8::Isolate* isolate = m_scriptState->isolate();
+ v8::Handle<v8::Context> context = m_scriptState->context();
v8::Handle<v8::Object> receiver = toV8(element, context->Global(), isolate).As<v8::Object>();
ASSERT(!receiver.IsEmpty());
@@ -223,6 +226,8 @@ void V8CustomElementLifecycleCallbacks::attributeChanged(Element* element, const
newValue.isNull() ? v8::Handle<v8::Value>(v8::Null(isolate)) : v8::Handle<v8::Value>(v8String(isolate, newValue))
};
+ InspectorInstrumentation::willExecuteCustomElementCallback(element);
+
v8::TryCatch exceptionCatcher;
exceptionCatcher.SetVerbose(true);
ScriptController::callFunction(executionContext(), callback, receiver, WTF_ARRAY_LENGTH(argv), argv, isolate);
@@ -230,17 +235,17 @@ void V8CustomElementLifecycleCallbacks::attributeChanged(Element* element, const
void V8CustomElementLifecycleCallbacks::call(const ScopedPersistent<v8::Function>& weakCallback, Element* element)
{
- if (!canInvokeCallback())
+ // FIXME: callbacks while paused should be queued up for execution to
+ // continue then be delivered in order rather than delivered immediately.
+ // Bug 329665 tracks similar behavior for other synchronous events.
+ if (!executionContext() || executionContext()->activeDOMObjectsAreStopped())
return;
- v8::HandleScope handleScope(toIsolate(executionContext()));
- v8::Handle<v8::Context> context = toV8Context(executionContext(), m_world.get());
- if (context.IsEmpty())
+ if (m_scriptState->contextIsEmpty())
return;
-
- v8::Context::Scope scope(context);
- v8::Isolate* isolate = context->GetIsolate();
-
+ ScriptState::Scope scope(m_scriptState.get());
+ v8::Isolate* isolate = m_scriptState->isolate();
+ v8::Handle<v8::Context> context = m_scriptState->context();
v8::Handle<v8::Function> callback = weakCallback.newLocal(isolate);
if (callback.IsEmpty())
return;
@@ -248,6 +253,8 @@ void V8CustomElementLifecycleCallbacks::call(const ScopedPersistent<v8::Function
v8::Handle<v8::Object> receiver = toV8(element, context->Global(), isolate).As<v8::Object>();
ASSERT(!receiver.IsEmpty());
+ InspectorInstrumentation::willExecuteCustomElementCallback(element);
+
v8::TryCatch exceptionCatcher;
exceptionCatcher.SetVerbose(true);
ScriptController::callFunction(executionContext(), callback, receiver, 0, 0, isolate);
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/V8CustomElementLifecycleCallbacks.h b/chromium/third_party/WebKit/Source/bindings/v8/V8CustomElementLifecycleCallbacks.h
index e911e2899cc..fe32ad90ef4 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/V8CustomElementLifecycleCallbacks.h
+++ b/chromium/third_party/WebKit/Source/bindings/v8/V8CustomElementLifecycleCallbacks.h
@@ -31,9 +31,9 @@
#ifndef V8CustomElementLifecycleCallbacks_h
#define V8CustomElementLifecycleCallbacks_h
-#include "bindings/v8/ActiveDOMCallback.h"
-#include "bindings/v8/DOMWrapperWorld.h"
#include "bindings/v8/ScopedPersistent.h"
+#include "bindings/v8/ScriptState.h"
+#include "core/dom/ContextLifecycleObserver.h"
#include "core/dom/custom/CustomElementLifecycleCallbacks.h"
#include "wtf/PassOwnPtr.h"
#include "wtf/PassRefPtr.h"
@@ -46,16 +46,16 @@ class Element;
class ExecutionContext;
class V8PerContextData;
-class V8CustomElementLifecycleCallbacks : public CustomElementLifecycleCallbacks, ActiveDOMCallback {
+class V8CustomElementLifecycleCallbacks FINAL : public CustomElementLifecycleCallbacks, ContextLifecycleObserver {
public:
- static PassRefPtr<V8CustomElementLifecycleCallbacks> create(ExecutionContext*, v8::Handle<v8::Object> prototype, v8::Handle<v8::Function> created, v8::Handle<v8::Function> attached, v8::Handle<v8::Function> detached, v8::Handle<v8::Function> attributeChanged);
+ static PassRefPtr<V8CustomElementLifecycleCallbacks> create(ScriptState*, v8::Handle<v8::Object> prototype, v8::Handle<v8::Function> created, v8::Handle<v8::Function> attached, v8::Handle<v8::Function> detached, v8::Handle<v8::Function> attributeChanged);
virtual ~V8CustomElementLifecycleCallbacks();
bool setBinding(CustomElementDefinition* owner, PassOwnPtr<CustomElementBinding>);
private:
- V8CustomElementLifecycleCallbacks(ExecutionContext*, v8::Handle<v8::Object> prototype, v8::Handle<v8::Function> created, v8::Handle<v8::Function> attached, v8::Handle<v8::Function> detached, v8::Handle<v8::Function> attributeChanged);
+ V8CustomElementLifecycleCallbacks(ScriptState*, v8::Handle<v8::Object> prototype, v8::Handle<v8::Function> created, v8::Handle<v8::Function> attached, v8::Handle<v8::Function> detached, v8::Handle<v8::Function> attributeChanged);
virtual void created(Element*) OVERRIDE;
virtual void attached(Element*) OVERRIDE;
@@ -67,7 +67,7 @@ private:
V8PerContextData* creationContextData();
CustomElementDefinition* m_owner;
- RefPtr<DOMWrapperWorld> m_world;
+ RefPtr<ScriptState> m_scriptState;
ScopedPersistent<v8::Object> m_prototype;
ScopedPersistent<v8::Function> m_created;
ScopedPersistent<v8::Function> m_attached;
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/V8DOMActivityLogger.cpp b/chromium/third_party/WebKit/Source/bindings/v8/V8DOMActivityLogger.cpp
new file mode 100644
index 00000000000..20ead4f4ce0
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/bindings/v8/V8DOMActivityLogger.cpp
@@ -0,0 +1,72 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "bindings/v8/V8DOMActivityLogger.h"
+
+#include "bindings/v8/V8Binding.h"
+#include "platform/weborigin/KURL.h"
+#include "wtf/HashMap.h"
+#include "wtf/MainThread.h"
+#include "wtf/text/StringHash.h"
+
+namespace WebCore {
+
+typedef HashMap<String, OwnPtr<V8DOMActivityLogger> > DOMActivityLoggerMapForMainWorld;
+typedef HashMap<int, OwnPtr<V8DOMActivityLogger>, WTF::IntHash<int>, WTF::UnsignedWithZeroKeyHashTraits<int> > DOMActivityLoggerMapForIsolatedWorld;
+
+static DOMActivityLoggerMapForMainWorld& domActivityLoggersForMainWorld()
+{
+ ASSERT(isMainThread());
+ DEFINE_STATIC_LOCAL(DOMActivityLoggerMapForMainWorld, map, ());
+ return map;
+}
+
+static DOMActivityLoggerMapForIsolatedWorld& domActivityLoggersForIsolatedWorld()
+{
+ ASSERT(isMainThread());
+ DEFINE_STATIC_LOCAL(DOMActivityLoggerMapForIsolatedWorld, map, ());
+ return map;
+}
+
+void V8DOMActivityLogger::setActivityLogger(int worldId, const String& extensionId, PassOwnPtr<V8DOMActivityLogger> logger)
+{
+ if (worldId)
+ domActivityLoggersForIsolatedWorld().set(worldId, logger);
+ else
+ domActivityLoggersForMainWorld().set(extensionId, logger);
+}
+
+V8DOMActivityLogger* V8DOMActivityLogger::activityLogger(int worldId, const String& extensionId)
+{
+ if (worldId) {
+ DOMActivityLoggerMapForIsolatedWorld& loggers = domActivityLoggersForIsolatedWorld();
+ DOMActivityLoggerMapForIsolatedWorld::iterator it = loggers.find(worldId);
+ return it == loggers.end() ? 0 : it->value.get();
+ }
+
+ if (extensionId.isEmpty())
+ return 0;
+
+ DOMActivityLoggerMapForMainWorld& loggers = domActivityLoggersForMainWorld();
+ DOMActivityLoggerMapForMainWorld::iterator it = loggers.find(extensionId);
+ return it == loggers.end() ? 0 : it->value.get();
+}
+
+V8DOMActivityLogger* V8DOMActivityLogger::activityLogger(int worldId, const KURL& url)
+{
+ // extension ID is ignored for worldId != 0.
+ if (worldId)
+ return activityLogger(worldId, String());
+
+ // To find an activity logger that corresponds to the main world of an
+ // extension, we need to obtain the extension ID. Extension ID is a hostname
+ // of a background page's URL.
+ if (!url.protocolIs("chrome-extension"))
+ return 0;
+
+ return activityLogger(worldId, url.host());
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/V8DOMActivityLogger.h b/chromium/third_party/WebKit/Source/bindings/v8/V8DOMActivityLogger.h
index 93915a65f2c..0f6b05c8e3c 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/V8DOMActivityLogger.h
+++ b/chromium/third_party/WebKit/Source/bindings/v8/V8DOMActivityLogger.h
@@ -31,16 +31,38 @@
#ifndef V8DOMActivityLogger_h
#define V8DOMActivityLogger_h
-#include <v8.h>
+#include "wtf/PassOwnPtr.h"
#include "wtf/text/WTFString.h"
+#include <v8.h>
namespace WebCore {
+class KURL;
+
class V8DOMActivityLogger {
public:
virtual ~V8DOMActivityLogger() { }
- virtual void log(const String& apiName, int argc, const v8::Handle<v8::Value>* argv, const String& extraInfo) { }
+ virtual void logGetter(const String& apiName) { }
+ virtual void logSetter(const String& apiName, const v8::Handle<v8::Value>& newValue) { }
+ virtual void logSetter(const String& apiName, const v8::Handle<v8::Value>& newValue, const v8::Handle<v8::Value>& oldValue) { }
+ virtual void logMethod(const String& apiName, int argc, const v8::Handle<v8::Value>* argv) { }
+
+ // Associates a logger with the world identified by worldId (worlId may be 0
+ // identifying the main world) and extension ID. Extension ID is used to
+ // identify a logger for main world only (worldId == 0). If the world is not
+ // a main world, an extension ID is ignored.
+ //
+ // A renderer process may host multiple extensions when the browser hits the
+ // renderer process limit. In such case, we assign multiple extensions to
+ // the same main world of a renderer process. In order to distinguish the
+ // extensions and their activity loggers in the main world, we require an
+ // extension ID. Otherwise, extension activities may be logged under
+ // a wrong extension ID.
+ static void setActivityLogger(int worldId, const String&, PassOwnPtr<V8DOMActivityLogger>);
+ static V8DOMActivityLogger* activityLogger(int worldId, const String& extensionId);
+ static V8DOMActivityLogger* activityLogger(int worldId, const KURL&);
+
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/V8DOMConfiguration.cpp b/chromium/third_party/WebKit/Source/bindings/v8/V8DOMConfiguration.cpp
index f92f9f0736e..13f2bf3659b 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/V8DOMConfiguration.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/V8DOMConfiguration.cpp
@@ -30,21 +30,24 @@
#include "bindings/v8/V8DOMConfiguration.h"
#include "bindings/v8/V8Binding.h"
+#include "bindings/v8/V8ObjectConstructor.h"
+#include "platform/TraceEvent.h"
namespace WebCore {
-void V8DOMConfiguration::installAttributes(v8::Handle<v8::ObjectTemplate> instanceTemplate, v8::Handle<v8::ObjectTemplate> prototype, const AttributeConfiguration* attributes, size_t attributeCount, v8::Isolate* isolate, WrapperWorldType currentWorldType)
+void V8DOMConfiguration::installAttributes(v8::Handle<v8::ObjectTemplate> instanceTemplate, v8::Handle<v8::ObjectTemplate> prototype, const AttributeConfiguration* attributes, size_t attributeCount, v8::Isolate* isolate)
{
for (size_t i = 0; i < attributeCount; ++i)
- installAttribute(instanceTemplate, prototype, attributes[i], isolate, currentWorldType);
+ installAttribute(instanceTemplate, prototype, attributes[i], isolate);
}
-void V8DOMConfiguration::installAccessors(v8::Handle<v8::ObjectTemplate> prototype, v8::Handle<v8::Signature> signature, const AccessorConfiguration* accessors, size_t accessorCount, v8::Isolate* isolate, WrapperWorldType currentWorldType)
+void V8DOMConfiguration::installAccessors(v8::Handle<v8::ObjectTemplate> prototype, v8::Handle<v8::Signature> signature, const AccessorConfiguration* accessors, size_t accessorCount, v8::Isolate* isolate)
{
+ bool isMainWorld = DOMWrapperWorld::current(isolate).isMainWorld();
for (size_t i = 0; i < accessorCount; ++i) {
v8::FunctionCallback getterCallback = accessors[i].getter;
v8::FunctionCallback setterCallback = accessors[i].setter;
- if (currentWorldType == MainWorld) {
+ if (isMainWorld) {
if (accessors[i].getterForMainWorld)
getterCallback = accessors[i].getterForMainWorld;
if (accessors[i].setterForMainWorld)
@@ -61,7 +64,7 @@ void V8DOMConfiguration::installAccessors(v8::Handle<v8::ObjectTemplate> prototy
setter = v8::FunctionTemplate::New(isolate, setterCallback, v8::External::New(isolate, const_cast<WrapperTypeInfo*>(accessors[i].data)), signature, 1);
setter->RemovePrototype();
}
- prototype->SetAccessorProperty(v8::String::NewFromUtf8(isolate, accessors[i].name, v8::String::kInternalizedString), getter, setter, accessors[i].attribute, accessors[i].settings);
+ prototype->SetAccessorProperty(v8AtomicString(isolate, accessors[i].name), getter, setter, accessors[i].attribute, accessors[i].settings);
}
}
@@ -69,20 +72,22 @@ void V8DOMConfiguration::installConstants(v8::Handle<v8::FunctionTemplate> funct
{
for (size_t i = 0; i < constantCount; ++i) {
const ConstantConfiguration* constant = &constants[i];
- functionDescriptor->Set(v8::String::NewFromUtf8(isolate, constant->name, v8::String::kInternalizedString), v8::Integer::New(isolate, constant->value), static_cast<v8::PropertyAttribute>(v8::ReadOnly | v8::DontDelete));
- prototype->Set(v8::String::NewFromUtf8(isolate, constant->name, v8::String::kInternalizedString), v8::Integer::New(isolate, constant->value), static_cast<v8::PropertyAttribute>(v8::ReadOnly | v8::DontDelete));
+ v8::Handle<v8::String> constantName = v8AtomicString(isolate, constant->name);
+ functionDescriptor->Set(constantName, v8::Integer::New(isolate, constant->value), static_cast<v8::PropertyAttribute>(v8::ReadOnly | v8::DontDelete));
+ prototype->Set(constantName, v8::Integer::New(isolate, constant->value), static_cast<v8::PropertyAttribute>(v8::ReadOnly | v8::DontDelete));
}
}
-void V8DOMConfiguration::installCallbacks(v8::Handle<v8::ObjectTemplate> prototype, v8::Handle<v8::Signature> signature, v8::PropertyAttribute attributes, const MethodConfiguration* callbacks, size_t callbackCount, v8::Isolate* isolate, WrapperWorldType currentWorldType)
+void V8DOMConfiguration::installCallbacks(v8::Handle<v8::ObjectTemplate> prototype, v8::Handle<v8::Signature> signature, v8::PropertyAttribute attributes, const MethodConfiguration* callbacks, size_t callbackCount, v8::Isolate* isolate)
{
+ bool isMainWorld = DOMWrapperWorld::current(isolate).isMainWorld();
for (size_t i = 0; i < callbackCount; ++i) {
v8::FunctionCallback callback = callbacks[i].callback;
- if (currentWorldType == MainWorld && callbacks[i].callbackForMainWorld)
+ if (isMainWorld && callbacks[i].callbackForMainWorld)
callback = callbacks[i].callbackForMainWorld;
v8::Local<v8::FunctionTemplate> functionTemplate = v8::FunctionTemplate::New(isolate, callback, v8Undefined(), signature, callbacks[i].length);
functionTemplate->RemovePrototype();
- prototype->Set(v8::String::NewFromUtf8(isolate, callbacks[i].name, v8::String::kInternalizedString), functionTemplate, attributes);
+ prototype->Set(v8AtomicString(isolate, callbacks[i].name), functionTemplate, attributes);
}
}
@@ -90,9 +95,9 @@ v8::Local<v8::Signature> V8DOMConfiguration::installDOMClassTemplate(v8::Handle<
const AttributeConfiguration* attributes, size_t attributeCount,
const AccessorConfiguration* accessors, size_t accessorCount,
const MethodConfiguration* callbacks, size_t callbackCount,
- v8::Isolate* isolate, WrapperWorldType currentWorldType)
+ v8::Isolate* isolate)
{
- functionDescriptor->SetClassName(v8::String::NewFromUtf8(isolate, interfaceName, v8::String::kInternalizedString));
+ functionDescriptor->SetClassName(v8AtomicString(isolate, interfaceName));
v8::Local<v8::ObjectTemplate> instanceTemplate = functionDescriptor->InstanceTemplate();
instanceTemplate->SetInternalFieldCount(fieldCount);
if (!parentClass.IsEmpty()) {
@@ -106,12 +111,26 @@ v8::Local<v8::Signature> V8DOMConfiguration::installDOMClassTemplate(v8::Handle<
v8::Local<v8::Signature> defaultSignature = v8::Signature::New(isolate, functionDescriptor);
if (attributeCount)
- installAttributes(instanceTemplate, functionDescriptor->PrototypeTemplate(), attributes, attributeCount, isolate, currentWorldType);
+ installAttributes(instanceTemplate, functionDescriptor->PrototypeTemplate(), attributes, attributeCount, isolate);
if (accessorCount)
- installAccessors(functionDescriptor->PrototypeTemplate(), defaultSignature, accessors, accessorCount, isolate, currentWorldType);
+ installAccessors(functionDescriptor->PrototypeTemplate(), defaultSignature, accessors, accessorCount, isolate);
if (callbackCount)
- installCallbacks(functionDescriptor->PrototypeTemplate(), defaultSignature, static_cast<v8::PropertyAttribute>(v8::DontDelete), callbacks, callbackCount, isolate, currentWorldType);
+ installCallbacks(functionDescriptor->PrototypeTemplate(), defaultSignature, static_cast<v8::PropertyAttribute>(v8::DontDelete), callbacks, callbackCount, isolate);
return defaultSignature;
}
+v8::Handle<v8::FunctionTemplate> V8DOMConfiguration::domClassTemplate(v8::Isolate* isolate, WrapperTypeInfo* wrapperTypeInfo, void (*configureDOMClassTemplate)(v8::Handle<v8::FunctionTemplate>, v8::Isolate*))
+{
+ V8PerIsolateData* data = V8PerIsolateData::from(isolate);
+ v8::Local<v8::FunctionTemplate> result = data->existingDOMTemplate(wrapperTypeInfo);
+ if (!result.IsEmpty())
+ return result;
+
+ TRACE_EVENT_SCOPED_SAMPLING_STATE("Blink", "BuildDOMTemplate");
+ result = v8::FunctionTemplate::New(isolate, V8ObjectConstructor::isValidConstructorMode);
+ configureDOMClassTemplate(result, isolate);
+ data->setDOMTemplate(wrapperTypeInfo, result);
+ return result;
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/V8DOMConfiguration.h b/chromium/third_party/WebKit/Source/bindings/v8/V8DOMConfiguration.h
index 18a2e3bf0d5..28b1e504aef 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/V8DOMConfiguration.h
+++ b/chromium/third_party/WebKit/Source/bindings/v8/V8DOMConfiguration.h
@@ -69,25 +69,14 @@ public:
v8::PropertyAttribute attribute;
};
- static void installAttributes(v8::Handle<v8::ObjectTemplate>, v8::Handle<v8::ObjectTemplate>, const AttributeConfiguration*, size_t attributeCount, v8::Isolate*, WrapperWorldType currentWorldType);
+ static void installAttributes(v8::Handle<v8::ObjectTemplate>, v8::Handle<v8::ObjectTemplate>, const AttributeConfiguration*, size_t attributeCount, v8::Isolate*);
template<class ObjectOrTemplate>
static inline void installAttribute(v8::Handle<ObjectOrTemplate> instanceTemplate, v8::Handle<ObjectOrTemplate> prototype, const AttributeConfiguration& attribute, v8::Isolate* isolate)
{
- (attribute.onPrototype ? prototype : instanceTemplate)->SetAccessor(v8::String::NewFromUtf8(isolate, attribute.name, v8::String::kInternalizedString),
- attribute.getter,
- attribute.setter,
- v8::External::New(isolate, const_cast<WrapperTypeInfo*>(attribute.data)),
- attribute.settings,
- attribute.attribute);
- }
-
- template<class ObjectOrTemplate>
- static inline void installAttribute(v8::Handle<ObjectOrTemplate> instanceTemplate, v8::Handle<ObjectOrTemplate> prototype, const AttributeConfiguration& attribute, v8::Isolate* isolate, WrapperWorldType currentWorldType)
- {
v8::AccessorGetterCallback getter = attribute.getter;
v8::AccessorSetterCallback setter = attribute.setter;
- if (currentWorldType == MainWorld) {
+ if (DOMWrapperWorld::current(isolate).isMainWorld()) {
if (attribute.getterForMainWorld)
getter = attribute.getterForMainWorld;
if (attribute.setterForMainWorld)
@@ -120,15 +109,17 @@ public:
int length;
};
- static void installCallbacks(v8::Handle<v8::ObjectTemplate>, v8::Handle<v8::Signature>, v8::PropertyAttribute, const MethodConfiguration*, size_t callbackCount, v8::Isolate*, WrapperWorldType);
+ static void installCallbacks(v8::Handle<v8::ObjectTemplate>, v8::Handle<v8::Signature>, v8::PropertyAttribute, const MethodConfiguration*, size_t callbackCount, v8::Isolate*);
- static void installAccessors(v8::Handle<v8::ObjectTemplate>, v8::Handle<v8::Signature>, const AccessorConfiguration*, size_t accessorCount, v8::Isolate*, WrapperWorldType);
+ static void installAccessors(v8::Handle<v8::ObjectTemplate>, v8::Handle<v8::Signature>, const AccessorConfiguration*, size_t accessorCount, v8::Isolate*);
static v8::Local<v8::Signature> installDOMClassTemplate(v8::Handle<v8::FunctionTemplate>, const char* interfaceName, v8::Handle<v8::FunctionTemplate> parentClass, size_t fieldCount,
const AttributeConfiguration*, size_t attributeCount,
const AccessorConfiguration*, size_t accessorCount,
const MethodConfiguration*, size_t callbackCount,
- v8::Isolate*, WrapperWorldType);
+ v8::Isolate*);
+
+ static v8::Handle<v8::FunctionTemplate> domClassTemplate(v8::Isolate*, WrapperTypeInfo*, void (*)(v8::Handle<v8::FunctionTemplate>, v8::Isolate*));
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/V8DOMWrapper.cpp b/chromium/third_party/WebKit/Source/bindings/v8/V8DOMWrapper.cpp
index 41dca146507..8a52d8c4296 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/V8DOMWrapper.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/V8DOMWrapper.cpp
@@ -31,11 +31,10 @@
#include "config.h"
#include "bindings/v8/V8DOMWrapper.h"
-#include "V8HTMLCollection.h"
-#include "V8HTMLDocument.h"
-#include "V8Window.h"
+#include "bindings/core/v8/V8HTMLCollection.h"
+#include "bindings/core/v8/V8HTMLDocument.h"
+#include "bindings/core/v8/V8Window.h"
#include "bindings/v8/V8Binding.h"
-#include "bindings/v8/V8HiddenPropertyName.h"
#include "bindings/v8/V8ObjectConstructor.h"
#include "bindings/v8/V8PerContextData.h"
#include "bindings/v8/V8ScriptRunner.h"
@@ -44,30 +43,28 @@ namespace WebCore {
static v8::Local<v8::Object> wrapInShadowTemplate(v8::Local<v8::Object> wrapper, Node* impl, v8::Isolate* isolate)
{
- // This is only for getting a unique pointer which we can pass to privateTemplate.
- static int shadowTemplateUniqueKey;
- WrapperWorldType currentWorldType = worldType(isolate);
+ static int shadowTemplateKey; // This address is used for a key to look up the dom template.
V8PerIsolateData* data = V8PerIsolateData::from(isolate);
- v8::Handle<v8::FunctionTemplate> shadowTemplate = data->privateTemplateIfExists(currentWorldType, &shadowTemplateUniqueKey);
+ v8::Handle<v8::FunctionTemplate> shadowTemplate = data->existingDOMTemplate(&shadowTemplateKey);
if (shadowTemplate.IsEmpty()) {
shadowTemplate = v8::FunctionTemplate::New(isolate);
if (shadowTemplate.IsEmpty())
return v8::Local<v8::Object>();
shadowTemplate->SetClassName(v8AtomicString(isolate, "HTMLDocument"));
- shadowTemplate->Inherit(V8HTMLDocument::domTemplate(isolate, currentWorldType));
+ shadowTemplate->Inherit(V8HTMLDocument::domTemplate(isolate));
shadowTemplate->InstanceTemplate()->SetInternalFieldCount(V8HTMLDocument::internalFieldCount);
- data->setPrivateTemplate(currentWorldType, &shadowTemplateUniqueKey, shadowTemplate);
+ data->setDOMTemplate(&shadowTemplateKey, shadowTemplate);
}
v8::Local<v8::Function> shadowConstructor = shadowTemplate->GetFunction();
if (shadowConstructor.IsEmpty())
return v8::Local<v8::Object>();
- v8::Local<v8::Object> shadow = V8ScriptRunner::instantiateObject(shadowConstructor);
+ v8::Local<v8::Object> shadow = V8ScriptRunner::instantiateObject(isolate, shadowConstructor);
if (shadow.IsEmpty())
return v8::Local<v8::Object>();
shadow->SetPrototype(wrapper);
- V8DOMWrapper::setNativeInfo(wrapper, &V8HTMLDocument::wrapperTypeInfo, impl);
+ V8DOMWrapper::setNativeInfoForHiddenWrapper(wrapper, &V8HTMLDocument::wrapperTypeInfo, impl);
return shadow;
}
@@ -76,7 +73,7 @@ v8::Local<v8::Object> V8DOMWrapper::createWrapper(v8::Handle<v8::Object> creatio
V8WrapperInstantiationScope scope(creationContext, isolate);
V8PerContextData* perContextData = V8PerContextData::from(scope.context());
- v8::Local<v8::Object> wrapper = perContextData ? perContextData->createWrapperFromCache(type) : V8ObjectConstructor::newInstance(type->domTemplate(isolate, worldTypeInMainThread(isolate))->GetFunction());
+ v8::Local<v8::Object> wrapper = perContextData ? perContextData->createWrapperFromCache(type) : V8ObjectConstructor::newInstance(isolate, type->domTemplate(isolate)->GetFunction());
if (type == &V8HTMLDocument::wrapperTypeInfo && !wrapper.IsEmpty())
wrapper = wrapInShadowTemplate(wrapper, static_cast<Node*>(impl), isolate);
@@ -84,59 +81,22 @@ v8::Local<v8::Object> V8DOMWrapper::createWrapper(v8::Handle<v8::Object> creatio
return wrapper;
}
-static bool hasInternalField(v8::Handle<v8::Value> value)
+bool V8DOMWrapper::isDOMWrapper(v8::Handle<v8::Value> value)
{
if (value.IsEmpty() || !value->IsObject())
return false;
- return v8::Handle<v8::Object>::Cast(value)->InternalFieldCount();
-}
-#ifndef NDEBUG
-bool V8DOMWrapper::maybeDOMWrapper(v8::Handle<v8::Value> value)
-{
- if (!hasInternalField(value))
- return false;
-
- v8::Handle<v8::Object> object = v8::Handle<v8::Object>::Cast(value);
- ASSERT(object->InternalFieldCount() >= v8DefaultWrapperInternalFieldCount);
-
- v8::HandleScope scope(v8::Isolate::GetCurrent());
- ASSERT(object->GetAlignedPointerFromInternalField(v8DOMWrapperObjectIndex));
-
- const WrapperTypeInfo* typeInfo = static_cast<const WrapperTypeInfo*>(object->GetAlignedPointerFromInternalField(v8DOMWrapperTypeIndex));
-
- return typeInfo->ginEmbedder == gin::kEmbedderBlink;
-}
-#endif
-
-bool V8DOMWrapper::isDOMWrapper(v8::Handle<v8::Value> value)
-{
- if (value.IsEmpty() || !value->IsObject())
+ if (v8::Handle<v8::Object>::Cast(value)->InternalFieldCount() < v8DefaultWrapperInternalFieldCount)
return false;
v8::Handle<v8::Object> wrapper = v8::Handle<v8::Object>::Cast(value);
- if (wrapper->InternalFieldCount() < v8DefaultWrapperInternalFieldCount)
- return false;
ASSERT(wrapper->GetAlignedPointerFromInternalField(v8DOMWrapperObjectIndex));
ASSERT(wrapper->GetAlignedPointerFromInternalField(v8DOMWrapperTypeIndex));
const WrapperTypeInfo* typeInfo = static_cast<const WrapperTypeInfo*>(wrapper->GetAlignedPointerFromInternalField(v8DOMWrapperTypeIndex));
-
- // FIXME: Add class id checks.
+ // FIXME: We should add a more strict way to check if the typeInfo is a typeInfo of some DOM wrapper.
+ // Even if it's a typeInfo of Blink, it's not guaranteed that it's a typeInfo of a DOM wrapper.
return typeInfo->ginEmbedder == gin::kEmbedderBlink;
}
-bool V8DOMWrapper::isWrapperOfType(v8::Handle<v8::Value> value, const WrapperTypeInfo* type)
-{
- if (!hasInternalField(value))
- return false;
-
- v8::Handle<v8::Object> wrapper = v8::Handle<v8::Object>::Cast(value);
- ASSERT(wrapper->InternalFieldCount() >= v8DefaultWrapperInternalFieldCount);
- ASSERT(wrapper->GetAlignedPointerFromInternalField(v8DOMWrapperObjectIndex));
-
- const WrapperTypeInfo* typeInfo = static_cast<const WrapperTypeInfo*>(wrapper->GetAlignedPointerFromInternalField(v8DOMWrapperTypeIndex));
- return typeInfo->ginEmbedder == gin::kEmbedderBlink && typeInfo == type;
-}
-
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/V8DOMWrapper.h b/chromium/third_party/WebKit/Source/bindings/v8/V8DOMWrapper.h
index 4bda879805b..db41c8f9034 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/V8DOMWrapper.h
+++ b/chromium/third_party/WebKit/Source/bindings/v8/V8DOMWrapper.h
@@ -34,6 +34,7 @@
#include "bindings/v8/DOMDataStore.h"
#include <v8.h>
#include "wtf/PassRefPtr.h"
+#include "wtf/RawPtr.h"
#include "wtf/text/AtomicString.h"
namespace WebCore {
@@ -42,60 +43,115 @@ struct WrapperTypeInfo;
class V8DOMWrapper {
public:
-#ifndef NDEBUG
- // Checks if a v8 value can be a DOM wrapper
- static bool maybeDOMWrapper(v8::Handle<v8::Value>);
-#endif
-
static v8::Local<v8::Object> createWrapper(v8::Handle<v8::Object> creationContext, const WrapperTypeInfo*, void*, v8::Isolate*);
template<typename V8T, typename T>
static inline v8::Handle<v8::Object> associateObjectWithWrapper(PassRefPtr<T>, const WrapperTypeInfo*, v8::Handle<v8::Object>, v8::Isolate*, WrapperConfiguration::Lifetime);
+ template<typename V8T, typename T>
+ static inline v8::Handle<v8::Object> associateObjectWithWrapper(RawPtr<T> object, const WrapperTypeInfo* wrapperTypeInfo, v8::Handle<v8::Object> wrapper, v8::Isolate* isolate, WrapperConfiguration::Lifetime lifetime)
+ {
+ return associateObjectWithWrapper<V8T, T>(object.get(), wrapperTypeInfo, wrapper, isolate, lifetime);
+ }
+ template<typename V8T, typename T>
+ static inline v8::Handle<v8::Object> associateObjectWithWrapper(T*, const WrapperTypeInfo*, v8::Handle<v8::Object>, v8::Isolate*, WrapperConfiguration::Lifetime);
static inline void setNativeInfo(v8::Handle<v8::Object>, const WrapperTypeInfo*, void*);
+ static inline void setNativeInfoForHiddenWrapper(v8::Handle<v8::Object>, const WrapperTypeInfo*, void*);
+ static inline void setNativeInfoWithPersistentHandle(v8::Handle<v8::Object>, const WrapperTypeInfo*, void*, PersistentNode*);
static inline void clearNativeInfo(v8::Handle<v8::Object>, const WrapperTypeInfo*);
static bool isDOMWrapper(v8::Handle<v8::Value>);
- static bool isWrapperOfType(v8::Handle<v8::Value>, const WrapperTypeInfo*);
};
- inline void V8DOMWrapper::setNativeInfo(v8::Handle<v8::Object> wrapper, const WrapperTypeInfo* type, void* object)
+ inline void V8DOMWrapper::setNativeInfo(v8::Handle<v8::Object> wrapper, const WrapperTypeInfo* wrapperTypeInfo, void* object)
+ {
+ ASSERT(wrapper->InternalFieldCount() >= 2);
+ ASSERT(object);
+ ASSERT(wrapperTypeInfo);
+#if ENABLE(OILPAN)
+ ASSERT(wrapperTypeInfo->gcType == RefCountedObject);
+#else
+ ASSERT(wrapperTypeInfo->gcType == RefCountedObject || wrapperTypeInfo->gcType == WillBeGarbageCollectedObject);
+#endif
+ wrapper->SetAlignedPointerInInternalField(v8DOMWrapperObjectIndex, object);
+ wrapper->SetAlignedPointerInInternalField(v8DOMWrapperTypeIndex, const_cast<WrapperTypeInfo*>(wrapperTypeInfo));
+ }
+
+ inline void V8DOMWrapper::setNativeInfoForHiddenWrapper(v8::Handle<v8::Object> wrapper, const WrapperTypeInfo* wrapperTypeInfo, void* object)
{
+ // see V8WindowShell::installDOMWindow() comment for why this version is needed and safe.
ASSERT(wrapper->InternalFieldCount() >= 2);
ASSERT(object);
- ASSERT(type);
+ ASSERT(wrapperTypeInfo);
+#if ENABLE(OILPAN)
+ ASSERT(wrapperTypeInfo->gcType != RefCountedObject);
+#else
+ ASSERT(wrapperTypeInfo->gcType == RefCountedObject || wrapperTypeInfo->gcType == WillBeGarbageCollectedObject);
+#endif
+
+ // Clear out the last internal field, which is assumed to contain a valid persistent pointer value.
+ if (wrapperTypeInfo->gcType == GarbageCollectedObject) {
+ wrapper->SetAlignedPointerInInternalField(wrapper->InternalFieldCount() - 1, 0);
+ } else if (wrapperTypeInfo->gcType == WillBeGarbageCollectedObject) {
+#if ENABLE(OILPAN)
+ wrapper->SetAlignedPointerInInternalField(wrapper->InternalFieldCount() - 1, 0);
+#endif
+ }
+ wrapper->SetAlignedPointerInInternalField(v8DOMWrapperObjectIndex, object);
+ wrapper->SetAlignedPointerInInternalField(v8DOMWrapperTypeIndex, const_cast<WrapperTypeInfo*>(wrapperTypeInfo));
+ }
+
+ inline void V8DOMWrapper::setNativeInfoWithPersistentHandle(v8::Handle<v8::Object> wrapper, const WrapperTypeInfo* wrapperTypeInfo, void* object, PersistentNode* handle)
+ {
+ ASSERT(wrapper->InternalFieldCount() >= 3);
+ ASSERT(object);
+ ASSERT(wrapperTypeInfo);
+ ASSERT(wrapperTypeInfo->gcType != RefCountedObject);
wrapper->SetAlignedPointerInInternalField(v8DOMWrapperObjectIndex, object);
- wrapper->SetAlignedPointerInInternalField(v8DOMWrapperTypeIndex, const_cast<WrapperTypeInfo*>(type));
+ wrapper->SetAlignedPointerInInternalField(v8DOMWrapperTypeIndex, const_cast<WrapperTypeInfo*>(wrapperTypeInfo));
+ // Persistent handle is stored in the last internal field.
+ wrapper->SetAlignedPointerInInternalField(wrapper->InternalFieldCount() - 1, handle);
}
- inline void V8DOMWrapper::clearNativeInfo(v8::Handle<v8::Object> wrapper, const WrapperTypeInfo* type)
+ inline void V8DOMWrapper::clearNativeInfo(v8::Handle<v8::Object> wrapper, const WrapperTypeInfo* wrapperTypeInfo)
{
ASSERT(wrapper->InternalFieldCount() >= 2);
- ASSERT(type);
- wrapper->SetAlignedPointerInInternalField(v8DOMWrapperTypeIndex, const_cast<WrapperTypeInfo*>(type));
+ ASSERT(wrapperTypeInfo);
+ // clearNativeInfo() is used only by NP objects, which are not garbage collected.
+ ASSERT(wrapperTypeInfo->gcType == RefCountedObject);
+ wrapper->SetAlignedPointerInInternalField(v8DOMWrapperTypeIndex, const_cast<WrapperTypeInfo*>(wrapperTypeInfo));
wrapper->SetAlignedPointerInInternalField(v8DOMWrapperObjectIndex, 0);
}
template<typename V8T, typename T>
- inline v8::Handle<v8::Object> V8DOMWrapper::associateObjectWithWrapper(PassRefPtr<T> object, const WrapperTypeInfo* type, v8::Handle<v8::Object> wrapper, v8::Isolate* isolate, WrapperConfiguration::Lifetime lifetime)
+ inline v8::Handle<v8::Object> V8DOMWrapper::associateObjectWithWrapper(PassRefPtr<T> object, const WrapperTypeInfo* wrapperTypeInfo, v8::Handle<v8::Object> wrapper, v8::Isolate* isolate, WrapperConfiguration::Lifetime lifetime)
{
- setNativeInfo(wrapper, type, V8T::toInternalPointer(object.get()));
- ASSERT(maybeDOMWrapper(wrapper));
+ setNativeInfo(wrapper, wrapperTypeInfo, V8T::toInternalPointer(object.get()));
+ ASSERT(isDOMWrapper(wrapper));
WrapperConfiguration configuration = buildWrapperConfiguration(object.get(), lifetime);
DOMDataStore::setWrapper<V8T>(object.leakRef(), wrapper, isolate, configuration);
return wrapper;
}
+ template<typename V8T, typename T>
+ inline v8::Handle<v8::Object> V8DOMWrapper::associateObjectWithWrapper(T* object, const WrapperTypeInfo* wrapperTypeInfo, v8::Handle<v8::Object> wrapper, v8::Isolate* isolate, WrapperConfiguration::Lifetime lifetime)
+ {
+ setNativeInfoWithPersistentHandle(wrapper, wrapperTypeInfo, V8T::toInternalPointer(object), new Persistent<T>(object));
+ ASSERT(isDOMWrapper(wrapper));
+ WrapperConfiguration configuration = buildWrapperConfiguration(object, lifetime);
+ DOMDataStore::setWrapper<V8T>(object, wrapper, isolate, configuration);
+ return wrapper;
+ }
+
class V8WrapperInstantiationScope {
public:
V8WrapperInstantiationScope(v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
: m_didEnterContext(false)
, m_context(isolate->GetCurrentContext())
{
- // FIXME: Remove all empty creationContexts from caller sites.
- // If a creationContext is empty, we will end up creating a new object
- // in the context currently entered. This is wrong.
- if (creationContext.IsEmpty())
- return;
+ // creationContext should not be empty. Because if we have an
+ // empty creationContext, we will end up creating
+ // a new object in the context currently entered. This is wrong.
+ RELEASE_ASSERT(!creationContext.IsEmpty());
v8::Handle<v8::Context> contextForWrapper = creationContext->CreationContext();
// For performance, we enter the context only if the currently running context
// is different from the context that we are about to enter.
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/V8ErrorHandler.cpp b/chromium/third_party/WebKit/Source/bindings/v8/V8ErrorHandler.cpp
index 758eb47fedf..c72ac25806b 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/V8ErrorHandler.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/V8ErrorHandler.cpp
@@ -31,63 +31,61 @@
#include "config.h"
#include "bindings/v8/V8ErrorHandler.h"
-#include "V8ErrorEvent.h"
+#include "bindings/core/v8/V8ErrorEvent.h"
#include "bindings/v8/ScriptController.h"
#include "bindings/v8/V8Binding.h"
-#include "bindings/v8/V8HiddenPropertyName.h"
+#include "bindings/v8/V8HiddenValue.h"
#include "bindings/v8/V8ScriptRunner.h"
#include "core/dom/Document.h"
#include "core/dom/ExecutionContext.h"
#include "core/events/ErrorEvent.h"
-#include "core/events/ThreadLocalEventNames.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
namespace WebCore {
-V8ErrorHandler::V8ErrorHandler(v8::Local<v8::Object> listener, bool isInline, v8::Isolate* isolate)
- : V8EventListener(listener, isInline, isolate)
+V8ErrorHandler::V8ErrorHandler(v8::Local<v8::Object> listener, bool isInline, ScriptState* scriptState)
+ : V8EventListener(listener, isInline, scriptState)
{
}
-v8::Local<v8::Value> V8ErrorHandler::callListenerFunction(ExecutionContext* context, v8::Handle<v8::Value> jsEvent, Event* event)
+v8::Local<v8::Value> V8ErrorHandler::callListenerFunction(v8::Handle<v8::Value> jsEvent, Event* event)
{
if (!event->hasInterface(EventNames::ErrorEvent))
- return V8EventListener::callListenerFunction(context, jsEvent, event);
+ return V8EventListener::callListenerFunction(jsEvent, event);
ErrorEvent* errorEvent = static_cast<ErrorEvent*>(event);
- v8::Isolate* isolate = toV8Context(context, world())->GetIsolate();
- if (errorEvent->world() && errorEvent->world() != world())
- return v8::Null(isolate);
+ if (errorEvent->world() && errorEvent->world() != &world())
+ return v8::Null(isolate());
- v8::Local<v8::Object> listener = getListenerObject(context);
+ v8::Local<v8::Object> listener = getListenerObject(scriptState()->executionContext());
v8::Local<v8::Value> returnValue;
if (!listener.IsEmpty() && listener->IsFunction()) {
v8::Local<v8::Function> callFunction = v8::Local<v8::Function>::Cast(listener);
- v8::Local<v8::Object> thisValue = isolate->GetCurrentContext()->Global();
+ v8::Local<v8::Object> thisValue = scriptState()->context()->Global();
- v8::Local<v8::Value> error = jsEvent->ToObject()->GetHiddenValue(V8HiddenPropertyName::error(isolate));
+ v8::Local<v8::Value> error = V8HiddenValue::getHiddenValue(isolate(), jsEvent->ToObject(), V8HiddenValue::error(isolate()));
if (error.IsEmpty())
- error = v8::Null(isolate);
+ error = v8::Null(isolate());
- v8::Handle<v8::Value> parameters[5] = { v8String(isolate, errorEvent->message()), v8String(isolate, errorEvent->filename()), v8::Integer::New(errorEvent->lineno(), isolate), v8::Integer::New(errorEvent->colno(), isolate), error };
+ v8::Handle<v8::Value> parameters[5] = { v8String(isolate(), errorEvent->message()), v8String(isolate(), errorEvent->filename()), v8::Integer::New(isolate(), errorEvent->lineno()), v8::Integer::New(isolate(), errorEvent->colno()), error };
v8::TryCatch tryCatch;
tryCatch.SetVerbose(true);
- if (worldType(isolate) == WorkerWorld)
- returnValue = V8ScriptRunner::callFunction(callFunction, context, thisValue, WTF_ARRAY_LENGTH(parameters), parameters, isolate);
+ if (scriptState()->executionContext()->isWorkerGlobalScope())
+ returnValue = V8ScriptRunner::callFunction(callFunction, scriptState()->executionContext(), thisValue, WTF_ARRAY_LENGTH(parameters), parameters, isolate());
else
- returnValue = ScriptController::callFunction(context, callFunction, thisValue, WTF_ARRAY_LENGTH(parameters), parameters, isolate);
+ returnValue = ScriptController::callFunction(scriptState()->executionContext(), callFunction, thisValue, WTF_ARRAY_LENGTH(parameters), parameters, isolate());
}
return returnValue;
}
// static
-void V8ErrorHandler::storeExceptionOnErrorEventWrapper(ErrorEvent* event, v8::Handle<v8::Value> data, v8::Isolate* isolate)
+void V8ErrorHandler::storeExceptionOnErrorEventWrapper(ErrorEvent* event, v8::Handle<v8::Value> data, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
{
- v8::Local<v8::Value> wrappedEvent = toV8(event, v8::Handle<v8::Object>(), isolate);
+ v8::Local<v8::Value> wrappedEvent = toV8(event, creationContext, isolate);
if (!wrappedEvent.IsEmpty()) {
ASSERT(wrappedEvent->IsObject());
- v8::Local<v8::Object>::Cast(wrappedEvent)->SetHiddenValue(V8HiddenPropertyName::error(isolate), data);
+ V8HiddenValue::setHiddenValue(isolate, v8::Local<v8::Object>::Cast(wrappedEvent), V8HiddenValue::error(isolate), data);
}
}
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/V8ErrorHandler.h b/chromium/third_party/WebKit/Source/bindings/v8/V8ErrorHandler.h
index cfaa69de587..8e1d5f22489 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/V8ErrorHandler.h
+++ b/chromium/third_party/WebKit/Source/bindings/v8/V8ErrorHandler.h
@@ -38,22 +38,22 @@
namespace WebCore {
class ErrorEvent;
-class Frame;
+class LocalFrame;
-class V8ErrorHandler : public V8EventListener {
+class V8ErrorHandler FINAL : public V8EventListener {
public:
- static PassRefPtr<V8ErrorHandler> create(v8::Local<v8::Object> listener, bool isInline, v8::Isolate* isolate)
+ static PassRefPtr<V8ErrorHandler> create(v8::Local<v8::Object> listener, bool isInline, ScriptState* scriptState)
{
- return adoptRef(new V8ErrorHandler(listener, isInline, isolate));
+ return adoptRef(new V8ErrorHandler(listener, isInline, scriptState));
}
- static void storeExceptionOnErrorEventWrapper(ErrorEvent*, v8::Handle<v8::Value>, v8::Isolate*);
+ static void storeExceptionOnErrorEventWrapper(ErrorEvent*, v8::Handle<v8::Value>, v8::Handle<v8::Object> creationContext, v8::Isolate*);
private:
- V8ErrorHandler(v8::Local<v8::Object> listener, bool isInline, v8::Isolate*);
+ V8ErrorHandler(v8::Local<v8::Object> listener, bool isInline, ScriptState*);
- virtual v8::Local<v8::Value> callListenerFunction(ExecutionContext*, v8::Handle<v8::Value> jsEvent, Event*);
- virtual bool shouldPreventDefault(v8::Local<v8::Value> returnValue);
+ virtual v8::Local<v8::Value> callListenerFunction(v8::Handle<v8::Value> jsEvent, Event*) OVERRIDE;
+ virtual bool shouldPreventDefault(v8::Local<v8::Value> returnValue) OVERRIDE;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/V8EventListener.cpp b/chromium/third_party/WebKit/Source/bindings/v8/V8EventListener.cpp
index 13144b96e9d..fc204607cee 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/V8EventListener.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/V8EventListener.cpp
@@ -34,19 +34,19 @@
#include "bindings/v8/ScriptController.h"
#include "bindings/v8/V8Binding.h"
#include "core/dom/Document.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
namespace WebCore {
-V8EventListener::V8EventListener(v8::Local<v8::Object> listener, bool isAttribute, v8::Isolate* isolate)
- : V8AbstractEventListener(isAttribute, DOMWrapperWorld::current(), isolate)
+V8EventListener::V8EventListener(v8::Local<v8::Object> listener, bool isAttribute, ScriptState* scriptState)
+ : V8AbstractEventListener(isAttribute, scriptState)
{
setListenerObject(listener);
}
-v8::Local<v8::Function> V8EventListener::getListenerFunction(ExecutionContext* context)
+v8::Local<v8::Function> V8EventListener::getListenerFunction(ExecutionContext*)
{
- v8::Local<v8::Object> listener = getListenerObject(context);
+ v8::Local<v8::Object> listener = getListenerObject(scriptState()->executionContext());
// Has the listener been disposed?
if (listener.IsEmpty())
@@ -67,22 +67,18 @@ v8::Local<v8::Function> V8EventListener::getListenerFunction(ExecutionContext* c
return v8::Local<v8::Function>();
}
-v8::Local<v8::Value> V8EventListener::callListenerFunction(ExecutionContext* context, v8::Handle<v8::Value> jsEvent, Event* event)
+v8::Local<v8::Value> V8EventListener::callListenerFunction(v8::Handle<v8::Value> jsEvent, Event* event)
{
- v8::Local<v8::Function> handlerFunction = getListenerFunction(context);
- v8::Local<v8::Object> receiver = getReceiverObject(context, event);
+ v8::Local<v8::Function> handlerFunction = getListenerFunction(scriptState()->executionContext());
+ v8::Local<v8::Object> receiver = getReceiverObject(event);
if (handlerFunction.IsEmpty() || receiver.IsEmpty())
return v8::Local<v8::Value>();
- // FIXME: Can |context| be 0 here?
- if (!context)
+ if (!scriptState()->executionContext()->isDocument())
return v8::Local<v8::Value>();
- if (!context->isDocument())
- return v8::Local<v8::Value>();
-
- Frame* frame = toDocument(context)->frame();
+ LocalFrame* frame = toDocument(scriptState()->executionContext())->frame();
if (!frame)
return v8::Local<v8::Value>();
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/V8EventListener.h b/chromium/third_party/WebKit/Source/bindings/v8/V8EventListener.h
index 1358848a5f1..93296ae659e 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/V8EventListener.h
+++ b/chromium/third_party/WebKit/Source/bindings/v8/V8EventListener.h
@@ -31,7 +31,6 @@
#ifndef V8EventListener_h
#define V8EventListener_h
-#include "bindings/v8/DOMWrapperWorld.h"
#include "bindings/v8/V8AbstractEventListener.h"
#include <v8.h>
#include "wtf/PassRefPtr.h"
@@ -39,23 +38,23 @@
namespace WebCore {
class Event;
- class Frame;
+ class LocalFrame;
// V8EventListener is a wrapper of a JS object implements EventListener interface (has handleEvent(event) method), or a JS function
// that can handle the event.
class V8EventListener : public V8AbstractEventListener {
public:
- static PassRefPtr<V8EventListener> create(v8::Local<v8::Object> listener, bool isAttribute, v8::Isolate* isolate)
+ static PassRefPtr<V8EventListener> create(v8::Local<v8::Object> listener, bool isAttribute, ScriptState* scriptState)
{
- return adoptRef(new V8EventListener(listener, isAttribute, isolate));
+ return adoptRef(new V8EventListener(listener, isAttribute, scriptState));
}
protected:
- V8EventListener(v8::Local<v8::Object> listener, bool isAttribute, v8::Isolate*);
+ V8EventListener(v8::Local<v8::Object> listener, bool isAttribute, ScriptState*);
v8::Local<v8::Function> getListenerFunction(ExecutionContext*);
- virtual v8::Local<v8::Value> callListenerFunction(ExecutionContext*, v8::Handle<v8::Value> jsEvent, Event*);
+ virtual v8::Local<v8::Value> callListenerFunction(v8::Handle<v8::Value> jsEvent, Event*) OVERRIDE;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/V8EventListenerList.cpp b/chromium/third_party/WebKit/Source/bindings/v8/V8EventListenerList.cpp
index 0606fb69fa6..ad44ef8bd1f 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/V8EventListenerList.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/V8EventListenerList.cpp
@@ -31,27 +31,24 @@
#include "config.h"
#include "bindings/v8/V8EventListenerList.h"
-#include "V8Window.h"
+#include "bindings/core/v8/V8Window.h"
#include "bindings/v8/V8Binding.h"
#include "bindings/v8/V8WorkerGlobalScopeEventListener.h"
namespace WebCore {
-PassRefPtr<EventListener> V8EventListenerList::getEventListener(v8::Local<v8::Value> value, bool isAttribute, ListenerLookupType lookup)
+PassRefPtr<EventListener> V8EventListenerList::getEventListener(ScriptState* scriptState, v8::Local<v8::Value> value, bool isAttribute, ListenerLookupType lookup)
{
- v8::Isolate* isolate = v8::Isolate::GetCurrent();
- v8::Handle<v8::Context> context = isolate->GetCurrentContext();
- if (context.IsEmpty())
- return 0;
+ ASSERT(!scriptState->contextIsEmpty());
if (lookup == ListenerFindOnly) {
// Used by EventTarget::removeEventListener, specifically
// EventTargetV8Internal::removeEventListenerMethod
ASSERT(!isAttribute);
- return V8EventListenerList::findWrapper(value, isolate);
+ return V8EventListenerList::findWrapper(value, scriptState);
}
- if (V8DOMWrapper::isWrapperOfType(toInnerGlobalObject(context), &V8Window::wrapperTypeInfo))
- return V8EventListenerList::findOrCreateWrapper<V8EventListener>(value, isAttribute, isolate);
- return V8EventListenerList::findOrCreateWrapper<V8WorkerGlobalScopeEventListener>(value, isAttribute, isolate);
+ if (toDOMWindow(scriptState->context()))
+ return V8EventListenerList::findOrCreateWrapper<V8EventListener>(value, isAttribute, scriptState);
+ return V8EventListenerList::findOrCreateWrapper<V8WorkerGlobalScopeEventListener>(value, isAttribute, scriptState);
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/V8EventListenerList.h b/chromium/third_party/WebKit/Source/bindings/v8/V8EventListenerList.h
index 3be3bb9f34f..34ee4106e01 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/V8EventListenerList.h
+++ b/chromium/third_party/WebKit/Source/bindings/v8/V8EventListenerList.h
@@ -31,15 +31,13 @@
#ifndef V8EventListenerList_h
#define V8EventListenerList_h
+#include "bindings/v8/V8Binding.h"
#include "bindings/v8/V8EventListener.h"
-#include "bindings/v8/V8HiddenPropertyName.h"
-
#include <v8.h>
-#include "wtf/PassRefPtr.h"
namespace WebCore {
-class Frame;
+class LocalFrame;
enum ListenerLookupType {
ListenerFindOnly,
@@ -49,18 +47,18 @@ enum ListenerLookupType {
// This is a container for V8EventListener objects that uses hidden properties of v8::Object to speed up lookups.
class V8EventListenerList {
public:
- static PassRefPtr<V8EventListener> findWrapper(v8::Local<v8::Value> value, v8::Isolate* isolate)
+ static PassRefPtr<V8EventListener> findWrapper(v8::Local<v8::Value> value, ScriptState* scriptState)
{
- ASSERT(isolate->InContext());
+ ASSERT(scriptState->isolate()->InContext());
if (!value->IsObject())
- return 0;
+ return nullptr;
- v8::Handle<v8::String> wrapperProperty = getHiddenProperty(false, isolate);
- return doFindWrapper(v8::Local<v8::Object>::Cast(value), wrapperProperty, isolate);
+ v8::Handle<v8::String> wrapperProperty = getHiddenProperty(false, scriptState->isolate());
+ return doFindWrapper(v8::Local<v8::Object>::Cast(value), wrapperProperty, scriptState);
}
template<typename WrapperType>
- static PassRefPtr<V8EventListener> findOrCreateWrapper(v8::Local<v8::Value>, bool isAttribute, v8::Isolate*);
+ static PassRefPtr<V8EventListener> findOrCreateWrapper(v8::Local<v8::Value>, bool isAttribute, ScriptState*);
static void clearWrapper(v8::Handle<v8::Object> listenerObject, bool isAttribute, v8::Isolate* isolate)
{
@@ -68,13 +66,13 @@ public:
listenerObject->DeleteHiddenValue(wrapperProperty);
}
- static PassRefPtr<EventListener> getEventListener(v8::Local<v8::Value>, bool isAttribute, ListenerLookupType);
+ static PassRefPtr<EventListener> getEventListener(ScriptState*, v8::Local<v8::Value>, bool isAttribute, ListenerLookupType);
private:
- static V8EventListener* doFindWrapper(v8::Local<v8::Object> object, v8::Handle<v8::String> wrapperProperty, v8::Isolate* isolate)
+ static V8EventListener* doFindWrapper(v8::Local<v8::Object> object, v8::Handle<v8::String> wrapperProperty, ScriptState* scriptState)
{
- ASSERT(isolate->InContext());
- v8::HandleScope scope(isolate);
+ v8::HandleScope scope(scriptState->isolate());
+ ASSERT(scriptState->isolate()->InContext());
v8::Local<v8::Value> listener = object->GetHiddenValue(wrapperProperty);
if (listener.IsEmpty())
return 0;
@@ -83,27 +81,28 @@ private:
static inline v8::Handle<v8::String> getHiddenProperty(bool isAttribute, v8::Isolate* isolate)
{
- return isAttribute ? V8HiddenPropertyName::attributeListener(isolate) : V8HiddenPropertyName::listener(isolate);
+ return isAttribute ? v8AtomicString(isolate, "attributeListener") : v8AtomicString(isolate, "listener");
}
};
template<typename WrapperType>
-PassRefPtr<V8EventListener> V8EventListenerList::findOrCreateWrapper(v8::Local<v8::Value> value, bool isAttribute, v8::Isolate* isolate)
+PassRefPtr<V8EventListener> V8EventListenerList::findOrCreateWrapper(v8::Local<v8::Value> value, bool isAttribute, ScriptState* scriptState)
{
+ v8::Isolate* isolate = scriptState->isolate();
ASSERT(isolate->InContext());
if (!value->IsObject()
// Non-callable attribute setter input is treated as null (no wrapper)
|| (isAttribute && !value->IsFunction()))
- return 0;
+ return nullptr;
v8::Local<v8::Object> object = v8::Local<v8::Object>::Cast(value);
v8::Handle<v8::String> wrapperProperty = getHiddenProperty(isAttribute, isolate);
- V8EventListener* wrapper = doFindWrapper(object, wrapperProperty, isolate);
+ V8EventListener* wrapper = doFindWrapper(object, wrapperProperty, scriptState);
if (wrapper)
return wrapper;
- RefPtr<V8EventListener> wrapperPtr = WrapperType::create(object, isAttribute, isolate);
+ RefPtr<V8EventListener> wrapperPtr = WrapperType::create(object, isAttribute, scriptState);
if (wrapperPtr)
object->SetHiddenValue(wrapperProperty, v8::External::New(isolate, wrapperPtr.get()));
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/V8GCController.cpp b/chromium/third_party/WebKit/Source/bindings/v8/V8GCController.cpp
index 133914ad9c4..b09bfe742a3 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/V8GCController.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/V8GCController.cpp
@@ -31,13 +31,12 @@
#include "config.h"
#include "bindings/v8/V8GCController.h"
-#include <algorithm>
-#include "V8MutationObserver.h"
-#include "V8Node.h"
-#include "V8ScriptRunner.h"
+#include "bindings/core/v8/V8MutationObserver.h"
+#include "bindings/core/v8/V8Node.h"
#include "bindings/v8/RetainedDOMInfo.h"
#include "bindings/v8/V8AbstractEventListener.h"
#include "bindings/v8/V8Binding.h"
+#include "bindings/v8/V8ScriptRunner.h"
#include "bindings/v8/WrapperTypeInfo.h"
#include "core/dom/Attr.h"
#include "core/dom/NodeTraversal.h"
@@ -46,8 +45,12 @@
#include "core/dom/shadow/ShadowRoot.h"
#include "core/html/HTMLImageElement.h"
#include "core/html/HTMLTemplateElement.h"
+#include "core/html/imports/HTMLImportsController.h"
+#include "core/inspector/InspectorTraceEvents.h"
#include "core/svg/SVGElement.h"
+#include "platform/Partitions.h"
#include "platform/TraceEvent.h"
+#include <algorithm>
namespace WebCore {
@@ -64,20 +67,23 @@ static void addReferencesForNodeWithEventListeners(v8::Isolate* isolate, Node* n
if (!v8listener->hasExistingListenerObject())
continue;
- // FIXME: update this to use the upcasting function which v8 will provide.
- v8::Persistent<v8::Value>* value = reinterpret_cast<v8::Persistent<v8::Value>*>(&(v8listener->existingListenerObjectPersistentHandle()));
- isolate->SetReference(wrapper, *value);
+ isolate->SetReference(wrapper, v8::Persistent<v8::Value>::Cast(v8listener->existingListenerObjectPersistentHandle()));
}
}
Node* V8GCController::opaqueRootForGC(Node* node, v8::Isolate*)
{
+ ASSERT(node);
// FIXME: Remove the special handling for image elements.
// The same special handling is in V8GCController::gcTree().
// Maybe should image elements be active DOM nodes?
// See https://code.google.com/p/chromium/issues/detail?id=164882
- if (node->inDocument() || (node->hasTagName(HTMLNames::imgTag) && toHTMLImageElement(node)->hasPendingActivity()))
- return &node->document();
+ if (node->inDocument() || (isHTMLImageElement(*node) && toHTMLImageElement(*node).hasPendingActivity())) {
+ Document& document = node->document();
+ if (HTMLImportsController* controller = document.importsController())
+ return controller->master();
+ return &document;
+ }
if (node->isAttributeNode()) {
Node* ownerElement = toAttr(node)->ownerElement();
@@ -117,12 +123,12 @@ public:
if (m_nodesInNewSpace.size() >= wrappersHandledByEachMinorGC)
return;
- // Casting to a Handle is safe here, since the Persistent cannot get GCd
+ // Casting to a Handle is safe here, since the Persistent doesn't get GCd
// during the GC prologue.
ASSERT((*reinterpret_cast<v8::Handle<v8::Value>*>(value))->IsObject());
v8::Handle<v8::Object>* wrapper = reinterpret_cast<v8::Handle<v8::Object>*>(value);
- ASSERT(V8DOMWrapper::maybeDOMWrapper(*wrapper));
- ASSERT(V8Node::hasInstanceInAnyWorld(*wrapper, m_isolate));
+ ASSERT(V8DOMWrapper::isDOMWrapper(*wrapper));
+ ASSERT(V8Node::hasInstance(*wrapper, m_isolate));
Node* node = V8Node::toNative(*wrapper);
// A minor DOM GC can handle only node wrappers in the main world.
// Note that node->wrapper().IsEmpty() returns true for nodes that
@@ -132,8 +138,18 @@ public:
ActiveDOMObject* activeDOMObject = type->toActiveDOMObject(*wrapper);
if (activeDOMObject && activeDOMObject->hasPendingActivity())
return;
+ // FIXME: Remove the special handling for image elements.
+ // The same special handling is in V8GCController::opaqueRootForGC().
+ // Maybe should image elements be active DOM nodes?
+ // See https://code.google.com/p/chromium/issues/detail?id=164882
+ if (isHTMLImageElement(*node) && toHTMLImageElement(*node).hasPendingActivity())
+ return;
+ // FIXME: Remove the special handling for SVG context elements.
+ if (node->isSVGElement() && toSVGElement(node)->isContextElement())
+ return;
+
m_nodesInNewSpace.append(node);
- node->setV8CollectableDuringMinorGC(true);
+ node->markV8CollectableDuringMinorGC();
}
}
@@ -144,82 +160,83 @@ public:
for (; nodeIterator < nodeIteratorEnd; ++nodeIterator) {
Node* node = *nodeIterator;
ASSERT(node->containsWrapper());
- if (node->isV8CollectableDuringMinorGC()) // This branch is just for performance.
+ if (node->isV8CollectableDuringMinorGC()) { // This branch is just for performance.
gcTree(m_isolate, node);
+ node->clearV8CollectableDuringMinorGC();
+ }
}
}
private:
- bool traverseTree(Node* rootNode, Vector<Node*, initialNodeVectorSize>* newSpaceNodes)
+ bool traverseTree(Node* rootNode, Vector<Node*, initialNodeVectorSize>* partiallyDependentNodes)
{
// To make each minor GC time bounded, we might need to give up
// traversing at some point for a large DOM tree. That being said,
// I could not observe the need even in pathological test cases.
for (Node* node = rootNode; node; node = NodeTraversal::next(*node)) {
if (node->containsWrapper()) {
- // FIXME: Remove the special handling for image elements.
- // FIXME: Remove the special handling for SVG context elements.
- // The same special handling is in V8GCController::opaqueRootForGC().
- // Maybe should image elements be active DOM nodes?
- // See https://code.google.com/p/chromium/issues/detail?id=164882
- if (!node->isV8CollectableDuringMinorGC() || (node->hasTagName(HTMLNames::imgTag) && toHTMLImageElement(node)->hasPendingActivity()) || (node->isSVGElement() && toSVGElement(node)->isContextElement())) {
+ if (!node->isV8CollectableDuringMinorGC()) {
// This node is not in the new space of V8. This indicates that
// the minor GC cannot anyway judge reachability of this DOM tree.
// Thus we give up traversing the DOM tree.
return false;
}
- node->setV8CollectableDuringMinorGC(false);
- newSpaceNodes->append(node);
+ node->clearV8CollectableDuringMinorGC();
+ partiallyDependentNodes->append(node);
}
if (ShadowRoot* shadowRoot = node->youngestShadowRoot()) {
- if (!traverseTree(shadowRoot, newSpaceNodes))
+ if (!traverseTree(shadowRoot, partiallyDependentNodes))
return false;
} else if (node->isShadowRoot()) {
if (ShadowRoot* shadowRoot = toShadowRoot(node)->olderShadowRoot()) {
- if (!traverseTree(shadowRoot, newSpaceNodes))
+ if (!traverseTree(shadowRoot, partiallyDependentNodes))
return false;
}
}
// <template> has a |content| property holding a DOM fragment which we must traverse,
// just like we do for the shadow trees above.
- if (node->hasTagName(HTMLNames::templateTag)) {
- if (!traverseTree(toHTMLTemplateElement(node)->content(), newSpaceNodes))
+ if (isHTMLTemplateElement(*node)) {
+ if (!traverseTree(toHTMLTemplateElement(*node).content(), partiallyDependentNodes))
return false;
}
+
+ // Document maintains the list of imported documents through HTMLImportsController.
+ if (node->isDocumentNode()) {
+ Document* document = toDocument(node);
+ HTMLImportsController* controller = document->importsController();
+ if (controller && document == controller->master()) {
+ for (unsigned i = 0; i < controller->loaderCount(); ++i) {
+ if (!traverseTree(controller->loaderDocumentAt(i), partiallyDependentNodes))
+ return false;
+ }
+ }
+ }
}
return true;
}
void gcTree(v8::Isolate* isolate, Node* startNode)
{
- Vector<Node*, initialNodeVectorSize> newSpaceNodes;
+ Vector<Node*, initialNodeVectorSize> partiallyDependentNodes;
Node* node = startNode;
while (Node* parent = node->parentOrShadowHostOrTemplateHostNode())
node = parent;
- if (!traverseTree(node, &newSpaceNodes))
+ if (!traverseTree(node, &partiallyDependentNodes))
return;
// We completed the DOM tree traversal. All wrappers in the DOM tree are
- // stored in newSpaceNodes and are expected to exist in the new space of V8.
+ // stored in partiallyDependentNodes and are expected to exist in the new space of V8.
// We report those wrappers to V8 as an object group.
- Node** nodeIterator = newSpaceNodes.begin();
- Node** const nodeIteratorEnd = newSpaceNodes.end();
+ Node** nodeIterator = partiallyDependentNodes.begin();
+ Node** const nodeIteratorEnd = partiallyDependentNodes.end();
if (nodeIterator == nodeIteratorEnd)
return;
- v8::UniqueId id(reinterpret_cast<intptr_t>((*nodeIterator)->unsafePersistent().value()));
+
+ Node* groupRoot = *nodeIterator;
for (; nodeIterator != nodeIteratorEnd; ++nodeIterator) {
- // This is safe because we know that GC won't happen before we
- // dispose the UnsafePersistent (we're just preparing a GC). Though,
- // we need to keep the UnsafePersistent alive until we're done with
- // v8::Persistent.
- UnsafePersistent<v8::Object> unsafeWrapper = (*nodeIterator)->unsafePersistent();
- v8::Persistent<v8::Object>* wrapper = unsafeWrapper.persistent();
- wrapper->MarkPartiallyDependent();
- // FIXME: update this to use the upcasting function which v8 will provide
- v8::Persistent<v8::Value>* value = reinterpret_cast<v8::Persistent<v8::Value>*>(wrapper);
- isolate->SetObjectGroupId(*value, id);
+ (*nodeIterator)->markAsDependentGroup(groupRoot, isolate);
}
}
@@ -238,16 +255,14 @@ public:
virtual void VisitPersistentHandle(v8::Persistent<v8::Value>* value, uint16_t classId) OVERRIDE
{
- // Casting to a Handle is safe here, since the Persistent cannot get GCd
- // during the GC prologue.
- ASSERT((*reinterpret_cast<v8::Handle<v8::Value>*>(value))->IsObject());
-
if (classId != v8DOMNodeClassId && classId != v8DOMObjectClassId)
return;
+ // Casting to a Handle is safe here, since the Persistent doesn't get GCd
+ // during the GC prologue.
+ ASSERT((*reinterpret_cast<v8::Handle<v8::Value>*>(value))->IsObject());
v8::Handle<v8::Object>* wrapper = reinterpret_cast<v8::Handle<v8::Object>*>(value);
-
- ASSERT(V8DOMWrapper::maybeDOMWrapper(*wrapper));
+ ASSERT(V8DOMWrapper::isDOMWrapper(*wrapper));
if (value->IsIndependent())
return;
@@ -255,26 +270,13 @@ public:
const WrapperTypeInfo* type = toWrapperTypeInfo(*wrapper);
void* object = toNative(*wrapper);
- if (V8MutationObserver::wrapperTypeInfo.equals(type)) {
- // FIXME: Allow opaqueRootForGC to operate on multiple roots and move this logic into V8MutationObserverCustom.
- MutationObserver* observer = static_cast<MutationObserver*>(object);
- HashSet<Node*> observedNodes = observer->getObservedNodes();
- for (HashSet<Node*>::iterator it = observedNodes.begin(); it != observedNodes.end(); ++it) {
- v8::UniqueId id(reinterpret_cast<intptr_t>(V8GCController::opaqueRootForGC(*it, m_isolate)));
- m_isolate->SetReferenceFromGroup(id, *value);
- }
- } else {
- ActiveDOMObject* activeDOMObject = type->toActiveDOMObject(*wrapper);
- if (activeDOMObject && activeDOMObject->hasPendingActivity())
- m_isolate->SetObjectGroupId(*value, liveRootId());
- }
+ ActiveDOMObject* activeDOMObject = type->toActiveDOMObject(*wrapper);
+ if (activeDOMObject && activeDOMObject->hasPendingActivity())
+ m_isolate->SetObjectGroupId(*value, liveRootId());
if (classId == v8DOMNodeClassId) {
- ASSERT(V8Node::hasInstanceInAnyWorld(*wrapper, m_isolate));
- ASSERT(!value->IsIndependent());
-
+ ASSERT(V8Node::hasInstance(*wrapper, m_isolate));
Node* node = static_cast<Node*>(object);
-
if (node->hasEventListeners())
addReferencesForNodeWithEventListeners(m_isolate, node, v8::Persistent<v8::Object>::Cast(*value));
Node* root = V8GCController::opaqueRootForGC(node, m_isolate);
@@ -282,9 +284,7 @@ public:
if (m_constructRetainedObjectInfos)
m_groupsWhichNeedRetainerInfo.append(root);
} else if (classId == v8DOMObjectClassId) {
- ASSERT(!value->IsIndependent());
- v8::Persistent<v8::Object>* wrapperPersistent = reinterpret_cast<v8::Persistent<v8::Object>*>(value);
- type->visitDOMWrapper(object, *wrapperPersistent, m_isolate);
+ type->visitDOMWrapper(object, v8::Persistent<v8::Object>::Cast(*value), m_isolate);
} else {
ASSERT_NOT_REACHED();
}
@@ -325,10 +325,18 @@ private:
bool m_constructRetainedObjectInfos;
};
+static unsigned long long usedHeapSize(v8::Isolate* isolate)
+{
+ v8::HeapStatistics heapStatistics;
+ isolate->GetHeapStatistics(&heapStatistics);
+ return heapStatistics.used_heap_size();
+}
+
void V8GCController::gcPrologue(v8::GCType type, v8::GCCallbackFlags flags)
{
// FIXME: It would be nice if the GC callbacks passed the Isolate directly....
v8::Isolate* isolate = v8::Isolate::GetCurrent();
+ TRACE_EVENT_BEGIN1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "GCEvent", "usedHeapSizeBefore", usedHeapSize(isolate));
if (type == v8::kGCTypeScavenge)
minorGCPrologue(isolate);
else if (type == v8::kGCTypeMarkSweepCompact)
@@ -340,14 +348,14 @@ void V8GCController::minorGCPrologue(v8::Isolate* isolate)
TRACE_EVENT_BEGIN0("v8", "minorGC");
if (isMainThread()) {
{
- TRACE_EVENT_SCOPED_SAMPLING_STATE("Blink", "MinorGC");
+ TRACE_EVENT_SCOPED_SAMPLING_STATE("Blink", "DOMMinorGC");
v8::HandleScope scope(isolate);
MinorGCWrapperVisitor visitor(isolate);
v8::V8::VisitHandlesForPartialDependence(isolate, &visitor);
visitor.notifyFinished();
}
V8PerIsolateData::from(isolate)->setPreviousSamplingState(TRACE_EVENT_GET_SAMPLING_STATE());
- TRACE_EVENT_SET_SAMPLING_STATE("V8", "MinorGC");
+ TRACE_EVENT_SET_SAMPLING_STATE("V8", "V8MinorGC");
}
}
@@ -358,13 +366,13 @@ void V8GCController::majorGCPrologue(bool constructRetainedObjectInfos, v8::Isol
TRACE_EVENT_BEGIN0("v8", "majorGC");
if (isMainThread()) {
{
- TRACE_EVENT_SCOPED_SAMPLING_STATE("Blink", "MajorGC");
+ TRACE_EVENT_SCOPED_SAMPLING_STATE("Blink", "DOMMajorGC");
MajorGCWrapperVisitor visitor(isolate, constructRetainedObjectInfos);
v8::V8::VisitHandlesWithClassIds(&visitor);
visitor.notifyFinished();
}
V8PerIsolateData::from(isolate)->setPreviousSamplingState(TRACE_EVENT_GET_SAMPLING_STATE());
- TRACE_EVENT_SET_SAMPLING_STATE("V8", "MajorGC");
+ TRACE_EVENT_SET_SAMPLING_STATE("V8", "V8MajorGC");
} else {
MajorGCWrapperVisitor visitor(isolate, constructRetainedObjectInfos);
v8::V8::VisitHandlesWithClassIds(&visitor);
@@ -380,6 +388,29 @@ void V8GCController::gcEpilogue(v8::GCType type, v8::GCCallbackFlags flags)
minorGCEpilogue(isolate);
else if (type == v8::kGCTypeMarkSweepCompact)
majorGCEpilogue(isolate);
+
+ // Forces a Blink heap garbage collection when a garbage collection
+ // was forced from V8. This is used for tests that force GCs from
+ // JavaScript to verify that objects die when expected.
+ if (flags & v8::kGCCallbackFlagForced) {
+ // This single GC is not enough for two reasons:
+ // (1) The GC is not precise because the GC scans on-stack pointers conservatively.
+ // (2) One GC is not enough to break a chain of persistent handles. It's possible that
+ // some heap allocated objects own objects that contain persistent handles
+ // pointing to other heap allocated objects. To break the chain, we need multiple GCs.
+ //
+ // Regarding (1), we force a precise GC at the end of the current event loop. So if you want
+ // to collect all garbage, you need to wait until the next event loop.
+ // Regarding (2), it would be OK in practice to trigger only one GC per gcEpilogue, because
+ // GCController.collectAll() forces 7 V8's GC.
+ Heap::collectGarbage(ThreadState::HeapPointersOnStack);
+
+ // Forces a precise GC at the end of the current event loop.
+ Heap::setForcePreciseGCForTesting();
+ }
+
+ TRACE_EVENT_END1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "GCEvent", "usedHeapSizeAfter", usedHeapSize(isolate));
+ TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "UpdateCounters", "data", InspectorUpdateCountersEvent::data());
}
void V8GCController::minorGCEpilogue(v8::Isolate* isolate)
@@ -398,25 +429,27 @@ void V8GCController::majorGCEpilogue(v8::Isolate* isolate)
TRACE_EVENT_SET_NONCONST_SAMPLING_STATE(V8PerIsolateData::from(isolate)->previousSamplingState());
}
-void V8GCController::hintForCollectGarbage()
+void V8GCController::collectGarbage(v8::Isolate* isolate)
{
- V8PerIsolateData* data = V8PerIsolateData::current();
- if (!data->shouldCollectGarbageSoon())
- return;
- const int longIdlePauseInMS = 1000;
- data->clearShouldCollectGarbageSoon();
- v8::V8::ContextDisposedNotification();
- v8::V8::IdleNotification(longIdlePauseInMS);
+ v8::HandleScope handleScope(isolate);
+ RefPtr<ScriptState> scriptState = ScriptState::create(v8::Context::New(isolate), DOMWrapperWorld::create());
+ ScriptState::Scope scope(scriptState.get());
+ V8ScriptRunner::compileAndRunInternalScript(v8String(isolate, "if (gc) gc();"), isolate);
+ scriptState->disposePerContextData();
}
-void V8GCController::collectGarbage(v8::Isolate* isolate)
+void V8GCController::reportDOMMemoryUsageToV8(v8::Isolate* isolate)
{
- v8::HandleScope handleScope(isolate);
- v8::Local<v8::Context> context = v8::Context::New(isolate);
- if (context.IsEmpty())
+ if (!isMainThread())
return;
- v8::Context::Scope contextScope(context);
- V8ScriptRunner::compileAndRunInternalScript(v8String(isolate, "if (gc) gc();"), isolate);
+
+ static size_t lastUsageReportedToV8 = 0;
+
+ size_t currentUsage = Partitions::currentDOMMemoryUsage();
+ int64_t diff = static_cast<int64_t>(currentUsage) - static_cast<int64_t>(lastUsageReportedToV8);
+ isolate->AdjustAmountOfExternalAllocatedMemory(diff);
+
+ lastUsageReportedToV8 = currentUsage;
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/V8GCController.h b/chromium/third_party/WebKit/Source/bindings/v8/V8GCController.h
index b0aa80227d5..b0c541a84b5 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/V8GCController.h
+++ b/chromium/third_party/WebKit/Source/bindings/v8/V8GCController.h
@@ -47,10 +47,11 @@ public:
static void majorGCPrologue(bool constructRetainedObjectInfos, v8::Isolate*);
static void majorGCEpilogue(v8::Isolate*);
- static void hintForCollectGarbage();
static void collectGarbage(v8::Isolate*);
static Node* opaqueRootForGC(Node*, v8::Isolate*);
+
+ static void reportDOMMemoryUsageToV8(v8::Isolate*);
};
}
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/V8GCForContextDispose.cpp b/chromium/third_party/WebKit/Source/bindings/v8/V8GCForContextDispose.cpp
index e7d40bd129e..688a212a30c 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/V8GCForContextDispose.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/V8GCForContextDispose.cpp
@@ -32,6 +32,7 @@
#include "bindings/v8/V8GCForContextDispose.h"
#include "wtf/StdLibExtras.h"
+#include <v8.h>
namespace WebCore {
@@ -46,7 +47,7 @@ void V8GCForContextDispose::notifyContextDisposed(bool isMainFrame)
m_didDisposeContextForMainFrame = m_didDisposeContextForMainFrame || isMainFrame;
v8::V8::ContextDisposedNotification();
if (!m_pseudoIdleTimer.isActive())
- m_pseudoIdleTimer.startOneShot(0.8);
+ m_pseudoIdleTimer.startOneShot(0.8, FROM_HERE);
}
void V8GCForContextDispose::notifyIdleSooner(double maximumFireInterval)
@@ -55,7 +56,7 @@ void V8GCForContextDispose::notifyIdleSooner(double maximumFireInterval)
double nextFireInterval = m_pseudoIdleTimer.nextFireInterval();
if (nextFireInterval > maximumFireInterval) {
m_pseudoIdleTimer.stop();
- m_pseudoIdleTimer.startOneShot(maximumFireInterval);
+ m_pseudoIdleTimer.startOneShot(maximumFireInterval, FROM_HERE);
}
}
}
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/V8GCForContextDispose.h b/chromium/third_party/WebKit/Source/bindings/v8/V8GCForContextDispose.h
index 3d16be47de2..53fbbfd53e3 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/V8GCForContextDispose.h
+++ b/chromium/third_party/WebKit/Source/bindings/v8/V8GCForContextDispose.h
@@ -31,7 +31,6 @@
#ifndef V8GCForContextDispose_h
#define V8GCForContextDispose_h
-#include <v8.h>
#include "platform/Timer.h"
namespace WebCore {
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/ScriptObject.cpp b/chromium/third_party/WebKit/Source/bindings/v8/V8GarbageCollected.h
index 36b1a54451a..697974839d9 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/ScriptObject.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/V8GarbageCollected.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 Google Inc. All rights reserved.
+ * Copyright (C) 2014 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
@@ -28,55 +28,62 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include "config.h"
-#include "bindings/v8/ScriptObject.h"
-
-#include "bindings/v8/ScriptScope.h"
-#include "bindings/v8/ScriptState.h"
-
-#include "V8InspectorFrontendHost.h"
+#ifndef V8GarbageCollected_h
+#define V8GarbageCollected_h
#include <v8.h>
namespace WebCore {
-ScriptObject::ScriptObject(ScriptState* scriptState, v8::Handle<v8::Object> v8Object)
- : ScriptValue(v8Object, scriptState->isolate())
- , m_scriptState(scriptState)
-{
-}
+template<typename T>
+class V8GarbageCollected {
+ WTF_MAKE_NONCOPYABLE(V8GarbageCollected);
+public:
+ static T* Cast(v8::Handle<v8::Value> value)
+ {
+ ASSERT(value->IsExternal());
+ T* result = static_cast<T*>(value.As<v8::External>()->Value());
+ RELEASE_ASSERT(result->m_handle == value);
+ return result;
+ }
-ScriptObject::ScriptObject(ScriptState* scriptState, const ScriptValue& scriptValue)
- : ScriptValue(scriptValue)
- , m_scriptState(scriptState)
-{
-}
+protected:
+ V8GarbageCollected(v8::Isolate* isolate)
+ : m_isolate(isolate)
+ , m_handle(isolate, v8::External::New(isolate, static_cast<T*>(this)))
+ , m_releasedToV8GarbageCollector(false)
+ {
+ }
-v8::Handle<v8::Object> ScriptObject::v8Object() const
-{
- ASSERT(v8Value()->IsObject());
- return v8::Handle<v8::Object>::Cast(v8Value());
-}
+ v8::Handle<v8::External> releaseToV8GarbageCollector()
+ {
+ ASSERT(!m_handle.isWeak()); // Call this exactly once.
+ m_releasedToV8GarbageCollector = true;
+ v8::Handle<v8::External> result = m_handle.newLocal(m_isolate);
+ m_handle.setWeak(static_cast<T*>(this), &weakCallback);
+ return result;
+ }
-bool ScriptGlobalObject::set(ScriptState* scriptState, const char* name, InspectorFrontendHost* value)
-{
- ScriptScope scope(scriptState);
- scope.global()->Set(v8AtomicString(scriptState->isolate(), name), toV8(value, v8::Handle<v8::Object>(), scriptState->isolate()));
- return scope.success();
-}
+ ~V8GarbageCollected()
+ {
+ ASSERT(!m_releasedToV8GarbageCollector || m_handle.isEmpty());
+ }
-bool ScriptGlobalObject::get(ScriptState* scriptState, const char* name, ScriptObject& value)
-{
- ScriptScope scope(scriptState);
- v8::Local<v8::Value> v8Value = scope.global()->Get(v8AtomicString(scriptState->isolate(), name));
- if (v8Value.IsEmpty())
- return false;
+ v8::Isolate* isolate() { return m_isolate; }
- if (!v8Value->IsObject())
- return false;
+private:
+ static void weakCallback(const v8::WeakCallbackData<v8::External, T>& data)
+ {
+ T* self = data.GetParameter();
+ self->m_handle.clear();
+ delete self;
+ }
- value = ScriptObject(scriptState, v8::Handle<v8::Object>::Cast(v8Value));
- return true;
-}
+ v8::Isolate* m_isolate;
+ ScopedPersistent<v8::External> m_handle;
+ bool m_releasedToV8GarbageCollector;
+};
} // namespace WebCore
+
+#endif // V8GarbageCollected_h
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/V8HiddenPropertyName.cpp b/chromium/third_party/WebKit/Source/bindings/v8/V8HiddenPropertyName.cpp
deleted file mode 100644
index 1108e9e7aa0..00000000000
--- a/chromium/third_party/WebKit/Source/bindings/v8/V8HiddenPropertyName.cpp
+++ /dev/null
@@ -1,79 +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 "bindings/v8/V8HiddenPropertyName.h"
-
-#include "bindings/v8/V8Binding.h"
-#include <string.h>
-#include "wtf/StdLibExtras.h"
-#include "wtf/Vector.h"
-
-namespace WebCore {
-
-#define V8_AS_STRING(x) V8_AS_STRING_IMPL(x)
-#define V8_AS_STRING_IMPL(x) #x
-
-#define V8_HIDDEN_PROPERTY_PREFIX "WebCore::HiddenProperty::"
-
-#define V8_DEFINE_HIDDEN_PROPERTY(name) \
-v8::Handle<v8::String> V8HiddenPropertyName::name(v8::Isolate* isolate) \
-{ \
- V8HiddenPropertyName* hiddenPropertyName = V8PerIsolateData::from(isolate)->hiddenPropertyName(); \
- if (hiddenPropertyName->m_##name.IsEmpty()) { \
- createString(V8_HIDDEN_PROPERTY_PREFIX V8_AS_STRING(name), &(hiddenPropertyName->m_##name), isolate); \
- } \
- return v8::Local<v8::String>::New(isolate, hiddenPropertyName->m_##name); \
-}
-
-V8_HIDDEN_PROPERTIES(V8_DEFINE_HIDDEN_PROPERTY);
-
-static v8::Handle<v8::String> hiddenReferenceName(const char* name, unsigned length)
-{
- ASSERT(length);
- Vector<char, 64> prefixedName;
- prefixedName.append(V8_HIDDEN_PROPERTY_PREFIX, sizeof(V8_HIDDEN_PROPERTY_PREFIX) - 1);
- prefixedName.append(name, length);
- return v8AtomicString(v8::Isolate::GetCurrent(), prefixedName.data(), static_cast<int>(prefixedName.size()));
-}
-
-void V8HiddenPropertyName::setNamedHiddenReference(v8::Handle<v8::Object> parent, const char* name, v8::Handle<v8::Value> child)
-{
- ASSERT(name);
- parent->SetHiddenValue(hiddenReferenceName(name, strlen(name)), child);
-}
-
-void V8HiddenPropertyName::createString(const char* key, v8::Persistent<v8::String>* handle, v8::Isolate* isolate)
-{
- v8::HandleScope scope(isolate);
- handle->Reset(isolate, v8AtomicString(isolate, key));
-}
-
-} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/V8HiddenPropertyName.h b/chromium/third_party/WebKit/Source/bindings/v8/V8HiddenPropertyName.h
deleted file mode 100644
index 76dc17ca1ae..00000000000
--- a/chromium/third_party/WebKit/Source/bindings/v8/V8HiddenPropertyName.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (C) 2012 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 V8HiddenPropertyName_h
-#define V8HiddenPropertyName_h
-
-#include <v8.h>
-
-namespace WebCore {
-
-#define V8_HIDDEN_PROPERTIES(V) \
- V(adaptorFunctionPeer) \
- V(attributeListener) \
- V(callback) \
- V(condition) \
- V(customElementAttached) \
- V(customElementAttributeChanged) \
- V(customElementCreated) \
- V(customElementDetached) \
- V(customElementDocument) \
- V(customElementIsInterfacePrototypeObject) \
- V(customElementNamespaceURI) \
- V(customElementTagName) \
- V(customElementType) \
- V(data) \
- V(detail) \
- V(document) \
- V(event) \
- V(error) \
- V(listener) \
- V(scriptState) \
- V(sleepFunction) \
- V(state) \
- V(toStringString) \
- V(typedArrayHiddenCopyMethod) \
- V(thenableHiddenPromise)
-
-class V8HiddenPropertyName {
-public:
- V8HiddenPropertyName() { }
-#define V8_DECLARE_PROPERTY(name) static v8::Handle<v8::String> name(v8::Isolate*);
- V8_HIDDEN_PROPERTIES(V8_DECLARE_PROPERTY);
-#undef V8_DECLARE_PROPERTY
-
- static void setNamedHiddenReference(v8::Handle<v8::Object> parent, const char* name, v8::Handle<v8::Value> child);
-
-private:
- static void createString(const char* key, v8::Persistent<v8::String>* handle, v8::Isolate*);
-#define V8_DECLARE_FIELD(name) v8::Persistent<v8::String> m_##name;
- V8_HIDDEN_PROPERTIES(V8_DECLARE_FIELD);
-#undef V8_DECLARE_FIELD
-};
-
-}
-
-#endif // V8HiddenPropertyName_h
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/V8HiddenValue.cpp b/chromium/third_party/WebKit/Source/bindings/v8/V8HiddenValue.cpp
new file mode 100644
index 00000000000..ab6e97d147c
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/bindings/v8/V8HiddenValue.cpp
@@ -0,0 +1,46 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "bindings/v8/V8HiddenValue.h"
+
+#include "bindings/v8/ScriptWrappable.h"
+#include "bindings/v8/V8Binding.h"
+
+namespace WebCore {
+
+#define V8_DEFINE_METHOD(name) \
+v8::Handle<v8::String> V8HiddenValue::name(v8::Isolate* isolate) \
+{ \
+ V8HiddenValue* hiddenValue = V8PerIsolateData::from(isolate)->hiddenValue(); \
+ if (hiddenValue->m_##name.isEmpty()) { \
+ hiddenValue->m_##name.set(isolate, v8AtomicString(isolate, #name)); \
+ } \
+ return hiddenValue->m_##name.newLocal(isolate); \
+}
+
+V8_HIDDEN_VALUES(V8_DEFINE_METHOD);
+
+v8::Local<v8::Value> V8HiddenValue::getHiddenValue(v8::Isolate* isolate, v8::Handle<v8::Object> object, v8::Handle<v8::String> key)
+{
+ return object->GetHiddenValue(key);
+}
+
+bool V8HiddenValue::setHiddenValue(v8::Isolate* isolate, v8::Handle<v8::Object> object, v8::Handle<v8::String> key, v8::Handle<v8::Value> value)
+{
+ return object->SetHiddenValue(key, value);
+}
+
+bool V8HiddenValue::deleteHiddenValue(v8::Isolate* isolate, v8::Handle<v8::Object> object, v8::Handle<v8::String> key)
+{
+ return object->DeleteHiddenValue(key);
+}
+
+v8::Local<v8::Value> V8HiddenValue::getHiddenValueFromMainWorldWrapper(v8::Isolate* isolate, ScriptWrappable* wrappable, v8::Handle<v8::String> key)
+{
+ v8::Local<v8::Object> wrapper = wrappable->newLocalWrapper(isolate);
+ return wrapper.IsEmpty() ? v8::Local<v8::Value>() : getHiddenValue(isolate, wrapper, key);
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/V8HiddenValue.h b/chromium/third_party/WebKit/Source/bindings/v8/V8HiddenValue.h
new file mode 100644
index 00000000000..75da4efe761
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/bindings/v8/V8HiddenValue.h
@@ -0,0 +1,61 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef V8HiddenValue_h
+#define V8HiddenValue_h
+
+#include "bindings/v8/ScopedPersistent.h"
+#include <v8.h>
+
+namespace WebCore {
+
+class ScriptWrappable;
+
+#define V8_HIDDEN_VALUES(V) \
+ V(arrayBufferData) \
+ V(customElementAttached) \
+ V(customElementAttributeChanged) \
+ V(customElementCreated) \
+ V(customElementDetached) \
+ V(customElementDocument) \
+ V(customElementIsInterfacePrototypeObject) \
+ V(customElementNamespaceURI) \
+ V(customElementTagName) \
+ V(customElementType) \
+ V(callback) \
+ V(condition) \
+ V(data) \
+ V(detail) \
+ V(document) \
+ V(error) \
+ V(event) \
+ V(idbCursorRequest) \
+ V(port1) \
+ V(port2) \
+ V(state) \
+ V(stringData) \
+ V(scriptState) \
+ V(thenableHiddenPromise) \
+ V(toStringString)
+
+class V8HiddenValue {
+public:
+#define V8_DECLARE_METHOD(name) static v8::Handle<v8::String> name(v8::Isolate* isolate);
+ V8_HIDDEN_VALUES(V8_DECLARE_METHOD);
+#undef V8_DECLARE_METHOD
+
+ static v8::Local<v8::Value> getHiddenValue(v8::Isolate*, v8::Handle<v8::Object>, v8::Handle<v8::String>);
+ static bool setHiddenValue(v8::Isolate*, v8::Handle<v8::Object>, v8::Handle<v8::String>, v8::Handle<v8::Value>);
+ static bool deleteHiddenValue(v8::Isolate*, v8::Handle<v8::Object>, v8::Handle<v8::String>);
+ static v8::Local<v8::Value> getHiddenValueFromMainWorldWrapper(v8::Isolate*, ScriptWrappable*, v8::Handle<v8::String>);
+
+private:
+#define V8_DECLARE_FIELD(name) ScopedPersistent<v8::String> m_##name;
+ V8_HIDDEN_VALUES(V8_DECLARE_FIELD);
+#undef V8_DECLARE_FIELD
+};
+
+} // namespace WebCore
+
+#endif // V8HiddenValue_h
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/V8Initializer.cpp b/chromium/third_party/WebKit/Source/bindings/v8/V8Initializer.cpp
index 9646ae76204..0f2f1f13261 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/V8Initializer.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/V8Initializer.cpp
@@ -26,11 +26,11 @@
#include "config.h"
#include "bindings/v8/V8Initializer.h"
-#include "V8DOMException.h"
-#include "V8ErrorEvent.h"
-#include "V8History.h"
-#include "V8Location.h"
-#include "V8Window.h"
+#include "bindings/core/v8/V8DOMException.h"
+#include "bindings/core/v8/V8ErrorEvent.h"
+#include "bindings/core/v8/V8History.h"
+#include "bindings/core/v8/V8Location.h"
+#include "bindings/core/v8/V8Window.h"
#include "bindings/v8/DOMWrapperWorld.h"
#include "bindings/v8/ScriptCallStackFactory.h"
#include "bindings/v8/ScriptController.h"
@@ -38,15 +38,15 @@
#include "bindings/v8/V8Binding.h"
#include "bindings/v8/V8ErrorHandler.h"
#include "bindings/v8/V8GCController.h"
-#include "bindings/v8/V8HiddenPropertyName.h"
#include "bindings/v8/V8PerContextData.h"
#include "core/dom/Document.h"
#include "core/dom/ExceptionCode.h"
-#include "core/inspector/ScriptCallStack.h"
#include "core/frame/ConsoleTypes.h"
-#include "core/frame/ContentSecurityPolicy.h"
-#include "core/frame/DOMWindow.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalDOMWindow.h"
+#include "core/frame/LocalFrame.h"
+#include "core/frame/csp/ContentSecurityPolicy.h"
+#include "core/inspector/ScriptCallStack.h"
+#include "platform/TraceEvent.h"
#include "public/platform/Platform.h"
#include "wtf/RefPtr.h"
#include "wtf/text/WTFString.h"
@@ -54,12 +54,12 @@
namespace WebCore {
-static Frame* findFrame(v8::Local<v8::Object> host, v8::Local<v8::Value> data, v8::Isolate* isolate)
+static LocalFrame* findFrame(v8::Local<v8::Object> host, v8::Local<v8::Value> data, v8::Isolate* isolate)
{
const WrapperTypeInfo* type = WrapperTypeInfo::unwrap(data);
if (V8Window::wrapperTypeInfo.equals(type)) {
- v8::Handle<v8::Object> windowWrapper = host->FindInstanceInPrototypeChain(V8Window::domTemplate(isolate, worldTypeInMainThread(isolate)));
+ v8::Handle<v8::Object> windowWrapper = V8Window::findInstanceInPrototypeChain(host, isolate);
if (windowWrapper.IsEmpty())
return 0;
return V8Window::toNative(windowWrapper)->frame();
@@ -85,30 +85,34 @@ static void reportFatalErrorInMainThread(const char* location, const char* messa
static void messageHandlerInMainThread(v8::Handle<v8::Message> message, v8::Handle<v8::Value> data)
{
- v8::Isolate* isolate = v8::Isolate::GetCurrent();
- // If called during context initialization, there will be no entered context.
- v8::Handle<v8::Context> enteredContext = isolate->GetEnteredContext();
- if (enteredContext.IsEmpty())
+ ASSERT(isMainThread());
+ // It's possible that messageHandlerInMainThread() is invoked while we're initializing a window.
+ // In that half-baked situation, we don't have a valid context nor a valid world,
+ // so just return immediately.
+ if (DOMWrapperWorld::windowIsBeingInitialized())
return;
- DOMWindow* firstWindow = toDOMWindow(enteredContext);
- if (!firstWindow->isCurrentlyDisplayedInFrame())
+ v8::Isolate* isolate = v8::Isolate::GetCurrent();
+ // If called during context initialization, there will be no entered window.
+ LocalDOMWindow* enteredWindow = enteredDOMWindow(isolate);
+ if (!enteredWindow || !enteredWindow->isCurrentlyDisplayedInFrame())
return;
String errorMessage = toCoreString(message->Get());
v8::Handle<v8::StackTrace> stackTrace = message->GetStackTrace();
- RefPtr<ScriptCallStack> callStack;
+ RefPtrWillBeRawPtr<ScriptCallStack> callStack = nullptr;
// Currently stack trace is only collected when inspector is open.
if (!stackTrace.IsEmpty() && stackTrace->GetFrameCount() > 0)
callStack = createScriptCallStack(stackTrace, ScriptCallStack::maxCallStackSizeToCapture, isolate);
v8::Handle<v8::Value> resourceName = message->GetScriptResourceName();
bool shouldUseDocumentURL = resourceName.IsEmpty() || !resourceName->IsString();
- String resource = shouldUseDocumentURL ? firstWindow->document()->url() : toCoreString(resourceName.As<v8::String>());
+ String resource = shouldUseDocumentURL ? enteredWindow->document()->url() : toCoreString(resourceName.As<v8::String>());
AccessControlStatus corsStatus = message->IsSharedCrossOrigin() ? SharableCrossOrigin : NotSharableCrossOrigin;
- RefPtr<ErrorEvent> event = ErrorEvent::create(errorMessage, resource, message->GetLineNumber(), message->GetStartColumn() + 1, DOMWrapperWorld::current());
+ ScriptState* scriptState = ScriptState::current(isolate);
+ RefPtrWillBeRawPtr<ErrorEvent> event = ErrorEvent::create(errorMessage, resource, message->GetLineNumber(), message->GetStartColumn() + 1, &scriptState->world());
if (V8DOMWrapper::isDOMWrapper(data)) {
v8::Handle<v8::Object> obj = v8::Handle<v8::Object>::Cast(data);
const WrapperTypeInfo* type = toWrapperTypeInfo(obj);
@@ -122,22 +126,24 @@ static void messageHandlerInMainThread(v8::Handle<v8::Message> message, v8::Hand
// This method might be called while we're creating a new context. In this case, we
// avoid storing the exception object, as we can't create a wrapper during context creation.
// FIXME: Can we even get here during initialization now that we bail out when GetEntered returns an empty handle?
- DOMWrapperWorld* world = DOMWrapperWorld::current();
- Frame* frame = firstWindow->document()->frame();
- if (world && frame && frame->script().existingWindowShell(world))
- V8ErrorHandler::storeExceptionOnErrorEventWrapper(event.get(), data, v8::Isolate::GetCurrent());
- firstWindow->document()->reportException(event.release(), callStack, corsStatus);
+ LocalFrame* frame = enteredWindow->document()->frame();
+ if (frame && frame->script().existingWindowShell(scriptState->world())) {
+ V8ErrorHandler::storeExceptionOnErrorEventWrapper(event.get(), data, scriptState->context()->Global(), isolate);
+ }
+ enteredWindow->document()->reportException(event.release(), callStack, corsStatus);
}
static void failedAccessCheckCallbackInMainThread(v8::Local<v8::Object> host, v8::AccessType type, v8::Local<v8::Value> data)
{
- Frame* target = findFrame(host, data, v8::Isolate::GetCurrent());
+ v8::Isolate* isolate = v8::Isolate::GetCurrent();
+ LocalFrame* target = findFrame(host, data, isolate);
if (!target)
return;
- DOMWindow* targetWindow = target->domWindow();
+ LocalDOMWindow* targetWindow = target->domWindow();
- ExceptionState exceptionState(v8::Handle<v8::Object>(), v8::Isolate::GetCurrent());
- exceptionState.throwSecurityError(targetWindow->sanitizedCrossDomainAccessErrorMessage(activeDOMWindow()), targetWindow->crossDomainAccessErrorMessage(activeDOMWindow()));
+ // FIXME: We should modify V8 to pass in more contextual information (context, property, and object).
+ ExceptionState exceptionState(ExceptionState::UnknownContext, 0, 0, isolate->GetCurrentContext()->Global(), isolate);
+ exceptionState.throwSecurityError(targetWindow->sanitizedCrossDomainAccessErrorMessage(callingDOMWindow(isolate)), targetWindow->crossDomainAccessErrorMessage(callingDOMWindow(isolate)));
exceptionState.throwIfNeeded();
}
@@ -145,22 +151,32 @@ static bool codeGenerationCheckCallbackInMainThread(v8::Local<v8::Context> conte
{
if (ExecutionContext* executionContext = toExecutionContext(context)) {
if (ContentSecurityPolicy* policy = toDocument(executionContext)->contentSecurityPolicy())
- return policy->allowEval(ScriptState::forContext(context));
+ return policy->allowEval(ScriptState::from(context));
}
return false;
}
+static void timerTraceProfilerInMainThread(const char* name, int status)
+{
+ if (!status) {
+ TRACE_EVENT_BEGIN0("V8", name);
+ } else {
+ TRACE_EVENT_END0("V8", name);
+ }
+}
+
static void initializeV8Common(v8::Isolate* isolate)
{
v8::ResourceConstraints constraints;
- constraints.ConfigureDefaults(static_cast<uint64_t>(blink::Platform::current()->physicalMemoryMB()) << 20, static_cast<uint32_t>(blink::Platform::current()->numberOfProcessors()));
+ constraints.ConfigureDefaults(static_cast<uint64_t>(blink::Platform::current()->physicalMemoryMB()) << 20, static_cast<uint32_t>(blink::Platform::current()->virtualMemoryLimitMB()) << 20, static_cast<uint32_t>(blink::Platform::current()->numberOfProcessors()));
v8::SetResourceConstraints(isolate, &constraints);
v8::V8::AddGCPrologueCallback(V8GCController::gcPrologue);
v8::V8::AddGCEpilogueCallback(V8GCController::gcEpilogue);
- v8::V8::IgnoreOutOfMemoryException();
- v8::Debug::SetLiveEditEnabled(false);
+ v8::Debug::SetLiveEditEnabled(isolate, false);
+
+ isolate->SetAutorunMicrotasks(false);
}
void V8Initializer::initializeMainThreadIfNeeded(v8::Isolate* isolate)
@@ -175,11 +191,14 @@ void V8Initializer::initializeMainThreadIfNeeded(v8::Isolate* isolate)
initializeV8Common(isolate);
v8::V8::SetFatalErrorHandler(reportFatalErrorInMainThread);
+ V8PerIsolateData::ensureInitialized(isolate);
v8::V8::AddMessageListener(messageHandlerInMainThread);
v8::V8::SetFailedAccessCheckCallbackFunction(failedAccessCheckCallbackInMainThread);
v8::V8::SetAllowCodeGenerationFromStringsCallback(codeGenerationCheckCallbackInMainThread);
+
+ isolate->SetEventLogger(timerTraceProfilerInMainThread);
+
ScriptProfiler::initialize();
- V8PerIsolateData::ensureInitialized(isolate);
}
static void reportFatalErrorInWorker(const char* location, const char* message)
@@ -197,16 +216,18 @@ static void messageHandlerInWorker(v8::Handle<v8::Message> message, v8::Handle<v
return;
isReportingException = true;
+ v8::Isolate* isolate = v8::Isolate::GetCurrent();
+ ScriptState* scriptState = ScriptState::current(isolate);
// During the frame teardown, there may not be a valid context.
- if (ExecutionContext* context = getExecutionContext()) {
+ if (ExecutionContext* context = scriptState->executionContext()) {
String errorMessage = toCoreString(message->Get());
- V8TRYCATCH_FOR_V8STRINGRESOURCE_VOID(V8StringResource<>, sourceURL, message->GetScriptResourceName());
+ TOSTRING_VOID(V8StringResource<>, sourceURL, message->GetScriptResourceName());
- RefPtr<ErrorEvent> event = ErrorEvent::create(errorMessage, sourceURL, message->GetLineNumber(), message->GetStartColumn() + 1, DOMWrapperWorld::current());
+ RefPtrWillBeRawPtr<ErrorEvent> event = ErrorEvent::create(errorMessage, sourceURL, message->GetLineNumber(), message->GetStartColumn() + 1, &DOMWrapperWorld::current(isolate));
AccessControlStatus corsStatus = message->IsSharedCrossOrigin() ? SharableCrossOrigin : NotSharableCrossOrigin;
- V8ErrorHandler::storeExceptionOnErrorEventWrapper(event.get(), data, v8::Isolate::GetCurrent());
- context->reportException(event.release(), 0, corsStatus);
+ V8ErrorHandler::storeExceptionOnErrorEventWrapper(event.get(), data, scriptState->context()->Global(), isolate);
+ context->reportException(event.release(), nullptr, corsStatus);
}
isReportingException = false;
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/V8LazyEventListener.cpp b/chromium/third_party/WebKit/Source/bindings/v8/V8LazyEventListener.cpp
index 1d80ffd89bf..23b8fcf52f8 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/V8LazyEventListener.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/V8LazyEventListener.cpp
@@ -31,29 +31,29 @@
#include "config.h"
#include "bindings/v8/V8LazyEventListener.h"
-#include "V8Document.h"
-#include "V8HTMLFormElement.h"
-#include "V8Node.h"
+#include "bindings/core/v8/V8Document.h"
+#include "bindings/core/v8/V8HTMLFormElement.h"
+#include "bindings/core/v8/V8Node.h"
#include "bindings/v8/ScriptController.h"
#include "bindings/v8/ScriptSourceCode.h"
#include "bindings/v8/V8Binding.h"
#include "bindings/v8/V8DOMWrapper.h"
-#include "bindings/v8/V8HiddenPropertyName.h"
+#include "bindings/v8/V8HiddenValue.h"
#include "bindings/v8/V8ScriptRunner.h"
#include "core/dom/Document.h"
#include "core/dom/Node.h"
#include "core/html/HTMLElement.h"
#include "core/html/HTMLFormElement.h"
#include "core/inspector/InspectorInstrumentation.h"
-#include "core/frame/ContentSecurityPolicy.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
+#include "core/frame/csp/ContentSecurityPolicy.h"
#include "wtf/StdLibExtras.h"
namespace WebCore {
V8LazyEventListener::V8LazyEventListener(const AtomicString& functionName, const AtomicString& eventParameterName, const String& code, const String sourceURL, const TextPosition& position, Node* node, v8::Isolate* isolate)
- : V8AbstractEventListener(true, mainThreadNormalWorld(), isolate)
+ : V8AbstractEventListener(true, isolate)
, m_functionName(functionName)
, m_eventParameterName(eventParameterName)
, m_code(code)
@@ -64,35 +64,31 @@ V8LazyEventListener::V8LazyEventListener(const AtomicString& functionName, const
}
template<typename T>
-v8::Handle<v8::Object> toObjectWrapper(T* domObject, v8::Isolate* isolate)
+v8::Handle<v8::Object> toObjectWrapper(T* domObject, ScriptState* scriptState)
{
if (!domObject)
- return v8::Object::New();
- v8::Handle<v8::Value> value = toV8(domObject, v8::Handle<v8::Object>(), isolate);
+ return v8::Object::New(scriptState->isolate());
+ v8::Handle<v8::Value> value = toV8(domObject, scriptState->context()->Global(), scriptState->isolate());
if (value.IsEmpty())
- return v8::Object::New();
- return v8::Local<v8::Object>::New(isolate, value.As<v8::Object>());
+ return v8::Object::New(scriptState->isolate());
+ return v8::Local<v8::Object>::New(scriptState->isolate(), value.As<v8::Object>());
}
-v8::Local<v8::Value> V8LazyEventListener::callListenerFunction(ExecutionContext* context, v8::Handle<v8::Value> jsEvent, Event* event)
+v8::Local<v8::Value> V8LazyEventListener::callListenerFunction(v8::Handle<v8::Value> jsEvent, Event* event)
{
- v8::Local<v8::Object> listenerObject = getListenerObject(context);
+ v8::Local<v8::Object> listenerObject = getListenerObject(scriptState()->executionContext());
if (listenerObject.IsEmpty())
return v8::Local<v8::Value>();
v8::Local<v8::Function> handlerFunction = listenerObject.As<v8::Function>();
- v8::Local<v8::Object> receiver = getReceiverObject(context, event);
+ v8::Local<v8::Object> receiver = getReceiverObject(event);
if (handlerFunction.IsEmpty() || receiver.IsEmpty())
return v8::Local<v8::Value>();
- // FIXME: Can |context| be 0 here?
- if (!context)
+ if (!scriptState()->executionContext()->isDocument())
return v8::Local<v8::Value>();
- if (!context->isDocument())
- return v8::Local<v8::Value>();
-
- Frame* frame = toDocument(context)->frame();
+ LocalFrame* frame = toDocument(scriptState()->executionContext())->frame();
if (!frame)
return v8::Local<v8::Value>();
@@ -105,11 +101,32 @@ v8::Local<v8::Value> V8LazyEventListener::callListenerFunction(ExecutionContext*
static void V8LazyEventListenerToString(const v8::FunctionCallbackInfo<v8::Value>& info)
{
- v8SetReturnValue(info, info.Holder()->GetHiddenValue(V8HiddenPropertyName::toStringString(info.GetIsolate())));
+ v8SetReturnValue(info, V8HiddenValue::getHiddenValue(info.GetIsolate(), info.Holder(), V8HiddenValue::toStringString(info.GetIsolate())));
+}
+
+void V8LazyEventListener::handleEvent(ExecutionContext* context, Event* event)
+{
+ v8::HandleScope handleScope(toIsolate(context));
+ // V8LazyEventListener doesn't know the associated context when created.
+ // Thus we lazily get the associated context and set a ScriptState on V8AbstractEventListener.
+ v8::Local<v8::Context> v8Context = toV8Context(context, world());
+ if (v8Context.IsEmpty())
+ return;
+ setScriptState(ScriptState::from(v8Context));
+
+ V8AbstractEventListener::handleEvent(context, event);
}
void V8LazyEventListener::prepareListenerObject(ExecutionContext* context)
{
+ v8::HandleScope handleScope(toIsolate(context));
+ // V8LazyEventListener doesn't know the associated context when created.
+ // Thus we lazily get the associated context and set a ScriptState on V8AbstractEventListener.
+ v8::Local<v8::Context> v8Context = toV8Context(context, world());
+ if (v8Context.IsEmpty())
+ return;
+ setScriptState(ScriptState::from(v8Context));
+
if (context->isDocument() && !toDocument(context)->allowInlineEventHandlers(m_node, this, m_sourceURL, m_position.m_line)) {
clearListenerObject();
return;
@@ -120,17 +137,7 @@ void V8LazyEventListener::prepareListenerObject(ExecutionContext* context)
ASSERT(context->isDocument());
- v8::Isolate* isolate = toIsolate(context);
- v8::HandleScope handleScope(isolate);
-
- // Use the outer scope to hold context.
- v8::Local<v8::Context> v8Context = toV8Context(context, world());
- // Bail out if we cannot get the context.
- if (v8Context.IsEmpty())
- return;
-
- v8::Context::Scope scope(v8Context);
-
+ ScriptState::Scope scope(scriptState());
String listenerSource = InspectorInstrumentation::preprocessEventListener(toDocument(context)->frame(), m_code, m_sourceURL, m_functionName);
// FIXME: Remove the following 'with' hack.
@@ -159,9 +166,9 @@ void V8LazyEventListener::prepareListenerObject(ExecutionContext* context)
"};"
"}}}})";
- v8::Handle<v8::String> codeExternalString = v8String(isolate, code);
+ v8::Handle<v8::String> codeExternalString = v8String(isolate(), code);
- v8::Local<v8::Value> result = V8ScriptRunner::compileAndRunInternalScript(codeExternalString, isolate, m_sourceURL, m_position, 0);
+ v8::Local<v8::Value> result = V8ScriptRunner::compileAndRunInternalScript(codeExternalString, isolate(), m_sourceURL, m_position);
if (result.IsEmpty())
return;
@@ -173,22 +180,22 @@ void V8LazyEventListener::prepareListenerObject(ExecutionContext* context)
if (m_node && m_node->isHTMLElement())
formElement = toHTMLElement(m_node)->formOwner();
- v8::Handle<v8::Object> nodeWrapper = toObjectWrapper<Node>(m_node, isolate);
- v8::Handle<v8::Object> formWrapper = toObjectWrapper<HTMLFormElement>(formElement, isolate);
- v8::Handle<v8::Object> documentWrapper = toObjectWrapper<Document>(m_node ? m_node->ownerDocument() : 0, isolate);
+ v8::Handle<v8::Object> nodeWrapper = toObjectWrapper<Node>(m_node, scriptState());
+ v8::Handle<v8::Object> formWrapper = toObjectWrapper<HTMLFormElement>(formElement, scriptState());
+ v8::Handle<v8::Object> documentWrapper = toObjectWrapper<Document>(m_node ? m_node->ownerDocument() : 0, scriptState());
- v8::Local<v8::Object> thisObject = v8::Object::New();
+ v8::Local<v8::Object> thisObject = v8::Object::New(isolate());
if (thisObject.IsEmpty())
return;
- if (!thisObject->ForceSet(v8::Integer::New(0, isolate), nodeWrapper))
+ if (!thisObject->ForceSet(v8::Integer::New(isolate(), 0), nodeWrapper))
return;
- if (!thisObject->ForceSet(v8::Integer::New(1, isolate), formWrapper))
+ if (!thisObject->ForceSet(v8::Integer::New(isolate(), 1), formWrapper))
return;
- if (!thisObject->ForceSet(v8::Integer::New(2, isolate), documentWrapper))
+ if (!thisObject->ForceSet(v8::Integer::New(isolate(), 2), documentWrapper))
return;
// FIXME: Remove this code when we stop doing the 'with' hack above.
- v8::Local<v8::Value> innerValue = V8ScriptRunner::callInternalFunction(intermediateFunction, thisObject, 0, 0, isolate);
+ v8::Local<v8::Value> innerValue = V8ScriptRunner::callInternalFunction(intermediateFunction, thisObject, 0, 0, isolate());
if (innerValue.IsEmpty() || !innerValue->IsFunction())
return;
@@ -202,20 +209,12 @@ void V8LazyEventListener::prepareListenerObject(ExecutionContext* context)
// source returned (sometimes a RegExp is applied as well) for some
// other use. That fails miserably if the actual wrapper source is
// returned.
- v8::Handle<v8::FunctionTemplate> toStringTemplate =
- V8PerIsolateData::current()->lazyEventListenerToStringTemplate();
- if (toStringTemplate.IsEmpty())
- toStringTemplate = v8::FunctionTemplate::New(isolate, V8LazyEventListenerToString);
- v8::Local<v8::Function> toStringFunction;
- if (!toStringTemplate.IsEmpty())
- toStringFunction = toStringTemplate->GetFunction();
- if (!toStringFunction.IsEmpty()) {
- String toStringString = "function " + m_functionName + "(" + m_eventParameterName + ") {\n " + m_code + "\n}";
- wrappedFunction->SetHiddenValue(V8HiddenPropertyName::toStringString(isolate), v8String(isolate, toStringString));
- wrappedFunction->Set(v8AtomicString(isolate, "toString"), toStringFunction);
- }
-
- wrappedFunction->SetName(v8String(isolate, m_functionName));
+ v8::Local<v8::Function> toStringFunction = v8::Function::New(isolate(), V8LazyEventListenerToString);
+ ASSERT(!toStringFunction.IsEmpty());
+ String toStringString = "function " + m_functionName + "(" + m_eventParameterName + ") {\n " + m_code + "\n}";
+ V8HiddenValue::setHiddenValue(isolate(), wrappedFunction, V8HiddenValue::toStringString(isolate()), v8String(isolate(), toStringString));
+ wrappedFunction->Set(v8AtomicString(isolate(), "toString"), toStringFunction);
+ wrappedFunction->SetName(v8String(isolate(), m_functionName));
// FIXME: Remove the following comment-outs.
// See https://bugs.webkit.org/show_bug.cgi?id=85152 for more details.
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/V8LazyEventListener.h b/chromium/third_party/WebKit/Source/bindings/v8/V8LazyEventListener.h
index 4bc040ff95b..7ab4d7d7c18 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/V8LazyEventListener.h
+++ b/chromium/third_party/WebKit/Source/bindings/v8/V8LazyEventListener.h
@@ -40,34 +40,38 @@
namespace WebCore {
class Event;
- class Frame;
+ class LocalFrame;
class HTMLFormElement;
class Node;
// V8LazyEventListener is a wrapper for a JavaScript code string that is compiled and evaluated when an event is fired.
// A V8LazyEventListener is either a HTML or SVG event handler.
- class V8LazyEventListener : public V8AbstractEventListener {
+ class V8LazyEventListener FINAL : public V8AbstractEventListener {
public:
static PassRefPtr<V8LazyEventListener> create(const AtomicString& functionName, const AtomicString& eventParameterName, const String& code, const String& sourceURL, const TextPosition& position, Node* node, v8::Isolate* isolate)
{
return adoptRef(new V8LazyEventListener(functionName, eventParameterName, code, sourceURL, position, node, isolate));
}
- virtual bool isLazy() const { return true; }
+ virtual bool isLazy() const OVERRIDE { return true; }
+ // V8LazyEventListener is always for the main world.
+ virtual DOMWrapperWorld& world() const OVERRIDE { return DOMWrapperWorld::mainWorld(); }
+
+ virtual void handleEvent(ExecutionContext*, Event*) OVERRIDE;
protected:
- virtual void prepareListenerObject(ExecutionContext*);
+ virtual void prepareListenerObject(ExecutionContext*) OVERRIDE;
private:
V8LazyEventListener(const AtomicString& functionName, const AtomicString& eventParameterName, const String& code, const String sourceURL, const TextPosition&, Node*, v8::Isolate*);
- virtual v8::Local<v8::Value> callListenerFunction(ExecutionContext*, v8::Handle<v8::Value> jsEvent, Event*);
+ virtual v8::Local<v8::Value> callListenerFunction(v8::Handle<v8::Value> jsEvent, Event*) OVERRIDE;
// 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; }
+ virtual bool wasCreatedFromMarkup() const OVERRIDE { return true; }
AtomicString m_functionName;
AtomicString m_eventParameterName;
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/V8MutationCallback.cpp b/chromium/third_party/WebKit/Source/bindings/v8/V8MutationCallback.cpp
index 6be6f16d6fc..8e0581acdcc 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/V8MutationCallback.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/V8MutationCallback.cpp
@@ -26,44 +26,39 @@
#include "config.h"
#include "bindings/v8/V8MutationCallback.h"
-#include "V8MutationObserver.h"
-#include "V8MutationRecord.h"
+#include "bindings/core/v8/V8MutationObserver.h"
+#include "bindings/core/v8/V8MutationRecord.h"
#include "bindings/v8/ScriptController.h"
#include "bindings/v8/V8Binding.h"
-#include "bindings/v8/V8HiddenPropertyName.h"
+#include "bindings/v8/V8HiddenValue.h"
#include "core/dom/ExecutionContext.h"
#include "wtf/Assertions.h"
namespace WebCore {
-V8MutationCallback::V8MutationCallback(v8::Handle<v8::Function> callback, ExecutionContext* context, v8::Handle<v8::Object> owner, v8::Isolate* isolate)
- : ActiveDOMCallback(context)
- , m_callback(isolate, callback)
- , m_world(DOMWrapperWorld::current())
- , m_isolate(isolate)
+V8MutationCallback::V8MutationCallback(v8::Handle<v8::Function> callback, v8::Handle<v8::Object> owner, ScriptState* scriptState)
+ : ActiveDOMCallback(scriptState->executionContext())
+ , m_callback(scriptState->isolate(), callback)
+ , m_scriptState(scriptState)
{
- owner->SetHiddenValue(V8HiddenPropertyName::callback(m_isolate), callback);
+ V8HiddenValue::setHiddenValue(scriptState->isolate(), owner, V8HiddenValue::callback(scriptState->isolate()), callback);
m_callback.setWeak(this, &setWeakCallback);
}
-void V8MutationCallback::call(const Vector<RefPtr<MutationRecord> >& mutations, MutationObserver* observer)
+void V8MutationCallback::call(const WillBeHeapVector<RefPtrWillBeMember<MutationRecord> >& mutations, MutationObserver* observer)
{
if (!canInvokeCallback())
return;
- v8::HandleScope handleScope(m_isolate);
+ v8::Isolate* isolate = m_scriptState->isolate();
- v8::Handle<v8::Context> v8Context = toV8Context(executionContext(), m_world.get());
- if (v8Context.IsEmpty())
+ if (m_scriptState->contextIsEmpty())
return;
+ ScriptState::Scope scope(m_scriptState.get());
- v8::Context::Scope scope(v8Context);
-
- v8::Handle<v8::Function> callback = m_callback.newLocal(m_isolate);
- if (callback.IsEmpty())
+ if (m_callback.isEmpty())
return;
-
- v8::Handle<v8::Value> observerHandle = toV8(observer, v8::Handle<v8::Object>(), m_isolate);
+ v8::Handle<v8::Value> observerHandle = toV8(observer, m_scriptState->context()->Global(), isolate);
if (observerHandle.IsEmpty()) {
if (!isScriptControllerTerminating())
CRASH();
@@ -74,11 +69,11 @@ void V8MutationCallback::call(const Vector<RefPtr<MutationRecord> >& mutations,
return;
v8::Handle<v8::Object> thisObject = v8::Handle<v8::Object>::Cast(observerHandle);
- v8::Handle<v8::Value> argv[] = { v8Array(mutations, m_isolate), observerHandle };
+ v8::Handle<v8::Value> argv[] = { v8Array(mutations, m_scriptState->context()->Global(), isolate), observerHandle };
v8::TryCatch exceptionCatcher;
exceptionCatcher.SetVerbose(true);
- ScriptController::callFunction(executionContext(), callback, thisObject, 2, argv, m_isolate);
+ ScriptController::callFunction(executionContext(), m_callback.newLocal(isolate), thisObject, WTF_ARRAY_LENGTH(argv), argv, isolate);
}
void V8MutationCallback::setWeakCallback(const v8::WeakCallbackData<v8::Function, V8MutationCallback>& data)
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/V8MutationCallback.h b/chromium/third_party/WebKit/Source/bindings/v8/V8MutationCallback.h
index 93a4820998a..fc5589a629b 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/V8MutationCallback.h
+++ b/chromium/third_party/WebKit/Source/bindings/v8/V8MutationCallback.h
@@ -27,9 +27,8 @@
#define V8MutationCallback_h
#include "bindings/v8/ActiveDOMCallback.h"
-#include "bindings/v8/DOMWrapperWorld.h"
#include "bindings/v8/ScopedPersistent.h"
-#include "bindings/v8/V8Utilities.h"
+#include "bindings/v8/ScriptState.h"
#include "core/dom/MutationCallback.h"
#include "wtf/OwnPtr.h"
#include "wtf/RefPtr.h"
@@ -39,25 +38,23 @@ namespace WebCore {
class ExecutionContext;
-class V8MutationCallback : public MutationCallback, public ActiveDOMCallback {
+class V8MutationCallback FINAL : public MutationCallback, public ActiveDOMCallback {
public:
- static PassOwnPtr<V8MutationCallback> create(v8::Handle<v8::Function> callback, ExecutionContext* context, v8::Handle<v8::Object> owner, v8::Isolate* isolate)
+ static PassOwnPtr<V8MutationCallback> create(v8::Handle<v8::Function> callback, v8::Handle<v8::Object> owner, ScriptState* scriptState)
{
- ASSERT(context);
- return adoptPtr(new V8MutationCallback(callback, context, owner, isolate));
+ return adoptPtr(new V8MutationCallback(callback, owner, scriptState));
}
- virtual void call(const Vector<RefPtr<MutationRecord> >&, MutationObserver*) OVERRIDE;
+ virtual void call(const WillBeHeapVector<RefPtrWillBeMember<MutationRecord> >&, MutationObserver*) OVERRIDE;
virtual ExecutionContext* executionContext() const OVERRIDE { return ContextLifecycleObserver::executionContext(); }
private:
- V8MutationCallback(v8::Handle<v8::Function>, ExecutionContext*, v8::Handle<v8::Object>, v8::Isolate*);
+ V8MutationCallback(v8::Handle<v8::Function>, v8::Handle<v8::Object>, ScriptState*);
static void setWeakCallback(const v8::WeakCallbackData<v8::Function, V8MutationCallback>&);
ScopedPersistent<v8::Function> m_callback;
- RefPtr<DOMWrapperWorld> m_world;
- v8::Isolate* m_isolate;
+ RefPtr<ScriptState> m_scriptState;
};
}
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/V8NPObject.cpp b/chromium/third_party/WebKit/Source/bindings/v8/V8NPObject.cpp
index 2912723fb82..a16369915c4 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/V8NPObject.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/V8NPObject.cpp
@@ -32,17 +32,18 @@
#include "bindings/v8/V8NPObject.h"
-#include "V8HTMLAppletElement.h"
-#include "V8HTMLEmbedElement.h"
-#include "V8HTMLObjectElement.h"
+#include "bindings/core/v8/V8HTMLAppletElement.h"
+#include "bindings/core/v8/V8HTMLEmbedElement.h"
+#include "bindings/core/v8/V8HTMLObjectElement.h"
#include "bindings/v8/NPV8Object.h"
-#include "bindings/v8/UnsafePersistent.h"
#include "bindings/v8/V8Binding.h"
#include "bindings/v8/V8NPUtils.h"
#include "bindings/v8/V8ObjectConstructor.h"
+#include "bindings/v8/V8PersistentValueMap.h"
#include "bindings/v8/npruntime_impl.h"
#include "bindings/v8/npruntime_priv.h"
#include "core/html/HTMLPlugInElement.h"
+#include "v8-util.h"
#include "wtf/OwnPtr.h"
namespace WebCore {
@@ -69,21 +70,18 @@ struct IdentifierRep {
static void npObjectInvokeImpl(const v8::FunctionCallbackInfo<v8::Value>& info, InvokeFunctionType functionId)
{
NPObject* npObject;
+ v8::Isolate* isolate = info.GetIsolate();
- WrapperWorldType currentWorldType = worldType(info.GetIsolate());
// These three types are subtypes of HTMLPlugInElement.
- if (V8HTMLAppletElement::hasInstance(info.Holder(), info.GetIsolate(), currentWorldType) || V8HTMLEmbedElement::hasInstance(info.Holder(), info.GetIsolate(), currentWorldType)
- || V8HTMLObjectElement::hasInstance(info.Holder(), info.GetIsolate(), currentWorldType)) {
- // The holder object is a subtype of HTMLPlugInElement.
- HTMLPlugInElement* element;
- if (V8HTMLAppletElement::hasInstance(info.Holder(), info.GetIsolate(), currentWorldType))
- element = V8HTMLAppletElement::toNative(info.Holder());
- else if (V8HTMLEmbedElement::hasInstance(info.Holder(), info.GetIsolate(), currentWorldType))
- element = V8HTMLEmbedElement::toNative(info.Holder());
- else
- element = V8HTMLObjectElement::toNative(info.Holder());
+ HTMLPlugInElement* element = V8HTMLAppletElement::toNativeWithTypeCheck(isolate, info.Holder());
+ if (!element) {
+ element = V8HTMLEmbedElement::toNativeWithTypeCheck(isolate, info.Holder());
+ if (!element) {
+ element = V8HTMLObjectElement::toNativeWithTypeCheck(isolate, info.Holder());
+ }
+ }
+ if (element) {
if (RefPtr<SharedPersistent<v8::Object> > wrapper = element->pluginWrapper()) {
- v8::Isolate* isolate = v8::Isolate::GetCurrent();
v8::HandleScope handleScope(isolate);
npObject = v8ObjectToNPObject(wrapper->newLocal(isolate));
} else
@@ -101,7 +99,7 @@ static void npObjectInvokeImpl(const v8::FunctionCallbackInfo<v8::Value>& info,
// Verify that our wrapper wasn't using a NPObject which has already been deleted.
if (!npObject || !_NPN_IsAlive(npObject)) {
- throwError(v8ReferenceError, "NPObject deleted", info.GetIsolate());
+ throwError(v8ReferenceError, "NPObject deleted", isolate);
return;
}
@@ -110,7 +108,7 @@ static void npObjectInvokeImpl(const v8::FunctionCallbackInfo<v8::Value>& info,
OwnPtr<NPVariant[]> npArgs = adoptArrayPtr(new NPVariant[numArgs]);
for (int i = 0; i < numArgs; i++)
- convertV8ObjectToNPVariant(info[i], npObject, &npArgs[i], info.GetIsolate());
+ convertV8ObjectToNPVariant(info[i], npObject, &npArgs[i], isolate);
NPVariant result;
VOID_TO_NPVARIANT(result);
@@ -137,7 +135,7 @@ static void npObjectInvokeImpl(const v8::FunctionCallbackInfo<v8::Value>& info,
}
if (!retval)
- throwError(v8GeneralError, "Error calling method on NPObject.", info.GetIsolate());
+ throwError(v8GeneralError, "Error calling method on NPObject.", isolate);
for (int i = 0; i < numArgs; i++)
_NPN_ReleaseVariantValue(&npArgs[i]);
@@ -145,7 +143,7 @@ static void npObjectInvokeImpl(const v8::FunctionCallbackInfo<v8::Value>& info,
// Unwrap return values.
v8::Handle<v8::Value> returnValue;
if (_NPN_IsAlive(npObject))
- returnValue = convertNPVariantToV8Object(&result, npObject, info.GetIsolate());
+ returnValue = convertNPVariantToV8Object(&result, npObject, isolate);
_NPN_ReleaseVariantValue(&result);
v8SetReturnValue(info, returnValue);
@@ -168,54 +166,72 @@ void npObjectInvokeDefaultHandler(const v8::FunctionCallbackInfo<v8::Value>& inf
npObjectInvokeImpl(info, InvokeDefault);
}
+class V8TemplateMapTraits : public V8PersistentValueMapTraits<PrivateIdentifier*, v8::FunctionTemplate, true> {
+public:
+ typedef v8::PersistentValueMap<PrivateIdentifier*, v8::FunctionTemplate, V8TemplateMapTraits> MapType;
+ typedef PrivateIdentifier WeakCallbackDataType;
+
+ static WeakCallbackDataType* WeakCallbackParameter(MapType* map, PrivateIdentifier* key, const v8::Local<v8::FunctionTemplate>& value)
+ {
+ return key;
+ }
+
+ static void DisposeCallbackData(WeakCallbackDataType* callbackData) { }
+
+ static MapType* MapFromWeakCallbackData(
+ const v8::WeakCallbackData<v8::FunctionTemplate, WeakCallbackDataType>&);
+
+ static PrivateIdentifier* KeyFromWeakCallbackData(
+ const v8::WeakCallbackData<v8::FunctionTemplate, WeakCallbackDataType>& data)
+ {
+ return data.GetParameter();
+ }
+
+ // Dispose traits:
+ static void Dispose(v8::Isolate* isolate, v8::UniquePersistent<v8::FunctionTemplate> value, PrivateIdentifier* key) { }
+};
+
+
class V8NPTemplateMap {
public:
// NPIdentifier is PrivateIdentifier*.
- typedef HashMap<PrivateIdentifier*, UnsafePersistent<v8::FunctionTemplate> > MapType;
+ typedef v8::PersistentValueMap<PrivateIdentifier*, v8::FunctionTemplate, V8TemplateMapTraits> MapType;
- UnsafePersistent<v8::FunctionTemplate> get(PrivateIdentifier* key)
+ v8::Local<v8::FunctionTemplate> get(PrivateIdentifier* key)
{
- return m_map.get(key);
+ return m_map.Get(key);
}
void set(PrivateIdentifier* key, v8::Handle<v8::FunctionTemplate> handle)
{
- ASSERT(!m_map.contains(key));
- v8::Persistent<v8::FunctionTemplate> wrapper(m_isolate, handle);
- wrapper.SetWeak(key, &setWeakCallback);
- m_map.set(key, UnsafePersistent<v8::FunctionTemplate>(wrapper));
+ ASSERT(!m_map.Contains(key));
+ m_map.Set(key, handle);
}
static V8NPTemplateMap& sharedInstance(v8::Isolate* isolate)
{
DEFINE_STATIC_LOCAL(V8NPTemplateMap, map, (isolate));
- ASSERT(isolate == map.m_isolate);
+ ASSERT(isolate == map.m_map.GetIsolate());
return map;
}
+ friend class V8TemplateMapTraits;
+
private:
explicit V8NPTemplateMap(v8::Isolate* isolate)
- : m_isolate(isolate)
- {
- }
-
- void clear(PrivateIdentifier* key)
+ : m_map(isolate)
{
- MapType::iterator it = m_map.find(key);
- ASSERT_WITH_SECURITY_IMPLICATION(it != m_map.end());
- it->value.dispose();
- m_map.remove(it);
- }
-
- static void setWeakCallback(const v8::WeakCallbackData<v8::FunctionTemplate, PrivateIdentifier>& data)
- {
- V8NPTemplateMap::sharedInstance(data.GetIsolate()).clear(data.GetParameter());
}
MapType m_map;
- v8::Isolate* m_isolate;
};
+V8TemplateMapTraits::MapType* V8TemplateMapTraits::MapFromWeakCallbackData(const v8::WeakCallbackData<v8::FunctionTemplate, WeakCallbackDataType>& data)
+{
+ return &V8NPTemplateMap::sharedInstance(data.GetIsolate()).m_map;
+}
+
+
static v8::Handle<v8::Value> npObjectGetProperty(v8::Local<v8::Object> self, NPIdentifier identifier, v8::Local<v8::Value> key, v8::Isolate* isolate)
{
NPObject* npObject = v8ObjectToNPObject(self);
@@ -251,19 +267,15 @@ static v8::Handle<v8::Value> npObjectGetProperty(v8::Local<v8::Object> self, NPI
return throwError(v8ReferenceError, "NPObject deleted", isolate);
PrivateIdentifier* id = static_cast<PrivateIdentifier*>(identifier);
- UnsafePersistent<v8::FunctionTemplate> functionTemplate = V8NPTemplateMap::sharedInstance(isolate).get(id);
- // FunctionTemplate caches function for each context.
- v8::Local<v8::Function> v8Function;
+ v8::Local<v8::FunctionTemplate> functionTemplate = V8NPTemplateMap::sharedInstance(isolate).get(id);
// Cache templates using identifier as the key.
- if (functionTemplate.isEmpty()) {
+ if (functionTemplate.IsEmpty()) {
// Create a new template.
- v8::Local<v8::FunctionTemplate> temp = v8::FunctionTemplate::New(isolate);
- temp->SetCallHandler(npObjectMethodHandler, key);
- V8NPTemplateMap::sharedInstance(isolate).set(id, temp);
- v8Function = temp->GetFunction();
- } else {
- v8Function = functionTemplate.newLocal(isolate)->GetFunction();
+ functionTemplate = v8::FunctionTemplate::New(isolate);
+ functionTemplate->SetCallHandler(npObjectMethodHandler, key);
+ V8NPTemplateMap::sharedInstance(isolate).set(id, functionTemplate);
}
+ v8::Local<v8::Function> v8Function = functionTemplate->GetFunction();
v8Function->SetName(v8::Handle<v8::String>::Cast(key));
return v8Function;
}
@@ -367,13 +379,22 @@ void npObjectPropertyEnumerator(const v8::PropertyCallbackInfo<v8::Array>& info,
uint32_t count;
NPIdentifier* identifiers;
if (npObject->_class->enumerate(npObject, &identifiers, &count)) {
- v8::Handle<v8::Array> properties = v8::Array::New(info.GetIsolate(), count);
+ uint32_t propertiesCount = 0;
for (uint32_t i = 0; i < count; ++i) {
IdentifierRep* identifier = static_cast<IdentifierRep*>(identifiers[i]);
- if (namedProperty)
- properties->Set(v8::Integer::New(i, info.GetIsolate()), v8AtomicString(info.GetIsolate(), identifier->string()));
- else
- properties->Set(v8::Integer::New(i, info.GetIsolate()), v8::Integer::New(identifier->number(), info.GetIsolate()));
+ if (namedProperty == identifier->m_isString)
+ ++propertiesCount;
+ }
+ v8::Handle<v8::Array> properties = v8::Array::New(info.GetIsolate(), propertiesCount);
+ for (uint32_t i = 0, propertyIndex = 0; i < count; ++i) {
+ IdentifierRep* identifier = static_cast<IdentifierRep*>(identifiers[i]);
+ if (namedProperty == identifier->m_isString) {
+ ASSERT(propertyIndex < propertiesCount);
+ if (namedProperty)
+ properties->Set(v8::Integer::New(info.GetIsolate(), propertyIndex++), v8AtomicString(info.GetIsolate(), identifier->string()));
+ else
+ properties->Set(v8::Integer::New(info.GetIsolate(), propertyIndex++), v8::Integer::New(info.GetIsolate(), identifier->number()));
+ }
}
v8SetReturnValue(info, properties);
@@ -398,18 +419,13 @@ static DOMWrapperMap<NPObject>& staticNPObjectMap()
return npObjectMap;
}
-template<>
-inline void DOMWrapperMap<NPObject>::setWeakCallback(const v8::WeakCallbackData<v8::Object, DOMWrapperMap<NPObject> >& data)
+template <>
+inline void DOMWrapperMap<NPObject>::PersistentValueMapTraits::Dispose(
+ v8::Isolate* isolate,
+ v8::UniquePersistent<v8::Object> value,
+ NPObject* npObject)
{
- NPObject* npObject = static_cast<NPObject*>(toNative(data.GetValue()));
-
ASSERT(npObject);
- ASSERT(staticNPObjectMap().containsKeyAndValue(npObject, data.GetValue()));
-
- // Must remove from our map before calling _NPN_ReleaseObject(). _NPN_ReleaseObject can
- // call forgetV8ObjectForNPObject, which uses the table as well.
- staticNPObjectMap().removeAndDispose(npObject);
-
if (_NPN_IsAlive(npObject))
_NPN_ReleaseObject(npObject);
}
@@ -447,7 +463,7 @@ v8::Local<v8::Object> createV8ObjectForNPObject(NPObject* object, NPObject* root
// V8DOMWrapper::associateObjectWithWrapper()
// to create a wrapper object.
v8::Handle<v8::Function> v8Function = npObjectDesc.Get(isolate)->GetFunction();
- v8::Local<v8::Object> value = V8ObjectConstructor::newInstance(v8Function);
+ v8::Local<v8::Object> value = V8ObjectConstructor::newInstance(isolate, v8Function);
if (value.IsEmpty())
return value;
@@ -459,7 +475,7 @@ v8::Local<v8::Object> createV8ObjectForNPObject(NPObject* object, NPObject* root
WrapperConfiguration configuration = buildWrapperConfiguration(object, WrapperConfiguration::Dependent);
staticNPObjectMap().set(object, value, configuration);
- ASSERT(V8DOMWrapper::maybeDOMWrapper(value));
+ ASSERT(V8DOMWrapper::isDOMWrapper(value));
return value;
}
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/V8NPObject.h b/chromium/third_party/WebKit/Source/bindings/v8/V8NPObject.h
index 4465b039868..dc5d336fbe5 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/V8NPObject.h
+++ b/chromium/third_party/WebKit/Source/bindings/v8/V8NPObject.h
@@ -31,9 +31,10 @@
#ifndef V8NPObject_h
#define V8NPObject_h
-#include <bindings/npruntime.h>
#include <v8.h>
+struct NPObject;
+
namespace WebCore {
// These functions can be replaced by normal JS operation.
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/V8NPUtils.cpp b/chromium/third_party/WebKit/Source/bindings/v8/V8NPUtils.cpp
index 7c0645f7a1f..df6eefe3b42 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/V8NPUtils.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/V8NPUtils.cpp
@@ -36,7 +36,7 @@
#include "bindings/v8/V8NPObject.h"
#include "bindings/v8/npruntime_impl.h"
#include "bindings/v8/npruntime_priv.h"
-#include "core/frame/DOMWindow.h"
+#include "core/frame/LocalDOMWindow.h"
#include "wtf/text/WTFString.h"
#include <stdlib.h>
@@ -69,7 +69,7 @@ void convertV8ObjectToNPVariant(v8::Local<v8::Value> object, NPObject* owner, NP
str->WriteUtf8(utf8Chars, length, 0, v8::String::HINT_MANY_WRITES_EXPECTED);
STRINGN_TO_NPVARIANT(utf8Chars, length-1, *result);
} else if (object->IsObject()) {
- DOMWindow* window = toDOMWindow(isolate->GetCurrentContext());
+ LocalDOMWindow* window = currentDOMWindow(isolate);
NPObject* npobject = npCreateV8ScriptObject(0, v8::Handle<v8::Object>::Cast(object), window, isolate);
if (npobject)
_NPN_RegisterObject(npobject, owner);
@@ -83,7 +83,7 @@ v8::Handle<v8::Value> convertNPVariantToV8Object(const NPVariant* variant, NPObj
switch (type) {
case NPVariantType_Int32:
- return v8::Integer::New(NPVARIANT_TO_INT32(*variant), isolate);
+ return v8::Integer::New(isolate, NPVARIANT_TO_INT32(*variant));
case NPVariantType_Double:
return v8::Number::New(isolate, NPVARIANT_TO_DOUBLE(*variant));
case NPVariantType_Bool:
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/V8NodeFilterCondition.cpp b/chromium/third_party/WebKit/Source/bindings/v8/V8NodeFilterCondition.cpp
index 3fcbc3c0f94..deecfa7b5c6 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/V8NodeFilterCondition.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/V8NodeFilterCondition.cpp
@@ -31,35 +31,41 @@
#include "config.h"
#include "bindings/v8/V8NodeFilterCondition.h"
-#include "V8Node.h"
+#include "bindings/core/v8/V8Node.h"
#include "bindings/v8/ScriptController.h"
-#include "bindings/v8/ScriptState.h"
-#include "bindings/v8/V8HiddenPropertyName.h"
+#include "bindings/v8/V8HiddenValue.h"
#include "core/dom/Node.h"
#include "core/dom/NodeFilter.h"
#include "wtf/OwnPtr.h"
namespace WebCore {
-V8NodeFilterCondition::V8NodeFilterCondition(v8::Handle<v8::Value> filter, v8::Handle<v8::Object> owner, v8::Isolate* isolate)
- : m_filter(isolate, filter)
+V8NodeFilterCondition::V8NodeFilterCondition(v8::Handle<v8::Value> filter, v8::Handle<v8::Object> owner, ScriptState* scriptState)
+ : m_scriptState(scriptState)
{
- owner->SetHiddenValue(V8HiddenPropertyName::condition(isolate), filter);
- m_filter.setWeak(this, &setWeakCallback);
+ // ..acceptNode(..) will only dispatch m_filter if m_filter->IsObject().
+ // We'll make sure m_filter is either usable by acceptNode or empty.
+ // (See the fast/dom/node-filter-gc test for a case where 'empty' happens.)
+ if (!filter.IsEmpty() && filter->IsObject()) {
+ V8HiddenValue::setHiddenValue(scriptState->isolate(), owner, V8HiddenValue::condition(scriptState->isolate()), filter);
+ m_filter.set(scriptState->isolate(), filter);
+ m_filter.setWeak(this, &setWeakCallback);
+ }
}
V8NodeFilterCondition::~V8NodeFilterCondition()
{
}
-short V8NodeFilterCondition::acceptNode(ScriptState* state, Node* node) const
+short V8NodeFilterCondition::acceptNode(Node* node, ExceptionState& exceptionState) const
{
- v8::Isolate* isolate = state->isolate();
- ASSERT(isolate->InContext());
+ v8::Isolate* isolate = m_scriptState->isolate();
+ ASSERT(!m_scriptState->context().IsEmpty());
v8::HandleScope handleScope(isolate);
v8::Handle<v8::Value> filter = m_filter.newLocal(isolate);
- ASSERT(!filter.IsEmpty());
- if (!filter->IsObject())
+
+ ASSERT(filter.IsEmpty() || filter->IsObject());
+ if (filter.IsEmpty())
return NodeFilter::FILTER_ACCEPT;
v8::TryCatch exceptionCatcher;
@@ -69,21 +75,21 @@ short V8NodeFilterCondition::acceptNode(ScriptState* state, Node* node) const
callback = v8::Handle<v8::Function>::Cast(filter);
else {
v8::Local<v8::Value> value = filter->ToObject()->Get(v8AtomicString(isolate, "acceptNode"));
- if (!value->IsFunction()) {
- throwTypeError("NodeFilter object does not have an acceptNode function", state->isolate());
+ if (value.IsEmpty() || !value->IsFunction()) {
+ exceptionState.throwTypeError("NodeFilter object does not have an acceptNode function");
return NodeFilter::FILTER_REJECT;
}
callback = v8::Handle<v8::Function>::Cast(value);
}
OwnPtr<v8::Handle<v8::Value>[]> info = adoptArrayPtr(new v8::Handle<v8::Value>[1]);
- info[0] = toV8(node, v8::Handle<v8::Object>(), state->isolate());
+ v8::Handle<v8::Object> context = m_scriptState->context()->Global();
+ info[0] = toV8(node, context, isolate);
- v8::Handle<v8::Object> object = isolate->GetCurrentContext()->Global();
- v8::Handle<v8::Value> result = ScriptController::callFunction(state->executionContext(), callback, object, 1, info.get(), isolate);
+ v8::Handle<v8::Value> result = ScriptController::callFunction(m_scriptState->executionContext(), callback, context, 1, info.get(), isolate);
if (exceptionCatcher.HasCaught()) {
- state->setException(exceptionCatcher.Exception());
+ exceptionState.rethrowV8Exception(exceptionCatcher.Exception());
return NodeFilter::FILTER_REJECT;
}
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/V8NodeFilterCondition.h b/chromium/third_party/WebKit/Source/bindings/v8/V8NodeFilterCondition.h
index 3d87020d5f2..de42cb5c13a 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/V8NodeFilterCondition.h
+++ b/chromium/third_party/WebKit/Source/bindings/v8/V8NodeFilterCondition.h
@@ -32,14 +32,16 @@
#define V8NodeFilterCondition_h
#include "bindings/v8/ScopedPersistent.h"
+#include "bindings/v8/ScriptState.h"
#include "core/dom/NodeFilterCondition.h"
+#include "platform/heap/Handle.h"
#include <v8.h>
#include "wtf/PassRefPtr.h"
namespace WebCore {
class Node;
-class ScriptState;
+class ExceptionState;
// V8NodeFilterCondition maintains a Javascript implemented callback for
// filtering Node returned by NodeIterator/TreeWalker.
@@ -58,25 +60,26 @@ class ScriptState;
// v | v | v
// NodeIterator --HiddenValue--> NodeFilter --HiddenValue--> JS Callback
// (V8)
-class V8NodeFilterCondition : public NodeFilterCondition {
+class V8NodeFilterCondition FINAL : public NodeFilterCondition {
public:
- static PassRefPtr<V8NodeFilterCondition> create(v8::Handle<v8::Value> filter, v8::Handle<v8::Object> owner, v8::Isolate* isolate)
+ static PassRefPtrWillBeRawPtr<V8NodeFilterCondition> create(v8::Handle<v8::Value> filter, v8::Handle<v8::Object> owner, ScriptState* scriptState)
{
- return adoptRef(new V8NodeFilterCondition(filter, owner, isolate));
+ return adoptRefWillBeNoop(new V8NodeFilterCondition(filter, owner, scriptState));
}
virtual ~V8NodeFilterCondition();
- virtual short acceptNode(ScriptState*, Node*) const;
+ virtual short acceptNode(Node*, ExceptionState&) const OVERRIDE;
private:
// As the value |filter| is maintained by V8GC, the |owner| which references
// V8NodeFilterCondition, usually a wrapper of NodeFilter, is specified here
// to hold a strong reference to |filter|.
- V8NodeFilterCondition(v8::Handle<v8::Value> filter, v8::Handle<v8::Object> owner, v8::Isolate*);
+ V8NodeFilterCondition(v8::Handle<v8::Value> filter, v8::Handle<v8::Object> owner, ScriptState*);
static void setWeakCallback(const v8::WeakCallbackData<v8::Value, V8NodeFilterCondition>&);
+ RefPtr<ScriptState> m_scriptState;
ScopedPersistent<v8::Value> m_filter;
};
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/V8ObjectConstructor.cpp b/chromium/third_party/WebKit/Source/bindings/v8/V8ObjectConstructor.cpp
index 6ebfbab7b71..d52bdc1a910 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/V8ObjectConstructor.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/V8ObjectConstructor.cpp
@@ -28,46 +28,38 @@
#include "bindings/v8/V8Binding.h"
#include "bindings/v8/V8ScriptRunner.h"
#include "core/dom/Document.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
#include "platform/TraceEvent.h"
namespace WebCore {
-v8::Local<v8::Object> V8ObjectConstructor::newInstance(v8::Handle<v8::Function> function)
+v8::Local<v8::Object> V8ObjectConstructor::newInstance(v8::Isolate* isolate, v8::Handle<v8::Function> function)
{
if (function.IsEmpty())
return v8::Local<v8::Object>();
- ConstructorMode constructorMode;
- return V8ScriptRunner::instantiateObject(function);
+ ConstructorMode constructorMode(isolate);
+ return V8ScriptRunner::instantiateObject(isolate, function);
}
-v8::Local<v8::Object> V8ObjectConstructor::newInstance(v8::Handle<v8::ObjectTemplate> objectTemplate)
-{
- if (objectTemplate.IsEmpty())
- return v8::Local<v8::Object>();
- ConstructorMode constructorMode;
- return V8ScriptRunner::instantiateObject(objectTemplate);
-}
-
-v8::Local<v8::Object> V8ObjectConstructor::newInstance(v8::Handle<v8::Function> function, int argc, v8::Handle<v8::Value> argv[])
+v8::Local<v8::Object> V8ObjectConstructor::newInstance(v8::Isolate* isolate, v8::Handle<v8::Function> function, int argc, v8::Handle<v8::Value> argv[])
{
if (function.IsEmpty())
return v8::Local<v8::Object>();
- ConstructorMode constructorMode;
- return V8ScriptRunner::instantiateObject(function, argc, argv);
+ ConstructorMode constructorMode(isolate);
+ return V8ScriptRunner::instantiateObject(isolate, function, argc, argv);
}
-v8::Local<v8::Object> V8ObjectConstructor::newInstanceInDocument(v8::Handle<v8::Function> function, int argc, v8::Handle<v8::Value> argv[], Document* document)
+v8::Local<v8::Object> V8ObjectConstructor::newInstanceInDocument(v8::Isolate* isolate, v8::Handle<v8::Function> function, int argc, v8::Handle<v8::Value> argv[], Document* document)
{
if (function.IsEmpty())
return v8::Local<v8::Object>();
- return V8ScriptRunner::instantiateObjectInDocument(function, document, argc, argv);
+ return V8ScriptRunner::instantiateObjectInDocument(isolate, function, document, argc, argv);
}
void V8ObjectConstructor::isValidConstructorMode(const v8::FunctionCallbackInfo<v8::Value>& info)
{
- if (ConstructorMode::current() == ConstructorMode::CreateNewObject) {
+ if (ConstructorMode::current(info.GetIsolate()) == ConstructorMode::CreateNewObject) {
throwTypeError("Illegal constructor", info.GetIsolate());
return;
}
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/V8ObjectConstructor.h b/chromium/third_party/WebKit/Source/bindings/v8/V8ObjectConstructor.h
index 2c9f6a26020..e1d204fa606 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/V8ObjectConstructor.h
+++ b/chromium/third_party/WebKit/Source/bindings/v8/V8ObjectConstructor.h
@@ -32,6 +32,7 @@
#define V8ObjectConstructor_h
#include "bindings/v8/V8PerIsolateData.h"
+#include "bindings/v8/V8RecursionScope.h"
#include <v8.h>
@@ -46,31 +47,37 @@ public:
CreateNewObject
};
- ConstructorMode()
+ ConstructorMode(v8::Isolate* isolate)
+ : m_isolate(isolate)
+ , m_microtaskSuppression(isolate)
{
- V8PerIsolateData* data = V8PerIsolateData::current();
+ V8PerIsolateData* data = V8PerIsolateData::from(m_isolate);
m_previous = data->m_constructorMode;
data->m_constructorMode = WrapExistingObject;
}
~ConstructorMode()
{
- V8PerIsolateData* data = V8PerIsolateData::current();
+ V8PerIsolateData* data = V8PerIsolateData::from(m_isolate);
data->m_constructorMode = m_previous;
}
- static bool current() { return V8PerIsolateData::current()->m_constructorMode; }
+ static bool current(v8::Isolate* isolate)
+ {
+ return V8PerIsolateData::from(isolate)->m_constructorMode;
+ }
private:
+ v8::Isolate* m_isolate;
bool m_previous;
+ V8RecursionScope::MicrotaskSuppression m_microtaskSuppression;
};
class V8ObjectConstructor {
public:
- static v8::Local<v8::Object> newInstance(v8::Handle<v8::Function>);
- static v8::Local<v8::Object> newInstance(v8::Handle<v8::ObjectTemplate>);
- static v8::Local<v8::Object> newInstance(v8::Handle<v8::Function>, int, v8::Handle<v8::Value> argv[]);
- static v8::Local<v8::Object> newInstanceInDocument(v8::Handle<v8::Function>, int, v8::Handle<v8::Value> argv[], Document*);
+ static v8::Local<v8::Object> newInstance(v8::Isolate*, v8::Handle<v8::Function>);
+ static v8::Local<v8::Object> newInstance(v8::Isolate*, v8::Handle<v8::Function>, int, v8::Handle<v8::Value> argv[]);
+ static v8::Local<v8::Object> newInstanceInDocument(v8::Isolate*, v8::Handle<v8::Function>, int, v8::Handle<v8::Value> argv[], Document*);
static void isValidConstructorMode(const v8::FunctionCallbackInfo<v8::Value>&);
};
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/V8PerContextData.cpp b/chromium/third_party/WebKit/Source/bindings/v8/V8PerContextData.cpp
index 8bf80076f08..1456bed0748 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/V8PerContextData.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/V8PerContextData.cpp
@@ -31,6 +31,7 @@
#include "config.h"
#include "bindings/v8/V8PerContextData.h"
+#include "bindings/v8/ScriptState.h"
#include "bindings/v8/V8Binding.h"
#include "bindings/v8/V8ObjectConstructor.h"
#include "wtf/StringExtras.h"
@@ -39,67 +40,49 @@
namespace WebCore {
-template<typename Map>
-static void disposeMapWithUnsafePersistentValues(Map* map)
+V8PerContextData::V8PerContextData(v8::Handle<v8::Context> context)
+ : m_wrapperBoilerplates(context->GetIsolate())
+ , m_constructorMap(context->GetIsolate())
+ , m_isolate(context->GetIsolate())
+ , m_contextHolder(adoptPtr(new gin::ContextHolder(context->GetIsolate())))
+ , m_context(m_isolate, context)
+ , m_customElementBindings(adoptPtr(new CustomElementBindingMap()))
+ , m_activityLogger(0)
{
- typename Map::iterator it = map->begin();
- for (; it != map->end(); ++it)
- it->value.dispose();
- map->clear();
+ m_contextHolder->SetContext(context);
+
+ v8::Context::Scope contextScope(context);
+ ASSERT(m_errorPrototype.isEmpty());
+ v8::Handle<v8::Object> object = v8::Handle<v8::Object>::Cast(context->Global()->Get(v8AtomicString(m_isolate, "Error")));
+ ASSERT(!object.IsEmpty());
+ v8::Handle<v8::Value> prototypeValue = object->Get(v8AtomicString(m_isolate, "prototype"));
+ ASSERT(!prototypeValue.IsEmpty());
+ m_errorPrototype.set(m_isolate, prototypeValue);
}
-void V8PerContextData::dispose()
+V8PerContextData::~V8PerContextData()
{
- v8::HandleScope handleScope(m_isolate);
- V8PerContextDataHolder::from(v8::Local<v8::Context>::New(m_isolate, m_context))->setPerContextData(0);
-
- disposeMapWithUnsafePersistentValues(&m_wrapperBoilerplates);
- disposeMapWithUnsafePersistentValues(&m_constructorMap);
- m_customElementBindings.clear();
-
- m_context.Reset();
}
-#define V8_STORE_PRIMORDIAL(name, Name) \
-{ \
- ASSERT(m_##name##Prototype.isEmpty()); \
- v8::Handle<v8::String> symbol = v8::String::NewFromUtf8(m_isolate, #Name, v8::String::kInternalizedString); \
- if (symbol.IsEmpty()) \
- return false; \
- v8::Handle<v8::Object> object = v8::Handle<v8::Object>::Cast(v8::Local<v8::Context>::New(m_isolate, m_context)->Global()->Get(symbol)); \
- if (object.IsEmpty()) \
- return false; \
- v8::Handle<v8::Value> prototypeValue = object->Get(prototypeString); \
- if (prototypeValue.IsEmpty()) \
- return false; \
- m_##name##Prototype.set(m_isolate, prototypeValue); \
+PassOwnPtr<V8PerContextData> V8PerContextData::create(v8::Handle<v8::Context> context)
+{
+ return adoptPtr(new V8PerContextData(context));
}
-bool V8PerContextData::init()
+V8PerContextData* V8PerContextData::from(v8::Handle<v8::Context> context)
{
- v8::Handle<v8::Context> context = v8::Local<v8::Context>::New(m_isolate, m_context);
- V8PerContextDataHolder::from(context)->setPerContextData(this);
-
- v8::Handle<v8::String> prototypeString = v8AtomicString(m_isolate, "prototype");
- if (prototypeString.IsEmpty())
- return false;
-
- V8_STORE_PRIMORDIAL(error, Error);
-
- return true;
+ return ScriptState::from(context)->perContextData();
}
-#undef V8_STORE_PRIMORDIAL
-
v8::Local<v8::Object> V8PerContextData::createWrapperFromCacheSlowCase(const WrapperTypeInfo* type)
{
ASSERT(!m_errorPrototype.isEmpty());
- v8::Context::Scope scope(v8::Local<v8::Context>::New(m_isolate, m_context));
+ v8::Context::Scope scope(context());
v8::Local<v8::Function> function = constructorForType(type);
- v8::Local<v8::Object> instanceTemplate = V8ObjectConstructor::newInstance(function);
+ v8::Local<v8::Object> instanceTemplate = V8ObjectConstructor::newInstance(m_isolate, function);
if (!instanceTemplate.IsEmpty()) {
- m_wrapperBoilerplates.set(type, UnsafePersistent<v8::Object>(m_isolate, instanceTemplate));
+ m_wrapperBoilerplates.Set(type, instanceTemplate);
return instanceTemplate->Clone();
}
return v8::Local<v8::Object>();
@@ -109,8 +92,8 @@ v8::Local<v8::Function> V8PerContextData::constructorForTypeSlowCase(const Wrapp
{
ASSERT(!m_errorPrototype.isEmpty());
- v8::Context::Scope scope(v8::Local<v8::Context>::New(m_isolate, m_context));
- v8::Handle<v8::FunctionTemplate> functionTemplate = type->domTemplate(m_isolate, worldType(m_isolate));
+ v8::Context::Scope scope(context());
+ v8::Handle<v8::FunctionTemplate> functionTemplate = type->domTemplate(m_isolate);
// Getting the function might fail if we're running out of stack or memory.
v8::TryCatch tryCatch;
v8::Local<v8::Function> function = functionTemplate->GetFunction();
@@ -131,11 +114,11 @@ v8::Local<v8::Function> V8PerContextData::constructorForTypeSlowCase(const Wrapp
&& type->wrapperTypePrototype == WrapperTypeObjectPrototype)
prototypeObject->SetAlignedPointerInInternalField(v8PrototypeTypeIndex, const_cast<WrapperTypeInfo*>(type));
type->installPerContextEnabledMethods(prototypeObject, m_isolate);
- if (type->wrapperTypePrototype == WrapperTypeErrorPrototype)
+ if (type->wrapperTypePrototype == WrapperTypeExceptionPrototype)
prototypeObject->SetPrototype(m_errorPrototype.newLocal(m_isolate));
}
- m_constructorMap.set(type, UnsafePersistent<v8::Function>(m_isolate, function));
+ m_constructorMap.Set(type, function);
return function;
}
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/V8PerContextData.h b/chromium/third_party/WebKit/Source/bindings/v8/V8PerContextData.h
index 63634f85cbe..7987c616892 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/V8PerContextData.h
+++ b/chromium/third_party/WebKit/Source/bindings/v8/V8PerContextData.h
@@ -33,8 +33,7 @@
#include "bindings/v8/CustomElementBinding.h"
#include "bindings/v8/ScopedPersistent.h"
-#include "bindings/v8/UnsafePersistent.h"
-#include "bindings/v8/V8DOMActivityLogger.h"
+#include "bindings/v8/V8PersistentValueMap.h"
#include "bindings/v8/WrapperTypeInfo.h"
#include "gin/public/context_holder.h"
#include "gin/public/gin_embedders.h"
@@ -48,7 +47,7 @@
namespace WebCore {
class CustomElementDefinition;
-class DOMWrapperWorld;
+class V8DOMActivityLogger;
class V8PerContextData;
struct V8NPObject;
typedef WTF::Vector<V8NPObject*> V8NPObjectVector;
@@ -59,139 +58,69 @@ enum V8ContextEmbedderDataField {
v8ContextPerContextDataIndex = static_cast<int>(gin::kPerContextDataStartIndex + gin::kEmbedderBlink),
};
-class V8PerContextDataHolder {
- WTF_MAKE_NONCOPYABLE(V8PerContextDataHolder);
-public:
- static void install(v8::Handle<v8::Context> context)
- {
- new V8PerContextDataHolder(context);
- }
-
- static V8PerContextDataHolder* from(v8::Handle<v8::Context> context)
- {
- return static_cast<V8PerContextDataHolder*>(context->GetAlignedPointerFromEmbedderData(v8ContextPerContextDataIndex));
- }
-
- V8PerContextData* perContextData() const { return m_perContextData; }
- void setPerContextData(V8PerContextData* data) { m_perContextData = data; }
-
- DOMWrapperWorld* isolatedWorld() const { return m_isolatedWorld; }
- void setIsolatedWorld(DOMWrapperWorld* world) { m_isolatedWorld = world; }
-
-private:
- explicit V8PerContextDataHolder(v8::Handle<v8::Context> context)
- : m_context(v8::Isolate::GetCurrent(), context)
- , m_perContextData(0)
- , m_isolatedWorld(0)
- {
- m_context.SetWeak(this, &V8PerContextDataHolder::weakCallback);
- context->SetAlignedPointerInEmbedderData(v8ContextPerContextDataIndex, this);
- }
-
- ~V8PerContextDataHolder() {}
-
- static void weakCallback(const v8::WeakCallbackData<v8::Context, V8PerContextDataHolder>& data)
- {
- data.GetValue()->SetAlignedPointerInEmbedderData(v8ContextPerContextDataIndex, 0);
- data.GetParameter()->m_context.Reset();
- delete data.GetParameter();
- }
-
- v8::Persistent<v8::Context> m_context;
- V8PerContextData* m_perContextData;
- DOMWrapperWorld* m_isolatedWorld;
-};
-
class V8PerContextData {
public:
- static PassOwnPtr<V8PerContextData> create(v8::Handle<v8::Context> context)
- {
- return adoptPtr(new V8PerContextData(context));
- }
+ static PassOwnPtr<V8PerContextData> create(v8::Handle<v8::Context>);
- ~V8PerContextData()
- {
- dispose();
- }
+ static V8PerContextData* from(v8::Handle<v8::Context>);
- bool init();
+ ~V8PerContextData();
- static V8PerContextData* from(v8::Handle<v8::Context> context)
- {
- return V8PerContextDataHolder::from(context)->perContextData();
- }
+ v8::Handle<v8::Context> context() { return m_context.newLocal(m_isolate); }
// 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(const WrapperTypeInfo* type)
{
- UnsafePersistent<v8::Object> boilerplate = m_wrapperBoilerplates.get(type);
- return !boilerplate.isEmpty() ? boilerplate.newLocal(v8::Isolate::GetCurrent())->Clone() : createWrapperFromCacheSlowCase(type);
+ v8::Local<v8::Object> boilerplate = m_wrapperBoilerplates.Get(type);
+ return !boilerplate.IsEmpty() ? boilerplate->Clone() : createWrapperFromCacheSlowCase(type);
}
v8::Local<v8::Function> constructorForType(const WrapperTypeInfo* type)
{
- UnsafePersistent<v8::Function> function = m_constructorMap.get(type);
- if (!function.isEmpty())
- return function.newLocal(v8::Isolate::GetCurrent());
- return constructorForTypeSlowCase(type);
+ v8::Local<v8::Function> function = m_constructorMap.Get(type);
+ return (!function.IsEmpty()) ? function : constructorForTypeSlowCase(type);
}
v8::Local<v8::Object> prototypeForType(const WrapperTypeInfo*);
- V8NPObjectMap* v8NPObjectMap()
- {
- return &m_v8NPObjectMap;
- }
-
- V8DOMActivityLogger* activityLogger()
- {
- return m_activityLogger;
- }
-
- void setActivityLogger(V8DOMActivityLogger* logger)
- {
- m_activityLogger = logger;
- }
+ V8NPObjectMap* v8NPObjectMap() { return &m_v8NPObjectMap; }
void addCustomElementBinding(CustomElementDefinition*, PassOwnPtr<CustomElementBinding>);
void clearCustomElementBinding(CustomElementDefinition*);
CustomElementBinding* customElementBinding(CustomElementDefinition*);
-private:
- explicit V8PerContextData(v8::Handle<v8::Context> context)
- : m_activityLogger(0)
- , m_isolate(v8::Isolate::GetCurrent())
- , m_context(m_isolate, context)
- , m_customElementBindings(adoptPtr(new CustomElementBindingMap()))
- {
- }
+ V8DOMActivityLogger* activityLogger() const { return m_activityLogger; }
+ void setActivityLogger(V8DOMActivityLogger* activityLogger) { m_activityLogger = activityLogger; }
- void dispose();
+private:
+ V8PerContextData(v8::Handle<v8::Context>);
v8::Local<v8::Object> createWrapperFromCacheSlowCase(const WrapperTypeInfo*);
v8::Local<v8::Function> constructorForTypeSlowCase(const WrapperTypeInfo*);
// For each possible type of wrapper, we keep a boilerplate object.
// The boilerplate is used to create additional wrappers of the same type.
- typedef WTF::HashMap<const WrapperTypeInfo*, UnsafePersistent<v8::Object> > WrapperBoilerplateMap;
+ typedef V8PersistentValueMap<const WrapperTypeInfo*, v8::Object, false> WrapperBoilerplateMap;
WrapperBoilerplateMap m_wrapperBoilerplates;
- typedef WTF::HashMap<const WrapperTypeInfo*, UnsafePersistent<v8::Function> > ConstructorMap;
+ typedef V8PersistentValueMap<const WrapperTypeInfo*, v8::Function, false> ConstructorMap;
ConstructorMap m_constructorMap;
V8NPObjectMap m_v8NPObjectMap;
- // We cache a pointer to the V8DOMActivityLogger associated with the world
- // corresponding to this context. The ownership of the pointer is retained
- // by the DOMActivityLoggerMap in DOMWrapperWorld.
- V8DOMActivityLogger* m_activityLogger;
+
v8::Isolate* m_isolate;
- v8::Persistent<v8::Context> m_context;
+ OwnPtr<gin::ContextHolder> m_contextHolder;
+
+ ScopedPersistent<v8::Context> m_context;
ScopedPersistent<v8::Value> m_errorPrototype;
typedef WTF::HashMap<CustomElementDefinition*, OwnPtr<CustomElementBinding> > CustomElementBindingMap;
OwnPtr<CustomElementBindingMap> m_customElementBindings;
+
+ // This is owned by a static hash map in V8DOMActivityLogger.
+ V8DOMActivityLogger* m_activityLogger;
};
class V8PerContextDebugData {
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/V8PerIsolateData.cpp b/chromium/third_party/WebKit/Source/bindings/v8/V8PerIsolateData.cpp
index 10064bc2dde..43dd26351e8 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/V8PerIsolateData.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/V8PerIsolateData.cpp
@@ -27,48 +27,74 @@
#include "bindings/v8/V8PerIsolateData.h"
#include "bindings/v8/DOMDataStore.h"
+#include "bindings/v8/PageScriptDebugServer.h"
#include "bindings/v8/ScriptGCEvent.h"
#include "bindings/v8/ScriptProfiler.h"
#include "bindings/v8/V8Binding.h"
-#include "bindings/v8/V8HiddenPropertyName.h"
+#include "bindings/v8/V8HiddenValue.h"
#include "bindings/v8/V8ObjectConstructor.h"
+#include "bindings/v8/V8RecursionScope.h"
#include "bindings/v8/V8ScriptRunner.h"
+#include "public/platform/Platform.h"
+#include "wtf/MainThread.h"
namespace WebCore {
+static V8PerIsolateData* mainThreadPerIsolateData = 0;
+
+#ifndef NDEBUG
+static void assertV8RecursionScope()
+{
+ ASSERT(V8RecursionScope::properlyUsed(v8::Isolate::GetCurrent()));
+}
+#endif
+
V8PerIsolateData::V8PerIsolateData(v8::Isolate* isolate)
: m_isolate(isolate)
- , m_stringCache(adoptPtr(new StringCache()))
- , m_workerDomDataStore(0)
- , m_hiddenPropertyName(adoptPtr(new V8HiddenPropertyName()))
+ , m_isolateHolder(adoptPtr(new gin::IsolateHolder(m_isolate, v8ArrayBufferAllocator())))
+ , m_stringCache(adoptPtr(new StringCache(m_isolate)))
+ , m_hiddenValue(adoptPtr(new V8HiddenValue()))
, m_constructorMode(ConstructorMode::CreateNewObject)
, m_recursionLevel(0)
#ifndef NDEBUG
, m_internalScriptRecursionLevel(0)
#endif
, m_gcEventData(adoptPtr(new GCEventData()))
- , m_shouldCollectGarbageSoon(false)
+ , m_performingMicrotaskCheckpoint(false)
{
+#ifndef NDEBUG
+ // currentThread will always be non-null in production, but can be null in Chromium unit tests.
+ if (blink::Platform::current()->currentThread())
+ isolate->AddCallCompletedCallback(&assertV8RecursionScope);
+#endif
+ if (isMainThread()) {
+ mainThreadPerIsolateData = this;
+ PageScriptDebugServer::setMainThreadIsolate(isolate);
+ }
}
V8PerIsolateData::~V8PerIsolateData()
{
+ if (m_scriptRegexpScriptState)
+ m_scriptRegexpScriptState->disposePerContextData();
+ if (isMainThread())
+ mainThreadPerIsolateData = 0;
}
-V8PerIsolateData* V8PerIsolateData::create(v8::Isolate* isolate)
+v8::Isolate* V8PerIsolateData::mainThreadIsolate()
{
- ASSERT(isolate);
- ASSERT(!isolate->GetData(gin::kEmbedderBlink));
- V8PerIsolateData* data = new V8PerIsolateData(isolate);
- isolate->SetData(gin::kEmbedderBlink, data);
- return data;
+ ASSERT(isMainThread());
+ ASSERT(mainThreadPerIsolateData);
+ return mainThreadPerIsolateData->isolate();
}
void V8PerIsolateData::ensureInitialized(v8::Isolate* isolate)
{
ASSERT(isolate);
- if (!isolate->GetData(gin::kEmbedderBlink))
- create(isolate);
+ if (!isolate->GetData(gin::kEmbedderBlink)) {
+ V8PerIsolateData* data = new V8PerIsolateData(isolate);
+ isolate->SetData(gin::kEmbedderBlink, data);
+ }
}
v8::Persistent<v8::Value>& V8PerIsolateData::ensureLiveRoot()
@@ -80,76 +106,92 @@ v8::Persistent<v8::Value>& V8PerIsolateData::ensureLiveRoot()
void V8PerIsolateData::dispose(v8::Isolate* isolate)
{
+#ifndef NDEBUG
+ if (blink::Platform::current()->currentThread())
+ isolate->RemoveCallCompletedCallback(&assertV8RecursionScope);
+#endif
void* data = isolate->GetData(gin::kEmbedderBlink);
delete static_cast<V8PerIsolateData*>(data);
isolate->SetData(gin::kEmbedderBlink, 0);
}
-v8::Handle<v8::FunctionTemplate> V8PerIsolateData::toStringTemplate()
+V8PerIsolateData::DOMTemplateMap& V8PerIsolateData::currentDOMTemplateMap()
{
- if (m_toStringTemplate.isEmpty())
- m_toStringTemplate.set(m_isolate, v8::FunctionTemplate::New(m_isolate, constructorOfToString));
- return m_toStringTemplate.newLocal(m_isolate);
+ if (DOMWrapperWorld::current(m_isolate).isMainWorld())
+ return m_domTemplateMapForMainWorld;
+ return m_domTemplateMapForNonMainWorld;
}
-v8::Handle<v8::FunctionTemplate> V8PerIsolateData::privateTemplate(WrapperWorldType currentWorldType, void* privatePointer, v8::FunctionCallback callback, v8::Handle<v8::Value> data, v8::Handle<v8::Signature> signature, int length)
+v8::Handle<v8::FunctionTemplate> V8PerIsolateData::domTemplate(void* domTemplateKey, v8::FunctionCallback callback, v8::Handle<v8::Value> data, v8::Handle<v8::Signature> signature, int length)
{
- TemplateMap& templates = templateMap(currentWorldType);
- TemplateMap::iterator result = templates.find(privatePointer);
- if (result != templates.end())
- return result->value.newLocal(m_isolate);
+ DOMTemplateMap& domTemplateMap = currentDOMTemplateMap();
+ DOMTemplateMap::iterator result = domTemplateMap.find(domTemplateKey);
+ if (result != domTemplateMap.end())
+ return result->value.Get(m_isolate);
+
v8::Local<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(m_isolate, callback, data, signature, length);
- templates.add(privatePointer, UnsafePersistent<v8::FunctionTemplate>(m_isolate, templ));
+ domTemplateMap.add(domTemplateKey, v8::Eternal<v8::FunctionTemplate>(m_isolate, templ));
return templ;
}
-v8::Handle<v8::FunctionTemplate> V8PerIsolateData::privateTemplateIfExists(WrapperWorldType currentWorldType, void* privatePointer)
+v8::Handle<v8::FunctionTemplate> V8PerIsolateData::existingDOMTemplate(void* domTemplateKey)
{
- TemplateMap& templates = templateMap(currentWorldType);
- TemplateMap::iterator result = templates.find(privatePointer);
- if (result != templates.end())
- return result->value.newLocal(m_isolate);
+ DOMTemplateMap& domTemplateMap = currentDOMTemplateMap();
+ DOMTemplateMap::iterator result = domTemplateMap.find(domTemplateKey);
+ if (result != domTemplateMap.end())
+ return result->value.Get(m_isolate);
return v8::Local<v8::FunctionTemplate>();
}
-void V8PerIsolateData::setPrivateTemplate(WrapperWorldType currentWorldType, void* privatePointer, v8::Handle<v8::FunctionTemplate> templ)
+void V8PerIsolateData::setDOMTemplate(void* domTemplateKey, v8::Handle<v8::FunctionTemplate> templ)
{
- templateMap(currentWorldType).add(privatePointer, UnsafePersistent<v8::FunctionTemplate>(m_isolate, templ));
+ currentDOMTemplateMap().add(domTemplateKey, v8::Eternal<v8::FunctionTemplate>(m_isolate, v8::Local<v8::FunctionTemplate>(templ)));
}
-v8::Handle<v8::FunctionTemplate> V8PerIsolateData::rawDOMTemplate(const WrapperTypeInfo* info, WrapperWorldType currentWorldType)
+v8::Local<v8::Context> V8PerIsolateData::ensureScriptRegexpContext()
{
- TemplateMap& templates = rawDOMTemplateMap(currentWorldType);
- TemplateMap::iterator result = templates.find(info);
- if (result != templates.end())
- return result->value.newLocal(m_isolate);
-
- v8::EscapableHandleScope handleScope(m_isolate);
- v8::Local<v8::FunctionTemplate> templ = createRawTemplate(m_isolate);
- templates.add(info, UnsafePersistent<v8::FunctionTemplate>(m_isolate, templ));
- return handleScope.Escape(templ);
+ if (!m_scriptRegexpScriptState) {
+ v8::Local<v8::Context> context(v8::Context::New(m_isolate));
+ m_scriptRegexpScriptState = ScriptState::create(context, DOMWrapperWorld::create());
+ }
+ return m_scriptRegexpScriptState->context();
}
-v8::Local<v8::Context> V8PerIsolateData::ensureRegexContext()
+bool V8PerIsolateData::hasInstance(const WrapperTypeInfo* info, v8::Handle<v8::Value> value)
{
- if (m_regexContext.isEmpty()) {
- v8::HandleScope handleScope(m_isolate);
- m_regexContext.set(m_isolate, v8::Context::New(m_isolate));
- }
- return m_regexContext.newLocal(m_isolate);
+ return hasInstance(info, value, m_domTemplateMapForMainWorld)
+ || hasInstance(info, value, m_domTemplateMapForNonMainWorld);
}
-bool V8PerIsolateData::hasInstance(const WrapperTypeInfo* info, v8::Handle<v8::Value> value, WrapperWorldType currentWorldType)
+bool V8PerIsolateData::hasInstance(const WrapperTypeInfo* info, v8::Handle<v8::Value> value, DOMTemplateMap& domTemplateMap)
{
- TemplateMap& templates = rawDOMTemplateMap(currentWorldType);
- TemplateMap::iterator result = templates.find(info);
- if (result == templates.end())
+ DOMTemplateMap::iterator result = domTemplateMap.find(info);
+ if (result == domTemplateMap.end())
return false;
- v8::HandleScope handleScope(m_isolate);
- return result->value.newLocal(m_isolate)->HasInstance(value);
+ v8::Handle<v8::FunctionTemplate> templ = result->value.Get(m_isolate);
+ return templ->HasInstance(value);
}
-void V8PerIsolateData::constructorOfToString(const v8::FunctionCallbackInfo<v8::Value>& info)
+v8::Handle<v8::Object> V8PerIsolateData::findInstanceInPrototypeChain(const WrapperTypeInfo* info, v8::Handle<v8::Value> value)
+{
+ v8::Handle<v8::Object> wrapper = findInstanceInPrototypeChain(info, value, m_domTemplateMapForMainWorld);
+ if (!wrapper.IsEmpty())
+ return wrapper;
+ return findInstanceInPrototypeChain(info, value, m_domTemplateMapForNonMainWorld);
+}
+
+v8::Handle<v8::Object> V8PerIsolateData::findInstanceInPrototypeChain(const WrapperTypeInfo* info, v8::Handle<v8::Value> value, DOMTemplateMap& domTemplateMap)
+{
+ if (value.IsEmpty() || !value->IsObject())
+ return v8::Handle<v8::Object>();
+ DOMTemplateMap::iterator result = domTemplateMap.find(info);
+ if (result == domTemplateMap.end())
+ return v8::Handle<v8::Object>();
+ v8::Handle<v8::FunctionTemplate> templ = result->value.Get(m_isolate);
+ return v8::Handle<v8::Object>::Cast(value)->FindInstanceInPrototypeChain(templ);
+}
+
+static void constructorOfToString(const v8::FunctionCallbackInfo<v8::Value>& info)
{
// The DOM constructors' toString functions grab the current toString
// for Functions by taking the toString function of itself and then
@@ -164,7 +206,14 @@ void V8PerIsolateData::constructorOfToString(const v8::FunctionCallbackInfo<v8::
v8SetReturnValue(info, v8::String::Empty(info.GetIsolate()));
return;
}
- v8SetReturnValue(info, V8ScriptRunner::callInternalFunction(v8::Handle<v8::Function>::Cast(value), info.This(), 0, 0, v8::Isolate::GetCurrent()));
+ v8SetReturnValue(info, V8ScriptRunner::callInternalFunction(v8::Handle<v8::Function>::Cast(value), info.This(), 0, 0, info.GetIsolate()));
+}
+
+v8::Handle<v8::FunctionTemplate> V8PerIsolateData::toStringTemplate()
+{
+ if (m_toStringTemplate.isEmpty())
+ m_toStringTemplate.set(m_isolate, v8::FunctionTemplate::New(m_isolate, constructorOfToString));
+ return m_toStringTemplate.newLocal(m_isolate);
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/V8PerIsolateData.h b/chromium/third_party/WebKit/Source/bindings/v8/V8PerIsolateData.h
index bfe9f5a636f..ead107cfd1f 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/V8PerIsolateData.h
+++ b/chromium/third_party/WebKit/Source/bindings/v8/V8PerIsolateData.h
@@ -27,9 +27,11 @@
#define V8PerIsolateData_h
#include "bindings/v8/ScopedPersistent.h"
-#include "bindings/v8/UnsafePersistent.h"
+#include "bindings/v8/ScriptState.h"
+#include "bindings/v8/V8HiddenValue.h"
#include "bindings/v8/WrapperTypeInfo.h"
#include "gin/public/gin_embedders.h"
+#include "gin/public/isolate_holder.h"
#include <v8.h>
#include "wtf/Forward.h"
#include "wtf/HashMap.h"
@@ -41,21 +43,15 @@ namespace WebCore {
class DOMDataStore;
class GCEventData;
class StringCache;
-class V8HiddenPropertyName;
struct WrapperTypeInfo;
class ExternalStringVisitor;
-typedef WTF::Vector<DOMDataStore*> DOMDataList;
+typedef WTF::Vector<DOMDataStore*> DOMDataStoreList;
class V8PerIsolateData {
public:
- static V8PerIsolateData* create(v8::Isolate*);
static void ensureInitialized(v8::Isolate*);
- static V8PerIsolateData* current()
- {
- return from(v8::Isolate::GetCurrent());
- }
static V8PerIsolateData* from(v8::Isolate* isolate)
{
ASSERT(isolate);
@@ -63,57 +59,23 @@ public:
return static_cast<V8PerIsolateData*>(isolate->GetData(gin::kEmbedderBlink));
}
static void dispose(v8::Isolate*);
+ static v8::Isolate* mainThreadIsolate();
- typedef HashMap<const void*, UnsafePersistent<v8::FunctionTemplate> > TemplateMap;
-
- TemplateMap& rawDOMTemplateMap(WrapperWorldType worldType)
- {
- if (worldType == MainWorld)
- return m_rawDOMTemplatesForMainWorld;
- return m_rawDOMTemplatesForNonMainWorld;
- }
-
- TemplateMap& templateMap(WrapperWorldType worldType)
- {
- if (worldType == MainWorld)
- return m_templatesForMainWorld;
- return m_templatesForNonMainWorld;
- }
+ v8::Isolate* isolate() { return m_isolate; }
v8::Handle<v8::FunctionTemplate> toStringTemplate();
- v8::Handle<v8::FunctionTemplate> lazyEventListenerToStringTemplate()
- {
- return v8::Local<v8::FunctionTemplate>::New(m_isolate, m_lazyEventListenerToStringTemplate);
- }
StringCache* stringCache() { return m_stringCache.get(); }
v8::Persistent<v8::Value>& ensureLiveRoot();
- DOMDataList& allStores() { return m_domDataList; }
-
- V8HiddenPropertyName* hiddenPropertyName() { return m_hiddenPropertyName.get(); }
-
- void registerDOMDataStore(DOMDataStore* domDataStore)
- {
- ASSERT(m_domDataList.find(domDataStore) == kNotFound);
- m_domDataList.append(domDataStore);
- }
-
- void unregisterDOMDataStore(DOMDataStore* domDataStore)
- {
- ASSERT(m_domDataList.find(domDataStore) != kNotFound);
- m_domDataList.remove(m_domDataList.find(domDataStore));
- }
-
- // DOMDataStore is owned outside V8PerIsolateData.
- DOMDataStore* workerDOMDataStore() { return m_workerDomDataStore; }
- void setWorkerDOMDataStore(DOMDataStore* store) { m_workerDomDataStore = store; }
-
int recursionLevel() const { return m_recursionLevel; }
int incrementRecursionLevel() { return ++m_recursionLevel; }
int decrementRecursionLevel() { return --m_recursionLevel; }
+ bool performingMicrotaskCheckpoint() const { return m_performingMicrotaskCheckpoint; }
+ void setPerformingMicrotaskCheckpoint(bool performingMicrotaskCheckpoint) { m_performingMicrotaskCheckpoint = performingMicrotaskCheckpoint; }
+
#ifndef NDEBUG
int internalScriptRecursionLevel() const { return m_internalScriptRecursionLevel; }
int incrementInternalScriptRecursionLevel() { return ++m_internalScriptRecursionLevel; }
@@ -121,24 +83,16 @@ public:
#endif
GCEventData* gcEventData() { return m_gcEventData.get(); }
+ V8HiddenValue* hiddenValue() { return m_hiddenValue.get(); }
- // Gives the system a hint that we should request garbage collection
- // upon the next close or navigation event, because some expensive
- // objects have been allocated that we want to take every opportunity
- // to collect.
- void setShouldCollectGarbageSoon() { m_shouldCollectGarbageSoon = true; }
- void clearShouldCollectGarbageSoon() { m_shouldCollectGarbageSoon = false; }
- bool shouldCollectGarbageSoon() const { return m_shouldCollectGarbageSoon; }
-
- v8::Handle<v8::FunctionTemplate> privateTemplate(WrapperWorldType, void* privatePointer, v8::FunctionCallback = 0, v8::Handle<v8::Value> data = v8::Handle<v8::Value>(), v8::Handle<v8::Signature> = v8::Handle<v8::Signature>(), int length = 0);
- v8::Handle<v8::FunctionTemplate> privateTemplateIfExists(WrapperWorldType, void* privatePointer);
- void setPrivateTemplate(WrapperWorldType, void* privatePointer, v8::Handle<v8::FunctionTemplate>);
-
- v8::Handle<v8::FunctionTemplate> rawDOMTemplate(const WrapperTypeInfo*, WrapperWorldType);
+ v8::Handle<v8::FunctionTemplate> domTemplate(void* domTemplateKey, v8::FunctionCallback = 0, v8::Handle<v8::Value> data = v8::Handle<v8::Value>(), v8::Handle<v8::Signature> = v8::Handle<v8::Signature>(), int length = 0);
+ v8::Handle<v8::FunctionTemplate> existingDOMTemplate(void* domTemplateKey);
+ void setDOMTemplate(void* domTemplateKey, v8::Handle<v8::FunctionTemplate>);
- bool hasInstance(const WrapperTypeInfo*, v8::Handle<v8::Value>, WrapperWorldType);
+ bool hasInstance(const WrapperTypeInfo*, v8::Handle<v8::Value>);
+ v8::Handle<v8::Object> findInstanceInPrototypeChain(const WrapperTypeInfo*, v8::Handle<v8::Value>);
- v8::Local<v8::Context> ensureRegexContext();
+ v8::Local<v8::Context> ensureScriptRegexpContext();
const char* previousSamplingState() const { return m_previousSamplingState; }
void setPreviousSamplingState(const char* name) { m_previousSamplingState = name; }
@@ -146,23 +100,21 @@ public:
private:
explicit V8PerIsolateData(v8::Isolate*);
~V8PerIsolateData();
- static void constructorOfToString(const v8::FunctionCallbackInfo<v8::Value>&);
+
+ typedef HashMap<const void*, v8::Eternal<v8::FunctionTemplate> > DOMTemplateMap;
+ DOMTemplateMap& currentDOMTemplateMap();
+ bool hasInstance(const WrapperTypeInfo*, v8::Handle<v8::Value>, DOMTemplateMap&);
+ v8::Handle<v8::Object> findInstanceInPrototypeChain(const WrapperTypeInfo*, v8::Handle<v8::Value>, DOMTemplateMap&);
v8::Isolate* m_isolate;
- TemplateMap m_rawDOMTemplatesForMainWorld;
- TemplateMap m_rawDOMTemplatesForNonMainWorld;
- TemplateMap m_templatesForMainWorld;
- TemplateMap m_templatesForNonMainWorld;
+ OwnPtr<gin::IsolateHolder> m_isolateHolder;
+ DOMTemplateMap m_domTemplateMapForMainWorld;
+ DOMTemplateMap m_domTemplateMapForNonMainWorld;
ScopedPersistent<v8::FunctionTemplate> m_toStringTemplate;
- v8::Persistent<v8::FunctionTemplate> m_lazyEventListenerToStringTemplate;
OwnPtr<StringCache> m_stringCache;
-
- Vector<DOMDataStore*> m_domDataList;
- DOMDataStore* m_workerDomDataStore;
-
- OwnPtr<V8HiddenPropertyName> m_hiddenPropertyName;
+ OwnPtr<V8HiddenValue> m_hiddenValue;
ScopedPersistent<v8::Value> m_liveRoot;
- ScopedPersistent<v8::Context> m_regexContext;
+ RefPtr<ScriptState> m_scriptRegexpScriptState;
const char* m_previousSamplingState;
@@ -175,7 +127,7 @@ private:
int m_internalScriptRecursionLevel;
#endif
OwnPtr<GCEventData> m_gcEventData;
- bool m_shouldCollectGarbageSoon;
+ bool m_performingMicrotaskCheckpoint;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/V8PersistentValueMap.h b/chromium/third_party/WebKit/Source/bindings/v8/V8PersistentValueMap.h
new file mode 100644
index 00000000000..0fa2ac2c902
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/bindings/v8/V8PersistentValueMap.h
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2014 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 V8PersistentValueMap_h
+#define V8PersistentValueMap_h
+
+#include "wtf/HashMap.h"
+#include <v8-util.h>
+#include <v8.h>
+
+namespace WebCore {
+
+/**
+ * A Traits class for v8::PersistentValueMap that uses wtf/HashMap as a
+ * backing store.
+ *
+ * The parameter is_weak will determine whether the references are 'weak'.
+ * If so, entries will be removed from the map as the weak references are
+ * collected.
+ */
+template<class KeyType, class ValueType, bool is_weak>
+class V8PersistentValueMapTraits {
+public:
+ // Map traits:
+ typedef HashMap<KeyType, v8::PersistentContainerValue> Impl;
+ typedef typename Impl::iterator Iterator;
+ static size_t Size(const Impl* impl) { return impl->size(); }
+ static bool Empty(Impl* impl) { return impl->isEmpty(); }
+ static void Swap(Impl& impl, Impl& other) { impl.swap(other); }
+ static Iterator Begin(Impl* impl) { return impl->begin(); }
+ static Iterator End(Impl* impl) { return impl->end(); }
+ static v8::PersistentContainerValue Value(Iterator& iter)
+ {
+ return iter->value;
+ }
+ static KeyType Key(Iterator& iter) { return iter->key; }
+ static v8::PersistentContainerValue Set(
+ Impl* impl, KeyType key, v8::PersistentContainerValue value)
+ {
+ v8::PersistentContainerValue oldValue = Get(impl, key);
+ impl->set(key, value);
+ return oldValue;
+ }
+ static v8::PersistentContainerValue Get(const Impl* impl, KeyType key)
+ {
+ return impl->get(key);
+ }
+
+ static v8::PersistentContainerValue Remove(Impl* impl, KeyType key)
+ {
+ return impl->take(key);
+ }
+
+ // Weak traits:
+ static const v8::PersistentContainerCallbackType kCallbackType = is_weak ? v8::kWeak : v8::kNotWeak;
+ typedef v8::PersistentValueMap<KeyType, ValueType, V8PersistentValueMapTraits<KeyType, ValueType, is_weak> > MapType;
+
+ typedef void WeakCallbackDataType;
+
+ static WeakCallbackDataType* WeakCallbackParameter(MapType* map, KeyType key, const v8::Local<ValueType>& value)
+ {
+ return 0;
+ }
+
+ static void DisposeCallbackData(WeakCallbackDataType* callbackData)
+ {
+ }
+
+ static MapType* MapFromWeakCallbackData(
+ const v8::WeakCallbackData<ValueType, WeakCallbackDataType>& data)
+ {
+ return 0;
+ }
+
+ static KeyType KeyFromWeakCallbackData(
+ const v8::WeakCallbackData<ValueType, WeakCallbackDataType>& data)
+ {
+ return KeyType();
+ }
+
+ // Dispose traits:
+ static void Dispose(v8::Isolate* isolate, v8::UniquePersistent<ValueType> value, KeyType key) { }
+};
+
+/**
+ * A map for safely storing persistent V8 values, based on
+ * v8::PersistentValueMap.
+ *
+ * If is_weak is set, values will be held weakly and map entries will be
+ * removed as their values are being collected.
+ */
+template<class KeyType, class ValueType, bool is_weak = true>
+class V8PersistentValueMap : public v8::PersistentValueMap<KeyType, ValueType, V8PersistentValueMapTraits<KeyType, ValueType, is_weak> > {
+public:
+ typedef V8PersistentValueMapTraits<KeyType, ValueType, is_weak> Traits;
+ explicit V8PersistentValueMap(v8::Isolate* isolate) : v8::PersistentValueMap<KeyType, ValueType, Traits>(isolate) { }
+};
+
+} // namespace WebCore
+
+#endif // V8PersistentValueMap_h
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8NodeListCustom.cpp b/chromium/third_party/WebKit/Source/bindings/v8/V8PersistentValueVector.h
index 341f1c23d5d..02f8314e937 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8NodeListCustom.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/V8PersistentValueVector.h
@@ -28,33 +28,50 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include "config.h"
-#include "V8NodeList.h"
+#ifndef V8PersistentValueVector_h
+#define V8PersistentValueVector_h
-#include "V8Node.h"
-#include "bindings/v8/V8Binding.h"
-#include "bindings/v8/V8GCController.h"
-#include "core/dom/LiveNodeList.h"
-#include "core/dom/NodeList.h"
-#include "wtf/RefPtr.h"
-#include "wtf/StdLibExtras.h"
+#include "wtf/Vector.h"
+#include <v8-util.h>
+#include <v8.h>
namespace WebCore {
-void V8NodeList::visitDOMWrapper(void* object, const v8::Persistent<v8::Object>& wrapper, v8::Isolate* isolate)
-{
- NodeList* impl = static_cast<NodeList*>(object);
- if (!impl->isLiveNodeList()) {
- setObjectGroup(object, wrapper, isolate);
- return;
+class WTFVectorPersistentValueVectorTraits {
+public:
+ typedef Vector<v8::PersistentContainerValue> Impl;
+ static void Append(Impl* impl, v8::PersistentContainerValue value)
+ {
+ impl->append(value);
}
- Node* owner = static_cast<LiveNodeList*>(impl)->ownerNode();
- if (!owner) {
- setObjectGroup(object, wrapper, isolate);
- return;
+ static bool IsEmpty(const Impl* impl)
+ {
+ return impl->isEmpty();
}
+ static size_t Size(const Impl* impl)
+ {
+ return impl->size();
+ }
+ static v8::PersistentContainerValue Get(const Impl* impl, size_t i)
+ {
+ return (i < impl->size()) ? impl->at(i) : v8::kPersistentContainerNotFound;
+ }
+ static void ReserveCapacity(Impl* impl, size_t capacity)
+ {
+ impl->reserveCapacity(capacity);
+ }
+ static void Clear(Impl* impl)
+ {
+ impl->clear();
+ }
+};
- setObjectGroup(V8GCController::opaqueRootForGC(owner, isolate), wrapper, isolate);
-}
+template<class ValueType>
+class V8PersistentValueVector : public v8::PersistentValueVector<ValueType, WTFVectorPersistentValueVectorTraits> {
+public:
+ explicit V8PersistentValueVector(v8::Isolate* isolate) : v8::PersistentValueVector<ValueType, WTFVectorPersistentValueVectorTraits>(isolate) { }
+};
} // namespace WebCore
+
+#endif // V8PersistentValueVector_h
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/V8RecursionScope.cpp b/chromium/third_party/WebKit/Source/bindings/v8/V8RecursionScope.cpp
index c08fba7c855..2519250f28f 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/V8RecursionScope.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/V8RecursionScope.cpp
@@ -38,14 +38,11 @@ namespace WebCore {
void V8RecursionScope::didLeaveScriptContext()
{
- // FIXME: Instrument any work that takes place when script exits to c++ (e.g. Mutation Observers).
+ Microtask::performCheckpoint();
// Indexed DB requires that transactions are created with an internal |active| flag
// set to true, but the flag becomes false when control returns to the event loop.
- IDBPendingTransactionMonitor::deactivateNewTransactions();
-
- if (m_isDocumentContext)
- Microtask::performCheckpoint();
+ IDBPendingTransactionMonitor::from(m_executionContext).deactivateNewTransactions();
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/V8RecursionScope.h b/chromium/third_party/WebKit/Source/bindings/v8/V8RecursionScope.h
index 3bc3da7d024..a73d93a8dc0 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/V8RecursionScope.h
+++ b/chromium/third_party/WebKit/Source/bindings/v8/V8RecursionScope.h
@@ -33,7 +33,9 @@
#include "bindings/v8/V8PerIsolateData.h"
#include "core/dom/ExecutionContext.h"
+#include "core/dom/ScriptForbiddenScope.h"
#include "wtf/Noncopyable.h"
+#include <v8.h>
namespace WebCore {
@@ -57,51 +59,66 @@ namespace WebCore {
class V8RecursionScope {
WTF_MAKE_NONCOPYABLE(V8RecursionScope);
public:
- explicit V8RecursionScope(ExecutionContext* context)
- : m_isDocumentContext(context && context->isDocument())
+ V8RecursionScope(v8::Isolate* isolate, ExecutionContext* context)
+ : m_isolate(isolate)
+ , m_executionContext(*context)
{
- V8PerIsolateData::current()->incrementRecursionLevel();
+ V8PerIsolateData::from(m_isolate)->incrementRecursionLevel();
+ ASSERT(!ScriptForbiddenScope::isScriptForbidden());
+ // If you want V8 to autorun microtasks, this class needs to have a
+ // v8::Isolate::SuppressMicrotaskExecutionScope member.
+ ASSERT(!isolate->WillAutorunMicrotasks());
}
~V8RecursionScope()
{
- if (!V8PerIsolateData::current()->decrementRecursionLevel())
+ if (!V8PerIsolateData::from(m_isolate)->decrementRecursionLevel())
didLeaveScriptContext();
}
- static int recursionLevel()
+ static int recursionLevel(v8::Isolate* isolate)
{
- return V8PerIsolateData::current()->recursionLevel();
+ return V8PerIsolateData::from(isolate)->recursionLevel();
}
#ifndef NDEBUG
- static bool properlyUsed()
+ static bool properlyUsed(v8::Isolate* isolate)
{
- return recursionLevel() > 0 || V8PerIsolateData::current()->internalScriptRecursionLevel() > 0;
+ return recursionLevel(isolate) > 0 || V8PerIsolateData::from(isolate)->internalScriptRecursionLevel() > 0;
}
#endif
class MicrotaskSuppression {
public:
- MicrotaskSuppression()
+ MicrotaskSuppression(v8::Isolate* isolate)
+#ifndef NDEBUG
+ : m_isolate(isolate)
+#endif
{
+ ASSERT(!ScriptForbiddenScope::isScriptForbidden());
#ifndef NDEBUG
- V8PerIsolateData::current()->incrementInternalScriptRecursionLevel();
+ V8PerIsolateData::from(m_isolate)->incrementInternalScriptRecursionLevel();
#endif
}
~MicrotaskSuppression()
{
#ifndef NDEBUG
- V8PerIsolateData::current()->decrementInternalScriptRecursionLevel();
+ V8PerIsolateData::from(m_isolate)->decrementInternalScriptRecursionLevel();
#endif
}
+
+ private:
+#ifndef NDEBUG
+ v8::Isolate* m_isolate;
+#endif
};
private:
void didLeaveScriptContext();
- bool m_isDocumentContext;
+ v8::Isolate* m_isolate;
+ ExecutionContext& m_executionContext;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/V8ScriptRunner.cpp b/chromium/third_party/WebKit/Source/bindings/v8/V8ScriptRunner.cpp
index ed6a1730117..625fddf8095 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/V8ScriptRunner.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/V8ScriptRunner.cpp
@@ -26,6 +26,7 @@
#include "config.h"
#include "bindings/v8/V8ScriptRunner.h"
+#include "bindings/v8/ScriptSourceCode.h"
#include "bindings/v8/V8Binding.h"
#include "bindings/v8/V8GCController.h"
#include "bindings/v8/V8RecursionScope.h"
@@ -36,70 +37,74 @@
namespace WebCore {
-PassOwnPtr<v8::ScriptData> V8ScriptRunner::precompileScript(v8::Handle<v8::String> code, ScriptResource* resource)
+v8::Local<v8::Script> V8ScriptRunner::compileScript(const ScriptSourceCode& source, v8::Isolate* isolate, AccessControlStatus corsStatus)
+{
+ return compileScript(v8String(isolate, source.source()), source.url(), source.startPosition(), source.resource(), isolate, corsStatus);
+}
+
+v8::Local<v8::Script> V8ScriptRunner::compileScript(v8::Handle<v8::String> code, const String& fileName, const TextPosition& scriptStartPosition, ScriptResource* resource, v8::Isolate* isolate, AccessControlStatus corsStatus)
{
- TRACE_EVENT0("v8", "v8.compile");
- TRACE_EVENT_SCOPED_SAMPLING_STATE("V8", "Compile");
// A pseudo-randomly chosen ID used to store and retrieve V8 ScriptData from
// the ScriptResource. If the format changes, this ID should be changed too.
static const unsigned dataTypeID = 0xECC13BD7;
- // Very small scripts are not worth the effort to preparse.
- static const int minPreparseLength = 1024;
-
- if (!resource || code->Length() < minPreparseLength)
- return nullptr;
-
- CachedMetadata* cachedMetadata = resource->cachedMetadata(dataTypeID);
- if (cachedMetadata)
- return adoptPtr(v8::ScriptData::New(cachedMetadata->data(), cachedMetadata->size()));
-
- OwnPtr<v8::ScriptData> scriptData = adoptPtr(v8::ScriptData::PreCompile(code));
- if (!scriptData)
- return nullptr;
+ // Very small scripts are not worth the effort to store cached data.
+ static const int minLengthForCachedData = 1024;
- resource->setCachedMetadata(dataTypeID, scriptData->Data(), scriptData->Length());
+ TRACE_EVENT1("v8", "v8.compile", "fileName", fileName.utf8());
+ TRACE_EVENT_SCOPED_SAMPLING_STATE("V8", "V8Compile");
- return scriptData.release();
-}
-
-v8::Local<v8::Script> V8ScriptRunner::compileScript(v8::Handle<v8::String> code, const String& fileName, const TextPosition& scriptStartPosition, v8::ScriptData* scriptData, v8::Isolate* isolate, AccessControlStatus corsStatus)
-{
- TRACE_EVENT0("v8", "v8.compile");
- TRACE_EVENT_SCOPED_SAMPLING_STATE("V8", "Compile");
+ // NOTE: For compatibility with WebCore, ScriptSourceCode's line starts at
+ // 1, whereas v8 starts at 0.
v8::Handle<v8::String> name = v8String(isolate, fileName);
- v8::Handle<v8::Integer> line = v8::Integer::New(scriptStartPosition.m_line.zeroBasedInt(), isolate);
- v8::Handle<v8::Integer> column = v8::Integer::New(scriptStartPosition.m_column.zeroBasedInt(), isolate);
+ v8::Handle<v8::Integer> line = v8::Integer::New(isolate, scriptStartPosition.m_line.zeroBasedInt());
+ v8::Handle<v8::Integer> column = v8::Integer::New(isolate, scriptStartPosition.m_column.zeroBasedInt());
v8::Handle<v8::Boolean> isSharedCrossOrigin = corsStatus == SharableCrossOrigin ? v8::True(isolate) : v8::False(isolate);
v8::ScriptOrigin origin(name, line, column, isSharedCrossOrigin);
- return v8::Script::Compile(code, &origin, scriptData);
+
+ v8::ScriptCompiler::CompileOptions options = v8::ScriptCompiler::kNoCompileOptions;
+ OwnPtr<v8::ScriptCompiler::CachedData> cachedData;
+ if (resource) {
+ CachedMetadata* cachedMetadata = resource->cachedMetadata(dataTypeID);
+ if (cachedMetadata) {
+ // Ownership of the buffer is not transferred to CachedData.
+ cachedData = adoptPtr(new v8::ScriptCompiler::CachedData(reinterpret_cast<const uint8_t*>(cachedMetadata->data()), cachedMetadata->size()));
+ } else if (code->Length() >= minLengthForCachedData) {
+ options = v8::ScriptCompiler::kProduceDataToCache;
+ }
+ }
+ // source takes ownership of cachedData.
+ v8::ScriptCompiler::Source source(code, origin, cachedData.leakPtr());
+ v8::Local<v8::Script> script = v8::ScriptCompiler::Compile(isolate, &source, options);
+ if (options == v8::ScriptCompiler::kProduceDataToCache) {
+ const v8::ScriptCompiler::CachedData* newCachedData = source.GetCachedData();
+ if (newCachedData) {
+ // Ownership of the buffer is not transferred; source's cachedData continues to own it.
+ resource->setCachedMetadata(dataTypeID, reinterpret_cast<const char*>(newCachedData->data), newCachedData->length);
+ }
+ }
+ return script;
}
v8::Local<v8::Value> V8ScriptRunner::runCompiledScript(v8::Handle<v8::Script> script, ExecutionContext* context, v8::Isolate* isolate)
{
- TRACE_EVENT0("v8", "v8.run");
- TRACE_EVENT_SCOPED_SAMPLING_STATE("V8", "Execution");
if (script.IsEmpty())
return v8::Local<v8::Value>();
+ TRACE_EVENT_SCOPED_SAMPLING_STATE("V8", "V8Execution");
+ TRACE_EVENT1("v8", "v8.run", "fileName", TRACE_STR_COPY(*v8::String::Utf8Value(script->GetUnboundScript()->GetScriptName())));
- if (V8RecursionScope::recursionLevel() >= kMaxRecursionDepth)
+ if (V8RecursionScope::recursionLevel(isolate) >= kMaxRecursionDepth)
return handleMaxRecursionDepthExceeded(isolate);
- if (handleOutOfMemory())
- return v8::Local<v8::Value>();
-
RELEASE_ASSERT(!context->isIteratingOverObservers());
// Run the script and keep track of the current recursion depth.
v8::Local<v8::Value> result;
{
- V8RecursionScope recursionScope(context);
+ V8RecursionScope recursionScope(isolate, context);
result = script->Run();
}
- if (handleOutOfMemory())
- ASSERT(result.IsEmpty());
-
if (result.IsEmpty())
return v8::Local<v8::Value>();
@@ -107,95 +112,84 @@ v8::Local<v8::Value> V8ScriptRunner::runCompiledScript(v8::Handle<v8::Script> sc
return result;
}
-v8::Local<v8::Value> V8ScriptRunner::compileAndRunInternalScript(v8::Handle<v8::String> source, v8::Isolate* isolate, const String& fileName, const TextPosition& scriptStartPosition, v8::ScriptData* scriptData)
+v8::Local<v8::Value> V8ScriptRunner::compileAndRunInternalScript(v8::Handle<v8::String> source, v8::Isolate* isolate, const String& fileName, const TextPosition& scriptStartPosition)
{
TRACE_EVENT0("v8", "v8.run");
- TRACE_EVENT_SCOPED_SAMPLING_STATE("V8", "Execution");
- v8::Handle<v8::Script> script = V8ScriptRunner::compileScript(source, fileName, scriptStartPosition, scriptData, isolate);
+ TRACE_EVENT_SCOPED_SAMPLING_STATE("V8", "V8Execution");
+ v8::Handle<v8::Script> script = V8ScriptRunner::compileScript(source, fileName, scriptStartPosition, 0, isolate);
if (script.IsEmpty())
return v8::Local<v8::Value>();
- V8RecursionScope::MicrotaskSuppression recursionScope;
+ V8RecursionScope::MicrotaskSuppression recursionScope(isolate);
v8::Local<v8::Value> result = script->Run();
crashIfV8IsDead();
return result;
}
-v8::Local<v8::Value> V8ScriptRunner::callFunction(v8::Handle<v8::Function> function, ExecutionContext* context, v8::Handle<v8::Value> receiver, int argc, v8::Handle<v8::Value> info[], v8::Isolate* isolate)
+v8::Local<v8::Value> V8ScriptRunner::callFunction(v8::Handle<v8::Function> function, ExecutionContext* context, v8::Handle<v8::Value> receiver, int argc, v8::Handle<v8::Value> args[], v8::Isolate* isolate)
{
TRACE_EVENT0("v8", "v8.callFunction");
- TRACE_EVENT_SCOPED_SAMPLING_STATE("V8", "Execution");
+ TRACE_EVENT_SCOPED_SAMPLING_STATE("V8", "V8Execution");
- if (V8RecursionScope::recursionLevel() >= kMaxRecursionDepth)
+ if (V8RecursionScope::recursionLevel(isolate) >= kMaxRecursionDepth)
return handleMaxRecursionDepthExceeded(isolate);
RELEASE_ASSERT(!context->isIteratingOverObservers());
- V8RecursionScope recursionScope(context);
- v8::Local<v8::Value> result = function->Call(receiver, argc, info);
+ V8RecursionScope recursionScope(isolate, context);
+ v8::Local<v8::Value> result = function->Call(receiver, argc, args);
crashIfV8IsDead();
return result;
}
-v8::Local<v8::Value> V8ScriptRunner::callInternalFunction(v8::Handle<v8::Function> function, v8::Handle<v8::Value> receiver, int argc, v8::Handle<v8::Value> info[], v8::Isolate* isolate)
+v8::Local<v8::Value> V8ScriptRunner::callInternalFunction(v8::Handle<v8::Function> function, v8::Handle<v8::Value> receiver, int argc, v8::Handle<v8::Value> args[], v8::Isolate* isolate)
{
TRACE_EVENT0("v8", "v8.callFunction");
- TRACE_EVENT_SCOPED_SAMPLING_STATE("V8", "Execution");
- V8RecursionScope::MicrotaskSuppression recursionScope;
- v8::Local<v8::Value> result = function->Call(receiver, argc, info);
- crashIfV8IsDead();
- return result;
-}
-
-v8::Local<v8::Value> V8ScriptRunner::callAsFunction(v8::Handle<v8::Object> object, v8::Handle<v8::Value> receiver, int argc, v8::Handle<v8::Value> info[])
-{
- TRACE_EVENT0("v8", "v8.callFunction");
- TRACE_EVENT_SCOPED_SAMPLING_STATE("V8", "Execution");
-
- V8RecursionScope::MicrotaskSuppression recursionScope;
- v8::Local<v8::Value> result = object->CallAsFunction(receiver, argc, info);
+ TRACE_EVENT_SCOPED_SAMPLING_STATE("V8", "V8Execution");
+ V8RecursionScope::MicrotaskSuppression recursionScope(isolate);
+ v8::Local<v8::Value> result = function->Call(receiver, argc, args);
crashIfV8IsDead();
return result;
}
-v8::Local<v8::Value> V8ScriptRunner::callAsConstructor(v8::Handle<v8::Object> object, int argc, v8::Handle<v8::Value> info[])
+v8::Local<v8::Value> V8ScriptRunner::callAsFunction(v8::Isolate* isolate, v8::Handle<v8::Object> object, v8::Handle<v8::Value> receiver, int argc, v8::Handle<v8::Value> args[])
{
TRACE_EVENT0("v8", "v8.callFunction");
- TRACE_EVENT_SCOPED_SAMPLING_STATE("V8", "Execution");
+ TRACE_EVENT_SCOPED_SAMPLING_STATE("V8", "V8Execution");
- V8RecursionScope::MicrotaskSuppression recursionScope;
- v8::Local<v8::Value> result = object->CallAsConstructor(argc, info);
+ V8RecursionScope::MicrotaskSuppression recursionScope(isolate);
+ v8::Local<v8::Value> result = object->CallAsFunction(receiver, argc, args);
crashIfV8IsDead();
return result;
}
-v8::Local<v8::Object> V8ScriptRunner::instantiateObject(v8::Handle<v8::ObjectTemplate> objectTemplate)
+v8::Local<v8::Object> V8ScriptRunner::instantiateObject(v8::Isolate* isolate, v8::Handle<v8::ObjectTemplate> objectTemplate)
{
TRACE_EVENT0("v8", "v8.newInstance");
- TRACE_EVENT_SCOPED_SAMPLING_STATE("V8", "Execution");
+ TRACE_EVENT_SCOPED_SAMPLING_STATE("V8", "V8Execution");
- V8RecursionScope::MicrotaskSuppression scope;
+ V8RecursionScope::MicrotaskSuppression scope(isolate);
v8::Local<v8::Object> result = objectTemplate->NewInstance();
crashIfV8IsDead();
return result;
}
-v8::Local<v8::Object> V8ScriptRunner::instantiateObject(v8::Handle<v8::Function> function, int argc, v8::Handle<v8::Value> argv[])
+v8::Local<v8::Object> V8ScriptRunner::instantiateObject(v8::Isolate* isolate, v8::Handle<v8::Function> function, int argc, v8::Handle<v8::Value> argv[])
{
TRACE_EVENT0("v8", "v8.newInstance");
- TRACE_EVENT_SCOPED_SAMPLING_STATE("V8", "Execution");
+ TRACE_EVENT_SCOPED_SAMPLING_STATE("V8", "V8Execution");
- V8RecursionScope::MicrotaskSuppression scope;
+ V8RecursionScope::MicrotaskSuppression scope(isolate);
v8::Local<v8::Object> result = function->NewInstance(argc, argv);
crashIfV8IsDead();
return result;
}
-v8::Local<v8::Object> V8ScriptRunner::instantiateObjectInDocument(v8::Handle<v8::Function> function, ExecutionContext* context, int argc, v8::Handle<v8::Value> argv[])
+v8::Local<v8::Object> V8ScriptRunner::instantiateObjectInDocument(v8::Isolate* isolate, v8::Handle<v8::Function> function, ExecutionContext* context, int argc, v8::Handle<v8::Value> argv[])
{
TRACE_EVENT0("v8", "v8.newInstance");
- TRACE_EVENT_SCOPED_SAMPLING_STATE("V8", "Execution");
- V8RecursionScope scope(context);
+ TRACE_EVENT_SCOPED_SAMPLING_STATE("V8", "V8Execution");
+ V8RecursionScope scope(isolate, context);
v8::Local<v8::Object> result = function->NewInstance(argc, argv);
crashIfV8IsDead();
return result;
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/V8ScriptRunner.h b/chromium/third_party/WebKit/Source/bindings/v8/V8ScriptRunner.h
index b36102f20ba..368401be41f 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/V8ScriptRunner.h
+++ b/chromium/third_party/WebKit/Source/bindings/v8/V8ScriptRunner.h
@@ -35,23 +35,23 @@
namespace WebCore {
class ScriptResource;
+class ScriptSourceCode;
class ExecutionContext;
class V8ScriptRunner {
public:
// For the following methods, the caller sites have to hold
// a HandleScope and a ContextScope.
- static PassOwnPtr<v8::ScriptData> precompileScript(v8::Handle<v8::String>, ScriptResource*);
- static v8::Local<v8::Script> compileScript(v8::Handle<v8::String>, const String&, const TextPosition&, v8::ScriptData*, v8::Isolate*, AccessControlStatus = SharableCrossOrigin);
+ static v8::Local<v8::Script> compileScript(const ScriptSourceCode&, v8::Isolate*, AccessControlStatus = SharableCrossOrigin);
+ static v8::Local<v8::Script> compileScript(v8::Handle<v8::String>, const String& fileName, const TextPosition&, ScriptResource*, v8::Isolate*, AccessControlStatus = SharableCrossOrigin);
static v8::Local<v8::Value> runCompiledScript(v8::Handle<v8::Script>, ExecutionContext*, v8::Isolate*);
- static v8::Local<v8::Value> compileAndRunInternalScript(v8::Handle<v8::String>, v8::Isolate*, const String& = String(), const TextPosition& = TextPosition(), v8::ScriptData* = 0);
+ static v8::Local<v8::Value> compileAndRunInternalScript(v8::Handle<v8::String>, v8::Isolate*, const String& = String(), const TextPosition& = TextPosition());
static v8::Local<v8::Value> callInternalFunction(v8::Handle<v8::Function>, v8::Handle<v8::Value> receiver, int argc, v8::Handle<v8::Value> info[], v8::Isolate*);
static v8::Local<v8::Value> callFunction(v8::Handle<v8::Function>, ExecutionContext*, v8::Handle<v8::Value> receiver, int argc, v8::Handle<v8::Value> info[], v8::Isolate*);
- static v8::Local<v8::Value> callAsFunction(v8::Handle<v8::Object>, v8::Handle<v8::Value> receiver, int argc, v8::Handle<v8::Value> info[]);
- static v8::Local<v8::Value> callAsConstructor(v8::Handle<v8::Object>, int argc, v8::Handle<v8::Value> info[]);
- static v8::Local<v8::Object> instantiateObject(v8::Handle<v8::ObjectTemplate>);
- static v8::Local<v8::Object> instantiateObject(v8::Handle<v8::Function>, int argc = 0, v8::Handle<v8::Value> argv[] = 0);
- static v8::Local<v8::Object> instantiateObjectInDocument(v8::Handle<v8::Function>, ExecutionContext*, int argc = 0, v8::Handle<v8::Value> argv[] = 0);
+ static v8::Local<v8::Value> callAsFunction(v8::Isolate*, v8::Handle<v8::Object>, v8::Handle<v8::Value> receiver, int argc, v8::Handle<v8::Value> info[]);
+ static v8::Local<v8::Object> instantiateObject(v8::Isolate*, v8::Handle<v8::ObjectTemplate>);
+ static v8::Local<v8::Object> instantiateObject(v8::Isolate*, v8::Handle<v8::Function>, int argc = 0, v8::Handle<v8::Value> argv[] = 0);
+ static v8::Local<v8::Object> instantiateObjectInDocument(v8::Isolate*, v8::Handle<v8::Function>, ExecutionContext*, int argc = 0, v8::Handle<v8::Value> argv[] = 0);
};
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/V8StringResource.cpp b/chromium/third_party/WebKit/Source/bindings/v8/V8StringResource.cpp
index bce62d4c2fa..3b76e8243f9 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/V8StringResource.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/V8StringResource.cpp
@@ -32,27 +32,9 @@
namespace WebCore {
-WebCoreStringResourceBase* WebCoreStringResourceBase::toWebCoreStringResourceBase(v8::Handle<v8::String> string)
-{
- v8::String::Encoding encoding;
- v8::String::ExternalStringResourceBase* resource = string->GetExternalStringResourceBase(&encoding);
- if (!resource)
- return 0;
- if (encoding == v8::String::ONE_BYTE_ENCODING)
- return static_cast<WebCoreStringResource8*>(resource);
- return static_cast<WebCoreStringResource16*>(resource);
-}
-
-void WebCoreStringResourceBase::visitStrings(ExternalStringVisitor* visitor)
-{
- visitor->visitJSExternalString(m_plainString.impl());
- if (m_plainString.impl() != m_atomicString.impl() && !m_atomicString.isNull())
- visitor->visitJSExternalString(m_atomicString.impl());
-}
-
template<class StringClass> struct StringTraits {
static const StringClass& fromStringResource(WebCoreStringResourceBase*);
- template<bool oneByte>
+ template <typename V8StringTrait>
static StringClass fromV8String(v8::Handle<v8::String>, int);
};
@@ -62,7 +44,7 @@ struct StringTraits<String> {
{
return resource->webcoreString();
}
- template<bool oneByte>
+ template <typename V8StringTrait>
static String fromV8String(v8::Handle<v8::String>, int);
};
@@ -72,59 +54,49 @@ struct StringTraits<AtomicString> {
{
return resource->atomicString();
}
- template<bool oneByte>
+ template <typename V8StringTrait>
static AtomicString fromV8String(v8::Handle<v8::String>, int);
};
-template<>
-String StringTraits<String>::fromV8String<false>(v8::Handle<v8::String> v8String, int length)
-{
- ASSERT(v8String->Length() == length);
- UChar* buffer;
- String result = String::createUninitialized(length, buffer);
- v8String->Write(reinterpret_cast<uint16_t*>(buffer), 0, length);
- return result;
-}
+struct V8StringTwoBytesTrait {
+ typedef UChar CharType;
+ ALWAYS_INLINE static void write(v8::Handle<v8::String> v8String, CharType* buffer, int length)
+ {
+ v8String->Write(reinterpret_cast<uint16_t*>(buffer), 0, length);
+ }
+};
-template<>
-AtomicString StringTraits<AtomicString>::fromV8String<false>(v8::Handle<v8::String> v8String, int length)
-{
- ASSERT(v8String->Length() == length);
- static const int inlineBufferSize = 16;
- if (length <= inlineBufferSize) {
- UChar inlineBuffer[inlineBufferSize];
- v8String->Write(reinterpret_cast<uint16_t*>(inlineBuffer), 0, length);
- return AtomicString(inlineBuffer, length);
+struct V8StringOneByteTrait {
+ typedef LChar CharType;
+ ALWAYS_INLINE static void write(v8::Handle<v8::String> v8String, CharType* buffer, int length)
+ {
+ v8String->WriteOneByte(buffer, 0, length);
}
- UChar* buffer;
- String result = String::createUninitialized(length, buffer);
- v8String->Write(reinterpret_cast<uint16_t*>(buffer), 0, length);
- return AtomicString(result);
-}
+};
-template<>
-String StringTraits<String>::fromV8String<true>(v8::Handle<v8::String> v8String, int length)
+template <typename V8StringTrait>
+String StringTraits<String>::fromV8String(v8::Handle<v8::String> v8String, int length)
{
ASSERT(v8String->Length() == length);
- LChar* buffer;
+ typename V8StringTrait::CharType* buffer;
String result = String::createUninitialized(length, buffer);
- v8String->WriteOneByte(buffer, 0, length);
+ V8StringTrait::write(v8String, buffer, length);
return result;
}
-template<>
-AtomicString StringTraits<AtomicString>::fromV8String<true>(v8::Handle<v8::String> v8String, int length)
+template <typename V8StringTrait>
+AtomicString StringTraits<AtomicString>::fromV8String(v8::Handle<v8::String> v8String, int length)
{
ASSERT(v8String->Length() == length);
- static const int inlineBufferSize = 32;
+ static const int inlineBufferSize = 32 / sizeof(typename V8StringTrait::CharType);
if (length <= inlineBufferSize) {
- LChar inlineBuffer[inlineBufferSize];
- v8String->WriteOneByte(inlineBuffer, 0, length);
+ typename V8StringTrait::CharType inlineBuffer[inlineBufferSize];
+ V8StringTrait::write(v8String, inlineBuffer, length);
return AtomicString(inlineBuffer, length);
}
- LChar* buffer;
+ typename V8StringTrait::CharType* buffer;
String string = String::createUninitialized(length, buffer);
- v8String->WriteOneByte(buffer, 0, length);
+ V8StringTrait::write(v8String, buffer, length);
return AtomicString(string);
}
@@ -132,7 +104,6 @@ template<typename StringType>
StringType v8StringToWebCoreString(v8::Handle<v8::String> v8String, ExternalMode external)
{
{
- // A lot of WebCoreStringResourceBase::toWebCoreStringResourceBase is copied here by hand for performance reasons.
// This portion of this function is very hot in certain Dromeao benchmarks.
v8::String::Encoding encoding;
v8::String::ExternalStringResourceBase* resource = v8String->GetExternalStringResourceBase(&encoding);
@@ -151,7 +122,7 @@ StringType v8StringToWebCoreString(v8::Handle<v8::String> v8String, ExternalMode
return StringType("");
bool oneByte = v8String->ContainsOnlyOneByte();
- StringType result(oneByte ? StringTraits<StringType>::template fromV8String<true>(v8String, length) : StringTraits<StringType>::template fromV8String<false>(v8String, length));
+ StringType result(oneByte ? StringTraits<StringType>::template fromV8String<V8StringOneByteTrait>(v8String, length) : StringTraits<StringType>::template fromV8String<V8StringTwoBytesTrait>(v8String, length));
if (external != Externalize || !v8String->CanMakeExternal())
return result;
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/V8StringResource.h b/chromium/third_party/WebKit/Source/bindings/v8/V8StringResource.h
index b8b57944a47..69f849b31e9 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/V8StringResource.h
+++ b/chromium/third_party/WebKit/Source/bindings/v8/V8StringResource.h
@@ -39,8 +39,6 @@ class ExternalStringVisitor;
// to manage the life-cycle of the underlying buffer of the external string.
class WebCoreStringResourceBase {
public:
- static WebCoreStringResourceBase* toWebCoreStringResourceBase(v8::Handle<v8::String>);
-
explicit WebCoreStringResourceBase(const String& string)
: m_plainString(string)
{
@@ -89,8 +87,6 @@ public:
return m_atomicString;
}
- void visitStrings(ExternalStringVisitor*);
-
protected:
// A shallow copy of the string. Keeps the string buffer alive until the V8 engine garbage collects it.
String m_plainString;
@@ -111,7 +107,7 @@ private:
#endif
};
-class WebCoreStringResource16 : public WebCoreStringResourceBase, public v8::String::ExternalStringResource {
+class WebCoreStringResource16 FINAL : public WebCoreStringResourceBase, public v8::String::ExternalStringResource {
public:
explicit WebCoreStringResource16(const String& string)
: WebCoreStringResourceBase(string)
@@ -132,7 +128,7 @@ public:
}
};
-class WebCoreStringResource8 : public WebCoreStringResourceBase, public v8::String::ExternalAsciiStringResource {
+class WebCoreStringResource8 FINAL : public WebCoreStringResourceBase, public v8::String::ExternalAsciiStringResource {
public:
explicit WebCoreStringResource8(const String& string)
: WebCoreStringResourceBase(string)
@@ -173,23 +169,37 @@ enum V8StringResourceMode {
template <V8StringResourceMode Mode = DefaultMode>
class V8StringResource {
public:
+ V8StringResource()
+ : m_mode(Externalize)
+ {
+ }
+
V8StringResource(v8::Handle<v8::Value> object)
: m_v8Object(object)
, m_mode(Externalize)
- , m_string()
{
}
- bool prepare();
- operator String() const { return toString<String>(); }
- operator AtomicString() const { return toString<AtomicString>(); }
+ void operator=(v8::Handle<v8::Value> object)
+ {
+ m_v8Object = object;
+ }
-private:
- bool prepareBase()
+ void operator=(const String& string)
+ {
+ setString(string);
+ }
+
+ bool prepare()
{
if (m_v8Object.IsEmpty())
return true;
+ if (!isValid()) {
+ setString(String());
+ return true;
+ }
+
if (LIKELY(m_v8Object->IsString()))
return true;
@@ -208,6 +218,11 @@ private:
}
return true;
}
+ operator String() const { return toString<String>(); }
+ operator AtomicString() const { return toString<AtomicString>(); }
+
+private:
+ bool isValid() const;
void setString(const String& string)
{
@@ -229,27 +244,19 @@ private:
String m_string;
};
-template<> inline bool V8StringResource<DefaultMode>::prepare()
+template<> inline bool V8StringResource<DefaultMode>::isValid() const
{
- return prepareBase();
+ return true;
}
-template<> inline bool V8StringResource<WithNullCheck>::prepare()
+template<> inline bool V8StringResource<WithNullCheck>::isValid() const
{
- if (m_v8Object.IsEmpty() || m_v8Object->IsNull()) {
- setString(String());
- return true;
- }
- return prepareBase();
+ return !m_v8Object->IsNull();
}
-template<> inline bool V8StringResource<WithUndefinedOrNullCheck>::prepare()
+template<> inline bool V8StringResource<WithUndefinedOrNullCheck>::isValid() const
{
- if (m_v8Object.IsEmpty() || m_v8Object->IsNull() || m_v8Object->IsUndefined()) {
- setString(String());
- return true;
- }
- return prepareBase();
+ return !m_v8Object->IsNull() && !m_v8Object->IsUndefined();
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/V8ThrowException.cpp b/chromium/third_party/WebKit/Source/bindings/v8/V8ThrowException.cpp
index 0f1ffcc69d3..ae2be273cff 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/V8ThrowException.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/V8ThrowException.cpp
@@ -25,7 +25,7 @@
#include "config.h"
#include "bindings/v8/V8ThrowException.h"
-#include "V8DOMException.h"
+#include "bindings/core/v8/V8DOMException.h"
#include "bindings/v8/V8Binding.h"
#include "core/dom/DOMException.h"
#include "core/dom/ExceptionCode.h"
@@ -55,7 +55,7 @@ v8::Handle<v8::Value> V8ThrowException::createDOMException(int ec, const String&
if (ec == TypeError)
return V8ThrowException::createTypeError(sanitizedMessage, isolate);
- RefPtr<DOMException> domException = DOMException::create(ec, sanitizedMessage, unsanitizedMessage);
+ RefPtrWillBeRawPtr<DOMException> domException = DOMException::create(ec, sanitizedMessage, unsanitizedMessage);
v8::Handle<v8::Value> exception = toV8(domException, creationContext, isolate);
if (exception.IsEmpty())
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/V8ThrowException.h b/chromium/third_party/WebKit/Source/bindings/v8/V8ThrowException.h
index 7a4d20f0609..26addf08538 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/V8ThrowException.h
+++ b/chromium/third_party/WebKit/Source/bindings/v8/V8ThrowException.h
@@ -47,10 +47,6 @@ public:
}
static v8::Handle<v8::Value> createDOMException(int, const String& sanitizedMessage, const String& unsanitizedMessage, const v8::Handle<v8::Object>& creationContext, v8::Isolate*);
- static v8::Handle<v8::Value> throwDOMException(int ec, const v8::Handle<v8::Object>& creationContext, v8::Isolate* isolate)
- {
- return throwDOMException(ec, String(), creationContext, isolate);
- }
static v8::Handle<v8::Value> throwDOMException(int ec, const String& message, const v8::Handle<v8::Object>& creationContext, v8::Isolate* isolate)
{
return throwDOMException(ec, message, String(), creationContext, isolate);
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/V8Utilities.cpp b/chromium/third_party/WebKit/Source/bindings/v8/V8Utilities.cpp
deleted file mode 100644
index 6a70b502c32..00000000000
--- a/chromium/third_party/WebKit/Source/bindings/v8/V8Utilities.cpp
+++ /dev/null
@@ -1,181 +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 "bindings/v8/V8Utilities.h"
-
-#include "V8MessagePort.h"
-#include "bindings/v8/ExceptionMessages.h"
-#include "bindings/v8/ScriptState.h"
-#include "bindings/v8/V8AbstractEventListener.h"
-#include "bindings/v8/V8Binding.h"
-#include "bindings/v8/custom/V8ArrayBufferCustom.h"
-#include "core/dom/Document.h"
-#include "core/dom/ExceptionCode.h"
-#include "core/dom/ExecutionContext.h"
-#include "core/dom/MessagePort.h"
-#include "core/frame/Frame.h"
-#include "core/workers/WorkerGlobalScope.h"
-#include "wtf/ArrayBuffer.h"
-#include "wtf/text/WTFString.h"
-#include <v8.h>
-
-
-namespace WebCore {
-
-// Use an array to hold dependents. It works like a ref-counted scheme.
-// A value can be added more than once to the DOM object.
-void createHiddenDependency(v8::Handle<v8::Object> object, v8::Local<v8::Value> value, int cacheIndex, v8::Isolate* isolate)
-{
- v8::Local<v8::Value> cache = object->GetInternalField(cacheIndex);
- if (cache->IsNull() || cache->IsUndefined()) {
- cache = v8::Array::New(isolate);
- object->SetInternalField(cacheIndex, cache);
- }
-
- v8::Local<v8::Array> cacheArray = v8::Local<v8::Array>::Cast(cache);
- cacheArray->Set(v8::Integer::New(cacheArray->Length(), isolate), value);
-}
-
-bool extractTransferables(v8::Local<v8::Value> value, MessagePortArray& ports, ArrayBufferArray& arrayBuffers, bool& notASequence, v8::Isolate* isolate)
-{
- if (isUndefinedOrNull(value)) {
- ports.resize(0);
- arrayBuffers.resize(0);
- return true;
- }
-
- uint32_t length = 0;
- if (value->IsArray()) {
- v8::Local<v8::Array> array = v8::Local<v8::Array>::Cast(value);
- length = array->Length();
- } else if (toV8Sequence(value, length, isolate).IsEmpty()) {
- notASequence = true;
- return false;
- }
-
- v8::Local<v8::Object> transferrables = v8::Local<v8::Object>::Cast(value);
-
- // Validate the passed array of transferrables.
- for (unsigned int i = 0; i < length; ++i) {
- v8::Local<v8::Value> transferrable = transferrables->Get(i);
- // Validation of non-null objects, per HTML5 spec 10.3.3.
- if (isUndefinedOrNull(transferrable)) {
- setDOMException(DataCloneError, isolate);
- return false;
- }
- // Validation of Objects implementing an interface, per WebIDL spec 4.1.15.
- if (V8MessagePort::hasInstance(transferrable, isolate, worldType(isolate))) {
- RefPtr<MessagePort> port = V8MessagePort::toNative(v8::Handle<v8::Object>::Cast(transferrable));
- // Check for duplicate MessagePorts.
- if (ports.contains(port)) {
- setDOMException(DataCloneError, isolate);
- return false;
- }
- ports.append(port.release());
- } else if (V8ArrayBuffer::hasInstance(transferrable, isolate, worldType(isolate)))
- arrayBuffers.append(V8ArrayBuffer::toNative(v8::Handle<v8::Object>::Cast(transferrable)));
- else {
- setDOMException(DataCloneError, isolate);
- return false;
- }
- }
- return true;
-}
-
-bool getMessagePortArray(v8::Local<v8::Value> value, const String& propertyName, MessagePortArray& ports, v8::Isolate* isolate)
-{
- if (isUndefinedOrNull(value)) {
- ports.resize(0);
- return true;
- }
- if (!value->IsArray()) {
- throwTypeError(ExceptionMessages::notASequenceTypeProperty(propertyName), isolate);
- return false;
- }
- bool success = false;
- ports = toRefPtrNativeArray<MessagePort, V8MessagePort>(value, propertyName, isolate, &success);
- return success;
-}
-
-bool getMessagePortArray(v8::Local<v8::Value> value, int argumentIndex, MessagePortArray& ports, v8::Isolate* isolate)
-{
- if (isUndefinedOrNull(value)) {
- ports.resize(0);
- return true;
- }
- if (!value->IsArray()) {
- throwTypeError(ExceptionMessages::notAnArrayTypeArgumentOrValue(argumentIndex), isolate);
- return false;
- }
- bool success = false;
- ports = toRefPtrNativeArray<MessagePort, V8MessagePort>(value, argumentIndex, isolate, &success);
- return success;
-}
-
-void removeHiddenDependency(v8::Handle<v8::Object> object, v8::Local<v8::Value> value, int cacheIndex, v8::Isolate* isolate)
-{
- v8::Local<v8::Value> cache = object->GetInternalField(cacheIndex);
- if (!cache->IsArray())
- return;
- v8::Local<v8::Array> cacheArray = v8::Local<v8::Array>::Cast(cache);
- for (int i = cacheArray->Length() - 1; i >= 0; --i) {
- v8::Local<v8::Value> cached = cacheArray->Get(v8::Integer::New(i, isolate));
- if (cached->StrictEquals(value)) {
- cacheArray->Delete(i);
- return;
- }
- }
-}
-
-void transferHiddenDependency(v8::Handle<v8::Object> object, EventListener* oldValue, v8::Local<v8::Value> newValue, int cacheIndex, v8::Isolate* isolate)
-{
- if (oldValue) {
- V8AbstractEventListener* oldListener = V8AbstractEventListener::cast(oldValue);
- if (oldListener) {
- v8::Local<v8::Object> oldListenerObject = oldListener->getExistingListenerObject();
- if (!oldListenerObject.IsEmpty())
- removeHiddenDependency(object, oldListenerObject, cacheIndex, isolate);
- }
- }
- // Non-callable input is treated as null and ignored
- if (newValue->IsFunction())
- createHiddenDependency(object, newValue, cacheIndex, isolate);
-}
-
-ExecutionContext* getExecutionContext()
-{
- if (WorkerScriptController* controller = WorkerScriptController::controllerForContext())
- return &controller->workerGlobalScope();
-
- return currentDocument();
-}
-
-} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/V8Utilities.h b/chromium/third_party/WebKit/Source/bindings/v8/V8Utilities.h
deleted file mode 100644
index 4a0efd41b96..00000000000
--- a/chromium/third_party/WebKit/Source/bindings/v8/V8Utilities.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (C) 2006, 2007, 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.
- */
-
-#ifndef V8Utilities_h
-#define V8Utilities_h
-
-#include "wtf/Forward.h"
-#include <v8.h>
-
-namespace WTF {
-class ArrayBuffer;
-}
-
-namespace WebCore {
-
- class EventListener;
- class MessagePort;
- class ExecutionContext;
-
- // Use an array to hold dependents. It works like a ref-counted scheme. A value can be added more than once to the DOM object.
- void createHiddenDependency(v8::Handle<v8::Object>, v8::Local<v8::Value>, int cacheIndex, v8::Isolate*);
- void removeHiddenDependency(v8::Handle<v8::Object>, v8::Local<v8::Value>, int cacheIndex, v8::Isolate*);
-
- // Combo create/remove, for EventHandler setters in generated bindings:
- void transferHiddenDependency(v8::Handle<v8::Object>, EventListener* oldValue, v8::Local<v8::Value> newValue, int cacheIndex, v8::Isolate*);
-
- ExecutionContext* getExecutionContext();
-
- typedef WTF::Vector<RefPtr<MessagePort>, 1> MessagePortArray;
- typedef WTF::Vector<RefPtr<ArrayBuffer>, 1> ArrayBufferArray;
-
- // Helper function which pulls the values out of a JS sequence and into a MessagePortArray.
- // Also validates the elements per sections 4.1.13 and 4.1.15 of the WebIDL spec and section 8.3.3
- // of the HTML5 spec and generates exceptions as appropriate. If the supplied argument's type isn't
- // a JS sequence, a type error is signalled by setting 'notASequence' to true -- the caller
- // then being responsible for generating a TypeError having a message that fits the context.
- // Returns true if the array was filled, or false if the passed value was not of an appropriate type.
- bool extractTransferables(v8::Local<v8::Value>, MessagePortArray&, ArrayBufferArray&, bool& notASequence, v8::Isolate*);
-
- bool getMessagePortArray(v8::Local<v8::Value>, const String& propertyName, MessagePortArray&, v8::Isolate*);
- bool getMessagePortArray(v8::Local<v8::Value>, int argumentIndex, MessagePortArray&, v8::Isolate*);
-
-} // namespace WebCore
-
-#endif // V8Utilities_h
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/V8ValueCache.cpp b/chromium/third_party/WebKit/Source/bindings/v8/V8ValueCache.cpp
index 0681d0c059b..6d64a56169c 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/V8ValueCache.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/V8ValueCache.cpp
@@ -27,11 +27,33 @@
#include "bindings/v8/V8ValueCache.h"
#include "bindings/v8/V8Binding.h"
-#include "bindings/v8/V8Utilities.h"
#include "wtf/text/StringHash.h"
namespace WebCore {
+StringCacheMapTraits::MapType* StringCacheMapTraits::MapFromWeakCallbackData(
+ const v8::WeakCallbackData<v8::String, WeakCallbackDataType>& data)
+{
+ return &(V8PerIsolateData::from(data.GetIsolate())->stringCache()->m_stringCache);
+}
+
+
+void StringCacheMapTraits::Dispose(
+ v8::Isolate* isolate, v8::UniquePersistent<v8::String> value, StringImpl* key)
+{
+ V8PerIsolateData::from(isolate)->stringCache()->InvalidateLastString();
+ key->deref();
+}
+
+
+StringCache::~StringCache()
+{
+ // The MapType::Dispose callback calls StringCache::InvalidateLastString,
+ // which will only work while the destructor has not yet finished. Thus,
+ // we need to clear the map before the destructor has completed.
+ m_stringCache.Clear();
+}
+
static v8::Local<v8::String> makeExternalString(const String& string, v8::Isolate* isolate)
{
if (string.is8Bit()) {
@@ -54,11 +76,11 @@ v8::Handle<v8::String> StringCache::v8ExternalStringSlow(StringImpl* stringImpl,
if (!stringImpl->length())
return v8::String::Empty(isolate);
- UnsafePersistent<v8::String> cachedV8String = m_stringCache.get(stringImpl);
- if (!cachedV8String.isEmpty()) {
+ StringCacheMapTraits::MapType::PersistentValueReference cachedV8String = m_stringCache.GetReference(stringImpl);
+ if (!cachedV8String.IsEmpty()) {
m_lastStringImpl = stringImpl;
m_lastV8String = cachedV8String;
- return cachedV8String.newLocal(isolate);
+ return m_lastV8String.NewLocal(isolate);
}
return createStringAndInsertIntoCache(stringImpl, isolate);
@@ -71,11 +93,11 @@ void StringCache::setReturnValueFromStringSlow(v8::ReturnValue<v8::Value> return
return;
}
- UnsafePersistent<v8::String> cachedV8String = m_stringCache.get(stringImpl);
- if (!cachedV8String.isEmpty()) {
+ StringCacheMapTraits::MapType::PersistentValueReference cachedV8String = m_stringCache.GetReference(stringImpl);
+ if (!cachedV8String.IsEmpty()) {
m_lastStringImpl = stringImpl;
m_lastV8String = cachedV8String;
- returnValue.Set(*cachedV8String.persistent());
+ m_lastV8String.SetReturnValue(returnValue);
return;
}
@@ -84,34 +106,27 @@ void StringCache::setReturnValueFromStringSlow(v8::ReturnValue<v8::Value> return
v8::Local<v8::String> StringCache::createStringAndInsertIntoCache(StringImpl* stringImpl, v8::Isolate* isolate)
{
- ASSERT(!m_stringCache.contains(stringImpl));
+ ASSERT(!m_stringCache.Contains(stringImpl));
ASSERT(stringImpl->length());
v8::Local<v8::String> newString = makeExternalString(String(stringImpl), isolate);
if (newString.IsEmpty())
return newString;
- v8::Persistent<v8::String> wrapper(isolate, newString);
+ v8::UniquePersistent<v8::String> wrapper(isolate, newString);
stringImpl->ref();
wrapper.MarkIndependent();
- wrapper.SetWeak(stringImpl, &setWeakCallback);
- m_lastV8String = UnsafePersistent<v8::String>(wrapper);
+ m_stringCache.Set(stringImpl, wrapper.Pass(), &m_lastV8String);
m_lastStringImpl = stringImpl;
- m_stringCache.set(stringImpl, m_lastV8String);
return newString;
}
-void StringCache::setWeakCallback(const v8::WeakCallbackData<v8::String, StringImpl>& data)
+void StringCache::InvalidateLastString()
{
- StringCache* stringCache = V8PerIsolateData::from(data.GetIsolate())->stringCache();
- stringCache->m_lastStringImpl = 0;
- stringCache->m_lastV8String.clear();
- ASSERT(stringCache->m_stringCache.contains(data.GetParameter()));
- stringCache->m_stringCache.get(data.GetParameter()).dispose();
- stringCache->m_stringCache.remove(data.GetParameter());
- data.GetParameter()->deref();
+ m_lastStringImpl = nullptr;
+ m_lastV8String.Reset();
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/V8ValueCache.h b/chromium/third_party/WebKit/Source/bindings/v8/V8ValueCache.h
index 44ee8db6e80..8110cd38d27 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/V8ValueCache.h
+++ b/chromium/third_party/WebKit/Source/bindings/v8/V8ValueCache.h
@@ -26,7 +26,7 @@
#ifndef V8ValueCache_h
#define V8ValueCache_h
-#include "bindings/v8/UnsafePersistent.h"
+#include "bindings/v8/V8PersistentValueMap.h"
#include <v8.h>
#include "wtf/HashMap.h"
#include "wtf/RefPtr.h"
@@ -35,15 +35,39 @@
namespace WebCore {
+class StringCacheMapTraits : public V8PersistentValueMapTraits<StringImpl*, v8::String, true> {
+public:
+ // Weak traits:
+ typedef StringImpl WeakCallbackDataType;
+ typedef v8::PersistentValueMap<StringImpl*, v8::String, StringCacheMapTraits> MapType;
+
+ static WeakCallbackDataType* WeakCallbackParameter(
+ MapType* map, StringImpl* key, v8::Local<v8::String>& value) { return key; }
+ static void DisposeCallbackData(WeakCallbackDataType* callbackData) { }
+
+ static MapType* MapFromWeakCallbackData(
+ const v8::WeakCallbackData<v8::String, WeakCallbackDataType>&);
+
+ static StringImpl* KeyFromWeakCallbackData(
+ const v8::WeakCallbackData<v8::String, WeakCallbackDataType>& data)
+ {
+ return data.GetParameter();
+ }
+
+ static void Dispose(v8::Isolate*, v8::UniquePersistent<v8::String> value, StringImpl* key);
+};
+
+
class StringCache {
public:
- StringCache() { }
+ StringCache(v8::Isolate* isolate) : m_stringCache(isolate) { }
+ ~StringCache();
v8::Handle<v8::String> v8ExternalString(StringImpl* stringImpl, v8::Isolate* isolate)
{
ASSERT(stringImpl);
if (m_lastStringImpl.get() == stringImpl)
- return m_lastV8String.newLocal(isolate);
+ return m_lastV8String.NewLocal(isolate);
return v8ExternalStringSlow(stringImpl, isolate);
}
@@ -51,20 +75,22 @@ public:
{
ASSERT(stringImpl);
if (m_lastStringImpl.get() == stringImpl)
- returnValue.Set(*m_lastV8String.persistent());
+ m_lastV8String.SetReturnValue(returnValue);
else
setReturnValueFromStringSlow(returnValue, stringImpl);
}
-private:
- static void setWeakCallback(const v8::WeakCallbackData<v8::String, StringImpl>&);
+ friend class StringCacheMapTraits;
+private:
v8::Handle<v8::String> v8ExternalStringSlow(StringImpl*, v8::Isolate*);
void setReturnValueFromStringSlow(v8::ReturnValue<v8::Value>, StringImpl*);
v8::Local<v8::String> createStringAndInsertIntoCache(StringImpl*, v8::Isolate*);
+ void InvalidateLastString();
+
+ StringCacheMapTraits::MapType m_stringCache;
+ StringCacheMapTraits::MapType::PersistentValueReference m_lastV8String;
- HashMap<StringImpl*, UnsafePersistent<v8::String> > m_stringCache;
- UnsafePersistent<v8::String> m_lastV8String;
// Note: RefPtr is a must as we cache by StringImpl* equality, not identity
// hence lastStringImpl might be not a key of the cache (in sense of identity)
// and hence it's not refed on addition.
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/V8WindowShell.cpp b/chromium/third_party/WebKit/Source/bindings/v8/V8WindowShell.cpp
index 3474312da86..8b9e8b2dbfb 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/V8WindowShell.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/V8WindowShell.cpp
@@ -31,28 +31,30 @@
#include "config.h"
#include "bindings/v8/V8WindowShell.h"
-#include "RuntimeEnabledFeatures.h"
-#include "V8Document.h"
-#include "V8HTMLCollection.h"
-#include "V8HTMLDocument.h"
-#include "V8Window.h"
+#include "bindings/core/v8/V8Document.h"
+#include "bindings/core/v8/V8HTMLCollection.h"
+#include "bindings/core/v8/V8HTMLDocument.h"
+#include "bindings/core/v8/V8Window.h"
#include "bindings/v8/DOMWrapperWorld.h"
#include "bindings/v8/ScriptController.h"
#include "bindings/v8/V8Binding.h"
+#include "bindings/v8/V8DOMActivityLogger.h"
#include "bindings/v8/V8GCForContextDispose.h"
-#include "bindings/v8/V8HiddenPropertyName.h"
+#include "bindings/v8/V8HiddenValue.h"
#include "bindings/v8/V8Initializer.h"
#include "bindings/v8/V8ObjectConstructor.h"
-#include "bindings/v8/V8PerContextData.h"
+#include "core/dom/ScriptForbiddenScope.h"
+#include "core/frame/LocalFrame.h"
+#include "core/frame/csp/ContentSecurityPolicy.h"
#include "core/html/HTMLCollection.h"
#include "core/html/HTMLIFrameElement.h"
#include "core/inspector/InspectorInstrumentation.h"
#include "core/loader/DocumentLoader.h"
#include "core/loader/FrameLoader.h"
#include "core/loader/FrameLoaderClient.h"
-#include "core/frame/ContentSecurityPolicy.h"
-#include "core/frame/Frame.h"
+#include "platform/RuntimeEnabledFeatures.h"
#include "platform/TraceEvent.h"
+#include "platform/heap/Handle.h"
#include "platform/weborigin/SecurityOrigin.h"
#include "public/platform/Platform.h"
#include "wtf/Assertions.h"
@@ -77,33 +79,31 @@ static void setInjectedScriptContextDebugId(v8::Handle<v8::Context> targetContex
V8PerContextDebugData::setContextDebugData(targetContext, "injected", debugId);
}
-PassOwnPtr<V8WindowShell> V8WindowShell::create(Frame* frame, PassRefPtr<DOMWrapperWorld> world, v8::Isolate* isolate)
+PassOwnPtr<V8WindowShell> V8WindowShell::create(LocalFrame* frame, DOMWrapperWorld& world, v8::Isolate* isolate)
{
- return adoptPtr(new V8WindowShell(frame, world, isolate));
+ return adoptPtr(new V8WindowShell(frame, &world, isolate));
}
-V8WindowShell::V8WindowShell(Frame* frame, PassRefPtr<DOMWrapperWorld> world, v8::Isolate* isolate)
+V8WindowShell::V8WindowShell(LocalFrame* frame, PassRefPtr<DOMWrapperWorld> world, v8::Isolate* isolate)
: m_frame(frame)
- , m_world(world)
, m_isolate(isolate)
+ , m_world(world)
{
}
void V8WindowShell::disposeContext(GlobalDetachmentBehavior behavior)
{
- m_perContextData.clear();
-
- if (!m_contextHolder)
+ if (!isContextInitialized())
return;
v8::HandleScope handleScope(m_isolate);
- v8::Handle<v8::Context> context = m_contextHolder->context();
+ v8::Handle<v8::Context> context = m_scriptState->context();
m_frame->loader().client()->willReleaseScriptContext(context, m_world->worldId());
if (behavior == DetachGlobal)
context->DetachGlobal();
- m_contextHolder.clear();
+ m_scriptState->disposePerContextData();
// 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
@@ -111,12 +111,9 @@ void V8WindowShell::disposeContext(GlobalDetachmentBehavior behavior)
V8GCForContextDispose::instanceTemplate().notifyContextDisposed(m_frame->isMainFrame());
}
-void V8WindowShell::clearForClose(bool destroyGlobal)
+void V8WindowShell::clearForClose()
{
- if (destroyGlobal)
- m_global.clear();
-
- if (!m_contextHolder)
+ if (!isContextInitialized())
return;
m_document.clear();
@@ -125,21 +122,19 @@ void V8WindowShell::clearForClose(bool destroyGlobal)
void V8WindowShell::clearForNavigation()
{
- if (!m_contextHolder)
+ if (!isContextInitialized())
return;
- v8::HandleScope handleScope(m_isolate);
- m_document.clear();
+ ScriptState::Scope scope(m_scriptState.get());
- v8::Handle<v8::Context> context = m_contextHolder->context();
- v8::Context::Scope contextScope(context);
+ m_document.clear();
// Clear the document wrapper cache before turning on access checks on
- // the old DOMWindow wrapper. This way, access to the document wrapper
- // will be protected by the security checks on the DOMWindow wrapper.
+ // the old LocalDOMWindow wrapper. This way, access to the document wrapper
+ // will be protected by the security checks on the LocalDOMWindow wrapper.
clearDocumentProperty();
- v8::Handle<v8::Object> windowWrapper = m_global.newLocal(m_isolate)->FindInstanceInPrototypeChain(V8Window::domTemplate(m_isolate, worldTypeInMainThread(m_isolate)));
+ v8::Handle<v8::Object> windowWrapper = V8Window::findInstanceInPrototypeChain(m_global.newLocal(m_isolate), m_isolate);
ASSERT(!windowWrapper.IsEmpty());
windowWrapper->TurnOnAccessCheck();
disposeContext(DetachGlobal);
@@ -147,16 +142,16 @@ void V8WindowShell::clearForNavigation()
// Create a new environment and setup the global object.
//
-// The global object corresponds to a DOMWindow instance. However, to
-// allow properties of the JS DOMWindow instance to be shadowed, we
-// use a shadow object as the global object and use the JS DOMWindow
-// instance as the prototype for that shadow object. The JS DOMWindow
+// The global object corresponds to a LocalDOMWindow instance. However, to
+// allow properties of the JS LocalDOMWindow instance to be shadowed, we
+// use a shadow object as the global object and use the JS LocalDOMWindow
+// instance as the prototype for that shadow object. The JS LocalDOMWindow
// instance is undetectable from JavaScript code because the __proto__
// accessors skip that object.
//
-// The shadow object and the DOMWindow instance are seen as one object
+// The shadow object and the LocalDOMWindow instance are seen as one object
// from JavaScript. The JavaScript object that corresponds to a
-// DOMWindow instance is the shadow object. When mapping a DOMWindow
+// LocalDOMWindow instance is the shadow object. When mapping a LocalDOMWindow
// instance to a V8 object, we return the shadow object.
//
// To implement split-window, see
@@ -169,7 +164,7 @@ void V8WindowShell::clearForNavigation()
// global object of the context. A variable declared in the global
// scope is a property of the inner window.
//
-// The outer window sticks to a Frame, it is exposed to JavaScript
+// The outer window sticks to a LocalFrame, it is exposed to JavaScript
// via window.window, window.self, window.parent, etc. The outer window
// has a security token which is the domain. The outer window cannot
// have its own properties. window.foo = 'x' is delegated to the
@@ -182,27 +177,31 @@ void V8WindowShell::clearForNavigation()
// it won't be able to reach the outer window via its global object.
bool V8WindowShell::initializeIfNeeded()
{
- if (m_contextHolder)
+ if (isContextInitialized())
return true;
- TRACE_EVENT0("v8", "V8WindowShell::initializeIfNeeded");
-
- v8::HandleScope handleScope(m_isolate);
-
- createContext();
- if (!m_contextHolder)
- return false;
+ DOMWrapperWorld::setWorldOfInitializingWindow(m_world.get());
+ bool result = initialize();
+ DOMWrapperWorld::setWorldOfInitializingWindow(0);
+ return result;
+}
- v8::Handle<v8::Context> context = m_contextHolder->context();
+bool V8WindowShell::initialize()
+{
+ TRACE_EVENT0("v8", "V8WindowShell::initialize");
+ TRACE_EVENT_SCOPED_SAMPLING_STATE("Blink", "InitializeWindow");
- V8PerContextDataHolder::install(context);
+ ScriptForbiddenScope::AllowUserAgentScript allowScript;
- m_world->setIsolatedWorldField(context);
+ v8::HandleScope handleScope(m_isolate);
- bool isMainWorld = m_world->isMainWorld();
+ createContext();
- v8::Context::Scope contextScope(context);
+ if (!isContextInitialized())
+ return false;
+ ScriptState::Scope scope(m_scriptState.get());
+ v8::Handle<v8::Context> context = m_scriptState->context();
if (m_global.isEmpty()) {
m_global.set(m_isolate, context->Global());
if (m_global.isEmpty()) {
@@ -211,44 +210,32 @@ bool V8WindowShell::initializeIfNeeded()
}
}
- if (!isMainWorld) {
- V8WindowShell* mainWindow = m_frame->script().existingWindowShell(mainThreadNormalWorld());
+ if (!m_world->isMainWorld()) {
+ V8WindowShell* mainWindow = m_frame->script().existingWindowShell(DOMWrapperWorld::mainWorld());
if (mainWindow && !mainWindow->context().IsEmpty())
setInjectedScriptContextDebugId(context, m_frame->script().contextDebugId(mainWindow->context()));
}
- m_perContextData = V8PerContextData::create(context);
- if (!m_perContextData->init()) {
- disposeContext(DoNotDetachGlobal);
- return false;
- }
- m_perContextData->setActivityLogger(DOMWrapperWorld::activityLogger(m_world->worldId()));
if (!installDOMWindow()) {
disposeContext(DoNotDetachGlobal);
return false;
}
- if (isMainWorld) {
+ if (m_world->isMainWorld()) {
+ // ActivityLogger for main world is updated within updateDocument().
updateDocument();
- setSecurityToken();
if (m_frame->document()) {
+ setSecurityToken(m_frame->document()->securityOrigin());
ContentSecurityPolicy* csp = m_frame->document()->contentSecurityPolicy();
context->AllowCodeGenerationFromStrings(csp->allowEval(0, ContentSecurityPolicy::SuppressReport));
context->SetErrorMessageForCodeGenerationFromStrings(v8String(m_isolate, csp->evalDisabledErrorMessage()));
}
} else {
- // Using the default security token means that the canAccess is always
- // called, which is slow.
- // FIXME: Use tokens where possible. This will mean keeping track of all
- // created contexts so that they can all be updated when the
- // document domain
- // changes.
- context->UseDefaultSecurityToken();
-
+ updateActivityLogger();
SecurityOrigin* origin = m_world->isolatedWorldSecurityOrigin();
+ setSecurityToken(origin);
if (origin && InspectorInstrumentation::hasFrontends()) {
- ScriptState* scriptState = ScriptState::forContext(v8::Local<v8::Context>::New(m_isolate, context));
- InspectorInstrumentation::didCreateIsolatedContext(m_frame, scriptState, origin);
+ InspectorInstrumentation::didCreateIsolatedContext(m_frame, m_scriptState.get(), origin);
}
}
m_frame->loader().client()->didCreateScriptContext(context, m_world->extensionGroup(), m_world->worldId());
@@ -257,14 +244,14 @@ bool V8WindowShell::initializeIfNeeded()
void V8WindowShell::createContext()
{
- // The activeDocumentLoader pointer could be 0 during frame shutdown.
+ // The documentLoader pointer could be 0 during frame shutdown.
// FIXME: Can we remove this check?
- if (!m_frame->loader().activeDocumentLoader())
+ if (!m_frame->loader().documentLoader())
return;
// Create a new environment using an empty template for the shadow
// object. Reuse the global object if one has been created earlier.
- v8::Handle<v8::ObjectTemplate> globalTemplate = V8Window::GetShadowObjectTemplate(m_isolate, m_world->isMainWorld() ? MainWorld : IsolatedWorld);
+ v8::Handle<v8::ObjectTemplate> globalTemplate = V8Window::getShadowObjectTemplate(m_isolate);
if (globalTemplate.IsEmpty())
return;
@@ -284,12 +271,10 @@ void V8WindowShell::createContext()
}
v8::ExtensionConfiguration extensionConfiguration(index, extensionNames.get());
- v8::HandleScope handleScope(m_isolate);
v8::Handle<v8::Context> context = v8::Context::New(m_isolate, &extensionConfiguration, globalTemplate, m_global.newLocal(m_isolate));
- if (!context.IsEmpty()) {
- m_contextHolder = adoptPtr(new gin::ContextHolder(m_isolate));
- m_contextHolder->SetContext(context);
- }
+ if (context.IsEmpty())
+ return;
+ m_scriptState = ScriptState::create(context, m_world);
double contextCreationDurationInMilliseconds = (currentTime() - contextCreationStartInSeconds) * 1000;
const char* histogramName = "WebCore.V8WindowShell.createContext.MainWorld";
@@ -298,36 +283,46 @@ void V8WindowShell::createContext()
blink::Platform::current()->histogramCustomCounts(histogramName, contextCreationDurationInMilliseconds, 0, 10000, 50);
}
+static v8::Handle<v8::Object> toInnerGlobalObject(v8::Handle<v8::Context> context)
+{
+ return v8::Handle<v8::Object>::Cast(context->Global()->GetPrototype());
+}
+
bool V8WindowShell::installDOMWindow()
{
- DOMWrapperWorld::setInitializingWindow(true);
- DOMWindow* window = m_frame->domWindow();
- v8::Local<v8::Object> windowWrapper = V8ObjectConstructor::newInstance(V8PerContextData::from(m_contextHolder->context())->constructorForType(&V8Window::wrapperTypeInfo));
+ LocalDOMWindow* window = m_frame->domWindow();
+ v8::Local<v8::Object> windowWrapper = V8ObjectConstructor::newInstance(m_isolate, m_scriptState->perContextData()->constructorForType(&V8Window::wrapperTypeInfo));
if (windowWrapper.IsEmpty())
return false;
V8Window::installPerContextEnabledProperties(windowWrapper, window, m_isolate);
- V8DOMWrapper::setNativeInfo(v8::Handle<v8::Object>::Cast(windowWrapper->GetPrototype()), &V8Window::wrapperTypeInfo, window);
+ V8DOMWrapper::setNativeInfoForHiddenWrapper(v8::Handle<v8::Object>::Cast(windowWrapper->GetPrototype()), &V8Window::wrapperTypeInfo, window);
// Install the windowWrapper as the prototype of the innerGlobalObject.
// The full structure of the global object is as follows:
//
// outerGlobalObject (Empty object, remains after navigation)
// -- has prototype --> innerGlobalObject (Holds global variables, changes during navigation)
- // -- has prototype --> DOMWindow instance
+ // -- has prototype --> LocalDOMWindow instance
// -- has prototype --> Window.prototype
// -- has prototype --> Object.prototype
//
// Note: Much of this prototype structure is hidden from web content. The
- // outer, inner, and DOMWindow instance all appear to be the same
+ // outer, inner, and LocalDOMWindow instance all appear to be the same
// JavaScript object.
//
- v8::Handle<v8::Object> innerGlobalObject = toInnerGlobalObject(m_contextHolder->context());
- V8DOMWrapper::setNativeInfo(innerGlobalObject, &V8Window::wrapperTypeInfo, window);
+ // Note: With Oilpan, the LocalDOMWindow object is garbage collected.
+ // Persistent references to this inner global object view of the LocalDOMWindow
+ // aren't kept, as that would prevent the global object from ever being released.
+ // It is safe not to do so, as the wrapper for the LocalDOMWindow being installed here
+ // already keeps a persistent reference, and it along with the inner global object
+ // views of the LocalDOMWindow will die together once that wrapper clears the persistent
+ // reference.
+ v8::Handle<v8::Object> innerGlobalObject = toInnerGlobalObject(m_scriptState->context());
+ V8DOMWrapper::setNativeInfoForHiddenWrapper(innerGlobalObject, &V8Window::wrapperTypeInfo, window);
innerGlobalObject->SetPrototype(windowWrapper);
- V8DOMWrapper::associateObjectWithWrapper<V8Window>(PassRefPtr<DOMWindow>(window), &V8Window::wrapperTypeInfo, windowWrapper, m_isolate, WrapperConfiguration::Dependent);
- DOMWrapperWorld::setInitializingWindow(false);
+ V8DOMWrapper::associateObjectWithWrapper<V8Window>(PassRefPtrWillBeRawPtr<LocalDOMWindow>(window), &V8Window::wrapperTypeInfo, windowWrapper, m_isolate, WrapperConfiguration::Dependent);
return true;
}
@@ -342,18 +337,16 @@ void V8WindowShell::updateDocumentProperty()
if (!m_world->isMainWorld())
return;
- v8::HandleScope handleScope(m_isolate);
- v8::Handle<v8::Context> context = m_contextHolder->context();
- v8::Context::Scope contextScope(context);
-
- v8::Handle<v8::Value> documentWrapper = toV8(m_frame->document(), v8::Handle<v8::Object>(), context->GetIsolate());
+ ScriptState::Scope scope(m_scriptState.get());
+ v8::Handle<v8::Context> context = m_scriptState->context();
+ v8::Handle<v8::Value> documentWrapper = toV8(m_frame->document(), context->Global(), context->GetIsolate());
ASSERT(documentWrapper == m_document.newLocal(m_isolate) || m_document.isEmpty());
if (m_document.isEmpty())
updateDocumentWrapper(v8::Handle<v8::Object>::Cast(documentWrapper));
checkDocumentWrapper(m_document.newLocal(m_isolate), m_frame->document());
// If instantiation of the document wrapper fails, clear the cache
- // and let the DOMWindow accessor handle access to the document.
+ // and let the LocalDOMWindow accessor handle access to the document.
if (documentWrapper.IsEmpty()) {
clearDocumentProperty();
return;
@@ -362,38 +355,40 @@ void V8WindowShell::updateDocumentProperty()
context->Global()->ForceSet(v8AtomicString(m_isolate, "document"), documentWrapper, static_cast<v8::PropertyAttribute>(v8::ReadOnly | v8::DontDelete));
// We also stash a reference to the document on the inner global object so that
- // DOMWindow objects we obtain from JavaScript references are guaranteed to have
+ // LocalDOMWindow objects we obtain from JavaScript references are guaranteed to have
// live Document objects.
- toInnerGlobalObject(context)->SetHiddenValue(V8HiddenPropertyName::document(m_isolate), documentWrapper);
+ V8HiddenValue::setHiddenValue(m_isolate, toInnerGlobalObject(context), V8HiddenValue::document(m_isolate), documentWrapper);
}
void V8WindowShell::clearDocumentProperty()
{
- ASSERT(m_contextHolder);
+ ASSERT(isContextInitialized());
if (!m_world->isMainWorld())
return;
v8::HandleScope handleScope(m_isolate);
- m_contextHolder->context()->Global()->ForceDelete(v8AtomicString(m_isolate, "document"));
+ m_scriptState->context()->Global()->ForceDelete(v8AtomicString(m_isolate, "document"));
}
-void V8WindowShell::setSecurityToken()
+void V8WindowShell::updateActivityLogger()
{
- ASSERT(m_world->isMainWorld());
-
- Document* document = m_frame->document();
+ m_scriptState->perContextData()->setActivityLogger(V8DOMActivityLogger::activityLogger(
+ m_world->worldId(), m_frame->document() ? m_frame->document()->baseURI() : KURL()));
+}
- // Ask the document's SecurityOrigin to generate a security token.
+void V8WindowShell::setSecurityToken(SecurityOrigin* origin)
+{
// If two tokens are equal, then the SecurityOrigins canAccess each other.
// If two tokens are not equal, then we have to call canAccess.
// Note: we can't use the HTTPOrigin if it was set from the DOM.
- SecurityOrigin* origin = document->securityOrigin();
String token;
// We stick with an empty token if document.domain was modified or if we
// are in the initial empty document, so that we can do a full canAccess
// check in those cases.
- if (!origin->domainWasSetInDOM()
- && !m_frame->loader().stateMachine()->isDisplayingInitialEmptyDocument())
- token = document->securityOrigin()->toString();
+ bool delaySet = m_world->isMainWorld()
+ && (origin->domainWasSetInDOM()
+ || m_frame->loader().stateMachine()->isDisplayingInitialEmptyDocument());
+ if (origin && !delaySet)
+ token = origin->toString();
// An empty or "null" token means we always have to call
// canAccess. The toString method on securityOrigins returns the
@@ -402,7 +397,7 @@ void V8WindowShell::setSecurityToken()
// case, we use the global object as the security token to avoid
// calling canAccess when a script accesses its own objects.
v8::HandleScope handleScope(m_isolate);
- v8::Handle<v8::Context> context = m_contextHolder->context();
+ v8::Handle<v8::Context> context = m_scriptState->context();
if (token.isEmpty() || token == "null") {
context->UseDefaultSecurityToken();
return;
@@ -417,12 +412,13 @@ void V8WindowShell::setSecurityToken()
void V8WindowShell::updateDocument()
{
ASSERT(m_world->isMainWorld());
- if (m_global.isEmpty())
+ if (!isGlobalInitialized())
return;
- if (!m_contextHolder)
+ if (!isContextInitialized())
return;
+ updateActivityLogger();
updateDocumentProperty();
- updateSecurityOrigin();
+ updateSecurityOrigin(m_frame->document()->securityOrigin());
}
static v8::Handle<v8::Value> getNamedProperty(HTMLDocument* htmlDocument, const AtomicString& key, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
@@ -430,16 +426,17 @@ static v8::Handle<v8::Value> getNamedProperty(HTMLDocument* htmlDocument, const
if (!htmlDocument->hasNamedItem(key) && !htmlDocument->hasExtraNamedItem(key))
return v8Undefined();
- RefPtr<HTMLCollection> items = htmlDocument->documentNamedItems(key);
+ RefPtrWillBeRawPtr<HTMLCollection> items = htmlDocument->documentNamedItems(key);
if (items->isEmpty())
return v8Undefined();
if (items->hasExactlyOneItem()) {
- Node* node = items->item(0);
+ Element* element = items->item(0);
+ ASSERT(element);
Frame* frame = 0;
- if (node->hasTagName(HTMLNames::iframeTag) && (frame = toHTMLIFrameElement(node)->contentFrame()))
+ if (isHTMLIFrameElement(*element) && (frame = toHTMLIFrameElement(*element).contentFrame()))
return toV8(frame->domWindow(), creationContext, isolate);
- return toV8(node, creationContext, isolate);
+ return toV8(element, creationContext, isolate);
}
return toV8(items.release(), creationContext, isolate);
}
@@ -466,12 +463,10 @@ void V8WindowShell::namedItemAdded(HTMLDocument* document, const AtomicString& n
{
ASSERT(m_world->isMainWorld());
- if (!m_contextHolder)
+ if (!isContextInitialized())
return;
- v8::HandleScope handleScope(m_isolate);
- v8::Context::Scope contextScope(m_contextHolder->context());
-
+ ScriptState::Scope scope(m_scriptState.get());
ASSERT(!m_document.isEmpty());
v8::Handle<v8::Object> documentHandle = m_document.newLocal(m_isolate);
checkDocumentWrapper(documentHandle, document);
@@ -482,28 +477,25 @@ void V8WindowShell::namedItemRemoved(HTMLDocument* document, const AtomicString&
{
ASSERT(m_world->isMainWorld());
- if (!m_contextHolder)
+ if (!isContextInitialized())
return;
if (document->hasNamedItem(name) || document->hasExtraNamedItem(name))
return;
- v8::HandleScope handleScope(m_isolate);
- v8::Context::Scope contextScope(m_contextHolder->context());
-
+ ScriptState::Scope scope(m_scriptState.get());
ASSERT(!m_document.isEmpty());
v8::Handle<v8::Object> documentHandle = m_document.newLocal(m_isolate);
checkDocumentWrapper(documentHandle, document);
documentHandle->Delete(v8String(m_isolate, name));
}
-void V8WindowShell::updateSecurityOrigin()
+void V8WindowShell::updateSecurityOrigin(SecurityOrigin* origin)
{
ASSERT(m_world->isMainWorld());
- if (!m_contextHolder)
+ if (!isContextInitialized())
return;
- v8::HandleScope handleScope(m_isolate);
- setSecurityToken();
+ setSecurityToken(origin);
}
} // WebCore
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/V8WindowShell.h b/chromium/third_party/WebKit/Source/bindings/v8/V8WindowShell.h
index b1c65ab9f42..548caa388fe 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/V8WindowShell.h
+++ b/chromium/third_party/WebKit/Source/bindings/v8/V8WindowShell.h
@@ -33,9 +33,8 @@
#include "bindings/v8/DOMWrapperWorld.h"
#include "bindings/v8/ScopedPersistent.h"
-#include "bindings/v8/V8PerContextData.h"
+#include "bindings/v8/ScriptState.h"
#include "bindings/v8/WrapperTypeInfo.h"
-#include "gin/public/context_holder.h"
#include "platform/weborigin/SecurityOrigin.h"
#include "wtf/Forward.h"
#include "wtf/HashMap.h"
@@ -47,17 +46,19 @@
namespace WebCore {
-class DOMWindow;
-class Frame;
+class LocalDOMWindow;
+class LocalFrame;
class HTMLDocument;
+class SecurityOrigin;
-// V8WindowShell represents all the per-global object state for a Frame that
+// V8WindowShell represents all the per-global object state for a LocalFrame that
// persist between navigations.
class V8WindowShell {
public:
- static PassOwnPtr<V8WindowShell> create(Frame*, PassRefPtr<DOMWrapperWorld>, v8::Isolate*);
+ static PassOwnPtr<V8WindowShell> create(LocalFrame*, DOMWrapperWorld&, v8::Isolate*);
- v8::Local<v8::Context> context() const { return m_contextHolder ? m_contextHolder->context() : v8::Local<v8::Context>(); }
+ v8::Local<v8::Context> context() const { return m_scriptState ? m_scriptState->context() : v8::Local<v8::Context>(); }
+ ScriptState* scriptState() const { return m_scriptState.get(); }
// Update document object of the frame.
void updateDocument();
@@ -67,21 +68,22 @@ public:
// Update the security origin of a document
// (e.g., after setting docoument.domain).
- void updateSecurityOrigin();
+ void updateSecurityOrigin(SecurityOrigin*);
- bool isContextInitialized() { return m_contextHolder; }
+ bool isContextInitialized() { return m_scriptState && !!m_scriptState->perContextData(); }
bool isGlobalInitialized() { return !m_global.isEmpty(); }
bool initializeIfNeeded();
void updateDocumentWrapper(v8::Handle<v8::Object> wrapper);
void clearForNavigation();
- void clearForClose(bool destroyGlobal);
+ void clearForClose();
- DOMWrapperWorld* world() { return m_world.get(); }
+ DOMWrapperWorld& world() { return *m_world; }
private:
- V8WindowShell(Frame*, PassRefPtr<DOMWrapperWorld>, v8::Isolate*);
+ V8WindowShell(LocalFrame*, PassRefPtr<DOMWrapperWorld>, v8::Isolate*);
+ bool initialize();
enum GlobalDetachmentBehavior {
DoNotDetachGlobal,
@@ -89,7 +91,7 @@ private:
};
void disposeContext(GlobalDetachmentBehavior);
- void setSecurityToken();
+ void setSecurityToken(SecurityOrigin*);
// The JavaScript wrapper for the document object is cached on the global
// object for fast access. UpdateDocumentProperty sets the wrapper
@@ -98,18 +100,18 @@ private:
void updateDocumentProperty();
void clearDocumentProperty();
+ // Updates Activity Logger for the current context.
+ void updateActivityLogger();
+
void createContext();
bool installDOMWindow();
static V8WindowShell* enteredIsolatedWorldContext();
- Frame* m_frame;
- RefPtr<DOMWrapperWorld> m_world;
+ LocalFrame* m_frame;
v8::Isolate* m_isolate;
-
- OwnPtr<V8PerContextData> m_perContextData;
-
- OwnPtr<gin::ContextHolder> m_contextHolder;
+ RefPtr<ScriptState> m_scriptState;
+ RefPtr<DOMWrapperWorld> m_world;
ScopedPersistent<v8::Object> m_global;
ScopedPersistent<v8::Object> m_document;
};
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/V8WorkerGlobalScopeEventListener.cpp b/chromium/third_party/WebKit/Source/bindings/v8/V8WorkerGlobalScopeEventListener.cpp
index da79d52d1c8..c66b8a24dc9 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/V8WorkerGlobalScopeEventListener.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/V8WorkerGlobalScopeEventListener.cpp
@@ -32,94 +32,84 @@
#include "bindings/v8/V8WorkerGlobalScopeEventListener.h"
-#include "V8Event.h"
-#include "V8EventTarget.h"
+#include "bindings/core/v8/V8Event.h"
+#include "bindings/core/v8/V8EventTarget.h"
#include "bindings/v8/V8Binding.h"
#include "bindings/v8/V8DOMWrapper.h"
#include "bindings/v8/V8GCController.h"
#include "bindings/v8/V8ScriptRunner.h"
#include "bindings/v8/WorkerScriptController.h"
#include "core/inspector/InspectorInstrumentation.h"
+#include "core/inspector/InspectorTraceEvents.h"
#include "core/workers/WorkerGlobalScope.h"
namespace WebCore {
-V8WorkerGlobalScopeEventListener::V8WorkerGlobalScopeEventListener(v8::Local<v8::Object> listener, bool isInline, v8::Isolate* isolate)
- : V8EventListener(listener, isInline, isolate)
+V8WorkerGlobalScopeEventListener::V8WorkerGlobalScopeEventListener(v8::Local<v8::Object> listener, bool isInline, ScriptState* scriptState)
+ : V8EventListener(listener, isInline, scriptState)
{
}
-void V8WorkerGlobalScopeEventListener::handleEvent(ExecutionContext* context, Event* event)
+void V8WorkerGlobalScopeEventListener::handleEvent(ExecutionContext*, Event* event)
{
- if (!context)
- return;
-
// The callback function on XMLHttpRequest can clear the event listener and destroys 'this' object. Keep a local reference to it.
// See issue 889829.
RefPtr<V8AbstractEventListener> protect(this);
- v8::Isolate* isolate = toIsolate(context);
- v8::HandleScope handleScope(isolate);
-
- WorkerScriptController* script = toWorkerGlobalScope(context)->script();
+ WorkerScriptController* script = toWorkerGlobalScope(scriptState()->executionContext())->script();
if (!script)
return;
- v8::Handle<v8::Context> v8Context = script->context();
- if (v8Context.IsEmpty())
+ if (scriptState()->contextIsEmpty())
return;
-
- // Enter the V8 context in which to perform the event handling.
- v8::Context::Scope scope(v8Context);
+ ScriptState::Scope scope(scriptState());
// Get the V8 wrapper for the event object.
- v8::Handle<v8::Value> jsEvent = toV8(event, v8::Handle<v8::Object>(), isolate);
+ v8::Handle<v8::Value> jsEvent = toV8(event, scriptState()->context()->Global(), isolate());
- invokeEventHandler(context, event, v8::Local<v8::Value>::New(isolate, jsEvent));
+ invokeEventHandler(event, v8::Local<v8::Value>::New(isolate(), jsEvent));
}
-v8::Local<v8::Value> V8WorkerGlobalScopeEventListener::callListenerFunction(ExecutionContext* context, v8::Handle<v8::Value> jsEvent, Event* event)
+v8::Local<v8::Value> V8WorkerGlobalScopeEventListener::callListenerFunction(v8::Handle<v8::Value> jsEvent, Event* event)
{
- v8::Local<v8::Function> handlerFunction = getListenerFunction(context);
- v8::Local<v8::Object> receiver = getReceiverObject(context, event);
+ v8::Local<v8::Function> handlerFunction = getListenerFunction(scriptState()->executionContext());
+ v8::Local<v8::Object> receiver = getReceiverObject(event);
if (handlerFunction.IsEmpty() || receiver.IsEmpty())
return v8::Local<v8::Value>();
+ TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "FunctionCall", "data", devToolsTraceEventData(scriptState()->executionContext(), handlerFunction, isolate()));
+ TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline.stack"), "CallStack", "stack", InspectorCallStackEvent::currentCallStack());
+ // FIXME(361045): remove InspectorInstrumentation calls once DevTools Timeline migrates to tracing.
InspectorInstrumentationCookie cookie;
- if (InspectorInstrumentation::timelineAgentEnabled(context)) {
- String resourceName("undefined");
+ if (InspectorInstrumentation::timelineAgentEnabled(scriptState()->executionContext())) {
+ int scriptId = 0;
+ String resourceName;
int lineNumber = 1;
- v8::ScriptOrigin origin = handlerFunction->GetScriptOrigin();
- if (!origin.ResourceName().IsEmpty()) {
- V8TRYCATCH_FOR_V8STRINGRESOURCE_RETURN(V8StringResource<>, stringResourceName, origin.ResourceName(), v8::Local<v8::Value>());
- resourceName = stringResourceName;
- lineNumber = handlerFunction->GetScriptLineNumber() + 1;
- }
- cookie = InspectorInstrumentation::willCallFunction(context, resourceName, lineNumber);
+ GetDevToolsFunctionInfo(handlerFunction, isolate(), scriptId, resourceName, lineNumber);
+ cookie = InspectorInstrumentation::willCallFunction(scriptState()->executionContext(), scriptId, resourceName, lineNumber);
}
- v8::Isolate* isolate = toIsolate(context);
v8::Handle<v8::Value> parameters[1] = { jsEvent };
- v8::Local<v8::Value> result = V8ScriptRunner::callFunction(handlerFunction, context, receiver, WTF_ARRAY_LENGTH(parameters), parameters, isolate);
+ v8::Local<v8::Value> result = V8ScriptRunner::callFunction(handlerFunction, scriptState()->executionContext(), receiver, WTF_ARRAY_LENGTH(parameters), parameters, isolate());
InspectorInstrumentation::didCallFunction(cookie);
+ TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "UpdateCounters", "data", InspectorUpdateCountersEvent::data());
return result;
}
-v8::Local<v8::Object> V8WorkerGlobalScopeEventListener::getReceiverObject(ExecutionContext* context, Event* event)
+v8::Local<v8::Object> V8WorkerGlobalScopeEventListener::getReceiverObject(Event* event)
{
- v8::Local<v8::Object> listener = getListenerObject(context);
+ v8::Local<v8::Object> listener = getListenerObject(scriptState()->executionContext());
if (!listener.IsEmpty() && !listener->IsFunction())
return listener;
EventTarget* target = event->currentTarget();
- v8::Isolate* isolate = toIsolate(context);
- v8::Handle<v8::Value> value = toV8(target, v8::Handle<v8::Object>(), isolate);
+ v8::Handle<v8::Value> value = toV8(target, scriptState()->context()->Global(), isolate());
if (value.IsEmpty())
return v8::Local<v8::Object>();
- return v8::Local<v8::Object>::New(isolate, v8::Handle<v8::Object>::Cast(value));
+ return v8::Local<v8::Object>::New(isolate(), v8::Handle<v8::Object>::Cast(value));
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/V8WorkerGlobalScopeEventListener.h b/chromium/third_party/WebKit/Source/bindings/v8/V8WorkerGlobalScopeEventListener.h
index 1acf7c44d7d..355a424afbc 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/V8WorkerGlobalScopeEventListener.h
+++ b/chromium/third_party/WebKit/Source/bindings/v8/V8WorkerGlobalScopeEventListener.h
@@ -39,21 +39,21 @@ namespace WebCore {
class Event;
- class V8WorkerGlobalScopeEventListener : public V8EventListener {
+ class V8WorkerGlobalScopeEventListener FINAL : public V8EventListener {
public:
- static PassRefPtr<V8WorkerGlobalScopeEventListener> create(v8::Local<v8::Object> listener, bool isInline, v8::Isolate* isolate)
+ static PassRefPtr<V8WorkerGlobalScopeEventListener> create(v8::Local<v8::Object> listener, bool isInline, ScriptState* scriptState)
{
- return adoptRef(new V8WorkerGlobalScopeEventListener(listener, isInline, isolate));
+ return adoptRef(new V8WorkerGlobalScopeEventListener(listener, isInline, scriptState));
}
- virtual void handleEvent(ExecutionContext*, Event*);
+ virtual void handleEvent(ExecutionContext*, Event*) OVERRIDE;
protected:
- V8WorkerGlobalScopeEventListener(v8::Local<v8::Object> listener, bool isInline, v8::Isolate*);
+ V8WorkerGlobalScopeEventListener(v8::Local<v8::Object> listener, bool isInline, ScriptState*);
private:
- virtual v8::Local<v8::Value> callListenerFunction(ExecutionContext*, v8::Handle<v8::Value> jsEvent, Event*);
- v8::Local<v8::Object> getReceiverObject(ExecutionContext*, Event*);
+ virtual v8::Local<v8::Value> callListenerFunction(v8::Handle<v8::Value> jsEvent, Event*) OVERRIDE;
+ v8::Local<v8::Object> getReceiverObject(Event*);
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/WorkerScriptController.cpp b/chromium/third_party/WebKit/Source/bindings/v8/WorkerScriptController.cpp
index 27170fecf89..3381f46b221 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/WorkerScriptController.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/WorkerScriptController.cpp
@@ -32,10 +32,10 @@
#include "bindings/v8/WorkerScriptController.h"
-#include "V8DedicatedWorkerGlobalScope.h"
-#include "V8ServiceWorkerGlobalScope.h"
-#include "V8SharedWorkerGlobalScope.h"
-#include "V8WorkerGlobalScope.h"
+#include "bindings/core/v8/V8DedicatedWorkerGlobalScope.h"
+#include "bindings/core/v8/V8SharedWorkerGlobalScope.h"
+#include "bindings/core/v8/V8WorkerGlobalScope.h"
+#include "bindings/modules/v8/V8ServiceWorkerGlobalScope.h"
#include "bindings/v8/ScriptSourceCode.h"
#include "bindings/v8/ScriptValue.h"
#include "bindings/v8/V8ErrorHandler.h"
@@ -50,6 +50,7 @@
#include "core/workers/WorkerGlobalScope.h"
#include "core/workers/WorkerObjectProxy.h"
#include "core/workers/WorkerThread.h"
+#include "platform/heap/ThreadState.h"
#include <v8.h>
#include "public/platform/Platform.h"
@@ -58,67 +59,77 @@
namespace WebCore {
WorkerScriptController::WorkerScriptController(WorkerGlobalScope& workerGlobalScope)
- : m_workerGlobalScope(workerGlobalScope)
+ : m_isolate(v8::Isolate::New())
+ , m_workerGlobalScope(workerGlobalScope)
, m_executionForbidden(false)
, m_executionScheduledToTerminate(false)
{
- v8::Isolate* isolate = v8::Isolate::New();
- isolate->Enter();
- V8Initializer::initializeWorker(isolate);
+ m_isolate->Enter();
+ V8Initializer::initializeWorker(m_isolate);
v8::V8::Initialize();
- m_isolateHolder = adoptPtr(new gin::IsolateHolder(isolate));
- V8PerIsolateData* data = V8PerIsolateData::create(isolate);
- m_domDataStore = adoptPtr(new DOMDataStore(WorkerWorld));
- data->setWorkerDOMDataStore(m_domDataStore.get());
+ V8PerIsolateData::ensureInitialized(m_isolate);
+ m_world = DOMWrapperWorld::create(WorkerWorldId);
+ m_interruptor = adoptPtr(new V8IsolateInterruptor(m_isolate));
+ ThreadState::current()->addInterruptor(m_interruptor.get());
}
+// We need to postpone V8 Isolate destruction until the very end of
+// worker thread finalization when all objects on the worker heap
+// are destroyed.
+class IsolateCleanupTask : public ThreadState::CleanupTask {
+public:
+ static PassOwnPtr<IsolateCleanupTask> create(v8::Isolate* isolate)
+ {
+ return adoptPtr(new IsolateCleanupTask(isolate));
+ }
+
+ virtual void postCleanup()
+ {
+ V8PerIsolateData::dispose(m_isolate);
+ m_isolate->Exit();
+ m_isolate->Dispose();
+ }
+
+private:
+ explicit IsolateCleanupTask(v8::Isolate* isolate) : m_isolate(isolate) { }
+
+ v8::Isolate* m_isolate;
+};
+
WorkerScriptController::~WorkerScriptController()
{
- m_domDataStore.clear();
+ ThreadState::current()->removeInterruptor(m_interruptor.get());
+
+ m_world->dispose();
// The corresponding call to didStartWorkerRunLoop is in
// WorkerThread::workerThread().
// See http://webkit.org/b/83104#c14 for why this is here.
blink::Platform::current()->didStopWorkerRunLoop(blink::WebWorkerRunLoop(&m_workerGlobalScope.thread()->runLoop()));
- disposeContext();
- V8PerIsolateData::dispose(isolate());
- v8::Isolate* v8Isolate = isolate();
- v8Isolate->Exit();
- m_isolateHolder.clear();
- v8Isolate->Dispose();
-}
+ if (isContextInitialized())
+ m_scriptState->disposePerContextData();
-void WorkerScriptController::disposeContext()
-{
- m_perContextData.clear();
- m_contextHolder.clear();
+ ThreadState::current()->addCleanupTask(IsolateCleanupTask::create(m_isolate));
}
bool WorkerScriptController::initializeContextIfNeeded()
{
- if (m_contextHolder)
+ v8::HandleScope handleScope(m_isolate);
+
+ if (isContextInitialized())
return true;
- v8::Handle<v8::Context> context = v8::Context::New(isolate());
+ v8::Handle<v8::Context> context = v8::Context::New(m_isolate);
if (context.IsEmpty())
return false;
- m_contextHolder = adoptPtr(new gin::ContextHolder(isolate()));
- m_contextHolder->SetContext(context);
-
- v8::Context::Scope scope(context);
-
- V8PerContextDataHolder::install(context);
+ m_scriptState = ScriptState::create(context, m_world);
- m_perContextData = V8PerContextData::create(context);
- if (!m_perContextData->init()) {
- disposeContext();
- return false;
- }
+ ScriptState::Scope scope(m_scriptState.get());
// Set DebugId for the new context.
- context->SetEmbedderData(0, v8AtomicString(isolate(), "worker"));
+ context->SetEmbedderData(0, v8AtomicString(m_isolate, "worker"));
// Create a new JS object and use it as the prototype for the shadow global object.
const WrapperTypeInfo* contextType = &V8DedicatedWorkerGlobalScope::wrapperTypeInfo;
@@ -126,17 +137,17 @@ bool WorkerScriptController::initializeContextIfNeeded()
contextType = &V8ServiceWorkerGlobalScope::wrapperTypeInfo;
else if (!m_workerGlobalScope.isDedicatedWorkerGlobalScope())
contextType = &V8SharedWorkerGlobalScope::wrapperTypeInfo;
- v8::Handle<v8::Function> workerGlobalScopeConstructor = m_perContextData->constructorForType(contextType);
- v8::Local<v8::Object> jsWorkerGlobalScope = V8ObjectConstructor::newInstance(workerGlobalScopeConstructor);
+ v8::Handle<v8::Function> workerGlobalScopeConstructor = m_scriptState->perContextData()->constructorForType(contextType);
+ v8::Local<v8::Object> jsWorkerGlobalScope = V8ObjectConstructor::newInstance(m_isolate, workerGlobalScopeConstructor);
if (jsWorkerGlobalScope.IsEmpty()) {
- disposeContext();
+ m_scriptState->disposePerContextData();
return false;
}
- V8DOMWrapper::associateObjectWithWrapper<V8WorkerGlobalScope>(PassRefPtr<WorkerGlobalScope>(m_workerGlobalScope), contextType, jsWorkerGlobalScope, isolate(), WrapperConfiguration::Dependent);
+ V8DOMWrapper::associateObjectWithWrapper<V8WorkerGlobalScope>(PassRefPtrWillBeRawPtr<WorkerGlobalScope>(&m_workerGlobalScope), contextType, jsWorkerGlobalScope, m_isolate, WrapperConfiguration::Dependent);
// Insert the object instance as the prototype of the shadow object.
- v8::Handle<v8::Object> globalObject = v8::Handle<v8::Object>::Cast(m_contextHolder->context()->Global()->GetPrototype());
+ v8::Handle<v8::Object> globalObject = v8::Handle<v8::Object>::Cast(m_scriptState->context()->Global()->GetPrototype());
globalObject->SetPrototype(jsWorkerGlobalScope);
return true;
@@ -144,25 +155,22 @@ bool WorkerScriptController::initializeContextIfNeeded()
ScriptValue WorkerScriptController::evaluate(const String& script, const String& fileName, const TextPosition& scriptStartPosition, WorkerGlobalScopeExecutionState* state)
{
- v8::HandleScope handleScope(isolate());
-
if (!initializeContextIfNeeded())
return ScriptValue();
- v8::Handle<v8::Context> context = m_contextHolder->context();
+ ScriptState::Scope scope(m_scriptState.get());
+
if (!m_disableEvalPending.isEmpty()) {
- context->AllowCodeGenerationFromStrings(false);
- context->SetErrorMessageForCodeGenerationFromStrings(v8String(isolate(), m_disableEvalPending));
+ m_scriptState->context()->AllowCodeGenerationFromStrings(false);
+ m_scriptState->context()->SetErrorMessageForCodeGenerationFromStrings(v8String(m_isolate, m_disableEvalPending));
m_disableEvalPending = String();
}
- v8::Context::Scope scope(context);
-
v8::TryCatch block;
- v8::Handle<v8::String> scriptString = v8String(isolate(), script);
- v8::Handle<v8::Script> compiledScript = V8ScriptRunner::compileScript(scriptString, fileName, scriptStartPosition, 0, isolate());
- v8::Local<v8::Value> result = V8ScriptRunner::runCompiledScript(compiledScript, &m_workerGlobalScope, isolate());
+ v8::Handle<v8::String> scriptString = v8String(m_isolate, script);
+ v8::Handle<v8::Script> compiledScript = V8ScriptRunner::compileScript(scriptString, fileName, scriptStartPosition, 0, m_isolate);
+ v8::Local<v8::Value> result = V8ScriptRunner::runCompiledScript(compiledScript, &m_workerGlobalScope, m_isolate);
if (!block.CanContinue()) {
m_workerGlobalScope.script()->forbidExecution();
@@ -175,9 +183,9 @@ ScriptValue WorkerScriptController::evaluate(const String& script, const String&
state->errorMessage = toCoreString(message->Get());
state->lineNumber = message->GetLineNumber();
state->columnNumber = message->GetStartColumn() + 1;
- V8TRYCATCH_FOR_V8STRINGRESOURCE_RETURN(V8StringResource<>, sourceURL, message->GetScriptResourceName(), ScriptValue());
+ TOSTRING_DEFAULT(V8StringResource<>, sourceURL, message->GetScriptResourceName(), ScriptValue());
state->sourceURL = sourceURL;
- state->exception = ScriptValue(block.Exception(), isolate());
+ state->exception = ScriptValue(m_scriptState.get(), block.Exception());
block.Reset();
} else
state->hadException = false;
@@ -185,10 +193,10 @@ ScriptValue WorkerScriptController::evaluate(const String& script, const String&
if (result.IsEmpty() || result->IsUndefined())
return ScriptValue();
- return ScriptValue(result, isolate());
+ return ScriptValue(m_scriptState.get(), result);
}
-void WorkerScriptController::evaluate(const ScriptSourceCode& sourceCode, RefPtr<ErrorEvent>* errorEvent)
+void WorkerScriptController::evaluate(const ScriptSourceCode& sourceCode, RefPtrWillBeRawPtr<ErrorEvent>* errorEvent)
{
if (isExecutionForbidden())
return;
@@ -198,12 +206,17 @@ void WorkerScriptController::evaluate(const ScriptSourceCode& sourceCode, RefPtr
if (state.hadException) {
if (errorEvent) {
*errorEvent = m_workerGlobalScope.shouldSanitizeScriptError(state.sourceURL, NotSharableCrossOrigin) ?
- ErrorEvent::createSanitizedError(0) : ErrorEvent::create(state.errorMessage, state.sourceURL, state.lineNumber, state.columnNumber, 0);
- V8ErrorHandler::storeExceptionOnErrorEventWrapper(errorEvent->get(), state.exception.v8Value(), isolate());
+ ErrorEvent::createSanitizedError(m_world.get()) : ErrorEvent::create(state.errorMessage, state.sourceURL, state.lineNumber, state.columnNumber, m_world.get());
+ V8ErrorHandler::storeExceptionOnErrorEventWrapper(errorEvent->get(), state.exception.v8Value(), m_scriptState->context()->Global(), m_isolate);
} else {
ASSERT(!m_workerGlobalScope.shouldSanitizeScriptError(state.sourceURL, NotSharableCrossOrigin));
- RefPtr<ErrorEvent> event = m_errorEventFromImportedScript ? m_errorEventFromImportedScript.release() : ErrorEvent::create(state.errorMessage, state.sourceURL, state.lineNumber, state.columnNumber, 0);
- m_workerGlobalScope.reportException(event, 0, NotSharableCrossOrigin);
+ RefPtrWillBeRawPtr<ErrorEvent> event = nullptr;
+ if (m_errorEventFromImportedScript) {
+ event = m_errorEventFromImportedScript.release();
+ } else {
+ event = ErrorEvent::create(state.errorMessage, state.sourceURL, state.lineNumber, state.columnNumber, m_world.get());
+ }
+ m_workerGlobalScope.reportException(event, nullptr, NotSharableCrossOrigin);
}
}
}
@@ -217,7 +230,7 @@ void WorkerScriptController::scheduleExecutionTermination()
MutexLocker locker(m_scheduledTerminationMutex);
m_executionScheduledToTerminate = true;
}
- v8::V8::TerminateExecution(isolate());
+ v8::V8::TerminateExecution(m_isolate);
}
bool WorkerScriptController::isExecutionTerminating() const
@@ -244,26 +257,10 @@ void WorkerScriptController::disableEval(const String& errorMessage)
m_disableEvalPending = errorMessage;
}
-void WorkerScriptController::rethrowExceptionFromImportedScript(PassRefPtr<ErrorEvent> errorEvent)
+void WorkerScriptController::rethrowExceptionFromImportedScript(PassRefPtrWillBeRawPtr<ErrorEvent> errorEvent)
{
m_errorEventFromImportedScript = errorEvent;
- throwError(V8ThrowException::createError(v8GeneralError, m_errorEventFromImportedScript->message(), isolate()), isolate());
-}
-
-WorkerScriptController* WorkerScriptController::controllerForContext()
-{
- v8::Isolate* isolate = v8::Isolate::GetCurrent();
- // Happens on frame destruction, check otherwise GetCurrent() will crash.
- if (!isolate || !isolate->InContext())
- return 0;
- v8::Handle<v8::Context> context = isolate->GetCurrentContext();
- v8::Handle<v8::Object> global = context->Global();
- global = global->FindInstanceInPrototypeChain(V8WorkerGlobalScope::domTemplate(isolate, WorkerWorld));
- // Return 0 if the current executing context is not the worker context.
- if (global.IsEmpty())
- return 0;
- WorkerGlobalScope* workerGlobalScope = V8WorkerGlobalScope::toNative(global);
- return workerGlobalScope->script();
+ throwError(V8ThrowException::createError(v8GeneralError, m_errorEventFromImportedScript->message(), m_isolate), m_isolate);
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/WorkerScriptController.h b/chromium/third_party/WebKit/Source/bindings/v8/WorkerScriptController.h
index 7b7ea1af507..2559269fdd0 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/WorkerScriptController.h
+++ b/chromium/third_party/WebKit/Source/bindings/v8/WorkerScriptController.h
@@ -34,17 +34,11 @@
#include "bindings/v8/ScriptValue.h"
#include "bindings/v8/V8Binding.h"
#include "core/events/ErrorEvent.h"
-#include "gin/public/context_holder.h"
-#include "gin/public/isolate_holder.h"
#include "wtf/OwnPtr.h"
#include "wtf/ThreadingPrimitives.h"
#include "wtf/text/TextPosition.h"
#include <v8.h>
-namespace gin {
-class IsolateHolder;
-}
-
namespace WebCore {
class ScriptSourceCode;
@@ -74,9 +68,11 @@ namespace WebCore {
WorkerGlobalScope& workerGlobalScope() { return m_workerGlobalScope; }
- void evaluate(const ScriptSourceCode&, RefPtr<ErrorEvent>* = 0);
+ bool initializeContextIfNeeded();
+
+ void evaluate(const ScriptSourceCode&, RefPtrWillBeRawPtr<ErrorEvent>* = 0);
- void rethrowExceptionFromImportedScript(PassRefPtr<ErrorEvent>);
+ void rethrowExceptionFromImportedScript(PassRefPtrWillBeRawPtr<ErrorEvent>);
// Async request to terminate a future JS execution. Eventually causes termination
// exception raised during JS execution, if the worker thread happens to run JS.
@@ -93,36 +89,32 @@ namespace WebCore {
void disableEval(const String&);
- // Returns WorkerScriptController for the currently executing context. 0 will be returned if the current executing context is not the worker context.
- static WorkerScriptController* controllerForContext();
-
// Evaluate a script file in the current execution environment.
ScriptValue evaluate(const String& script, const String& fileName, const TextPosition& scriptStartPosition, WorkerGlobalScopeExecutionState*);
- // Returns a local handle of the context.
- v8::Local<v8::Context> context() { return m_contextHolder ? m_contextHolder->context() : v8::Local<v8::Context>(); }
+ v8::Isolate* isolate() const { return m_isolate; }
+ DOMWrapperWorld& world() const { return *m_world; }
+ ScriptState* scriptState() { return m_scriptState.get(); }
+ v8::Local<v8::Context> context() { return m_scriptState ? m_scriptState->context() : v8::Local<v8::Context>(); }
+ bool isContextInitialized() { return m_scriptState && !!m_scriptState->perContextData(); }
// Send a notification about current thread is going to be idle.
// Returns true if the embedder should stop calling idleNotification
// until real work has been done.
bool idleNotification() { return v8::V8::IdleNotification(); }
- v8::Isolate* isolate() const { return m_isolateHolder->isolate(); }
private:
- bool initializeContextIfNeeded();
- void disposeContext();
-
+ v8::Isolate* m_isolate;
WorkerGlobalScope& m_workerGlobalScope;
- OwnPtr<gin::IsolateHolder> m_isolateHolder;
- OwnPtr<gin::ContextHolder> m_contextHolder;
- OwnPtr<V8PerContextData> m_perContextData;
+ RefPtr<ScriptState> m_scriptState;
+ RefPtr<DOMWrapperWorld> m_world;
String m_disableEvalPending;
- OwnPtr<DOMDataStore> m_domDataStore;
bool m_executionForbidden;
bool m_executionScheduledToTerminate;
mutable Mutex m_scheduledTerminationMutex;
- RefPtr<ErrorEvent> m_errorEventFromImportedScript;
+ RefPtrWillBePersistent<ErrorEvent> m_errorEventFromImportedScript;
+ OwnPtr<V8IsolateInterruptor> m_interruptor;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/WorkerScriptDebugServer.cpp b/chromium/third_party/WebKit/Source/bindings/v8/WorkerScriptDebugServer.cpp
index 935a2d26dc5..920508e1e43 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/WorkerScriptDebugServer.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/WorkerScriptDebugServer.cpp
@@ -42,11 +42,10 @@
namespace WebCore {
-WorkerScriptDebugServer::WorkerScriptDebugServer(WorkerGlobalScope* workerGlobalScope, const String& mode)
+WorkerScriptDebugServer::WorkerScriptDebugServer(WorkerGlobalScope* workerGlobalScope)
: ScriptDebugServer(v8::Isolate::GetCurrent())
, m_listener(0)
, m_workerGlobalScope(workerGlobalScope)
- , m_debuggerTaskMode(mode)
{
ASSERT(m_isolate);
}
@@ -54,16 +53,17 @@ WorkerScriptDebugServer::WorkerScriptDebugServer(WorkerGlobalScope* workerGlobal
void WorkerScriptDebugServer::addListener(ScriptDebugListener* listener)
{
v8::HandleScope scope(m_isolate);
- v8::Local<v8::Context> debuggerContext = v8::Debug::GetDebugContext();
- v8::Context::Scope contextScope(debuggerContext);
-
ASSERT(!m_listener);
- m_listener = listener;
+ v8::Debug::SetDebugEventListener(&WorkerScriptDebugServer::v8DebugEventCallback, v8::External::New(m_isolate, this));
ensureDebuggerScriptCompiled();
+ m_listener = listener;
+
+ v8::Local<v8::Context> debuggerContext = v8::Debug::GetDebugContext();
+ v8::Context::Scope contextScope(debuggerContext);
+
v8::Local<v8::Object> debuggerScript = m_debuggerScript.newLocal(m_isolate);
ASSERT(!debuggerScript->IsUndefined());
- v8::Debug::SetDebugEventListener2(&WorkerScriptDebugServer::v8DebugEventCallback, v8::External::New(m_isolate, this));
v8::Handle<v8::Function> getScriptsFunction = v8::Local<v8::Function>::Cast(debuggerScript->Get(v8AtomicString(m_isolate, "getWorkerScripts")));
v8::Handle<v8::Value> value = V8ScriptRunner::callInternalFunction(getScriptsFunction, debuggerScript, 0, 0, m_isolate);
@@ -72,15 +72,16 @@ void WorkerScriptDebugServer::addListener(ScriptDebugListener* listener)
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, m_isolate))));
+ dispatchDidParseSource(listener, v8::Handle<v8::Object>::Cast(scriptsArray->Get(v8::Integer::New(m_isolate, i))));
}
void WorkerScriptDebugServer::removeListener(ScriptDebugListener* listener)
{
ASSERT(m_listener == listener);
continueProgram();
+ discardDebuggerScript();
m_listener = 0;
- v8::Debug::SetDebugEventListener2(0);
+ v8::Debug::SetDebugEventListener(0);
}
void WorkerScriptDebugServer::interruptAndRunTask(PassOwnPtr<Task> task)
@@ -98,7 +99,7 @@ void WorkerScriptDebugServer::runMessageLoopOnPause(v8::Handle<v8::Context>)
{
MessageQueueWaitResult result;
do {
- result = m_workerGlobalScope->thread()->runLoop().runInMode(m_workerGlobalScope, m_debuggerTaskMode);
+ result = m_workerGlobalScope->thread()->runLoop().runDebuggerTask();
// Keep waiting until execution is resumed.
} while (result == MessageQueueMessageReceived && isPaused());
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/WorkerScriptDebugServer.h b/chromium/third_party/WebKit/Source/bindings/v8/WorkerScriptDebugServer.h
index befaaa90942..81fde7da0e5 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/WorkerScriptDebugServer.h
+++ b/chromium/third_party/WebKit/Source/bindings/v8/WorkerScriptDebugServer.h
@@ -32,21 +32,18 @@
#define WorkerScriptDebugServer_h
#include "bindings/v8/ScriptDebugServer.h"
-
-namespace v8 {
-class Isolate;
-}
+#include <v8.h>
namespace WebCore {
class WorkerGlobalScope;
class WorkerThread;
-class WorkerScriptDebugServer : public ScriptDebugServer {
+class WorkerScriptDebugServer FINAL : public ScriptDebugServer {
WTF_MAKE_NONCOPYABLE(WorkerScriptDebugServer);
public:
- WorkerScriptDebugServer(WorkerGlobalScope*, const String&);
- ~WorkerScriptDebugServer() { }
+ explicit WorkerScriptDebugServer(WorkerGlobalScope*);
+ virtual ~WorkerScriptDebugServer() { }
void addListener(ScriptDebugListener*);
void removeListener(ScriptDebugListener*);
@@ -54,14 +51,13 @@ public:
void interruptAndRunTask(PassOwnPtr<Task>);
private:
- virtual ScriptDebugListener* getDebugListenerForContext(v8::Handle<v8::Context>);
- virtual void runMessageLoopOnPause(v8::Handle<v8::Context>);
- virtual void quitMessageLoopOnPause();
+ virtual ScriptDebugListener* getDebugListenerForContext(v8::Handle<v8::Context>) OVERRIDE;
+ virtual void runMessageLoopOnPause(v8::Handle<v8::Context>) OVERRIDE;
+ virtual void quitMessageLoopOnPause() OVERRIDE;
typedef HashMap<WorkerGlobalScope*, ScriptDebugListener*> ListenersMap;
ScriptDebugListener* m_listener;
WorkerGlobalScope* m_workerGlobalScope;
- String m_debuggerTaskMode;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/WrapperTypeInfo.h b/chromium/third_party/WebKit/Source/bindings/v8/WrapperTypeInfo.h
index 227083d018b..3d92f6adb0d 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/WrapperTypeInfo.h
+++ b/chromium/third_party/WebKit/Source/bindings/v8/WrapperTypeInfo.h
@@ -32,13 +32,13 @@
#define WrapperTypeInfo_h
#include "gin/public/wrapper_info.h"
+#include "platform/heap/Handle.h"
#include "wtf/Assertions.h"
#include <v8.h>
namespace WebCore {
class ActiveDOMObject;
- class DOMDataStore;
class EventTarget;
class Node;
@@ -51,13 +51,7 @@ namespace WebCore {
static const uint16_t v8DOMNodeClassId = 1;
static const uint16_t v8DOMObjectClassId = 2;
- enum WrapperWorldType {
- MainWorld,
- IsolatedWorld,
- WorkerWorld
- };
-
- typedef v8::Handle<v8::FunctionTemplate> (*DomTemplateFunction)(v8::Isolate*, WrapperWorldType);
+ typedef v8::Handle<v8::FunctionTemplate> (*DomTemplateFunction)(v8::Isolate*);
typedef void (*DerefObjectFunction)(void*);
typedef ActiveDOMObject* (*ToActiveDOMObjectFunction)(v8::Handle<v8::Object>);
typedef EventTarget* (*ToEventTargetFunction)(v8::Handle<v8::Object>);
@@ -66,7 +60,13 @@ namespace WebCore {
enum WrapperTypePrototype {
WrapperTypeObjectPrototype,
- WrapperTypeErrorPrototype
+ WrapperTypeExceptionPrototype
+ };
+
+ enum GCType {
+ GarbageCollectedObject,
+ WillBeGarbageCollectedObject,
+ RefCountedObject,
};
inline void setObjectGroup(void* object, const v8::Persistent<v8::Object>& wrapper, v8::Isolate* isolate)
@@ -100,12 +100,9 @@ namespace WebCore {
return false;
}
- v8::Handle<v8::FunctionTemplate> domTemplate(v8::Isolate* isolate, WrapperWorldType worldType) const { return domTemplateFunction(isolate, worldType); }
-
- void derefObject(void* object) const
+ v8::Handle<v8::FunctionTemplate> domTemplate(v8::Isolate* isolate) const
{
- if (derefObjectFunction)
- derefObjectFunction(object);
+ return domTemplateFunction(isolate);
}
void installPerContextEnabledMethods(v8::Handle<v8::Object> prototypeTemplate, v8::Isolate* isolate) const
@@ -147,6 +144,7 @@ namespace WebCore {
const InstallPerContextEnabledPrototypePropertiesFunction installPerContextEnabledMethodsFunction;
const WrapperTypeInfo* parentClass;
const WrapperTypePrototype wrapperTypePrototype;
+ const GCType gcType;
};
@@ -162,30 +160,60 @@ namespace WebCore {
}
template<typename T, int offset>
- inline T* getInternalField(v8::Handle<v8::Object> object)
+ inline T* getInternalField(v8::Handle<v8::Object> wrapper)
{
- ASSERT(offset < object->InternalFieldCount());
- return static_cast<T*>(object->GetAlignedPointerFromInternalField(offset));
+ ASSERT(offset < wrapper->InternalFieldCount());
+ return static_cast<T*>(wrapper->GetAlignedPointerFromInternalField(offset));
+ }
+
+ inline void* toNative(const v8::Persistent<v8::Object>& wrapper)
+ {
+ return getInternalField<void, v8DOMWrapperObjectIndex>(wrapper);
+ }
+
+ inline void* toNative(v8::Handle<v8::Object> wrapper)
+ {
+ return getInternalField<void, v8DOMWrapperObjectIndex>(wrapper);
}
- inline void* toNative(const v8::Persistent<v8::Object>& object)
+ inline const WrapperTypeInfo* toWrapperTypeInfo(const v8::Persistent<v8::Object>& wrapper)
{
- return getInternalField<void, v8DOMWrapperObjectIndex>(object);
+ return getInternalField<WrapperTypeInfo, v8DOMWrapperTypeIndex>(wrapper);
}
- inline void* toNative(v8::Handle<v8::Object> object)
+ inline const WrapperTypeInfo* toWrapperTypeInfo(v8::Handle<v8::Object> wrapper)
{
- return getInternalField<void, v8DOMWrapperObjectIndex>(object);
+ return getInternalField<WrapperTypeInfo, v8DOMWrapperTypeIndex>(wrapper);
}
- inline const WrapperTypeInfo* toWrapperTypeInfo(const v8::Persistent<v8::Object>& object)
+ inline const PersistentNode* toPersistentHandle(const v8::Handle<v8::Object>& wrapper)
{
- return getInternalField<WrapperTypeInfo, v8DOMWrapperTypeIndex>(object);
+ // Persistent handle is stored in the last internal field.
+ return static_cast<PersistentNode*>(wrapper->GetAlignedPointerFromInternalField(wrapper->InternalFieldCount() - 1));
}
- inline const WrapperTypeInfo* toWrapperTypeInfo(v8::Handle<v8::Object> object)
+ inline void releaseObject(v8::Handle<v8::Object> wrapper)
{
- return getInternalField<WrapperTypeInfo, v8DOMWrapperTypeIndex>(object);
+ const WrapperTypeInfo* typeInfo = toWrapperTypeInfo(wrapper);
+ if (typeInfo->gcType == GarbageCollectedObject) {
+ const PersistentNode* handle = toPersistentHandle(wrapper);
+ // This will be null iff a wrapper for a hidden wrapper object,
+ // see V8DOMWrapper::setNativeInfoForHiddenWrapper().
+ delete handle;
+ } else if (typeInfo->gcType == WillBeGarbageCollectedObject) {
+#if ENABLE(OILPAN)
+ const PersistentNode* handle = toPersistentHandle(wrapper);
+ // This will be null iff a wrapper for a hidden wrapper object,
+ // see V8DOMWrapper::setNativeInfoForHiddenWrapper().
+ delete handle;
+#else
+ ASSERT(typeInfo->derefObjectFunction);
+ typeInfo->derefObjectFunction(toNative(wrapper));
+#endif
+ } else {
+ ASSERT(typeInfo->derefObjectFunction);
+ typeInfo->derefObjectFunction(toNative(wrapper));
+ }
}
struct WrapperConfiguration {
@@ -194,7 +222,7 @@ namespace WebCore {
Dependent, Independent
};
- void configureWrapper(v8::Persistent<v8::Object>* wrapper) const
+ void configureWrapper(v8::PersistentBase<v8::Object>* wrapper) const
{
wrapper->SetWrapperClassId(classId);
if (lifetime == Independent)
@@ -216,11 +244,6 @@ namespace WebCore {
WrapperConfiguration configuration = {v8DOMNodeClassId, lifetime};
return configuration;
}
-
- template<class ElementType>
- class WrapperTypeTraits {
- // specialized classes have thier own functions, which are generated by binding generator.
- };
}
#endif // WrapperTypeInfo_h
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8AlgorithmCustom.cpp b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8AlgorithmCustom.cpp
deleted file mode 100644
index c8c4ccaa0e8..00000000000
--- a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8AlgorithmCustom.cpp
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright (C) 2013 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 "V8Algorithm.h"
-
-#include "V8AesCbcParams.h"
-#include "V8AesCtrParams.h"
-#include "V8AesKeyGenParams.h"
-#include "V8HmacKeyParams.h"
-#include "V8HmacParams.h"
-#include "V8RsaKeyGenParams.h"
-#include "V8RsaSsaParams.h"
-#include "platform/NotImplemented.h"
-
-namespace WebCore {
-
-v8::Handle<v8::Object> wrap(Algorithm* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
-{
- ASSERT(impl);
-
- // Wrap as the more derived type.
- switch (impl->type()) {
- case blink::WebCryptoAlgorithmParamsTypeNone:
- return V8Algorithm::createWrapper(impl, creationContext, isolate);
- case blink::WebCryptoAlgorithmParamsTypeAesCbcParams:
- return wrap(static_cast<AesCbcParams*>(impl), creationContext, isolate);
- case blink::WebCryptoAlgorithmParamsTypeAesKeyGenParams:
- return wrap(static_cast<AesKeyGenParams*>(impl), creationContext, isolate);
- case blink::WebCryptoAlgorithmParamsTypeHmacParams:
- return wrap(static_cast<HmacParams*>(impl), creationContext, isolate);
- case blink::WebCryptoAlgorithmParamsTypeHmacKeyParams:
- return wrap(static_cast<HmacKeyParams*>(impl), creationContext, isolate);
- case blink::WebCryptoAlgorithmParamsTypeRsaSsaParams:
- return wrap(static_cast<RsaSsaParams*>(impl), creationContext, isolate);
- case blink::WebCryptoAlgorithmParamsTypeRsaKeyGenParams:
- return wrap(static_cast<RsaKeyGenParams*>(impl), creationContext, isolate);
- case blink::WebCryptoAlgorithmParamsTypeAesCtrParams:
- return wrap(static_cast<AesCtrParams*>(impl), creationContext, isolate);
- case blink::WebCryptoAlgorithmParamsTypeAesGcmParams:
- case blink::WebCryptoAlgorithmParamsTypeRsaOaepParams:
- // TODO
- notImplemented();
- break;
- }
-
- ASSERT_NOT_REACHED();
- return v8::Handle<v8::Object>();
-}
-
-} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8ArrayBufferCustom.cpp b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8ArrayBufferCustom.cpp
index 8eb4c2b818d..f3494cf694e 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8ArrayBufferCustom.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8ArrayBufferCustom.cpp
@@ -31,7 +31,6 @@
#include "config.h"
#include "bindings/v8/custom/V8ArrayBufferCustom.h"
-#include "bindings/v8/ScriptPromiseResolver.h"
#include "bindings/v8/V8Binding.h"
#include "wtf/ArrayBuffer.h"
#include "wtf/StdLibExtras.h"
@@ -49,15 +48,10 @@ V8ArrayBufferDeallocationObserver* V8ArrayBufferDeallocationObserver::instanceTe
const WrapperTypeInfo V8ArrayBuffer::wrapperTypeInfo = {
gin::kEmbedderBlink,
0, V8ArrayBuffer::derefObject,
- 0, 0, 0, 0, 0, WrapperTypeObjectPrototype
+ 0, 0, 0, 0, 0, WrapperTypeObjectPrototype, RefCountedObject
};
-bool V8ArrayBuffer::hasInstance(v8::Handle<v8::Value> value, v8::Isolate*, WrapperWorldType)
-{
- return value->IsArrayBuffer();
-}
-
-bool V8ArrayBuffer::hasInstanceInAnyWorld(v8::Handle<v8::Value> value, v8::Isolate*)
+bool V8ArrayBuffer::hasInstance(v8::Handle<v8::Value> value, v8::Isolate*)
{
return value->IsArrayBuffer();
}
@@ -82,12 +76,11 @@ v8::Handle<v8::Object> V8ArrayBuffer::createWrapper(PassRefPtr<ArrayBuffer> impl
ArrayBuffer* V8ArrayBuffer::toNative(v8::Handle<v8::Object> object)
{
ASSERT(object->IsArrayBuffer());
- void* arraybufferPtr = object->GetAlignedPointerFromInternalField(v8DOMWrapperObjectIndex);
- if (arraybufferPtr)
- return reinterpret_cast<ArrayBuffer*>(arraybufferPtr);
-
v8::Local<v8::ArrayBuffer> v8buffer = object.As<v8::ArrayBuffer>();
- ASSERT(!v8buffer->IsExternal());
+ if (v8buffer->IsExternal()) {
+ RELEASE_ASSERT(toWrapperTypeInfo(object)->ginEmbedder == gin::kEmbedderBlink);
+ return reinterpret_cast<ArrayBuffer*>(WebCore::toNative(object));
+ }
v8::ArrayBuffer::Contents v8Contents = v8buffer->Externalize();
ArrayBufferContents contents(v8Contents.Data(), v8Contents.ByteLength(),
@@ -95,9 +88,12 @@ ArrayBuffer* V8ArrayBuffer::toNative(v8::Handle<v8::Object> object)
RefPtr<ArrayBuffer> buffer = ArrayBuffer::create(contents);
V8DOMWrapper::associateObjectWithWrapper<V8ArrayBuffer>(buffer.release(), &wrapperTypeInfo, object, v8::Isolate::GetCurrent(), WrapperConfiguration::Dependent);
- arraybufferPtr = object->GetAlignedPointerFromInternalField(v8DOMWrapperObjectIndex);
- ASSERT(arraybufferPtr);
- return reinterpret_cast<ArrayBuffer*>(arraybufferPtr);
+ return reinterpret_cast<ArrayBuffer*>(WebCore::toNative(object));
+}
+
+ArrayBuffer* V8ArrayBuffer::toNativeWithTypeCheck(v8::Isolate* isolate, v8::Handle<v8::Value> value)
+{
+ return V8ArrayBuffer::hasInstance(value, isolate) ? V8ArrayBuffer::toNative(v8::Handle<v8::Object>::Cast(value)) : 0;
}
template<>
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8ArrayBufferCustom.h b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8ArrayBufferCustom.h
index 2c5ff8e1cac..779095f7c9a 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8ArrayBufferCustom.h
+++ b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8ArrayBufferCustom.h
@@ -34,9 +34,9 @@
namespace WebCore {
-class V8ArrayBufferDeallocationObserver: public WTF::ArrayBufferDeallocationObserver {
+class V8ArrayBufferDeallocationObserver FINAL: public WTF::ArrayBufferDeallocationObserver {
public:
- virtual void arrayBufferDeallocated(unsigned sizeInBytes)
+ virtual void arrayBufferDeallocated(unsigned sizeInBytes) OVERRIDE
{
v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(-static_cast<int>(sizeInBytes));
}
@@ -51,9 +51,9 @@ protected:
class V8ArrayBuffer {
public:
- static bool hasInstance(v8::Handle<v8::Value>, v8::Isolate*, WrapperWorldType);
- static bool hasInstanceInAnyWorld(v8::Handle<v8::Value>, v8::Isolate*);
+ static bool hasInstance(v8::Handle<v8::Value>, v8::Isolate*);
static ArrayBuffer* toNative(v8::Handle<v8::Object>);
+ static ArrayBuffer* toNativeWithTypeCheck(v8::Isolate*, v8::Handle<v8::Value>);
static void derefObject(void*);
static const WrapperTypeInfo wrapperTypeInfo;
static const int internalFieldCount = v8DefaultWrapperInternalFieldCount;
@@ -75,13 +75,6 @@ private:
static v8::Handle<v8::Object> createWrapper(PassRefPtr<ArrayBuffer>, v8::Handle<v8::Object> creationContext, v8::Isolate*);
};
-template<>
-class WrapperTypeTraits<ArrayBuffer > {
-public:
- static const WrapperTypeInfo* wrapperTypeInfo() { return &V8ArrayBuffer::wrapperTypeInfo; }
-};
-
-
inline v8::Handle<v8::Object> wrap(ArrayBuffer* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
{
ASSERT(impl);
@@ -115,7 +108,7 @@ inline void v8SetReturnValue(const CallbackInfo& info, ArrayBuffer* impl)
template<class CallbackInfo>
inline void v8SetReturnValueForMainWorld(const CallbackInfo& info, ArrayBuffer* impl)
{
- ASSERT(worldType(info.GetIsolate()) == MainWorld);
+ ASSERT(DOMWrapperWorld::current(info.GetIsolate()).isMainWorld());
if (UNLIKELY(!impl)) {
v8SetReturnValueNull(info);
return;
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8ArrayBufferViewCustom.cpp b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8ArrayBufferViewCustom.cpp
index 4f00d0df933..5ee873dd6cb 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8ArrayBufferViewCustom.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8ArrayBufferViewCustom.cpp
@@ -82,5 +82,9 @@ ArrayBufferView* V8ArrayBufferView::toNative(v8::Handle<v8::Object> object)
return 0;
}
+ArrayBufferView* V8ArrayBufferView::toNativeWithTypeCheck(v8::Isolate* isolate, v8::Handle<v8::Value> value)
+{
+ return V8ArrayBufferView::hasInstance(value, isolate) ? V8ArrayBufferView::toNative(v8::Handle<v8::Object>::Cast(value)) : 0;
+}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8ArrayBufferViewCustom.h b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8ArrayBufferViewCustom.h
index 94fcd1344d8..7ff95bf68ee 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8ArrayBufferViewCustom.h
+++ b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8ArrayBufferViewCustom.h
@@ -43,15 +43,12 @@ namespace WebCore {
class V8ArrayBufferView {
public:
- static bool hasInstance(v8::Handle<v8::Value> value, v8::Isolate*, WrapperWorldType)
- {
- return value->IsArrayBufferView();
- }
- static bool hasInstanceInAnyWorld(v8::Handle<v8::Value> value, v8::Isolate*)
+ static bool hasInstance(v8::Handle<v8::Value> value, v8::Isolate*)
{
return value->IsArrayBufferView();
}
static ArrayBufferView* toNative(v8::Handle<v8::Object>);
+ static ArrayBufferView* toNativeWithTypeCheck(v8::Isolate*, v8::Handle<v8::Value>);
static inline void* toInternalPointer(ArrayBufferView* impl)
{
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8ArrayBufferViewCustomScript.js b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8ArrayBufferViewCustomScript.js
deleted file mode 100644
index d3448599a90..00000000000
--- a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8ArrayBufferViewCustomScript.js
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2011 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. 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.
- */
-
-(function() {
- return function(source, length, offset) {
- if (offset == 0) {
- for (var i = 0; i < length; i++)
- this[i] = source[i];
- } else {
- for (var i = 0; i < length; i++)
- this[i + offset] = source[i];
- }
- }
-})();
-
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8AudioNodeCustom.cpp b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8AudioNodeCustom.cpp
index fcc9d085027..762b58580fb 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8AudioNodeCustom.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8AudioNodeCustom.cpp
@@ -24,25 +24,25 @@
#include "config.h"
#if ENABLE(WEB_AUDIO)
-#include "V8AudioNode.h"
+#include "bindings/modules/v8/V8AudioNode.h"
-#include "V8AnalyserNode.h"
-#include "V8AudioBufferSourceNode.h"
-#include "V8AudioDestinationNode.h"
-#include "V8BiquadFilterNode.h"
-#include "V8ChannelMergerNode.h"
-#include "V8ChannelSplitterNode.h"
-#include "V8ConvolverNode.h"
-#include "V8DelayNode.h"
-#include "V8DynamicsCompressorNode.h"
-#include "V8GainNode.h"
-#include "V8MediaElementAudioSourceNode.h"
-#include "V8MediaStreamAudioDestinationNode.h"
-#include "V8MediaStreamAudioSourceNode.h"
-#include "V8OscillatorNode.h"
-#include "V8PannerNode.h"
-#include "V8ScriptProcessorNode.h"
-#include "V8WaveShaperNode.h"
+#include "bindings/modules/v8/V8AnalyserNode.h"
+#include "bindings/modules/v8/V8AudioBufferSourceNode.h"
+#include "bindings/modules/v8/V8AudioDestinationNode.h"
+#include "bindings/modules/v8/V8BiquadFilterNode.h"
+#include "bindings/modules/v8/V8ChannelMergerNode.h"
+#include "bindings/modules/v8/V8ChannelSplitterNode.h"
+#include "bindings/modules/v8/V8ConvolverNode.h"
+#include "bindings/modules/v8/V8DelayNode.h"
+#include "bindings/modules/v8/V8DynamicsCompressorNode.h"
+#include "bindings/modules/v8/V8GainNode.h"
+#include "bindings/modules/v8/V8MediaElementAudioSourceNode.h"
+#include "bindings/modules/v8/V8MediaStreamAudioDestinationNode.h"
+#include "bindings/modules/v8/V8MediaStreamAudioSourceNode.h"
+#include "bindings/modules/v8/V8OscillatorNode.h"
+#include "bindings/modules/v8/V8PannerNode.h"
+#include "bindings/modules/v8/V8ScriptProcessorNode.h"
+#include "bindings/modules/v8/V8WaveShaperNode.h"
#include "bindings/v8/V8Binding.h"
#include "modules/webaudio/AnalyserNode.h"
#include "modules/webaudio/AudioBufferSourceNode.h"
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8BiquadFilterNodeCustom.cpp b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8BiquadFilterNodeCustom.cpp
deleted file mode 100644
index 862d040c3b4..00000000000
--- a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8BiquadFilterNodeCustom.cpp
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2012, Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. 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"
-#if ENABLE(WEB_AUDIO)
-#include "V8BiquadFilterNode.h"
-
-#include "bindings/v8/V8Binding.h"
-#include "modules/webaudio/BiquadFilterNode.h"
-
-namespace WebCore {
-
-void V8BiquadFilterNode::typeAttributeSetterCustom(v8::Local<v8::Value> value, const v8::PropertyCallbackInfo<void>& info)
-{
- BiquadFilterNode* imp = V8BiquadFilterNode::toNative(info.Holder());
-
- if (value->IsNumber()) {
- bool ok = false;
- uint32_t type = toUInt32(value, ok);
- ASSERT(ok);
- if (!imp->setType(type))
- throwTypeError("Illegal BiquadFilterNode type", info.GetIsolate());
- return;
- }
-
- if (value->IsString()) {
- String type = toCoreString(value.As<v8::String>());
- if (type == "lowpass" || type == "highpass" || type == "bandpass" || type == "lowshelf" || type == "highshelf" || type == "peaking" || type == "notch" || type == "allpass") {
- imp->setType(type);
- return;
- }
- }
-
- throwTypeError("Illegal BiquadFilterNode type", info.GetIsolate());
-}
-
-} // namespace WebCore
-
-#endif // ENABLE(WEB_AUDIO)
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8BlobCustom.cpp b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8BlobCustom.cpp
index db9fbbb4295..594b9772cbd 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8BlobCustom.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8BlobCustom.cpp
@@ -29,11 +29,10 @@
*/
#include "config.h"
-#include "V8Blob.h"
+#include "bindings/core/v8/V8Blob.h"
#include "bindings/v8/ExceptionState.h"
#include "bindings/v8/custom/V8BlobCustomHelpers.h"
-#include "core/fileapi/BlobBuilder.h"
namespace WebCore {
@@ -41,7 +40,7 @@ void V8Blob::constructorCustom(const v8::FunctionCallbackInfo<v8::Value>& info)
{
ExceptionState exceptionState(ExceptionState::ConstructionContext, "Blob", info.Holder(), info.GetIsolate());
if (!info.Length()) {
- RefPtr<Blob> blob = Blob::create();
+ RefPtrWillBeRawPtr<Blob> blob = Blob::create();
v8SetReturnValue(info, blob.release());
return;
}
@@ -72,12 +71,14 @@ void V8Blob::constructorCustom(const v8::FunctionCallbackInfo<v8::Value>& info)
}
}
- BlobBuilder blobBuilder;
+ OwnPtr<BlobData> blobData = BlobData::create();
+ blobData->setContentType(properties.contentType());
v8::Local<v8::Object> blobParts = v8::Local<v8::Object>::Cast(info[0]);
- if (!V8BlobCustomHelpers::processBlobParts(blobParts, length, properties.endings(), blobBuilder, info.GetIsolate()))
+ if (!V8BlobCustomHelpers::processBlobParts(blobParts, length, properties.normalizeLineEndingsToNative(), *blobData, info.GetIsolate()))
return;
- RefPtr<Blob> blob = blobBuilder.createBlob(properties.contentType());
+ long long blobSize = blobData->length();
+ RefPtrWillBeRawPtr<Blob> blob = Blob::create(BlobDataHandle::create(blobData.release(), blobSize));
v8SetReturnValue(info, blob.release());
}
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8BlobCustomHelpers.cpp b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8BlobCustomHelpers.cpp
index 62bdc36e7b2..e6ec3535ba6 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8BlobCustomHelpers.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8BlobCustomHelpers.cpp
@@ -29,16 +29,14 @@
*/
#include "config.h"
-#include "V8BlobCustomHelpers.h"
+#include "bindings/v8/custom/V8BlobCustomHelpers.h"
-#include "V8Blob.h"
+#include "bindings/core/v8/V8Blob.h"
#include "bindings/v8/Dictionary.h"
#include "bindings/v8/ExceptionState.h"
#include "bindings/v8/V8Binding.h"
-#include "bindings/v8/V8Utilities.h"
#include "bindings/v8/custom/V8ArrayBufferCustom.h"
#include "bindings/v8/custom/V8ArrayBufferViewCustom.h"
-#include "core/fileapi/BlobBuilder.h"
#include "wtf/DateMath.h"
namespace WebCore {
@@ -46,7 +44,7 @@ namespace WebCore {
namespace V8BlobCustomHelpers {
ParsedProperties::ParsedProperties(bool hasFileProperties)
- : m_endings("transparent")
+ : m_normalizeLineEndingsToNative(false)
, m_hasFileProperties(hasFileProperties)
#ifndef NDEBUG
, m_hasLastModified(false)
@@ -71,19 +69,20 @@ void ParsedProperties::setDefaultLastModified()
bool ParsedProperties::parseBlobPropertyBag(v8::Local<v8::Value> propertyBag, const char* blobClassName, ExceptionState& exceptionState, v8::Isolate* isolate)
{
- ASSERT(m_endings == "transparent");
+ TONATIVE_DEFAULT(Dictionary, dictionary, Dictionary(propertyBag, isolate), false);
- V8TRYCATCH_RETURN(Dictionary, dictionary, Dictionary(propertyBag, isolate), false);
-
- V8TRYCATCH_RETURN(bool, containsEndings, dictionary.get("endings", m_endings), false);
+ String endings;
+ TONATIVE_DEFAULT(bool, containsEndings, dictionary.get("endings", endings), false);
if (containsEndings) {
- if (m_endings != "transparent" && m_endings != "native") {
+ if (endings != "transparent" && endings != "native") {
exceptionState.throwTypeError("The 'endings' property must be either 'transparent' or 'native'.");
return false;
}
+ if (endings == "native")
+ m_normalizeLineEndingsToNative = true;
}
- V8TRYCATCH_RETURN(bool, containsType, dictionary.get("type", m_contentType), false);
+ TONATIVE_DEFAULT(bool, containsType, dictionary.get("type", m_contentType), false);
if (containsType) {
if (!m_contentType.containsOnlyASCII()) {
exceptionState.throwDOMException(SyntaxError, "The 'type' property must consist of ASCII characters.");
@@ -96,9 +95,9 @@ bool ParsedProperties::parseBlobPropertyBag(v8::Local<v8::Value> propertyBag, co
return true;
v8::Local<v8::Value> lastModified;
- V8TRYCATCH_RETURN(bool, containsLastModified, dictionary.get("lastModified", lastModified), false);
+ TONATIVE_DEFAULT(bool, containsLastModified, dictionary.get("lastModified", lastModified), false);
if (containsLastModified) {
- V8TRYCATCH_RETURN(long long, lastModifiedInt, toInt64(lastModified), false);
+ TONATIVE_DEFAULT(long long, lastModifiedInt, toInt64(lastModified), false);
setLastModified(static_cast<double>(lastModifiedInt) / msPerSecond);
} else {
setDefaultLastModified();
@@ -107,30 +106,28 @@ bool ParsedProperties::parseBlobPropertyBag(v8::Local<v8::Value> propertyBag, co
return true;
}
-bool processBlobParts(v8::Local<v8::Object> blobParts, uint32_t blobPartsLength, const String& endings, BlobBuilder& blobBuilder, v8::Isolate* isolate)
+bool processBlobParts(v8::Local<v8::Object> blobParts, uint32_t blobPartsLength, bool normalizeLineEndingsToNative, BlobData& blobData, v8::Isolate* isolate)
{
- ASSERT(endings == "transparent" || endings == "native");
-
for (uint32_t i = 0; i < blobPartsLength; ++i) {
- v8::Local<v8::Value> item = blobParts->Get(v8::Uint32::New(i, isolate));
+ v8::Local<v8::Value> item = blobParts->Get(v8::Uint32::New(isolate, i));
if (item.IsEmpty())
return false;
- if (V8ArrayBuffer::hasInstance(item, isolate, worldType(isolate))) {
+ if (V8ArrayBuffer::hasInstance(item, isolate)) {
ArrayBuffer* arrayBuffer = V8ArrayBuffer::toNative(v8::Handle<v8::Object>::Cast(item));
ASSERT(arrayBuffer);
- blobBuilder.append(arrayBuffer);
- } else if (V8ArrayBufferView::hasInstance(item, isolate, worldType(isolate))) {
+ blobData.appendArrayBuffer(arrayBuffer);
+ } else if (V8ArrayBufferView::hasInstance(item, isolate)) {
ArrayBufferView* arrayBufferView = V8ArrayBufferView::toNative(v8::Handle<v8::Object>::Cast(item));
ASSERT(arrayBufferView);
- blobBuilder.append(arrayBufferView);
- } else if (V8Blob::hasInstance(item, isolate, worldType(isolate))) {
+ blobData.appendArrayBufferView(arrayBufferView);
+ } else if (V8Blob::hasInstance(item, isolate)) {
Blob* blob = V8Blob::toNative(v8::Handle<v8::Object>::Cast(item));
ASSERT(blob);
- blobBuilder.append(blob);
+ blob->appendTo(blobData);
} else {
- V8TRYCATCH_FOR_V8STRINGRESOURCE_RETURN(V8StringResource<>, stringValue, item, false);
- blobBuilder.append(stringValue, endings);
+ TOSTRING_DEFAULT(V8StringResource<>, stringValue, item, false);
+ blobData.appendText(stringValue, normalizeLineEndingsToNative);
}
}
return true;
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8BlobCustomHelpers.h b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8BlobCustomHelpers.h
index 37a173120bb..93cc08dce79 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8BlobCustomHelpers.h
+++ b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8BlobCustomHelpers.h
@@ -35,7 +35,7 @@
namespace WebCore {
-class BlobBuilder;
+class BlobData;
class ExceptionState;
// Shared code between the custom constructor bindings for Blob and File.
@@ -53,7 +53,7 @@ public:
explicit ParsedProperties(bool hasFileProperties);
const String& contentType() const { return m_contentType; }
- const String& endings() const { return m_endings; }
+ bool normalizeLineEndingsToNative() const { return m_normalizeLineEndingsToNative; }
void setLastModified(double);
void setDefaultLastModified();
double lastModified() const
@@ -70,7 +70,7 @@ public:
private:
String m_contentType;
- String m_endings;
+ bool m_normalizeLineEndingsToNative;
// False if this contains the properties of a BlobPropertyBag.
bool m_hasFileProperties;
@@ -81,10 +81,10 @@ private:
#endif // NDEBUG
};
-// Appends the blobParts passed to a Blob or File constructor into a BlobBuilder.
+// Appends the blobParts passed to a Blob or File constructor into a BlobData.
// http://www.w3.org/TR/FileAPI/#constructorParams
// Returns true if everything went well, false if a JS exception was thrown.
-bool processBlobParts(v8::Local<v8::Object> blobParts, uint32_t blobPartsLength, const String& endings, BlobBuilder&, v8::Isolate*);
+bool processBlobParts(v8::Local<v8::Object> blobParts, uint32_t blobPartsLength, bool normalizeLineEndingsToNative, BlobData&, v8::Isolate*);
} // namespace V8BlobCustomHelpers
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8CSSRuleCustom.cpp b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8CSSRuleCustom.cpp
index 0fbd080bbd4..4aff8aa4090 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8CSSRuleCustom.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8CSSRuleCustom.cpp
@@ -29,20 +29,19 @@
*/
#include "config.h"
-#include "V8CSSRule.h"
+#include "bindings/core/v8/V8CSSRule.h"
-#include "V8CSSCharsetRule.h"
-#include "V8CSSFontFaceRule.h"
-#include "V8CSSImportRule.h"
-#include "V8CSSKeyframeRule.h"
-#include "V8CSSKeyframesRule.h"
-#include "V8CSSMediaRule.h"
-#include "V8CSSPageRule.h"
-#include "V8CSSStyleRule.h"
-#include "V8CSSSupportsRule.h"
-#include "V8CSSViewportRule.h"
-#include "V8WebKitCSSFilterRule.h"
-#include "V8WebKitCSSRegionRule.h"
+#include "bindings/core/v8/V8CSSCharsetRule.h"
+#include "bindings/core/v8/V8CSSFontFaceRule.h"
+#include "bindings/core/v8/V8CSSImportRule.h"
+#include "bindings/core/v8/V8CSSKeyframeRule.h"
+#include "bindings/core/v8/V8CSSKeyframesRule.h"
+#include "bindings/core/v8/V8CSSMediaRule.h"
+#include "bindings/core/v8/V8CSSPageRule.h"
+#include "bindings/core/v8/V8CSSStyleRule.h"
+#include "bindings/core/v8/V8CSSSupportsRule.h"
+#include "bindings/core/v8/V8CSSViewportRule.h"
+#include "bindings/core/v8/V8WebKitCSSFilterRule.h"
namespace WebCore {
@@ -52,7 +51,7 @@ v8::Handle<v8::Object> wrap(CSSRule* impl, v8::Handle<v8::Object> creationContex
switch (impl->type()) {
case CSSRule::UNKNOWN_RULE:
// CSSUnknownRule.idl is explicitly excluded as it doesn't add anything
- // over CSSRule.idl (see bindings/derived_sources.gyp: 'idl_files').
+ // over CSSRule.idl (see core/core.gypi: 'core_idl_files').
// -> Use the base class wrapper here.
return V8CSSRule::createWrapper(impl, creationContext, isolate);
case CSSRule::STYLE_RULE:
@@ -75,8 +74,6 @@ v8::Handle<v8::Object> wrap(CSSRule* impl, v8::Handle<v8::Object> creationContex
return wrap(toCSSSupportsRule(impl), creationContext, isolate);
case CSSRule::VIEWPORT_RULE:
return wrap(toCSSViewportRule(impl), creationContext, isolate);
- case CSSRule::WEBKIT_REGION_RULE:
- return wrap(toCSSRegionRule(impl), creationContext, isolate);
case CSSRule::WEBKIT_FILTER_RULE:
return wrap(toCSSFilterRule(impl), creationContext, isolate);
}
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8CSSStyleDeclarationCustom.cpp b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8CSSStyleDeclarationCustom.cpp
index 6d118a383c3..c7f3d7ab009 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8CSSStyleDeclarationCustom.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8CSSStyleDeclarationCustom.cpp
@@ -29,12 +29,12 @@
*/
#include "config.h"
-#include "V8CSSStyleDeclaration.h"
+#include "bindings/core/v8/V8CSSStyleDeclaration.h"
-#include "CSSPropertyNames.h"
#include "bindings/v8/ExceptionState.h"
#include "bindings/v8/V8Binding.h"
-#include "core/css/CSSParser.h"
+#include "core/CSSPropertyNames.h"
+#include "core/css/parser/BisonCSSParser.h"
#include "core/css/CSSPrimitiveValue.h"
#include "core/css/CSSStyleDeclaration.h"
#include "core/css/CSSValue.h"
@@ -49,7 +49,6 @@
#include "wtf/text/StringConcatenate.h"
using namespace WTF;
-using namespace std;
namespace WebCore {
@@ -81,17 +80,51 @@ static bool hasCSSPropertyNamePrefix(const String& propertyName, const char* pre
}
struct CSSPropertyInfo {
- unsigned propID: 30; // CSSPropertyID
- unsigned nameWithDash: 1;
- unsigned nameWithCssPrefix: 1;
+ CSSPropertyID propID;
};
-static inline void countCssPropertyInfoUsage(const CSSPropertyInfo& propInfo)
+static CSSPropertyID cssResolvedPropertyID(const String& propertyName)
{
- if (propInfo.nameWithDash)
- UseCounter::count(activeDOMWindow(), UseCounter::CSSStyleDeclarationPropertyName);
- if (propInfo.propID == CSSPropertyFloat && !propInfo.nameWithCssPrefix)
- UseCounter::count(activeDOMWindow(), UseCounter::CSSStyleDeclarationFloatPropertyName);
+ unsigned length = propertyName.length();
+ if (!length)
+ return CSSPropertyInvalid;
+
+ StringBuilder builder;
+ builder.reserveCapacity(length);
+
+ unsigned i = 0;
+ bool hasSeenDash = false;
+
+ if (hasCSSPropertyNamePrefix(propertyName, "css"))
+ i += 3;
+ else if (hasCSSPropertyNamePrefix(propertyName, "webkit"))
+ builder.append('-');
+ else if (isASCIIUpper(propertyName[0]))
+ return CSSPropertyInvalid;
+
+ bool hasSeenUpper = isASCIIUpper(propertyName[i]);
+
+ builder.append(toASCIILower(propertyName[i++]));
+
+ for (; i < length; ++i) {
+ UChar c = propertyName[i];
+ if (!isASCIIUpper(c)) {
+ if (c == '-')
+ hasSeenDash = true;
+ builder.append(c);
+ } else {
+ hasSeenUpper = true;
+ builder.append('-');
+ builder.append(toASCIILower(c));
+ }
+ }
+
+ // Reject names containing both dashes and upper-case characters, such as "border-rightColor".
+ if (hasSeenDash && hasSeenUpper)
+ return CSSPropertyInvalid;
+
+ String propName = builder.toString();
+ return cssPropertyID(propName);
}
// When getting properties on CSSStyleDeclarations, the name used from
@@ -110,52 +143,13 @@ static CSSPropertyInfo* cssPropertyInfo(v8::Handle<v8::String> v8PropertyName)
DEFINE_STATIC_LOCAL(CSSPropertyInfoMap, map, ());
CSSPropertyInfo* propInfo = map.get(propertyName);
if (!propInfo) {
- unsigned length = propertyName.length();
- if (!length)
- return 0;
-
- StringBuilder builder;
- builder.reserveCapacity(length);
-
- unsigned i = 0;
- bool hasSeenDash = false;
- bool hasSeenCssPrefix = false;
-
- if (hasCSSPropertyNamePrefix(propertyName, "css")) {
- hasSeenCssPrefix = true;
- i += 3;
- } else if (hasCSSPropertyNamePrefix(propertyName, "webkit")) {
- builder.append('-');
- } else if (isASCIIUpper(propertyName[0])) {
- return 0;
- }
-
- builder.append(toASCIILower(propertyName[i++]));
-
- for (; i < length; ++i) {
- UChar c = propertyName[i];
- if (!isASCIIUpper(c)) {
- if (c == '-')
- hasSeenDash = true;
- builder.append(c);
- }
- else {
- builder.append('-');
- builder.append(toASCIILower(c));
- }
- }
-
- String propName = builder.toString();
- CSSPropertyID propertyID = cssPropertyID(propName);
- if (propertyID && RuntimeCSSEnabled::isCSSPropertyEnabled(propertyID)) {
- propInfo = new CSSPropertyInfo();
- propInfo->propID = propertyID;
- propInfo->nameWithDash = hasSeenDash;
- propInfo->nameWithCssPrefix = hasSeenCssPrefix;
- map.add(propertyName, propInfo);
- }
+ propInfo = new CSSPropertyInfo();
+ propInfo->propID = cssResolvedPropertyID(propertyName);
+ map.add(propertyName, propInfo);
}
- return propInfo;
+ if (propInfo->propID && RuntimeCSSEnabled::isCSSPropertyEnabled(propInfo->propID))
+ return propInfo;
+ return 0;
}
void V8CSSStyleDeclaration::namedPropertyEnumeratorCustom(const v8::PropertyCallbackInfo<v8::Array>& info)
@@ -170,7 +164,7 @@ void V8CSSStyleDeclaration::namedPropertyEnumeratorCustom(const v8::PropertyCall
if (RuntimeCSSEnabled::isCSSPropertyEnabled(propertyId))
propertyNames.append(getJSPropertyName(propertyId));
}
- sort(propertyNames.begin(), propertyNames.end(), codePointCompareLessThan);
+ std::sort(propertyNames.begin(), propertyNames.end(), codePointCompareLessThan);
propertyNamesLength = propertyNames.size();
}
@@ -178,7 +172,7 @@ void V8CSSStyleDeclaration::namedPropertyEnumeratorCustom(const v8::PropertyCall
for (unsigned i = 0; i < propertyNamesLength; ++i) {
String key = propertyNames.at(i);
ASSERT(!key.isNull());
- properties->Set(v8::Integer::New(i, info.GetIsolate()), v8String(info.GetIsolate(), key));
+ properties->Set(v8::Integer::New(info.GetIsolate(), i), v8String(info.GetIsolate(), key));
}
v8SetReturnValue(info, properties);
@@ -188,8 +182,7 @@ void V8CSSStyleDeclaration::namedPropertyQueryCustom(v8::Local<v8::String> v8Nam
{
// NOTE: cssPropertyInfo lookups incur several mallocs.
// Successful lookups have the same cost the first time, but are cached.
- if (CSSPropertyInfo* propInfo = cssPropertyInfo(v8Name)) {
- countCssPropertyInfoUsage(*propInfo);
+ if (cssPropertyInfo(v8Name)) {
v8SetReturnValueInt(info, 0);
return;
}
@@ -208,32 +201,27 @@ void V8CSSStyleDeclaration::namedPropertyGetterCustom(v8::Local<v8::String> name
if (!propInfo)
return;
- countCssPropertyInfoUsage(*propInfo);
- CSSStyleDeclaration* imp = V8CSSStyleDeclaration::toNative(info.Holder());
- RefPtr<CSSValue> cssValue = imp->getPropertyCSSValueInternal(static_cast<CSSPropertyID>(propInfo->propID));
+ CSSStyleDeclaration* impl = V8CSSStyleDeclaration::toNative(info.Holder());
+ RefPtrWillBeRawPtr<CSSValue> cssValue = impl->getPropertyCSSValueInternal(static_cast<CSSPropertyID>(propInfo->propID));
if (cssValue) {
v8SetReturnValueStringOrNull(info, cssValue->cssText(), info.GetIsolate());
return;
}
- String result = imp->getPropertyValueInternal(static_cast<CSSPropertyID>(propInfo->propID));
- if (result.isNull())
- result = ""; // convert null to empty string.
-
+ String result = impl->getPropertyValueInternal(static_cast<CSSPropertyID>(propInfo->propID));
v8SetReturnValueString(info, result, info.GetIsolate());
}
void V8CSSStyleDeclaration::namedPropertySetterCustom(v8::Local<v8::String> name, v8::Local<v8::Value> value, const v8::PropertyCallbackInfo<v8::Value>& info)
{
- CSSStyleDeclaration* imp = V8CSSStyleDeclaration::toNative(info.Holder());
+ CSSStyleDeclaration* impl = V8CSSStyleDeclaration::toNative(info.Holder());
CSSPropertyInfo* propInfo = cssPropertyInfo(name);
if (!propInfo)
return;
- countCssPropertyInfoUsage(*propInfo);
- V8TRYCATCH_FOR_V8STRINGRESOURCE_VOID(V8StringResource<WithNullCheck>, propertyValue, value);
+ TOSTRING_VOID(V8StringResource<WithNullCheck>, propertyValue, value);
ExceptionState exceptionState(ExceptionState::SetterContext, getPropertyName(static_cast<CSSPropertyID>(propInfo->propID)), "CSSStyleDeclaration", info.Holder(), info.GetIsolate());
- imp->setPropertyInternal(static_cast<CSSPropertyID>(propInfo->propID), propertyValue, false, exceptionState);
+ impl->setPropertyInternal(static_cast<CSSPropertyID>(propInfo->propID), propertyValue, false, exceptionState);
if (exceptionState.throwIfNeeded())
return;
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8CSSValueCustom.cpp b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8CSSValueCustom.cpp
index 3db5c35477c..44dc8e69ab8 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8CSSValueCustom.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8CSSValueCustom.cpp
@@ -29,16 +29,12 @@
*/
#include "config.h"
-#include "V8CSSValue.h"
+#include "bindings/core/v8/V8CSSValue.h"
-#include "V8CSSPrimitiveValue.h"
-#include "V8CSSValueList.h"
-#include "V8SVGColor.h"
-#include "V8SVGPaint.h"
-#include "V8WebKitCSSFilterValue.h"
-#include "V8WebKitCSSMixFunctionValue.h"
-#include "V8WebKitCSSTransformValue.h"
-#include "core/css/CSSMixFunctionValue.h"
+#include "bindings/core/v8/V8CSSPrimitiveValue.h"
+#include "bindings/core/v8/V8CSSValueList.h"
+#include "bindings/core/v8/V8WebKitCSSFilterValue.h"
+#include "bindings/core/v8/V8WebKitCSSTransformValue.h"
namespace WebCore {
@@ -47,18 +43,12 @@ v8::Handle<v8::Object> wrap(CSSValue* impl, v8::Handle<v8::Object> creationConte
ASSERT(impl);
if (impl->isTransformValue())
return wrap(toCSSTransformValue(impl), creationContext, isolate);
- if (impl->isMixFunctionValue())
- return wrap(toCSSMixFunctionValue(impl), creationContext, isolate);
if (impl->isFilterValue())
return wrap(toCSSFilterValue(impl), creationContext, isolate);
if (impl->isValueList())
return wrap(toCSSValueList(impl), creationContext, isolate);
if (impl->isPrimitiveValue())
return wrap(toCSSPrimitiveValue(impl), creationContext, isolate);
- if (impl->isSVGPaint())
- return wrap(toSVGPaint(impl), creationContext, isolate);
- if (impl->isSVGColor())
- return wrap(toSVGColor(impl), creationContext, isolate);
return V8CSSValue::createWrapper(impl, creationContext, isolate);
}
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8CanvasRenderingContext2DCustom.cpp b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8CanvasRenderingContext2DCustom.cpp
index 3e13d83e57e..d9d036df3cc 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8CanvasRenderingContext2DCustom.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8CanvasRenderingContext2DCustom.cpp
@@ -29,14 +29,14 @@
*/
#include "config.h"
-#include "V8CanvasRenderingContext2D.h"
+#include "bindings/core/v8/V8CanvasRenderingContext2D.h"
-#include "V8CanvasGradient.h"
-#include "V8CanvasPattern.h"
-#include "V8HTMLCanvasElement.h"
-#include "V8HTMLImageElement.h"
-#include "V8HTMLVideoElement.h"
-#include "V8ImageData.h"
+#include "bindings/core/v8/V8CanvasGradient.h"
+#include "bindings/core/v8/V8CanvasPattern.h"
+#include "bindings/core/v8/V8HTMLCanvasElement.h"
+#include "bindings/core/v8/V8HTMLImageElement.h"
+#include "bindings/core/v8/V8HTMLVideoElement.h"
+#include "bindings/core/v8/V8ImageData.h"
#include "bindings/v8/V8Binding.h"
#include "core/html/canvas/CanvasGradient.h"
#include "core/html/canvas/CanvasPattern.h"
@@ -59,13 +59,10 @@ static v8::Handle<v8::Value> toV8Object(CanvasStyle* style, v8::Handle<v8::Objec
static PassRefPtr<CanvasStyle> toCanvasStyle(v8::Handle<v8::Value> value, v8::Isolate* isolate)
{
- if (V8CanvasGradient::hasInstance(value, isolate, worldType(isolate)))
- return CanvasStyle::createFromGradient(V8CanvasGradient::toNative(v8::Handle<v8::Object>::Cast(value)));
-
- if (V8CanvasPattern::hasInstance(value, isolate, worldType(isolate)))
- return CanvasStyle::createFromPattern(V8CanvasPattern::toNative(v8::Handle<v8::Object>::Cast(value)));
-
- return 0;
+ RefPtr<CanvasStyle> canvasStyle = CanvasStyle::createFromGradient(V8CanvasGradient::toNativeWithTypeCheck(isolate, value));
+ if (canvasStyle)
+ return canvasStyle;
+ return CanvasStyle::createFromPattern(V8CanvasPattern::toNativeWithTypeCheck(isolate, value));
}
void V8CanvasRenderingContext2D::strokeStyleAttributeGetterCustom(const v8::PropertyCallbackInfo<v8::Value>& info)
@@ -77,10 +74,12 @@ void V8CanvasRenderingContext2D::strokeStyleAttributeGetterCustom(const v8::Prop
void V8CanvasRenderingContext2D::strokeStyleAttributeSetterCustom(v8::Local<v8::Value> value, const v8::PropertyCallbackInfo<void>& info)
{
CanvasRenderingContext2D* impl = V8CanvasRenderingContext2D::toNative(info.Holder());
- if (value->IsString())
- impl->setStrokeColor(toCoreString(value.As<v8::String>()));
- else
- impl->setStrokeStyle(toCanvasStyle(value, info.GetIsolate()));
+ if (RefPtr<CanvasStyle> canvasStyle = toCanvasStyle(value, info.GetIsolate())) {
+ impl->setStrokeStyle(canvasStyle);
+ } else {
+ TOSTRING_VOID(V8StringResource<>, colorString, value);
+ impl->setStrokeColor(colorString);
+ }
}
void V8CanvasRenderingContext2D::fillStyleAttributeGetterCustom(const v8::PropertyCallbackInfo<v8::Value>& info)
@@ -92,10 +91,12 @@ void V8CanvasRenderingContext2D::fillStyleAttributeGetterCustom(const v8::Proper
void V8CanvasRenderingContext2D::fillStyleAttributeSetterCustom(v8::Local<v8::Value> value, const v8::PropertyCallbackInfo<void>& info)
{
CanvasRenderingContext2D* impl = V8CanvasRenderingContext2D::toNative(info.Holder());
- if (value->IsString())
- impl->setFillColor(toCoreString(value.As<v8::String>()));
- else
- impl->setFillStyle(toCanvasStyle(value, info.GetIsolate()));
+ if (RefPtr<CanvasStyle> canvasStyle = toCanvasStyle(value, info.GetIsolate())) {
+ impl->setFillStyle(canvasStyle);
+ } else {
+ TOSTRING_VOID(V8StringResource<>, colorString, value);
+ impl->setFillColor(colorString);
+ }
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8CanvasRenderingContextCustom.cpp b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8CanvasRenderingContextCustom.cpp
deleted file mode 100644
index 66a73c48541..00000000000
--- a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8CanvasRenderingContextCustom.cpp
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2007-2009 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "V8CanvasRenderingContext.h"
-
-#include "V8CanvasRenderingContext2D.h"
-#include "V8WebGLRenderingContext.h"
-#include "core/html/canvas/CanvasRenderingContext.h"
-
-namespace WebCore {
-
-v8::Handle<v8::Object> wrap(CanvasRenderingContext* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
-{
- ASSERT(impl);
- if (impl->is2d())
- return wrap(toCanvasRenderingContext2D(impl), creationContext, isolate);
- if (impl->is3d())
- return wrap(toWebGLRenderingContext(impl), creationContext, isolate);
- ASSERT_NOT_REACHED();
- return v8::Handle<v8::Object>();
-}
-
-} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8ClientCustom.cpp b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8ClientCustom.cpp
new file mode 100644
index 00000000000..b7975759511
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8ClientCustom.cpp
@@ -0,0 +1,39 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "bindings/modules/v8/V8Client.h"
+
+#include "bindings/v8/ExceptionMessages.h"
+#include "bindings/v8/ExceptionState.h"
+#include "bindings/v8/SerializedScriptValue.h"
+#include "bindings/v8/V8Binding.h"
+#include "core/dom/MessagePort.h"
+#include "modules/serviceworkers/ServiceWorker.h"
+#include "wtf/ArrayBuffer.h"
+
+namespace WebCore {
+
+void V8Client::postMessageMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& info)
+{
+ ExceptionState exceptionState(ExceptionState::ExecutionContext, "postMessage", "ServiceWorker", info.Holder(), info.GetIsolate());
+ Client* client = V8Client::toNative(info.Holder());
+ MessagePortArray ports;
+ ArrayBufferArray arrayBuffers;
+ if (info.Length() > 1) {
+ const int transferablesArgIndex = 1;
+ if (!SerializedScriptValue::extractTransferables(info[transferablesArgIndex], transferablesArgIndex, ports, arrayBuffers, exceptionState, info.GetIsolate())) {
+ exceptionState.throwIfNeeded();
+ return;
+ }
+ }
+ RefPtr<SerializedScriptValue> message = SerializedScriptValue::create(info[0], &ports, &arrayBuffers, exceptionState, info.GetIsolate());
+ if (exceptionState.throwIfNeeded())
+ return;
+ ExecutionContext* context = currentExecutionContext(info.GetIsolate());
+ client->postMessage(context, message.release(), &ports, exceptionState);
+ exceptionState.throwIfNeeded();
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8CryptoCustom.cpp b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8CryptoCustom.cpp
index d183e31f9f5..d69042811c2 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8CryptoCustom.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8CryptoCustom.cpp
@@ -23,12 +23,11 @@
*/
#include "config.h"
-#include "V8Crypto.h"
+#include "bindings/modules/v8/V8Crypto.h"
#include "bindings/v8/ExceptionMessages.h"
#include "bindings/v8/ExceptionState.h"
#include "bindings/v8/V8Binding.h"
-#include "bindings/v8/V8Utilities.h"
#include "bindings/v8/custom/V8ArrayBufferViewCustom.h"
#include "core/dom/ExceptionCode.h"
#include "modules/crypto/Crypto.h"
@@ -36,9 +35,6 @@
namespace WebCore {
-// This custom binding is shared by V8WorkerCrypto. As such:
-// * Do not call V8Crypto::toNative()
-// * Must be threadsafe
void V8Crypto::getRandomValuesMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& info)
{
ExceptionState exceptionState(ExceptionState::ExecutionContext, "getRandomValues", "Crypto", info.Holder(), info.GetIsolate());
@@ -49,13 +45,14 @@ void V8Crypto::getRandomValuesMethodCustom(const v8::FunctionCallbackInfo<v8::Va
}
v8::Handle<v8::Value> buffer = info[0];
- if (!V8ArrayBufferView::hasInstance(buffer, info.GetIsolate(), worldType(info.GetIsolate()))) {
+ if (!V8ArrayBufferView::hasInstance(buffer, info.GetIsolate())) {
exceptionState.throwTypeError("First argument is not an ArrayBufferView");
} else {
ArrayBufferView* arrayBufferView = V8ArrayBufferView::toNative(v8::Handle<v8::Object>::Cast(buffer));
ASSERT(arrayBufferView);
- Crypto::getRandomValues(arrayBufferView, exceptionState);
+ Crypto* crypto = V8Crypto::toNative(info.Holder());
+ crypto->getRandomValues(arrayBufferView, exceptionState);
}
if (exceptionState.throwIfNeeded())
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8CustomEventCustom.cpp b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8CustomEventCustom.cpp
index 143f0cac326..f0ef6e4d600 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8CustomEventCustom.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8CustomEventCustom.cpp
@@ -29,23 +29,22 @@
*/
#include "config.h"
-#include "V8CustomEvent.h"
+#include "bindings/core/v8/V8CustomEvent.h"
-#include "RuntimeEnabledFeatures.h"
-#include "V8Event.h"
+#include "bindings/core/v8/V8Event.h"
#include "bindings/v8/Dictionary.h"
-#include "bindings/v8/ScriptState.h"
#include "bindings/v8/SerializedScriptValue.h"
#include "bindings/v8/V8Binding.h"
#include "bindings/v8/V8DOMWrapper.h"
-#include "bindings/v8/V8HiddenPropertyName.h"
+#include "bindings/v8/V8HiddenValue.h"
#include "core/dom/ContextFeatures.h"
+#include "platform/RuntimeEnabledFeatures.h"
namespace WebCore {
static v8::Handle<v8::Value> cacheState(v8::Handle<v8::Object> customEvent, v8::Handle<v8::Value> detail, v8::Isolate* isolate)
{
- customEvent->SetHiddenValue(V8HiddenPropertyName::detail(isolate), detail);
+ V8HiddenValue::setHiddenValue(isolate, customEvent, V8HiddenValue::detail(isolate), detail);
return detail;
}
@@ -54,7 +53,7 @@ void V8CustomEvent::detailAttributeGetterCustom(const v8::PropertyCallbackInfo<v
{
CustomEvent* event = V8CustomEvent::toNative(info.Holder());
- v8::Handle<v8::Value> result = info.Holder()->GetHiddenValue(V8HiddenPropertyName::detail(info.GetIsolate()));
+ v8::Handle<v8::Value> result = V8HiddenValue::getHiddenValue(info.GetIsolate(), info.Holder(), V8HiddenValue::detail(info.GetIsolate()));
if (!result.IsEmpty()) {
v8SetReturnValue(info, result);
@@ -64,7 +63,7 @@ void V8CustomEvent::detailAttributeGetterCustom(const v8::PropertyCallbackInfo<v
if (!event->serializedDetail()) {
// If we're in an isolated world and the event was created in the main world,
// we need to find the 'detail' property on the main world wrapper and clone it.
- v8::Local<v8::Value> mainWorldDetail = getHiddenValueFromMainWorldWrapper(info.GetIsolate(), event, V8HiddenPropertyName::detail(info.GetIsolate()));
+ v8::Local<v8::Value> mainWorldDetail = V8HiddenValue::getHiddenValueFromMainWorldWrapper(info.GetIsolate(), event, V8HiddenValue::detail(info.GetIsolate()));
if (!mainWorldDetail.IsEmpty())
event->setSerializedDetail(SerializedScriptValue::createAndSwallowExceptions(mainWorldDetail, info.GetIsolate()));
}
@@ -83,16 +82,16 @@ void V8CustomEvent::initCustomEventMethodCustom(const v8::FunctionCallbackInfo<v
CustomEvent* event = V8CustomEvent::toNative(info.Holder());
ASSERT(!event->serializedDetail());
- V8TRYCATCH_FOR_V8STRINGRESOURCE_VOID(V8StringResource<>, typeArg, info[0]);
- V8TRYCATCH_VOID(bool, canBubbleArg, info[1]->BooleanValue());
- V8TRYCATCH_VOID(bool, cancelableArg, info[2]->BooleanValue());
+ TOSTRING_VOID(V8StringResource<>, typeArg, info[0]);
+ TONATIVE_VOID(bool, canBubbleArg, info[1]->BooleanValue());
+ TONATIVE_VOID(bool, cancelableArg, info[2]->BooleanValue());
v8::Handle<v8::Value> detailsArg = info[3];
event->initEvent(typeArg, canBubbleArg, cancelableArg);
if (!detailsArg.IsEmpty()) {
- info.Holder()->SetHiddenValue(V8HiddenPropertyName::detail(info.GetIsolate()), detailsArg);
- if (isolatedWorldForIsolate(info.GetIsolate()))
+ V8HiddenValue::setHiddenValue(info.GetIsolate(), info.Holder(), V8HiddenValue::detail(info.GetIsolate()), detailsArg);
+ if (DOMWrapperWorld::current(info.GetIsolate()).isIsolatedWorld())
event->setSerializedDetail(SerializedScriptValue::createAndSwallowExceptions(detailsArg, info.GetIsolate()));
}
}
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8CustomSQLStatementErrorCallback.cpp b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8CustomSQLStatementErrorCallback.cpp
index fc597c11034..0f411122352 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8CustomSQLStatementErrorCallback.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8CustomSQLStatementErrorCallback.cpp
@@ -29,10 +29,10 @@
*/
#include "config.h"
-#include "V8SQLStatementErrorCallback.h"
-#include "V8SQLError.h"
-#include "V8SQLTransaction.h"
+#include "bindings/modules/v8/V8SQLError.h"
+#include "bindings/modules/v8/V8SQLStatementErrorCallback.h"
+#include "bindings/modules/v8/V8SQLTransaction.h"
#include "bindings/v8/ScriptController.h"
#include "core/dom/ExecutionContext.h"
#include "wtf/Assertions.h"
@@ -44,23 +44,22 @@ bool V8SQLStatementErrorCallback::handleEvent(SQLTransaction* transaction, SQLEr
if (!canInvokeCallback())
return true;
- v8::Isolate* isolate = v8::Isolate::GetCurrent();
- v8::HandleScope handleScope(isolate);
-
- v8::Handle<v8::Context> v8Context = toV8Context(executionContext(), m_world.get());
- if (v8Context.IsEmpty())
+ v8::Isolate* isolate = m_scriptState->isolate();
+ if (m_scriptState->contextIsEmpty())
return true;
- v8::Context::Scope scope(v8Context);
+ ScriptState::Scope scope(m_scriptState.get());
- v8::Handle<v8::Value> transactionHandle = toV8(transaction, v8::Handle<v8::Object>(), v8Context->GetIsolate());
- v8::Handle<v8::Value> errorHandle = toV8(error, v8::Handle<v8::Object>(), isolate);
+ v8::Handle<v8::Value> transactionHandle = toV8(transaction, m_scriptState->context()->Global(), isolate);
+ v8::Handle<v8::Value> errorHandle = toV8(error, m_scriptState->context()->Global(), isolate);
if (transactionHandle.IsEmpty() || errorHandle.IsEmpty()) {
if (!isScriptControllerTerminating())
CRASH();
return true;
}
+ ASSERT(transactionHandle->IsObject());
+
v8::Handle<v8::Value> argv[] = {
transactionHandle,
errorHandle
@@ -69,7 +68,7 @@ bool V8SQLStatementErrorCallback::handleEvent(SQLTransaction* transaction, SQLEr
v8::TryCatch exceptionCatcher;
exceptionCatcher.SetVerbose(true);
- v8::Handle<v8::Value> result = ScriptController::callFunction(executionContext(), m_callback.newLocal(isolate), isolate->GetCurrentContext()->Global(), 2, argv, isolate);
+ v8::Handle<v8::Value> result = ScriptController::callFunction(executionContext(), m_callback.newLocal(isolate), m_scriptState->context()->Global(), WTF_ARRAY_LENGTH(argv), argv, isolate);
// FIXME: This comment doesn't make much sense given what the code is actually doing.
//
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8CustomXPathNSResolver.cpp b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8CustomXPathNSResolver.cpp
index f2c4d730d24..6331ef1bf99 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8CustomXPathNSResolver.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8CustomXPathNSResolver.cpp
@@ -32,20 +32,19 @@
#include "bindings/v8/ScriptController.h"
#include "bindings/v8/V8Binding.h"
-#include "bindings/v8/V8Utilities.h"
#include "core/dom/ExecutionContext.h"
+#include "core/frame/LocalDOMWindow.h"
+#include "core/frame/FrameConsole.h"
+#include "core/frame/FrameHost.h"
+#include "core/frame/LocalFrame.h"
#include "core/inspector/ScriptCallStack.h"
-#include "core/frame/DOMWindow.h"
-#include "core/frame/Frame.h"
-#include "core/page/Page.h"
-#include "core/page/PageConsole.h"
#include "wtf/text/WTFString.h"
namespace WebCore {
-PassRefPtr<V8CustomXPathNSResolver> V8CustomXPathNSResolver::create(v8::Handle<v8::Object> resolver, v8::Isolate* isolate)
+PassRefPtrWillBeRawPtr<V8CustomXPathNSResolver> V8CustomXPathNSResolver::create(v8::Handle<v8::Object> resolver, v8::Isolate* isolate)
{
- return adoptRef(new V8CustomXPathNSResolver(resolver, isolate));
+ return adoptRefWillBeNoop(new V8CustomXPathNSResolver(resolver, isolate));
}
V8CustomXPathNSResolver::V8CustomXPathNSResolver(v8::Handle<v8::Object> resolver, v8::Isolate* isolate)
@@ -71,9 +70,9 @@ AtomicString V8CustomXPathNSResolver::lookupNamespaceURI(const String& prefix)
}
if (lookupNamespaceURIFunc.IsEmpty() && !m_resolver->IsFunction()) {
- Frame* frame = activeDOMWindow()->frame();
- if (frame && frame->page())
- frame->page()->console().addMessage(JSMessageSource, ErrorMessageLevel, "XPathNSResolver does not have a lookupNamespaceURI method.");
+ LocalFrame* frame = callingDOMWindow(m_isolate)->frame();
+ if (frame && frame->host())
+ frame->console().addMessage(JSMessageSource, ErrorMessageLevel, "XPathNSResolver does not have a lookupNamespaceURI method.");
return nullAtom;
}
@@ -85,14 +84,19 @@ AtomicString V8CustomXPathNSResolver::lookupNamespaceURI(const String& prefix)
v8::Handle<v8::Value> argv[argc] = { v8String(m_isolate, prefix) };
v8::Handle<v8::Function> function = lookupNamespaceURIFunc.IsEmpty() ? v8::Handle<v8::Function>::Cast(m_resolver) : lookupNamespaceURIFunc;
- v8::Handle<v8::Value> retval = ScriptController::callFunction(activeExecutionContext(), function, m_resolver, argc, argv, m_isolate);
+ v8::Handle<v8::Value> retval = ScriptController::callFunction(callingExecutionContext(m_isolate), function, m_resolver, argc, argv, m_isolate);
// Eat exceptions from namespace resolver and return an empty string. This will most likely cause NamespaceError.
if (tryCatch.HasCaught())
return nullAtom;
- V8TRYCATCH_FOR_V8STRINGRESOURCE_RETURN(V8StringResource<WithNullCheck>, returnString, retval, nullAtom);
+ TOSTRING_DEFAULT(V8StringResource<WithNullCheck>, returnString, retval, nullAtom);
return returnString;
}
+void V8CustomXPathNSResolver::trace(Visitor* visitor)
+{
+ XPathNSResolver::trace(visitor);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8CustomXPathNSResolver.h b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8CustomXPathNSResolver.h
index aa3e01a243d..4c6712bb9f3 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8CustomXPathNSResolver.h
+++ b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8CustomXPathNSResolver.h
@@ -42,13 +42,15 @@ namespace WebCore {
// V8CustomXPathNSResolver does not create a persistent handle to the
// given resolver object. So the lifetime of V8CustomXPathNSResolver
// must not exceed the lifetime of the passed handle.
-class V8CustomXPathNSResolver : public XPathNSResolver {
+class V8CustomXPathNSResolver FINAL : public XPathNSResolver {
public:
- static PassRefPtr<V8CustomXPathNSResolver> create(v8::Handle<v8::Object> resolver, v8::Isolate*);
+ static PassRefPtrWillBeRawPtr<V8CustomXPathNSResolver> create(v8::Handle<v8::Object> resolver, v8::Isolate*);
virtual ~V8CustomXPathNSResolver();
virtual AtomicString lookupNamespaceURI(const String& prefix) OVERRIDE;
+ virtual void trace(Visitor*) OVERRIDE;
+
private:
V8CustomXPathNSResolver(v8::Handle<v8::Object> resolver, v8::Isolate*);
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8DataViewCustom.cpp b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8DataViewCustom.cpp
index 73efbd69ad4..3d7572ca3ca 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8DataViewCustom.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8DataViewCustom.cpp
@@ -35,7 +35,7 @@ namespace WebCore {
static void initializeScriptWrappableForInterface(DataView* object)
{
if (ScriptWrappable::wrapperCanBeStoredInObject(object))
- ScriptWrappable::setTypeInfoInObject(object, &V8DataView::wrapperTypeInfo);
+ ScriptWrappable::fromObject(object)->setTypeInfo(&V8DataView::wrapperTypeInfo);
else
ASSERT_NOT_REACHED();
}
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8DataViewCustom.h b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8DataViewCustom.h
index 502c010fe46..6459cbdd6e2 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8DataViewCustom.h
+++ b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8DataViewCustom.h
@@ -59,10 +59,6 @@ public:
typedef V8TypedArray<DataView> V8DataView;
-template<>
-class WrapperTypeTraits<DataView> : public TypedArrayWrapperTraits<DataView> { };
-
-
inline v8::Handle<v8::Object> wrap(DataView* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
{
return V8TypedArray<DataView>::wrap(impl, creationContext, isolate);
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8DedicatedWorkerGlobalScopeCustom.cpp b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8DedicatedWorkerGlobalScopeCustom.cpp
index a356f03e4fe..b95c50747e7 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8DedicatedWorkerGlobalScopeCustom.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8DedicatedWorkerGlobalScopeCustom.cpp
@@ -29,13 +29,12 @@
*/
#include "config.h"
-#include "V8DedicatedWorkerGlobalScope.h"
+#include "bindings/core/v8/V8DedicatedWorkerGlobalScope.h"
#include "bindings/v8/ExceptionMessages.h"
#include "bindings/v8/ExceptionState.h"
#include "bindings/v8/SerializedScriptValue.h"
#include "bindings/v8/V8Binding.h"
-#include "bindings/v8/V8Utilities.h"
#include "bindings/v8/V8WorkerGlobalScopeEventListener.h"
#include "core/workers/DedicatedWorkerGlobalScope.h"
#include "wtf/ArrayBuffer.h"
@@ -44,23 +43,21 @@ namespace WebCore {
void V8DedicatedWorkerGlobalScope::postMessageMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& info)
{
+ ExceptionState exceptionState(ExceptionState::ExecutionContext, "postMessage", "WorkerGlobalScope", info.Holder(), info.GetIsolate());
DedicatedWorkerGlobalScope* workerGlobalScope = V8DedicatedWorkerGlobalScope::toNative(info.Holder());
MessagePortArray ports;
ArrayBufferArray arrayBuffers;
if (info.Length() > 1) {
const int transferablesArgIndex = 1;
- bool notASequence = false;
- if (!extractTransferables(info[transferablesArgIndex], ports, arrayBuffers, notASequence, info.GetIsolate())) {
- if (notASequence)
- throwTypeError(ExceptionMessages::failedToExecute("postMessage", "WorkerGlobalScope", ExceptionMessages::notAnArrayTypeArgumentOrValue(transferablesArgIndex + 1)), info.GetIsolate());
+ if (!SerializedScriptValue::extractTransferables(info[transferablesArgIndex], transferablesArgIndex, ports, arrayBuffers, exceptionState, info.GetIsolate())) {
+ exceptionState.throwIfNeeded();
return;
}
}
- bool didThrow = false;
- RefPtr<SerializedScriptValue> message = SerializedScriptValue::create(info[0], &ports, &arrayBuffers, didThrow, info.GetIsolate());
- if (didThrow)
+ RefPtr<SerializedScriptValue> message = SerializedScriptValue::create(info[0], &ports, &arrayBuffers, exceptionState, info.GetIsolate());
+ if (exceptionState.throwIfNeeded())
return;
- ExceptionState exceptionState(info.Holder(), info.GetIsolate());
+
workerGlobalScope->postMessage(message.release(), &ports, exceptionState);
exceptionState.throwIfNeeded();
}
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8DeviceMotionEventCustom.cpp b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8DeviceMotionEventCustom.cpp
index a170e1cde5f..ecf0ca7e9ee 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8DeviceMotionEventCustom.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8DeviceMotionEventCustom.cpp
@@ -24,7 +24,7 @@
*/
#include "config.h"
-#include "V8DeviceMotionEvent.h"
+#include "bindings/modules/v8/V8DeviceMotionEvent.h"
#include "bindings/v8/V8Binding.h"
#include "modules/device_orientation/DeviceMotionData.h"
@@ -34,66 +34,66 @@ namespace WebCore {
namespace {
-RefPtr<DeviceMotionData::Acceleration> readAccelerationArgument(v8::Local<v8::Value> value, v8::Isolate* isolate)
+PassRefPtrWillBeRawPtr<DeviceMotionData::Acceleration> readAccelerationArgument(v8::Local<v8::Value> value, v8::Isolate* isolate)
{
if (isUndefinedOrNull(value))
- return 0;
+ return nullptr;
// Given the test above, this will always yield an object.
v8::Local<v8::Object> object = value->ToObject();
v8::Local<v8::Value> xValue = object->Get(v8AtomicString(isolate, "x"));
if (xValue.IsEmpty())
- return 0;
+ return nullptr;
bool canProvideX = !isUndefinedOrNull(xValue);
double x = xValue->NumberValue();
v8::Local<v8::Value> yValue = object->Get(v8AtomicString(isolate, "y"));
if (yValue.IsEmpty())
- return 0;
+ return nullptr;
bool canProvideY = !isUndefinedOrNull(yValue);
double y = yValue->NumberValue();
v8::Local<v8::Value> zValue = object->Get(v8AtomicString(isolate, "z"));
if (zValue.IsEmpty())
- return 0;
+ return nullptr;
bool canProvideZ = !isUndefinedOrNull(zValue);
double z = zValue->NumberValue();
if (!canProvideX && !canProvideY && !canProvideZ)
- return 0;
+ return nullptr;
return DeviceMotionData::Acceleration::create(canProvideX, x, canProvideY, y, canProvideZ, z);
}
-RefPtr<DeviceMotionData::RotationRate> readRotationRateArgument(v8::Local<v8::Value> value, v8::Isolate* isolate)
+PassRefPtrWillBeRawPtr<DeviceMotionData::RotationRate> readRotationRateArgument(v8::Local<v8::Value> value, v8::Isolate* isolate)
{
if (isUndefinedOrNull(value))
- return 0;
+ return nullptr;
// Given the test above, this will always yield an object.
v8::Local<v8::Object> object = value->ToObject();
v8::Local<v8::Value> alphaValue = object->Get(v8AtomicString(isolate, "alpha"));
if (alphaValue.IsEmpty())
- return 0;
+ return nullptr;
bool canProvideAlpha = !isUndefinedOrNull(alphaValue);
double alpha = alphaValue->NumberValue();
v8::Local<v8::Value> betaValue = object->Get(v8AtomicString(isolate, "beta"));
if (betaValue.IsEmpty())
- return 0;
+ return nullptr;
bool canProvideBeta = !isUndefinedOrNull(betaValue);
double beta = betaValue->NumberValue();
v8::Local<v8::Value> gammaValue = object->Get(v8AtomicString(isolate, "gamma"));
if (gammaValue.IsEmpty())
- return 0;
+ return nullptr;
bool canProvideGamma = !isUndefinedOrNull(gammaValue);
double gamma = gammaValue->NumberValue();
if (!canProvideAlpha && !canProvideBeta && !canProvideGamma)
- return 0;
+ return nullptr;
return DeviceMotionData::RotationRate::create(canProvideAlpha, alpha, canProvideBeta, beta, canProvideGamma, gamma);
}
@@ -102,18 +102,18 @@ RefPtr<DeviceMotionData::RotationRate> readRotationRateArgument(v8::Local<v8::Va
void V8DeviceMotionEvent::initDeviceMotionEventMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& info)
{
- DeviceMotionEvent* imp = V8DeviceMotionEvent::toNative(info.Holder());
+ DeviceMotionEvent* impl = V8DeviceMotionEvent::toNative(info.Holder());
v8::Isolate* isolate = info.GetIsolate();
- V8TRYCATCH_FOR_V8STRINGRESOURCE_VOID(V8StringResource<>, type, info[0]);
+ TOSTRING_VOID(V8StringResource<>, type, info[0]);
bool bubbles = info[1]->BooleanValue();
bool cancelable = info[2]->BooleanValue();
- RefPtr<DeviceMotionData::Acceleration> acceleration = readAccelerationArgument(info[3], isolate);
- RefPtr<DeviceMotionData::Acceleration> accelerationIncludingGravity = readAccelerationArgument(info[4], isolate);
- RefPtr<DeviceMotionData::RotationRate> rotationRate = readRotationRateArgument(info[5], isolate);
+ RefPtrWillBeRawPtr<DeviceMotionData::Acceleration> acceleration = readAccelerationArgument(info[3], isolate);
+ RefPtrWillBeRawPtr<DeviceMotionData::Acceleration> accelerationIncludingGravity = readAccelerationArgument(info[4], isolate);
+ RefPtrWillBeRawPtr<DeviceMotionData::RotationRate> rotationRate = readRotationRateArgument(info[5], isolate);
bool intervalProvided = !isUndefinedOrNull(info[6]);
double interval = info[6]->NumberValue();
- RefPtr<DeviceMotionData> deviceMotionData = DeviceMotionData::create(acceleration, accelerationIncludingGravity, rotationRate, intervalProvided, interval);
- imp->initDeviceMotionEvent(type, bubbles, cancelable, deviceMotionData.get());
+ RefPtrWillBeRawPtr<DeviceMotionData> deviceMotionData = DeviceMotionData::create(acceleration.release(), accelerationIncludingGravity.release(), rotationRate.release(), intervalProvided, interval);
+ impl->initDeviceMotionEvent(type, bubbles, cancelable, deviceMotionData.get());
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8DeviceOrientationEventCustom.cpp b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8DeviceOrientationEventCustom.cpp
index ef2a0a92e48..c9d68ec2057 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8DeviceOrientationEventCustom.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8DeviceOrientationEventCustom.cpp
@@ -24,7 +24,7 @@
*/
#include "config.h"
-#include "V8DeviceOrientationEvent.h"
+#include "bindings/modules/v8/V8DeviceOrientationEvent.h"
#include "bindings/v8/V8Binding.h"
#include "modules/device_orientation/DeviceOrientationData.h"
@@ -34,8 +34,8 @@ namespace WebCore {
void V8DeviceOrientationEvent::initDeviceOrientationEventMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& info)
{
- DeviceOrientationEvent* imp = V8DeviceOrientationEvent::toNative(info.Holder());
- V8TRYCATCH_FOR_V8STRINGRESOURCE_VOID(V8StringResource<>, type, info[0]);
+ DeviceOrientationEvent* impl = V8DeviceOrientationEvent::toNative(info.Holder());
+ TOSTRING_VOID(V8StringResource<>, type, info[0]);
bool bubbles = info[1]->BooleanValue();
bool cancelable = info[2]->BooleanValue();
// If alpha, beta, gamma or absolute are null or undefined, mark them as not provided.
@@ -48,8 +48,8 @@ void V8DeviceOrientationEvent::initDeviceOrientationEventMethodCustom(const v8::
double gamma = info[5]->NumberValue();
bool absoluteProvided = !isUndefinedOrNull(info[6]);
bool absolute = info[6]->BooleanValue();
- RefPtr<DeviceOrientationData> orientation = DeviceOrientationData::create(alphaProvided, alpha, betaProvided, beta, gammaProvided, gamma, absoluteProvided, absolute);
- imp->initDeviceOrientationEvent(type, bubbles, cancelable, orientation.get());
+ RefPtrWillBeRawPtr<DeviceOrientationData> orientation = DeviceOrientationData::create(alphaProvided, alpha, betaProvided, beta, gammaProvided, gamma, absoluteProvided, absolute);
+ impl->initDeviceOrientationEvent(type, bubbles, cancelable, orientation.get());
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8DocumentCustom.cpp b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8DocumentCustom.cpp
index 94ed248cb90..930ba77f07d 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8DocumentCustom.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8DocumentCustom.cpp
@@ -29,16 +29,16 @@
*/
#include "config.h"
-#include "V8Document.h"
+#include "bindings/core/v8/V8Document.h"
-#include "V8CanvasRenderingContext2D.h"
-#include "V8DOMImplementation.h"
-#include "V8Node.h"
-#include "V8Touch.h"
-#include "V8TouchList.h"
-#include "V8WebGLRenderingContext.h"
-#include "V8XPathNSResolver.h"
-#include "V8XPathResult.h"
+#include "bindings/core/v8/V8CanvasRenderingContext2D.h"
+#include "bindings/core/v8/V8DOMImplementation.h"
+#include "bindings/core/v8/V8Node.h"
+#include "bindings/core/v8/V8Touch.h"
+#include "bindings/core/v8/V8TouchList.h"
+#include "bindings/core/v8/V8WebGLRenderingContext.h"
+#include "bindings/core/v8/V8XPathNSResolver.h"
+#include "bindings/core/v8/V8XPathResult.h"
#include "bindings/v8/ExceptionMessages.h"
#include "bindings/v8/ExceptionState.h"
#include "bindings/v8/ScriptController.h"
@@ -49,8 +49,8 @@
#include "core/dom/ExceptionCode.h"
#include "core/dom/Node.h"
#include "core/dom/TouchList.h"
+#include "core/frame/LocalFrame.h"
#include "core/html/canvas/CanvasRenderingContext.h"
-#include "core/frame/Frame.h"
#include "core/xml/DocumentXPathEvaluator.h"
#include "core/xml/XPathNSResolver.h"
#include "core/xml/XPathResult.h"
@@ -60,27 +60,23 @@ namespace WebCore {
void V8Document::evaluateMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& info)
{
- RefPtr<Document> document = V8Document::toNative(info.Holder());
+ RefPtrWillBeRawPtr<Document> document = V8Document::toNative(info.Holder());
+ ASSERT(document);
ExceptionState exceptionState(ExceptionState::ExecutionContext, "evaluate", "Document", info.Holder(), info.GetIsolate());
- V8TRYCATCH_FOR_V8STRINGRESOURCE_VOID(V8StringResource<>, expression, info[0]);
- RefPtr<Node> contextNode;
- if (V8Node::hasInstance(info[1], info.GetIsolate(), worldType(info.GetIsolate())))
- contextNode = V8Node::toNative(v8::Handle<v8::Object>::Cast(info[1]));
+ TOSTRING_VOID(V8StringResource<>, expression, info[0]);
+ RefPtrWillBeRawPtr<Node> contextNode = V8Node::toNativeWithTypeCheck(info.GetIsolate(), info[1]);
const int resolverArgumentIndex = 2;
- RefPtr<XPathNSResolver> resolver = toXPathNSResolver(info[resolverArgumentIndex], info.GetIsolate());
+ RefPtrWillBeRawPtr<XPathNSResolver> resolver = toXPathNSResolver(info[resolverArgumentIndex], info.GetIsolate());
if (!resolver && !isUndefinedOrNull(info[resolverArgumentIndex])) {
- exceptionState.throwTypeError(ExceptionMessages::incorrectArgumentType(resolverArgumentIndex + 1, "is not a resolver function."));
+ exceptionState.throwTypeError(ExceptionMessages::argumentNullOrIncorrectType(resolverArgumentIndex + 1, "XPathNSResolver"));
exceptionState.throwIfNeeded();
return;
}
int type = toInt32(info[3]);
- RefPtr<XPathResult> inResult;
- if (V8XPathResult::hasInstance(info[4], info.GetIsolate(), worldType(info.GetIsolate())))
- inResult = V8XPathResult::toNative(v8::Handle<v8::Object>::Cast(info[4]));
-
- V8TRYCATCH_VOID(RefPtr<XPathResult>, result, DocumentXPathEvaluator::evaluate(document.get(), expression, contextNode.get(), resolver.release(), type, inResult.get(), exceptionState));
+ RefPtrWillBeRawPtr<XPathResult> inResult = V8XPathResult::toNativeWithTypeCheck(info.GetIsolate(), info[4]);
+ TONATIVE_VOID(RefPtrWillBeRawPtr<XPathResult>, result, DocumentXPathEvaluator::evaluate(*document, expression, contextNode.get(), resolver.release(), type, inResult.get(), exceptionState));
if (exceptionState.throwIfNeeded())
return;
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8ElementCustom.cpp b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8ElementCustom.cpp
new file mode 100644
index 00000000000..0083ac9b055
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8ElementCustom.cpp
@@ -0,0 +1,236 @@
+/*
+ * Copyright (C) 2014 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 "bindings/core/v8/V8Element.h"
+
+#include "bindings/core/v8/V8AnimationEffect.h"
+#include "bindings/core/v8/V8AnimationPlayer.h"
+#include "bindings/v8/Dictionary.h"
+#include "bindings/v8/ExceptionState.h"
+#include "bindings/v8/V8Binding.h"
+#include "bindings/v8/V8BindingMacros.h"
+#include "core/animation/ElementAnimation.h"
+#include "core/dom/Element.h"
+#include "core/frame/UseCounter.h"
+#include "platform/RuntimeEnabledFeatures.h"
+#include "wtf/GetPtr.h"
+
+namespace WebCore {
+
+void V8Element::scrollLeftAttributeSetterCustom(v8::Local<v8::Value> value, const v8::PropertyCallbackInfo<void>& info)
+{
+ ExceptionState exceptionState(ExceptionState::SetterContext, "scrollLeft", "Element", info.Holder(), info.GetIsolate());
+ Element* impl = V8Element::toNative(info.Holder());
+
+ if (RuntimeEnabledFeatures::cssomSmoothScrollEnabled() && value->IsObject()) {
+ TONATIVE_VOID(Dictionary, scrollOptionsHorizontal, Dictionary(value, info.GetIsolate()));
+ impl->setScrollLeft(scrollOptionsHorizontal, exceptionState);
+ exceptionState.throwIfNeeded();
+ return;
+ }
+
+ TONATIVE_VOID_EXCEPTIONSTATE(float, position, toInt32(value, exceptionState), exceptionState);
+ impl->setScrollLeft(position);
+}
+
+void V8Element::scrollTopAttributeSetterCustom(v8::Local<v8::Value> value, const v8::PropertyCallbackInfo<void>& info)
+{
+ ExceptionState exceptionState(ExceptionState::SetterContext, "scrollTop", "Element", info.Holder(), info.GetIsolate());
+ Element* impl = V8Element::toNative(info.Holder());
+
+ if (RuntimeEnabledFeatures::cssomSmoothScrollEnabled() && value->IsObject()) {
+ TONATIVE_VOID(Dictionary, scrollOptionsVertical, Dictionary(value, info.GetIsolate()));
+ impl->setScrollTop(scrollOptionsVertical, exceptionState);
+ exceptionState.throwIfNeeded();
+ return;
+ }
+
+ TONATIVE_VOID_EXCEPTIONSTATE(float, position, toInt32(value, exceptionState), exceptionState);
+ impl->setScrollTop(position);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Overload resolution for animate()
+// FIXME: needs support for union types http://crbug.com/240176
+////////////////////////////////////////////////////////////////////////////////
+
+// AnimationPlayer animate(AnimationEffect? effect);
+void animate1Method(const v8::FunctionCallbackInfo<v8::Value>& info)
+{
+ Element* impl = V8Element::toNative(info.Holder());
+ TONATIVE_VOID(AnimationEffect*, effect, V8AnimationEffect::toNativeWithTypeCheck(info.GetIsolate(), info[0]));
+ v8SetReturnValueFast(info, WTF::getPtr(ElementAnimation::animate(*impl, effect)), impl);
+}
+
+// [RaisesException] AnimationPlayer animate(sequence<Dictionary> effect);
+void animate2Method(const v8::FunctionCallbackInfo<v8::Value>& info)
+{
+ ExceptionState exceptionState(ExceptionState::ExecutionContext, "animate", "Element", info.Holder(), info.GetIsolate());
+ Element* impl = V8Element::toNative(info.Holder());
+ TONATIVE_VOID(Vector<Dictionary>, keyframes, toNativeArray<Dictionary>(info[0], 1, info.GetIsolate()));
+ RefPtr<AnimationPlayer> result = ElementAnimation::animate(*impl, keyframes, exceptionState);
+ if (exceptionState.throwIfNeeded())
+ return;
+ v8SetReturnValueFast(info, WTF::getPtr(result.release()), impl);
+}
+
+// AnimationPlayer animate(AnimationEffect? effect, double timing);
+void animate3Method(const v8::FunctionCallbackInfo<v8::Value>& info)
+{
+ Element* impl = V8Element::toNative(info.Holder());
+ TONATIVE_VOID(AnimationEffect*, effect, V8AnimationEffect::toNativeWithTypeCheck(info.GetIsolate(), info[0]));
+ TONATIVE_VOID(double, duration, static_cast<double>(info[1]->NumberValue()));
+ v8SetReturnValueFast(info, WTF::getPtr(ElementAnimation::animate(*impl, effect, duration)), impl);
+}
+
+// AnimationPlayer animate(AnimationEffect? effect, Dictionary timing);
+void animate4Method(const v8::FunctionCallbackInfo<v8::Value>& info)
+{
+ Element* impl = V8Element::toNative(info.Holder());
+ TONATIVE_VOID(AnimationEffect*, effect, V8AnimationEffect::toNativeWithTypeCheck(info.GetIsolate(), info[0]));
+ TONATIVE_VOID(Dictionary, timingInput, Dictionary(info[1], info.GetIsolate()));
+ if (!timingInput.isUndefinedOrNull() && !timingInput.isObject()) {
+ throwTypeError(ExceptionMessages::failedToExecute("animate", "Element", "parameter 2 ('timingInput') is not an object."), info.GetIsolate());
+ return;
+ }
+ v8SetReturnValueFast(info, WTF::getPtr(ElementAnimation::animate(*impl, effect, timingInput)), impl);
+}
+
+// [RaisesException] AnimationPlayer animate(sequence<Dictionary> effect, double timing);
+void animate5Method(const v8::FunctionCallbackInfo<v8::Value>& info)
+{
+ ExceptionState exceptionState(ExceptionState::ExecutionContext, "animate", "Element", info.Holder(), info.GetIsolate());
+ Element* impl = V8Element::toNative(info.Holder());
+ TONATIVE_VOID(Vector<Dictionary>, keyframes, toNativeArray<Dictionary>(info[0], 1, info.GetIsolate()));
+ TONATIVE_VOID(double, duration, static_cast<double>(info[1]->NumberValue()));
+ RefPtr<AnimationPlayer> result = ElementAnimation::animate(*impl, keyframes, duration, exceptionState);
+ if (exceptionState.throwIfNeeded())
+ return;
+ v8SetReturnValueFast(info, WTF::getPtr(result.release()), impl);
+}
+
+// [RaisesException] AnimationPlayer animate(sequence<Dictionary> effect, Dictionary timing);
+void animate6Method(const v8::FunctionCallbackInfo<v8::Value>& info)
+{
+ ExceptionState exceptionState(ExceptionState::ExecutionContext, "animate", "Element", info.Holder(), info.GetIsolate());
+ Element* impl = V8Element::toNative(info.Holder());
+ TONATIVE_VOID(Vector<Dictionary>, keyframes, toNativeArray<Dictionary>(info[0], 1, info.GetIsolate()));
+ TONATIVE_VOID(Dictionary, timingInput, Dictionary(info[1], info.GetIsolate()));
+ if (!timingInput.isUndefinedOrNull() && !timingInput.isObject()) {
+ exceptionState.throwTypeError("parameter 2 ('timingInput') is not an object.");
+ exceptionState.throwIfNeeded();
+ return;
+ }
+ RefPtr<AnimationPlayer> result = ElementAnimation::animate(*impl, keyframes, timingInput, exceptionState);
+ if (exceptionState.throwIfNeeded())
+ return;
+ v8SetReturnValueFast(info, WTF::getPtr(result.release()), impl);
+}
+
+void V8Element::animateMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& info)
+{
+ v8::Isolate* isolate = info.GetIsolate();
+ ExceptionState exceptionState(ExceptionState::ExecutionContext, "animate", "Element", info.Holder(), isolate);
+ // AnimationPlayer animate(
+ // (AnimationEffect or sequence<Dictionary>)? effect,
+ // optional (double or Dictionary) timing);
+ switch (info.Length()) {
+ case 1:
+ // null resolved as to AnimationEffect, as if the member were nullable:
+ // (AnimationEffect? or sequence<Dictionary>)
+ // instead of the *union* being nullable:
+ // (AnimationEffect or sequence<Dictionary>)?
+ // AnimationPlayer animate(AnimationEffect? effect);
+ if (info[0]->IsNull()) {
+ animate1Method(info);
+ return;
+ }
+ // AnimationPlayer animate(AnimationEffect effect);
+ if (V8AnimationEffect::hasInstance(info[0], isolate)) {
+ animate1Method(info);
+ return;
+ }
+ // [MeasureAs=ElementAnimateKeyframeListEffectNoTiming]
+ // AnimationPlayer animate(sequence<Dictionary> effect);
+ if (info[0]->IsArray()) {
+ UseCounter::count(callingExecutionContext(isolate), UseCounter::ElementAnimateKeyframeListEffectNoTiming);
+ animate2Method(info);
+ return;
+ }
+ break;
+ case 2:
+ // As above, null resolved to AnimationEffect
+ // AnimationPlayer animate(AnimationEffect? effect, Dictionary timing);
+ if (info[0]->IsNull() && info[1]->IsObject()) {
+ animate4Method(info);
+ return;
+ }
+ // AnimationPlayer animate(AnimationEffect? effect, double timing);
+ if (info[0]->IsNull()) {
+ animate3Method(info);
+ return;
+ }
+ // AnimationPlayer animate(AnimationEffect effect, Dictionary timing);
+ if (V8AnimationEffect::hasInstance(info[0], isolate)
+ && info[1]->IsObject()) {
+ animate4Method(info);
+ return;
+ }
+ // AnimationPlayer animate(AnimationEffect effect, double timing);
+ if (V8AnimationEffect::hasInstance(info[0], isolate)) {
+ animate3Method(info);
+ return;
+ }
+ // [MeasureAs=ElementAnimateKeyframeListEffectObjectTiming]
+ // AnimationPlayer animate(sequence<Dictionary> effect, Dictionary timing);
+ if (info[0]->IsArray() && info[1]->IsObject()) {
+ UseCounter::count(callingExecutionContext(isolate), UseCounter::ElementAnimateKeyframeListEffectObjectTiming);
+ animate6Method(info);
+ return;
+ }
+ // [MeasureAs=ElementAnimateKeyframeListEffectDoubleTiming]
+ // AnimationPlayer animate(sequence<Dictionary> effect, double timing);
+ if (info[0]->IsArray()) {
+ UseCounter::count(callingExecutionContext(isolate), UseCounter::ElementAnimateKeyframeListEffectDoubleTiming);
+ animate5Method(info);
+ return;
+ }
+ break;
+ default:
+ throwArityTypeError(exceptionState, "[1]", info.Length());
+ return;
+ break;
+ }
+ exceptionState.throwTypeError("No function was found that matched the signature provided.");
+ exceptionState.throwIfNeeded();
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8EntryCustom.cpp b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8EntryCustom.cpp
index 98fc46d1cbf..e74cf314240 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8EntryCustom.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8EntryCustom.cpp
@@ -29,11 +29,11 @@
*/
#include "config.h"
-#include "V8Entry.h"
+#include "bindings/modules/v8/V8Entry.h"
-#include "V8Attr.h"
-#include "V8DirectoryEntry.h"
-#include "V8FileEntry.h"
+#include "bindings/core/v8/V8Attr.h"
+#include "bindings/modules/v8/V8DirectoryEntry.h"
+#include "bindings/modules/v8/V8FileEntry.h"
#include "bindings/v8/V8Binding.h"
#include "wtf/RefPtr.h"
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8EntrySyncCustom.cpp b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8EntrySyncCustom.cpp
index 2ebd101e94f..b079b7699ad 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8EntrySyncCustom.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8EntrySyncCustom.cpp
@@ -29,11 +29,11 @@
*/
#include "config.h"
-#include "V8EntrySync.h"
+#include "bindings/modules/v8/V8EntrySync.h"
-#include "V8Attr.h"
-#include "V8DirectoryEntrySync.h"
-#include "V8FileEntrySync.h"
+#include "bindings/core/v8/V8Attr.h"
+#include "bindings/modules/v8/V8DirectoryEntrySync.h"
+#include "bindings/modules/v8/V8FileEntrySync.h"
#include "bindings/v8/V8Binding.h"
#include "wtf/RefPtr.h"
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8ErrorEventCustom.cpp b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8ErrorEventCustom.cpp
index 01ed71acdac..8021350dfbd 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8ErrorEventCustom.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8ErrorEventCustom.cpp
@@ -29,25 +29,23 @@
*/
#include "config.h"
-#include "V8ErrorEvent.h"
+#include "bindings/core/v8/V8ErrorEvent.h"
-#include "RuntimeEnabledFeatures.h"
-#include "V8Event.h"
+#include "bindings/core/v8/V8Event.h"
#include "bindings/v8/DOMWrapperWorld.h"
#include "bindings/v8/Dictionary.h"
-#include "bindings/v8/ScriptState.h"
#include "bindings/v8/SerializedScriptValue.h"
#include "bindings/v8/V8Binding.h"
#include "bindings/v8/V8DOMWrapper.h"
-#include "bindings/v8/V8HiddenPropertyName.h"
+#include "bindings/v8/V8HiddenValue.h"
#include "core/dom/ContextFeatures.h"
+#include "platform/RuntimeEnabledFeatures.h"
namespace WebCore {
void V8ErrorEvent::errorAttributeGetterCustom(const v8::PropertyCallbackInfo<v8::Value>& info)
{
- v8::Handle<v8::Value> error = info.Holder()->GetHiddenValue(V8HiddenPropertyName::error(info.GetIsolate()));
-
+ v8::Handle<v8::Value> error = V8HiddenValue::getHiddenValue(info.GetIsolate(), info.Holder(), V8HiddenValue::error(info.GetIsolate()));
if (!error.IsEmpty()) {
v8SetReturnValue(info, error);
return;
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8EventCustom.cpp b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8EventCustom.cpp
index d313239f485..86217c40a83 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8EventCustom.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8EventCustom.cpp
@@ -29,16 +29,15 @@
*/
#include "config.h"
-#include "V8Event.h"
+#include "bindings/core/v8/V8Event.h"
-#include "EventHeaders.h"
-#include "EventInterfaces.h"
-#include "V8Clipboard.h"
+#include "EventModulesHeaders.h"
+#include "EventModulesInterfaces.h"
+#include "bindings/core/v8/V8DataTransfer.h"
#include "bindings/v8/V8Binding.h"
-#include "core/dom/Clipboard.h"
+#include "core/clipboard/Clipboard.h"
#include "core/events/ClipboardEvent.h"
#include "core/events/Event.h"
-#include "core/events/ThreadLocalEventNames.h"
namespace WebCore {
@@ -67,6 +66,7 @@ v8::Handle<v8::Object> wrap(Event* event, v8::Handle<v8::Object> creationContext
return V8Event::createWrapper(event, creationContext, isolate);
EVENT_INTERFACES_FOR_EACH(TRY_TO_WRAP_WITH_INTERFACE)
+ EVENT_MODULES_INTERFACES_FOR_EACH(TRY_TO_WRAP_WITH_INTERFACE)
return V8Event::createWrapper(event, creationContext, isolate);
}
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8EventTargetCustom.cpp b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8EventTargetCustom.cpp
index 8bb41db3bcb..89e7b660449 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8EventTargetCustom.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8EventTargetCustom.cpp
@@ -29,10 +29,12 @@
*/
#include "config.h"
-#include "V8EventTarget.h"
+#include "bindings/core/v8/V8EventTarget.h"
-#include "EventTargetHeaders.h"
-#include "EventTargetInterfaces.h"
+#include "core/EventTargetHeaders.h"
+#include "core/EventTargetInterfaces.h"
+#include "modules/EventTargetModulesHeaders.h"
+#include "modules/EventTargetModulesInterfaces.h"
namespace WebCore {
@@ -47,6 +49,7 @@ v8::Handle<v8::Value> toV8(EventTarget* impl, v8::Handle<v8::Object> creationCon
AtomicString desiredInterface = impl->interfaceName();
EVENT_TARGET_INTERFACES_FOR_EACH(TRY_TO_WRAP_WITH_INTERFACE)
+ EVENT_TARGET_MODULES_INTERFACES_FOR_EACH(TRY_TO_WRAP_WITH_INTERFACE)
ASSERT_NOT_REACHED();
return v8Undefined();
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8FileCustom.cpp b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8FileCustom.cpp
index ecbb7815d46..d01acf369cc 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8FileCustom.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8FileCustom.cpp
@@ -29,12 +29,11 @@
*/
#include "config.h"
-#include "V8File.h"
+#include "bindings/core/v8/V8File.h"
-#include "RuntimeEnabledFeatures.h"
#include "bindings/v8/ExceptionState.h"
#include "bindings/v8/custom/V8BlobCustomHelpers.h"
-#include "core/fileapi/BlobBuilder.h"
+#include "platform/RuntimeEnabledFeatures.h"
namespace WebCore {
@@ -66,7 +65,7 @@ void V8File::constructorCustom(const v8::FunctionCallbackInfo<v8::Value>& info)
}
}
- V8TRYCATCH_FOR_V8STRINGRESOURCE_VOID(V8StringResource<>, fileName, info[1]);
+ TOSTRING_VOID(V8StringResource<>, fileName, info[1]);
V8BlobCustomHelpers::ParsedProperties properties(true);
if (info.Length() > 2) {
@@ -84,12 +83,14 @@ void V8File::constructorCustom(const v8::FunctionCallbackInfo<v8::Value>& info)
properties.setDefaultLastModified();
}
- BlobBuilder blobBuilder;
+ OwnPtr<BlobData> blobData = BlobData::create();
+ blobData->setContentType(properties.contentType());
v8::Local<v8::Object> blobParts = v8::Local<v8::Object>::Cast(info[0]);
- if (!V8BlobCustomHelpers::processBlobParts(blobParts, length, properties.endings(), blobBuilder, info.GetIsolate()))
+ if (!V8BlobCustomHelpers::processBlobParts(blobParts, length, properties.normalizeLineEndingsToNative(), *blobData, info.GetIsolate()))
return;
- RefPtr<File> file = blobBuilder.createFile(properties.contentType(), fileName, properties.lastModified());
+ long long fileSize = blobData->length();
+ RefPtrWillBeRawPtr<File> file = File::create(fileName, properties.lastModified(), BlobDataHandle::create(blobData.release(), fileSize));
v8SetReturnValue(info, file.release());
}
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8FileReaderCustom.cpp b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8FileReaderCustom.cpp
index c6ee39e6f4b..333040712e5 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8FileReaderCustom.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8FileReaderCustom.cpp
@@ -29,7 +29,7 @@
*/
#include "config.h"
-#include "V8FileReader.h"
+#include "bindings/core/v8/V8FileReader.h"
#include "bindings/v8/V8Binding.h"
#include "bindings/v8/custom/V8ArrayBufferCustom.h"
@@ -40,12 +40,12 @@ namespace WebCore {
void V8FileReader::resultAttributeGetterCustom(const v8::PropertyCallbackInfo<v8::Value>& info)
{
v8::Handle<v8::Object> holder = info.Holder();
- FileReader* imp = V8FileReader::toNative(holder);
- if (imp->readType() == FileReaderLoader::ReadAsArrayBuffer) {
- v8SetReturnValueFast(info, imp->arrayBufferResult(), imp);
+ FileReader* impl = V8FileReader::toNative(holder);
+ if (impl->readType() == FileReaderLoader::ReadAsArrayBuffer) {
+ v8SetReturnValueFast(info, impl->arrayBufferResult(), impl);
return;
}
- v8SetReturnValueStringOrNull(info, imp->stringResult(), info.GetIsolate());
+ v8SetReturnValueStringOrNull(info, impl->stringResult(), info.GetIsolate());
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8Float32ArrayCustom.h b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8Float32ArrayCustom.h
index 17ef9710e0a..3caa7d1da2a 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8Float32ArrayCustom.h
+++ b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8Float32ArrayCustom.h
@@ -59,10 +59,6 @@ public:
typedef V8TypedArray<Float32Array> V8Float32Array;
-template<>
-class WrapperTypeTraits<Float32Array> : public TypedArrayWrapperTraits<Float32Array> { };
-
-
inline v8::Handle<v8::Object> wrap(Float32Array* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
{
return V8TypedArray<Float32Array>::wrap(impl, creationContext, isolate);
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8Float64ArrayCustom.h b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8Float64ArrayCustom.h
index 30ec270d288..0e793b6525f 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8Float64ArrayCustom.h
+++ b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8Float64ArrayCustom.h
@@ -59,10 +59,6 @@ public:
typedef V8TypedArray<Float64Array> V8Float64Array;
-template<>
-class WrapperTypeTraits<Float64Array> : public TypedArrayWrapperTraits<Float64Array> { };
-
-
inline v8::Handle<v8::Object> wrap(Float64Array* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
{
return V8TypedArray<Float64Array>::wrap(impl, creationContext, isolate);
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8FormDataCustom.cpp b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8FormDataCustom.cpp
deleted file mode 100644
index 890bf034789..00000000000
--- a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8FormDataCustom.cpp
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * 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 "V8FormData.h"
-
-#include "V8Blob.h"
-#include "V8HTMLFormElement.h"
-#include "bindings/v8/V8Binding.h"
-#include "bindings/v8/V8Utilities.h"
-#include "core/html/DOMFormData.h"
-
-namespace WebCore {
-
-void V8FormData::appendMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& info)
-{
- if (info.Length() < 2) {
- throwError(v8SyntaxError, "Not enough arguments", info.GetIsolate());
- return;
- }
-
- DOMFormData* domFormData = V8FormData::toNative(info.Holder());
- V8TRYCATCH_FOR_V8STRINGRESOURCE_VOID(V8StringResource<WithNullCheck>, name, info[0]);
-
- v8::Handle<v8::Value> arg = info[1];
- if (V8Blob::hasInstance(arg, info.GetIsolate(), worldType(info.GetIsolate()))) {
- v8::Handle<v8::Object> object = v8::Handle<v8::Object>::Cast(arg);
- Blob* blob = V8Blob::toNative(object);
- ASSERT(blob);
-
- String filename;
- if (info.Length() >= 3) {
- V8TRYCATCH_FOR_V8STRINGRESOURCE_VOID(V8StringResource<WithUndefinedOrNullCheck>, filenameResource, info[2]);
- filename = filenameResource;
- }
-
- domFormData->append(name, blob, filename);
- } else {
- V8TRYCATCH_FOR_V8STRINGRESOURCE_VOID(V8StringResource<WithNullCheck>, argString, arg);
- domFormData->append(name, argString);
- }
-}
-
-} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8GeolocationCustom.cpp b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8GeolocationCustom.cpp
index 3ce2878edde..e09d99c34bd 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8GeolocationCustom.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8GeolocationCustom.cpp
@@ -24,31 +24,29 @@
*/
#include "config.h"
-#include "V8Geolocation.h"
+#include "bindings/modules/v8/V8Geolocation.h"
-#include "V8PositionCallback.h"
-#include "V8PositionErrorCallback.h"
+#include "bindings/modules/v8/V8PositionCallback.h"
+#include "bindings/modules/v8/V8PositionErrorCallback.h"
#include "bindings/v8/V8Binding.h"
#include "bindings/v8/V8Callback.h"
-#include "bindings/v8/V8Utilities.h"
#include "modules/geolocation/Geolocation.h"
-using namespace std;
using namespace WTF;
namespace WebCore {
-static PassRefPtr<PositionOptions> createPositionOptions(v8::Local<v8::Value> value, v8::Isolate* isolate, bool& succeeded)
+static PositionOptions* createPositionOptions(v8::Local<v8::Value> value, v8::Isolate* isolate, bool& succeeded, ExceptionState& exceptionState)
{
succeeded = true;
// Create default options.
- RefPtr<PositionOptions> options = PositionOptions::create();
+ PositionOptions* options = PositionOptions::create();
// Argument is optional (hence undefined is allowed), and null is allowed.
if (isUndefinedOrNull(value)) {
// Use default options.
- return options.release();
+ return options;
}
// Given the above test, this will always yield an object.
@@ -61,13 +59,13 @@ static PassRefPtr<PositionOptions> createPositionOptions(v8::Local<v8::Value> va
v8::Local<v8::Value> enableHighAccuracyValue = object->Get(v8AtomicString(isolate, "enableHighAccuracy"));
if (enableHighAccuracyValue.IsEmpty()) {
succeeded = false;
- return 0;
+ return nullptr;
}
if (!enableHighAccuracyValue->IsUndefined()) {
v8::Local<v8::Boolean> enableHighAccuracyBoolean = enableHighAccuracyValue->ToBoolean();
if (enableHighAccuracyBoolean.IsEmpty()) {
succeeded = false;
- return 0;
+ return nullptr;
}
options->setEnableHighAccuracy(enableHighAccuracyBoolean->Value());
}
@@ -75,100 +73,88 @@ static PassRefPtr<PositionOptions> createPositionOptions(v8::Local<v8::Value> va
v8::Local<v8::Value> timeoutValue = object->Get(v8AtomicString(isolate, "timeout"));
if (timeoutValue.IsEmpty()) {
succeeded = false;
- return 0;
+ return nullptr;
}
if (!timeoutValue->IsUndefined()) {
v8::Local<v8::Number> timeoutNumber = timeoutValue->ToNumber();
if (timeoutNumber.IsEmpty()) {
succeeded = false;
- return 0;
- }
- double timeoutDouble = timeoutNumber->Value();
- // If the value is positive infinity, there's nothing to do.
- if (!(std::isinf(timeoutDouble) && timeoutDouble > 0)) {
- v8::Local<v8::Int32> timeoutInt32 = timeoutValue->ToInt32();
- if (timeoutInt32.IsEmpty()) {
- succeeded = false;
- return 0;
- }
- // Wrap to int32 and force non-negative to match behavior of window.setTimeout.
- options->setTimeout(max(0, timeoutInt32->Value()));
+ return nullptr;
}
+ if (timeoutNumber->Value() <= 0)
+ options->setTimeout(0);
+ else
+ options->setTimeout(toUInt32(timeoutValue, Clamp, exceptionState));
}
v8::Local<v8::Value> maximumAgeValue = object->Get(v8AtomicString(isolate, "maximumAge"));
if (maximumAgeValue.IsEmpty()) {
succeeded = false;
- return 0;
+ return nullptr;
}
if (!maximumAgeValue->IsUndefined()) {
v8::Local<v8::Number> maximumAgeNumber = maximumAgeValue->ToNumber();
if (maximumAgeNumber.IsEmpty()) {
succeeded = false;
- return 0;
- }
- double maximumAgeDouble = maximumAgeNumber->Value();
- if (std::isinf(maximumAgeDouble) && maximumAgeDouble > 0) {
- // If the value is positive infinity, clear maximumAge.
- options->clearMaximumAge();
- } else {
- v8::Local<v8::Int32> maximumAgeInt32 = maximumAgeValue->ToInt32();
- if (maximumAgeInt32.IsEmpty()) {
- succeeded = false;
- return 0;
- }
- // Wrap to int32 and force non-negative to match behavior of window.setTimeout.
- options->setMaximumAge(max(0, maximumAgeInt32->Value()));
+ return nullptr;
}
+ if (maximumAgeNumber->Value() <= 0)
+ options->setMaximumAge(0);
+ else
+ options->setMaximumAge(toUInt32(maximumAgeValue, Clamp, exceptionState));
}
- return options.release();
+ return options;
}
void V8Geolocation::getCurrentPositionMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& info)
{
bool succeeded = false;
- OwnPtr<PositionCallback> positionCallback = createFunctionOnlyCallback<V8PositionCallback>(info[0], succeeded, info.GetIsolate());
+ ExceptionState exceptionState(ExceptionState::ExecutionContext, "getCurrentPosition", "Geolocation", info.Holder(), info.GetIsolate());
+
+ OwnPtr<PositionCallback> positionCallback = createFunctionOnlyCallback<V8PositionCallback>(info[0], 1, succeeded, info.GetIsolate(), exceptionState);
if (!succeeded)
return;
ASSERT(positionCallback);
// Argument is optional (hence undefined is allowed), and null is allowed.
- OwnPtr<PositionErrorCallback> positionErrorCallback = createFunctionOnlyCallback<V8PositionErrorCallback>(info[1], succeeded, info.GetIsolate(), CallbackAllowUndefined | CallbackAllowNull);
+ OwnPtr<PositionErrorCallback> positionErrorCallback = createFunctionOnlyCallback<V8PositionErrorCallback>(info[1], 2, succeeded, info.GetIsolate(), exceptionState, CallbackAllowUndefined | CallbackAllowNull);
if (!succeeded)
return;
- RefPtr<PositionOptions> positionOptions = createPositionOptions(info[2], info.GetIsolate(), succeeded);
+ PositionOptions* positionOptions = createPositionOptions(info[2], info.GetIsolate(), succeeded, exceptionState);
if (!succeeded)
return;
ASSERT(positionOptions);
Geolocation* geolocation = V8Geolocation::toNative(info.Holder());
- geolocation->getCurrentPosition(positionCallback.release(), positionErrorCallback.release(), positionOptions.release());
+ geolocation->getCurrentPosition(positionCallback.release(), positionErrorCallback.release(), positionOptions);
}
void V8Geolocation::watchPositionMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& info)
{
bool succeeded = false;
- OwnPtr<PositionCallback> positionCallback = createFunctionOnlyCallback<V8PositionCallback>(info[0], succeeded, info.GetIsolate());
+ ExceptionState exceptionState(ExceptionState::ExecutionContext, "watchCurrentPosition", "Geolocation", info.Holder(), info.GetIsolate());
+
+ OwnPtr<PositionCallback> positionCallback = createFunctionOnlyCallback<V8PositionCallback>(info[0], 1, succeeded, info.GetIsolate(), exceptionState);
if (!succeeded)
return;
ASSERT(positionCallback);
// Argument is optional (hence undefined is allowed), and null is allowed.
- OwnPtr<PositionErrorCallback> positionErrorCallback = createFunctionOnlyCallback<V8PositionErrorCallback>(info[1], succeeded, info.GetIsolate(), CallbackAllowUndefined | CallbackAllowNull);
+ OwnPtr<PositionErrorCallback> positionErrorCallback = createFunctionOnlyCallback<V8PositionErrorCallback>(info[1], 2, succeeded, info.GetIsolate(), exceptionState, CallbackAllowUndefined | CallbackAllowNull);
if (!succeeded)
return;
- RefPtr<PositionOptions> positionOptions = createPositionOptions(info[2], info.GetIsolate(), succeeded);
+ PositionOptions* positionOptions = createPositionOptions(info[2], info.GetIsolate(), succeeded, exceptionState);
if (!succeeded)
return;
ASSERT(positionOptions);
Geolocation* geolocation = V8Geolocation::toNative(info.Holder());
- int watchId = geolocation->watchPosition(positionCallback.release(), positionErrorCallback.release(), positionOptions.release());
+ int watchId = geolocation->watchPosition(positionCallback.release(), positionErrorCallback.release(), positionOptions);
v8SetReturnValue(info, watchId);
}
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8HTMLAllCollectionCustom.cpp b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8HTMLAllCollectionCustom.cpp
index 670b36cbadd..c0383741326 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8HTMLAllCollectionCustom.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8HTMLAllCollectionCustom.cpp
@@ -29,10 +29,10 @@
*/
#include "config.h"
-#include "V8HTMLAllCollection.h"
+#include "bindings/core/v8/V8HTMLAllCollection.h"
-#include "V8Node.h"
-#include "V8NodeList.h"
+#include "bindings/core/v8/V8Element.h"
+#include "bindings/core/v8/V8NodeList.h"
#include "bindings/v8/V8Binding.h"
#include "core/dom/NamedNodesCollection.h"
#include "core/html/HTMLAllCollection.h"
@@ -43,7 +43,7 @@ namespace WebCore {
template<class CallbackInfo>
static v8::Handle<v8::Value> getNamedItems(HTMLAllCollection* collection, AtomicString name, const CallbackInfo& info)
{
- Vector<RefPtr<Node> > namedItems;
+ WillBeHeapVector<RefPtrWillBeMember<Element> > namedItems;
collection->namedItems(name, namedItems);
if (!namedItems.size())
@@ -62,7 +62,7 @@ static v8::Handle<v8::Value> getItem(HTMLAllCollection* collection, v8::Handle<v
{
v8::Local<v8::Uint32> index = argument->ToArrayIndex();
if (index.IsEmpty()) {
- V8TRYCATCH_FOR_V8STRINGRESOURCE_RETURN(V8StringResource<>, name, argument, v8::Undefined(info.GetIsolate()));
+ TOSTRING_DEFAULT(V8StringResource<>, name, argument, v8::Undefined(info.GetIsolate()));
v8::Handle<v8::Value> result = getNamedItems(collection, name, info);
if (result.IsEmpty())
@@ -71,29 +71,14 @@ static v8::Handle<v8::Value> getItem(HTMLAllCollection* collection, v8::Handle<v
return result;
}
- RefPtr<Node> result = collection->item(index->Uint32Value());
+ RefPtrWillBeRawPtr<Element> result = collection->item(index->Uint32Value());
return toV8(result.release(), info.Holder(), info.GetIsolate());
}
void V8HTMLAllCollection::itemMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& info)
{
- HTMLAllCollection* imp = V8HTMLAllCollection::toNative(info.Holder());
- v8SetReturnValue(info, getItem(imp, info[0], info));
-}
-
-void V8HTMLAllCollection::namedItemMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& info)
-{
- V8TRYCATCH_FOR_V8STRINGRESOURCE_VOID(V8StringResource<>, name, info[0]);
-
- HTMLAllCollection* imp = V8HTMLAllCollection::toNative(info.Holder());
- v8::Handle<v8::Value> result = getNamedItems(imp, name, info);
-
- if (result.IsEmpty()) {
- v8SetReturnValueNull(info);
- return;
- }
-
- v8SetReturnValue(info, result);
+ HTMLAllCollection* impl = V8HTMLAllCollection::toNative(info.Holder());
+ v8SetReturnValue(info, getItem(impl, info[0], info));
}
void V8HTMLAllCollection::legacyCallCustom(const v8::FunctionCallbackInfo<v8::Value>& info)
@@ -101,25 +86,24 @@ void V8HTMLAllCollection::legacyCallCustom(const v8::FunctionCallbackInfo<v8::Va
if (info.Length() < 1)
return;
- HTMLAllCollection* imp = V8HTMLAllCollection::toNative(info.Holder());
- Node* ownerNode = imp->ownerNode();
- ASSERT(ownerNode);
+ HTMLAllCollection* impl = V8HTMLAllCollection::toNative(info.Holder());
+ Node& ownerNode = impl->ownerNode();
- UseCounter::count(ownerNode->document(), UseCounter::DocumentAllLegacyCall);
+ UseCounter::count(ownerNode.document(), UseCounter::DocumentAllLegacyCall);
if (info.Length() == 1) {
- v8SetReturnValue(info, getItem(imp, info[0], info));
+ v8SetReturnValue(info, getItem(impl, info[0], info));
return;
}
// If there is a second argument it is the index of the item we want.
- V8TRYCATCH_FOR_V8STRINGRESOURCE_VOID(V8StringResource<>, name, info[0]);
+ TOSTRING_VOID(V8StringResource<>, name, info[0]);
v8::Local<v8::Uint32> index = info[1]->ToArrayIndex();
if (index.IsEmpty())
return;
- if (Node* node = imp->namedItemWithIndex(name, index->Uint32Value())) {
- v8SetReturnValueFast(info, node, imp);
+ if (Node* node = impl->namedItemWithIndex(name, index->Uint32Value())) {
+ v8SetReturnValueFast(info, node, impl);
return;
}
}
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8HTMLCanvasElementCustom.cpp b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8HTMLCanvasElementCustom.cpp
index c69cbdde418..46a15946f72 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8HTMLCanvasElementCustom.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8HTMLCanvasElementCustom.cpp
@@ -30,13 +30,12 @@
*/
#include "config.h"
-#include "V8HTMLCanvasElement.h"
+#include "bindings/core/v8/V8HTMLCanvasElement.h"
-#include "V8CanvasRenderingContext2D.h"
-#include "V8Node.h"
-#include "V8WebGLRenderingContext.h"
+#include "bindings/core/v8/V8CanvasRenderingContext2D.h"
+#include "bindings/core/v8/V8Node.h"
+#include "bindings/core/v8/V8WebGLRenderingContext.h"
#include "bindings/v8/ExceptionState.h"
-#include "bindings/v8/ScriptState.h"
#include "bindings/v8/V8Binding.h"
#include "core/html/HTMLCanvasElement.h"
#include "core/html/canvas/Canvas2DContextAttributes.h"
@@ -52,34 +51,34 @@ void V8HTMLCanvasElement::getContextMethodCustom(const v8::FunctionCallbackInfo<
{
v8::Handle<v8::Object> holder = info.Holder();
v8::Isolate* isolate = info.GetIsolate();
- HTMLCanvasElement* imp = V8HTMLCanvasElement::toNative(holder);
- V8TRYCATCH_FOR_V8STRINGRESOURCE_VOID(V8StringResource<>, contextIdResource, info[0]);
+ HTMLCanvasElement* impl = V8HTMLCanvasElement::toNative(holder);
+ TOSTRING_VOID(V8StringResource<>, contextIdResource, info[0]);
String contextId = contextIdResource;
RefPtr<CanvasContextAttributes> attributes;
- if (contextId == "webgl" || contextId == "experimental-webgl" || contextId == "webkit-3d") {
+ if (contextId == "webgl" || contextId == "experimental-webgl") {
RefPtr<WebGLContextAttributes> webGLAttributes = WebGLContextAttributes::create();
if (info.Length() > 1 && info[1]->IsObject()) {
v8::Handle<v8::Object> jsAttributes = info[1]->ToObject();
v8::Handle<v8::String> alpha = v8AtomicString(isolate, "alpha");
- if (jsAttributes->Has(alpha))
+ if (jsAttributes->Has(alpha) && !isUndefinedOrNull(jsAttributes->Get(alpha)))
webGLAttributes->setAlpha(jsAttributes->Get(alpha)->BooleanValue());
v8::Handle<v8::String> depth = v8AtomicString(isolate, "depth");
- if (jsAttributes->Has(depth))
+ if (jsAttributes->Has(depth) && !isUndefinedOrNull(jsAttributes->Get(depth)))
webGLAttributes->setDepth(jsAttributes->Get(depth)->BooleanValue());
v8::Handle<v8::String> stencil = v8AtomicString(isolate, "stencil");
- if (jsAttributes->Has(stencil))
+ if (jsAttributes->Has(stencil) && !isUndefinedOrNull(jsAttributes->Get(stencil)))
webGLAttributes->setStencil(jsAttributes->Get(stencil)->BooleanValue());
v8::Handle<v8::String> antialias = v8AtomicString(isolate, "antialias");
- if (jsAttributes->Has(antialias))
+ if (jsAttributes->Has(antialias) && !isUndefinedOrNull(jsAttributes->Get(antialias)))
webGLAttributes->setAntialias(jsAttributes->Get(antialias)->BooleanValue());
v8::Handle<v8::String> premultipliedAlpha = v8AtomicString(isolate, "premultipliedAlpha");
- if (jsAttributes->Has(premultipliedAlpha))
+ if (jsAttributes->Has(premultipliedAlpha) && !isUndefinedOrNull(jsAttributes->Get(premultipliedAlpha)))
webGLAttributes->setPremultipliedAlpha(jsAttributes->Get(premultipliedAlpha)->BooleanValue());
v8::Handle<v8::String> preserveDrawingBuffer = v8AtomicString(isolate, "preserveDrawingBuffer");
- if (jsAttributes->Has(preserveDrawingBuffer))
+ if (jsAttributes->Has(preserveDrawingBuffer) && !isUndefinedOrNull(jsAttributes->Get(preserveDrawingBuffer)))
webGLAttributes->setPreserveDrawingBuffer(jsAttributes->Get(preserveDrawingBuffer)->BooleanValue());
v8::Handle<v8::String> failIfMajorPerformanceCaveat = v8AtomicString(isolate, "failIfMajorPerformanceCaveat");
- if (jsAttributes->Has(failIfMajorPerformanceCaveat))
+ if (jsAttributes->Has(failIfMajorPerformanceCaveat) && !isUndefinedOrNull(jsAttributes->Get(failIfMajorPerformanceCaveat)))
webGLAttributes->setFailIfMajorPerformanceCaveat(jsAttributes->Get(failIfMajorPerformanceCaveat)->BooleanValue());
}
attributes = webGLAttributes;
@@ -88,23 +87,23 @@ void V8HTMLCanvasElement::getContextMethodCustom(const v8::FunctionCallbackInfo<
if (info.Length() > 1 && info[1]->IsObject()) {
v8::Handle<v8::Object> jsAttributes = info[1]->ToObject();
v8::Handle<v8::String> alpha = v8AtomicString(isolate, "alpha");
- if (jsAttributes->Has(alpha))
+ if (jsAttributes->Has(alpha) && !isUndefinedOrNull(jsAttributes->Get(alpha)))
canvas2DAttributes->setAlpha(jsAttributes->Get(alpha)->BooleanValue());
}
attributes = canvas2DAttributes;
}
- CanvasRenderingContext* result = imp->getContext(contextId, attributes.get());
+ CanvasRenderingContext* result = impl->getContext(contextId, attributes.get());
if (!result) {
v8SetReturnValueNull(info);
return;
}
if (result->is2d()) {
v8::Handle<v8::Value> v8Result = toV8(toCanvasRenderingContext2D(result), info.Holder(), info.GetIsolate());
- if (InspectorInstrumentation::canvasAgentEnabled(&imp->document())) {
- ScriptState* scriptState = ScriptState::forContext(isolate->GetCurrentContext());
- ScriptObject context(scriptState, v8::Handle<v8::Object>::Cast(v8Result));
- ScriptObject wrapped = InspectorInstrumentation::wrapCanvas2DRenderingContextForInstrumentation(&imp->document(), context);
- if (!wrapped.hasNoValue()) {
+ if (InspectorInstrumentation::canvasAgentEnabled(&impl->document())) {
+ ScriptState* scriptState = ScriptState::current(isolate);
+ ScriptValue context(scriptState, v8Result);
+ ScriptValue wrapped = InspectorInstrumentation::wrapCanvas2DRenderingContextForInstrumentation(&impl->document(), context);
+ if (!wrapped.isEmpty()) {
v8SetReturnValue(info, wrapped.v8Value());
return;
}
@@ -114,11 +113,11 @@ void V8HTMLCanvasElement::getContextMethodCustom(const v8::FunctionCallbackInfo<
}
if (result->is3d()) {
v8::Handle<v8::Value> v8Result = toV8(toWebGLRenderingContext(result), info.Holder(), info.GetIsolate());
- if (InspectorInstrumentation::canvasAgentEnabled(&imp->document())) {
- ScriptState* scriptState = ScriptState::forContext(isolate->GetCurrentContext());
- ScriptObject glContext(scriptState, v8::Handle<v8::Object>::Cast(v8Result));
- ScriptObject wrapped = InspectorInstrumentation::wrapWebGLRenderingContextForInstrumentation(&imp->document(), glContext);
- if (!wrapped.hasNoValue()) {
+ if (InspectorInstrumentation::canvasAgentEnabled(&impl->document())) {
+ ScriptState* scriptState = ScriptState::current(isolate);
+ ScriptValue glContext(scriptState, v8Result);
+ ScriptValue wrapped = InspectorInstrumentation::wrapWebGLRenderingContextForInstrumentation(&impl->document(), glContext);
+ if (!wrapped.isEmpty()) {
v8SetReturnValue(info, wrapped.v8Value());
return;
}
@@ -136,7 +135,7 @@ void V8HTMLCanvasElement::toDataURLMethodCustom(const v8::FunctionCallbackInfo<v
HTMLCanvasElement* canvas = V8HTMLCanvasElement::toNative(holder);
ExceptionState exceptionState(ExceptionState::ExecutionContext, "toDataURL", "HTMLCanvasElement", info.Holder(), info.GetIsolate());
- V8TRYCATCH_FOR_V8STRINGRESOURCE_VOID(V8StringResource<>, type, info[0]);
+ TOSTRING_VOID(V8StringResource<>, type, info[0]);
double quality;
double* qualityPtr = 0;
if (info.Length() > 1 && info[1]->IsNumber()) {
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8HTMLCollectionCustom.cpp b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8HTMLCollectionCustom.cpp
index 33fd4ca1d38..05883e60cee 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8HTMLCollectionCustom.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8HTMLCollectionCustom.cpp
@@ -29,12 +29,12 @@
*/
#include "config.h"
-#include "V8HTMLCollection.h"
+#include "bindings/core/v8/V8HTMLCollection.h"
-#include "V8HTMLAllCollection.h"
-#include "V8HTMLFormControlsCollection.h"
-#include "V8HTMLOptionsCollection.h"
-#include "V8Node.h"
+#include "bindings/core/v8/V8HTMLAllCollection.h"
+#include "bindings/core/v8/V8HTMLFormControlsCollection.h"
+#include "bindings/core/v8/V8HTMLOptionsCollection.h"
+#include "bindings/core/v8/V8Node.h"
#include "bindings/v8/V8Binding.h"
#include "core/html/HTMLCollection.h"
@@ -45,11 +45,11 @@ v8::Handle<v8::Object> wrap(HTMLCollection* impl, v8::Handle<v8::Object> creatio
ASSERT(impl);
switch (impl->type()) {
case FormControls:
- return wrap(static_cast<HTMLFormControlsCollection*>(impl), creationContext, isolate);
+ return wrap(toHTMLFormControlsCollection(impl), creationContext, isolate);
case SelectOptions:
- return wrap(static_cast<HTMLOptionsCollection*>(impl), creationContext, isolate);
+ return wrap(toHTMLOptionsCollection(impl), creationContext, isolate);
case DocAll:
- return wrap(static_cast<HTMLAllCollection*>(impl), creationContext, isolate);
+ return wrap(toHTMLAllCollection(impl), creationContext, isolate);
default:
break;
}
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8HTMLDocumentCustom.cpp b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8HTMLDocumentCustom.cpp
index 49f76e73080..1f1a99bf49f 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8HTMLDocumentCustom.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8HTMLDocumentCustom.cpp
@@ -29,20 +29,20 @@
*/
#include "config.h"
-#include "V8HTMLDocument.h"
+#include "bindings/core/v8/V8HTMLDocument.h"
-#include "HTMLNames.h"
-#include "V8HTMLAllCollection.h"
-#include "V8HTMLCollection.h"
-#include "V8Node.h"
-#include "V8Window.h"
+#include "bindings/core/v8/V8HTMLAllCollection.h"
+#include "bindings/core/v8/V8HTMLCollection.h"
+#include "bindings/core/v8/V8Node.h"
+#include "bindings/core/v8/V8Window.h"
#include "bindings/v8/ScriptController.h"
#include "bindings/v8/V8Binding.h"
+#include "core/HTMLNames.h"
+#include "core/frame/LocalFrame.h"
#include "core/html/HTMLAllCollection.h"
#include "core/html/HTMLCollection.h"
#include "core/html/HTMLDocument.h"
#include "core/html/HTMLIFrameElement.h"
-#include "core/frame/Frame.h"
#include "wtf/OwnPtr.h"
#include "wtf/RefPtr.h"
#include "wtf/StdLibExtras.h"
@@ -56,15 +56,18 @@ void V8HTMLDocument::openMethodCustom(const v8::FunctionCallbackInfo<v8::Value>&
HTMLDocument* htmlDocument = V8HTMLDocument::toNative(info.Holder());
if (info.Length() > 2) {
- if (RefPtr<Frame> frame = htmlDocument->frame()) {
+ if (RefPtr<LocalFrame> frame = htmlDocument->frame()) {
// Fetch the global object for the frame.
- v8::Local<v8::Context> context = frame->script().currentWorldContext();
+ v8::Local<v8::Context> context = toV8Context(frame.get(), DOMWrapperWorld::current(info.GetIsolate()));
// Bail out if we cannot get the context.
if (context.IsEmpty())
return;
v8::Local<v8::Object> global = context->Global();
// Get the open property of the global object.
v8::Local<v8::Value> function = global->Get(v8AtomicString(info.GetIsolate(), "open"));
+ // Failed; return without throwing (new) exception.
+ if (function.IsEmpty())
+ return;
// If the open property is not a function throw a type error.
if (!function->IsFunction()) {
throwTypeError("open is not a function", info.GetIsolate());
@@ -80,7 +83,11 @@ void V8HTMLDocument::openMethodCustom(const v8::FunctionCallbackInfo<v8::Value>&
}
}
- htmlDocument->open(activeDOMWindow()->document());
+ ExceptionState exceptionState(ExceptionState::ExecutionContext, "open", "Document", info.Holder(), info.GetIsolate());
+ htmlDocument->open(callingDOMWindow(info.GetIsolate())->document(), exceptionState);
+ if (exceptionState.throwIfNeeded())
+ return;
+
v8SetReturnValue(info, info.Holder());
}
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8HTMLElementCustom.cpp b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8HTMLElementCustom.cpp
index dae4512d1dc..78706afe722 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8HTMLElementCustom.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8HTMLElementCustom.cpp
@@ -29,9 +29,9 @@
*/
#include "config.h"
-#include "V8HTMLElement.h"
+#include "bindings/core/v8/V8HTMLElement.h"
-#include "V8HTMLElementWrapperFactory.h"
+#include "core/V8HTMLElementWrapperFactory.h" // FIXME: should be bindings/core/v8
namespace WebCore {
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8HTMLFormControlsCollectionCustom.cpp b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8HTMLFormControlsCollectionCustom.cpp
deleted file mode 100644
index ab84454965f..00000000000
--- a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8HTMLFormControlsCollectionCustom.cpp
+++ /dev/null
@@ -1,71 +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 "V8HTMLFormControlsCollection.h"
-
-#include "V8Node.h"
-#include "V8RadioNodeList.h"
-#include "bindings/v8/V8Binding.h"
-#include "core/html/HTMLCollection.h"
-#include "core/html/RadioNodeList.h"
-
-namespace WebCore {
-
-template<typename CallbackInfo>
-static v8::Handle<v8::Value> getNamedItems(HTMLFormControlsCollection* collection, const AtomicString& name, const CallbackInfo& info)
-{
- Vector<RefPtr<Node> > namedItems;
- collection->namedItems(name, namedItems);
-
- if (!namedItems.size())
- return v8Undefined();
-
- if (namedItems.size() == 1)
- return toV8(namedItems.at(0).release(), info.Holder(), info.GetIsolate());
-
- return toV8(collection->ownerNode()->radioNodeList(name).get(), info.Holder(), info.GetIsolate());
-}
-
-void V8HTMLFormControlsCollection::namedItemMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& info)
-{
- V8TRYCATCH_FOR_V8STRINGRESOURCE_VOID(V8StringResource<>, name, info[0]);
- HTMLFormControlsCollection* imp = V8HTMLFormControlsCollection::toNative(info.Holder());
- v8::Handle<v8::Value> result = getNamedItems(imp, name, info);
-
- if (result.IsEmpty()) {
- v8SetReturnValueNull(info);
- return;
- }
-
- v8SetReturnValue(info, result);
-}
-
-} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8HTMLFrameElementCustom.cpp b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8HTMLFrameElementCustom.cpp
deleted file mode 100644
index 8c011d0d922..00000000000
--- a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8HTMLFrameElementCustom.cpp
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2007-2009 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "V8HTMLFrameElement.h"
-
-#include "HTMLNames.h"
-#include "bindings/v8/BindingSecurity.h"
-#include "bindings/v8/ExceptionState.h"
-#include "bindings/v8/V8Binding.h"
-#include "core/html/HTMLFrameElement.h"
-#include "core/html/parser/HTMLParserIdioms.h"
-
-namespace WebCore {
-
-using namespace HTMLNames;
-
-void V8HTMLFrameElement::locationAttributeSetterCustom(v8::Local<v8::Value> value, const v8::PropertyCallbackInfo<void>& info)
-{
- HTMLFrameElement* frame = V8HTMLFrameElement::toNative(info.Holder());
- V8TRYCATCH_FOR_V8STRINGRESOURCE_VOID(V8StringResource<WithNullCheck>, locationValue, value);
-
- ExceptionState exceptionState(info.Holder(), info.GetIsolate());
- if (protocolIsJavaScript(stripLeadingAndTrailingHTMLSpaces(locationValue)) && !BindingSecurity::shouldAllowAccessToFrame(frame->contentFrame(), exceptionState)) {
- exceptionState.throwIfNeeded();
- return;
- }
-
- frame->setLocation(locationValue);
-}
-
-} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8HTMLOptionsCollectionCustom.cpp b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8HTMLOptionsCollectionCustom.cpp
index 094bf4acc8b..08ffb16adbd 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8HTMLOptionsCollectionCustom.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8HTMLOptionsCollectionCustom.cpp
@@ -29,12 +29,11 @@
*/
#include "config.h"
-#include "V8HTMLOptionsCollection.h"
+#include "bindings/core/v8/V8HTMLOptionsCollection.h"
-#include "V8HTMLOptionElement.h"
-#include "V8Node.h"
-#include "V8NodeList.h"
-#include "bindings/v8/ExceptionMessages.h"
+#include "bindings/core/v8/V8HTMLOptionElement.h"
+#include "bindings/core/v8/V8Node.h"
+#include "bindings/core/v8/V8NodeList.h"
#include "bindings/v8/ExceptionState.h"
#include "bindings/v8/V8Binding.h"
#include "core/dom/ExceptionCode.h"
@@ -45,50 +44,23 @@
namespace WebCore {
-template<typename CallbackInfo>
-static void getNamedItems(HTMLOptionsCollection* collection, const AtomicString& name, const CallbackInfo& info)
-{
- Vector<RefPtr<Node> > namedItems;
- collection->namedItems(name, namedItems);
-
- if (!namedItems.size()) {
- v8SetReturnValueNull(info);
- return;
- }
-
- if (namedItems.size() == 1) {
- v8SetReturnValueFast(info, namedItems.at(0).release(), collection);
- return;
- }
-
- v8SetReturnValueFast(info, NamedNodesCollection::create(namedItems), collection);
-}
-
-void V8HTMLOptionsCollection::namedItemMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& info)
-{
- V8TRYCATCH_FOR_V8STRINGRESOURCE_VOID(V8StringResource<>, name, info[0]);
- HTMLOptionsCollection* imp = V8HTMLOptionsCollection::toNative(info.Holder());
- getNamedItems(imp, name, info);
-}
-
void V8HTMLOptionsCollection::addMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& info)
{
ExceptionState exceptionState(ExceptionState::ExecutionContext, "add", "HTMLOptionsCollection", info.Holder(), info.GetIsolate());
- if (!V8HTMLOptionElement::hasInstance(info[0], info.GetIsolate(), worldType(info.GetIsolate()))) {
+ if (!V8HTMLOptionElement::hasInstance(info[0], info.GetIsolate())) {
exceptionState.throwTypeError("The element provided was not an HTMLOptionElement.");
} else {
- HTMLOptionsCollection* imp = V8HTMLOptionsCollection::toNative(info.Holder());
+ HTMLOptionsCollection* impl = V8HTMLOptionsCollection::toNative(info.Holder());
HTMLOptionElement* option = V8HTMLOptionElement::toNative(v8::Handle<v8::Object>(v8::Handle<v8::Object>::Cast(info[0])));
if (info.Length() < 2) {
- imp->add(option, exceptionState);
+ impl->add(option, exceptionState);
} else {
- bool ok;
- V8TRYCATCH_VOID(int, index, toInt32(info[1], ok));
- if (!ok)
- exceptionState.throwTypeError("The index provided could not be interpreted as an integer.");
- else
- imp->add(option, index, exceptionState);
+ int index = toInt32(info[1], exceptionState);
+ if (exceptionState.throwIfNeeded())
+ return;
+
+ impl->add(option, index, exceptionState);
}
}
@@ -97,7 +69,7 @@ void V8HTMLOptionsCollection::addMethodCustom(const v8::FunctionCallbackInfo<v8:
void V8HTMLOptionsCollection::lengthAttributeSetterCustom(v8::Local<v8::Value> value, const v8::PropertyCallbackInfo<void>& info)
{
- HTMLOptionsCollection* imp = V8HTMLOptionsCollection::toNative(info.Holder());
+ HTMLOptionsCollection* impl = V8HTMLOptionsCollection::toNative(info.Holder());
double v = value->NumberValue();
unsigned newLength = 0;
ExceptionState exceptionState(ExceptionState::SetterContext, "length", "HTMLOptionsCollection", info.Holder(), info.GetIsolate());
@@ -113,7 +85,7 @@ void V8HTMLOptionsCollection::lengthAttributeSetterCustom(v8::Local<v8::Value> v
if (exceptionState.throwIfNeeded())
return;
- imp->setLength(newLength, exceptionState);
+ impl->setLength(newLength, exceptionState);
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8HTMLPlugInElementCustom.cpp b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8HTMLPlugInElementCustom.cpp
index d29360ac3cb..ac4f4cde34c 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8HTMLPlugInElementCustom.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8HTMLPlugInElementCustom.cpp
@@ -30,9 +30,9 @@
#include "config.h"
-#include "V8HTMLAppletElement.h"
-#include "V8HTMLEmbedElement.h"
-#include "V8HTMLObjectElement.h"
+#include "bindings/core/v8/V8HTMLAppletElement.h"
+#include "bindings/core/v8/V8HTMLEmbedElement.h"
+#include "bindings/core/v8/V8HTMLObjectElement.h"
#include "bindings/v8/SharedPersistent.h"
#include "bindings/v8/V8Binding.h"
#include "bindings/v8/V8NPObject.h"
@@ -46,8 +46,8 @@ namespace WebCore {
template <class C>
static void npObjectNamedGetter(v8::Local<v8::String> name, const v8::PropertyCallbackInfo<v8::Value>& info)
{
- HTMLPlugInElement* imp = C::toNative(info.Holder());
- RefPtr<SharedPersistent<v8::Object> > wrapper = imp->pluginWrapper();
+ HTMLPlugInElement* impl = C::toNative(info.Holder());
+ RefPtr<SharedPersistent<v8::Object> > wrapper = impl->pluginWrapper();
if (!wrapper)
return;
@@ -61,8 +61,8 @@ static void npObjectNamedGetter(v8::Local<v8::String> name, const v8::PropertyCa
template <class C>
static void npObjectNamedSetter(v8::Local<v8::String> name, v8::Local<v8::Value> value, const v8::PropertyCallbackInfo<v8::Value>& info)
{
- HTMLPlugInElement* imp = C::toNative(info.Holder());
- RefPtr<SharedPersistent<v8::Object> > wrapper = imp->pluginWrapper();
+ HTMLPlugInElement* impl = C::toNative(info.Holder());
+ RefPtr<SharedPersistent<v8::Object> > wrapper = impl->pluginWrapper();
if (!wrapper)
return;
@@ -105,30 +105,30 @@ void V8HTMLObjectElement::namedPropertySetterCustom(v8::Local<v8::String> name,
void V8HTMLAppletElement::legacyCallCustom(const v8::FunctionCallbackInfo<v8::Value>& info)
{
- HTMLPlugInElement* imp = V8HTMLAppletElement::toNative(info.Holder());
- UseCounter::count(imp->document(), UseCounter::HTMLAppletElementLegacyCall);
+ HTMLPlugInElement* impl = V8HTMLAppletElement::toNative(info.Holder());
+ UseCounter::count(impl->document(), UseCounter::HTMLAppletElementLegacyCall);
npObjectInvokeDefaultHandler(info);
}
void V8HTMLEmbedElement::legacyCallCustom(const v8::FunctionCallbackInfo<v8::Value>& info)
{
- HTMLPlugInElement* imp = V8HTMLEmbedElement::toNative(info.Holder());
- UseCounter::count(imp->document(), UseCounter::HTMLEmbedElementLegacyCall);
+ HTMLPlugInElement* impl = V8HTMLEmbedElement::toNative(info.Holder());
+ UseCounter::count(impl->document(), UseCounter::HTMLEmbedElementLegacyCall);
npObjectInvokeDefaultHandler(info);
}
void V8HTMLObjectElement::legacyCallCustom(const v8::FunctionCallbackInfo<v8::Value>& info)
{
- HTMLPlugInElement* imp = V8HTMLObjectElement::toNative(info.Holder());
- UseCounter::count(imp->document(), UseCounter::HTMLObjectElementLegacyCall);
+ HTMLPlugInElement* impl = V8HTMLObjectElement::toNative(info.Holder());
+ UseCounter::count(impl->document(), UseCounter::HTMLObjectElementLegacyCall);
npObjectInvokeDefaultHandler(info);
}
template <class C>
void npObjectIndexedGetter(uint32_t index, const v8::PropertyCallbackInfo<v8::Value>& info)
{
- HTMLPlugInElement* imp = C::toNative(info.Holder());
- RefPtr<SharedPersistent<v8::Object> > wrapper = imp->pluginWrapper();
+ HTMLPlugInElement* impl = C::toNative(info.Holder());
+ RefPtr<SharedPersistent<v8::Object> > wrapper = impl->pluginWrapper();
if (!wrapper)
return;
@@ -142,8 +142,8 @@ void npObjectIndexedGetter(uint32_t index, const v8::PropertyCallbackInfo<v8::Va
template <class C>
void npObjectIndexedSetter(uint32_t index, v8::Local<v8::Value> value, const v8::PropertyCallbackInfo<v8::Value>& info)
{
- HTMLPlugInElement* imp = C::toNative(info.Holder());
- RefPtr<SharedPersistent<v8::Object> > wrapper = imp->pluginWrapper();
+ HTMLPlugInElement* impl = C::toNative(info.Holder());
+ RefPtr<SharedPersistent<v8::Object> > wrapper = impl->pluginWrapper();
if (!wrapper)
return;
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8HistoryCustom.cpp b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8HistoryCustom.cpp
index 427e8776532..ec963bf1204 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8HistoryCustom.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8HistoryCustom.cpp
@@ -29,13 +29,13 @@
*/
#include "config.h"
-#include "V8History.h"
+#include "bindings/core/v8/V8History.h"
-#include "V8Window.h"
+#include "bindings/core/v8/V8Window.h"
#include "bindings/v8/ExceptionState.h"
#include "bindings/v8/SerializedScriptValue.h"
#include "bindings/v8/V8Binding.h"
-#include "bindings/v8/V8HiddenPropertyName.h"
+#include "bindings/v8/V8HiddenValue.h"
#include "core/dom/ExceptionCode.h"
#include "core/frame/History.h"
@@ -45,7 +45,7 @@ void V8History::stateAttributeGetterCustom(const v8::PropertyCallbackInfo<v8::Va
{
History* history = V8History::toNative(info.Holder());
- v8::Handle<v8::Value> value = info.Holder()->GetHiddenValue(V8HiddenPropertyName::state(info.GetIsolate()));
+ v8::Handle<v8::Value> value = V8HiddenValue::getHiddenValue(info.GetIsolate(), info.Holder(), V8HiddenValue::state(info.GetIsolate()));
if (!value.IsEmpty() && !history->stateChanged()) {
v8SetReturnValue(info, value);
@@ -54,42 +54,40 @@ void V8History::stateAttributeGetterCustom(const v8::PropertyCallbackInfo<v8::Va
RefPtr<SerializedScriptValue> serialized = history->state();
value = serialized ? serialized->deserialize(info.GetIsolate()) : v8::Handle<v8::Value>(v8::Null(info.GetIsolate()));
- info.Holder()->SetHiddenValue(V8HiddenPropertyName::state(info.GetIsolate()), value);
+ V8HiddenValue::setHiddenValue(info.GetIsolate(), info.Holder(), V8HiddenValue::state(info.GetIsolate()), value);
v8SetReturnValue(info, value);
}
void V8History::pushStateMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& info)
{
- bool didThrow = false;
- RefPtr<SerializedScriptValue> historyState = SerializedScriptValue::create(info[0], 0, 0, didThrow, info.GetIsolate());
- if (didThrow)
+ ExceptionState exceptionState(ExceptionState::ExecutionContext, "pushState", "History", info.Holder(), info.GetIsolate());
+ RefPtr<SerializedScriptValue> historyState = SerializedScriptValue::create(info[0], 0, 0, exceptionState, info.GetIsolate());
+ if (exceptionState.throwIfNeeded())
return;
- V8TRYCATCH_FOR_V8STRINGRESOURCE_VOID(V8StringResource<WithUndefinedOrNullCheck>, title, info[1]);
- V8TRYCATCH_FOR_V8STRINGRESOURCE_VOID(V8StringResource<WithUndefinedOrNullCheck>, url, argumentOrNull(info, 2));
+ TOSTRING_VOID(V8StringResource<WithUndefinedOrNullCheck>, title, info[1]);
+ TOSTRING_VOID(V8StringResource<WithUndefinedOrNullCheck>, url, argumentOrNull(info, 2));
- ExceptionState exceptionState(info.Holder(), info.GetIsolate());
History* history = V8History::toNative(info.Holder());
- history->stateObjectAdded(historyState.release(), title, url, SameDocumentNavigationPushState, exceptionState);
- info.Holder()->DeleteHiddenValue(V8HiddenPropertyName::state(info.GetIsolate()));
+ history->stateObjectAdded(historyState.release(), title, url, FrameLoadTypeStandard, exceptionState);
+ V8HiddenValue::deleteHiddenValue(info.GetIsolate(), info.Holder(), V8HiddenValue::state(info.GetIsolate()));
exceptionState.throwIfNeeded();
}
void V8History::replaceStateMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& info)
{
- bool didThrow = false;
- RefPtr<SerializedScriptValue> historyState = SerializedScriptValue::create(info[0], 0, 0, didThrow, info.GetIsolate());
- if (didThrow)
+ ExceptionState exceptionState(ExceptionState::ExecutionContext, "replaceState", "History", info.Holder(), info.GetIsolate());
+ RefPtr<SerializedScriptValue> historyState = SerializedScriptValue::create(info[0], 0, 0, exceptionState, info.GetIsolate());
+ if (exceptionState.throwIfNeeded())
return;
- V8TRYCATCH_FOR_V8STRINGRESOURCE_VOID(V8StringResource<WithUndefinedOrNullCheck>, title, info[1]);
- V8TRYCATCH_FOR_V8STRINGRESOURCE_VOID(V8StringResource<WithUndefinedOrNullCheck>, url, argumentOrNull(info, 2));
+ TOSTRING_VOID(V8StringResource<WithUndefinedOrNullCheck>, title, info[1]);
+ TOSTRING_VOID(V8StringResource<WithUndefinedOrNullCheck>, url, argumentOrNull(info, 2));
- ExceptionState exceptionState(info.Holder(), info.GetIsolate());
History* history = V8History::toNative(info.Holder());
- history->stateObjectAdded(historyState.release(), title, url, SameDocumentNavigationReplaceState, exceptionState);
- info.Holder()->DeleteHiddenValue(V8HiddenPropertyName::state(info.GetIsolate()));
+ history->stateObjectAdded(historyState.release(), title, url, FrameLoadTypeRedirectWithLockedBackForwardList, exceptionState);
+ V8HiddenValue::deleteHiddenValue(info.GetIsolate(), info.Holder(), V8HiddenValue::state(info.GetIsolate()));
exceptionState.throwIfNeeded();
}
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8ImageDataCustom.cpp b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8ImageDataCustom.cpp
index 813731456ec..c940c7c44f8 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8ImageDataCustom.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8ImageDataCustom.cpp
@@ -29,7 +29,7 @@
*/
#include "config.h"
-#include "V8ImageData.h"
+#include "bindings/core/v8/V8ImageData.h"
#include "bindings/v8/custom/V8Uint8ClampedArrayCustom.h"
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8InjectedScriptHostCustom.cpp b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8InjectedScriptHostCustom.cpp
index cb545e6e3a3..772649e1bfb 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8InjectedScriptHostCustom.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8InjectedScriptHostCustom.cpp
@@ -29,21 +29,21 @@
*/
#include "config.h"
-#include "V8InjectedScriptHost.h"
-
-#include "V8Database.h"
-#include "V8HTMLAllCollection.h"
-#include "V8HTMLCollection.h"
-#include "V8Node.h"
-#include "V8NodeList.h"
-#include "V8Storage.h"
+#include "bindings/core/v8/V8InjectedScriptHost.h"
+
+#include "bindings/core/v8/V8EventTarget.h"
+#include "bindings/core/v8/V8HTMLAllCollection.h"
+#include "bindings/core/v8/V8HTMLCollection.h"
+#include "bindings/core/v8/V8Node.h"
+#include "bindings/core/v8/V8NodeList.h"
+#include "bindings/core/v8/V8Storage.h"
+#include "bindings/modules/v8/V8Database.h"
#include "bindings/v8/BindingSecurity.h"
#include "bindings/v8/ExceptionState.h"
#include "bindings/v8/ScriptDebugServer.h"
#include "bindings/v8/ScriptValue.h"
#include "bindings/v8/V8AbstractEventListener.h"
#include "bindings/v8/V8Binding.h"
-#include "bindings/v8/V8HiddenPropertyName.h"
#include "bindings/v8/V8ScriptRunner.h"
#include "bindings/v8/custom/V8Float32ArrayCustom.h"
#include "bindings/v8/custom/V8Float64ArrayCustom.h"
@@ -54,6 +54,8 @@
#include "bindings/v8/custom/V8Uint32ArrayCustom.h"
#include "bindings/v8/custom/V8Uint8ArrayCustom.h"
#include "bindings/v8/custom/V8Uint8ClampedArrayCustom.h"
+#include "core/events/EventTarget.h"
+#include "core/frame/LocalDOMWindow.h"
#include "core/inspector/InjectedScript.h"
#include "core/inspector/InjectedScriptHost.h"
#include "core/inspector/InspectorDOMAgent.h"
@@ -62,25 +64,22 @@
namespace WebCore {
-Node* InjectedScriptHost::scriptValueAsNode(ScriptValue value)
+Node* InjectedScriptHost::scriptValueAsNode(ScriptState* scriptState, ScriptValue value)
{
- v8::HandleScope scope(value.isolate());
+ ScriptState::Scope scope(scriptState);
if (!value.isObject() || value.isNull())
return 0;
return V8Node::toNative(v8::Handle<v8::Object>::Cast(value.v8Value()));
}
-ScriptValue InjectedScriptHost::nodeAsScriptValue(ScriptState* state, Node* node)
+ScriptValue InjectedScriptHost::nodeAsScriptValue(ScriptState* scriptState, Node* node)
{
- v8::Isolate* isolate = state->isolate();
- v8::HandleScope scope(isolate);
- v8::Local<v8::Context> context = state->context();
- v8::Context::Scope contextScope(context);
-
- ExceptionState exceptionState(v8::Handle<v8::Object>(), isolate);
- if (!BindingSecurity::shouldAllowAccessToNode(node, exceptionState))
- return ScriptValue(v8::Null(isolate), isolate);
- return ScriptValue(toV8(node, v8::Handle<v8::Object>(), isolate), isolate);
+ ScriptState::Scope scope(scriptState);
+ v8::Isolate* isolate = scriptState->isolate();
+ ExceptionState exceptionState(ExceptionState::ExecutionContext, "nodeAsScriptValue", "InjectedScriptHost", scriptState->context()->Global(), isolate);
+ if (!BindingSecurity::shouldAllowAccessToNode(isolate, node, exceptionState))
+ return ScriptValue(scriptState, v8::Null(isolate));
+ return ScriptValue(scriptState, toV8(node, scriptState->context()->Global(), isolate));
}
void V8InjectedScriptHost::inspectedObjectMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& info)
@@ -95,7 +94,7 @@ void V8InjectedScriptHost::inspectedObjectMethodCustom(const v8::FunctionCallbac
InjectedScriptHost* host = V8InjectedScriptHost::toNative(info.Holder());
InjectedScriptHost::InspectableObject* object = host->inspectedObject(info[0]->ToInt32()->Value());
- v8SetReturnValue(info, object->get(ScriptState::current()).v8Value());
+ v8SetReturnValue(info, object->get(ScriptState::current(info.GetIsolate())).v8Value());
}
void V8InjectedScriptHost::internalConstructorNameMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& info)
@@ -119,7 +118,7 @@ void V8InjectedScriptHost::isHTMLAllCollectionMethodCustom(const v8::FunctionCal
return;
}
- v8SetReturnValue(info, V8HTMLAllCollection::hasInstance(info[0], info.GetIsolate(), worldType(info.GetIsolate())));
+ v8SetReturnValue(info, V8HTMLAllCollection::hasInstance(info[0], info.GetIsolate()));
}
void V8InjectedScriptHost::typeMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& info)
@@ -153,32 +152,31 @@ void V8InjectedScriptHost::typeMethodCustom(const v8::FunctionCallbackInfo<v8::V
v8SetReturnValue(info, v8AtomicString(isolate, "regexp"));
return;
}
- WrapperWorldType currentWorldType = worldType(isolate);
- if (V8Node::hasInstance(value, isolate, currentWorldType)) {
+ if (V8Node::hasInstance(value, isolate)) {
v8SetReturnValue(info, v8AtomicString(isolate, "node"));
return;
}
- if (V8NodeList::hasInstance(value, isolate, currentWorldType)) {
+ if (V8NodeList::hasInstance(value, isolate)) {
v8SetReturnValue(info, v8AtomicString(isolate, "array"));
return;
}
- if (V8HTMLCollection::hasInstance(value, isolate, currentWorldType)) {
+ if (V8HTMLCollection::hasInstance(value, isolate)) {
v8SetReturnValue(info, v8AtomicString(isolate, "array"));
return;
}
- if (V8Int8Array::hasInstance(value, isolate, currentWorldType) || V8Int16Array::hasInstance(value, isolate, currentWorldType) || V8Int32Array::hasInstance(value, isolate, currentWorldType)) {
+ if (V8Int8Array::hasInstance(value, isolate) || V8Int16Array::hasInstance(value, isolate) || V8Int32Array::hasInstance(value, isolate)) {
v8SetReturnValue(info, v8AtomicString(isolate, "array"));
return;
}
- if (V8Uint8Array::hasInstance(value, isolate, currentWorldType) || V8Uint16Array::hasInstance(value, isolate, currentWorldType) || V8Uint32Array::hasInstance(value, isolate, currentWorldType)) {
+ if (V8Uint8Array::hasInstance(value, isolate) || V8Uint16Array::hasInstance(value, isolate) || V8Uint32Array::hasInstance(value, isolate)) {
v8SetReturnValue(info, v8AtomicString(isolate, "array"));
return;
}
- if (V8Float32Array::hasInstance(value, isolate, currentWorldType) || V8Float64Array::hasInstance(value, isolate, currentWorldType)) {
+ if (V8Float32Array::hasInstance(value, isolate) || V8Float64Array::hasInstance(value, isolate)) {
v8SetReturnValue(info, v8AtomicString(isolate, "array"));
return;
}
- if (V8Uint8ClampedArray::hasInstance(value, isolate, currentWorldType)) {
+ if (V8Uint8ClampedArray::hasInstance(value, isolate)) {
v8SetReturnValue(info, v8AtomicString(isolate, "array"));
return;
}
@@ -207,12 +205,12 @@ void V8InjectedScriptHost::functionDetailsMethodCustom(const v8::FunctionCallbac
int lineNumber = function->GetScriptLineNumber();
int columnNumber = function->GetScriptColumnNumber();
- v8::Local<v8::Object> location = v8::Object::New();
- location->Set(v8AtomicString(isolate, "lineNumber"), v8::Integer::New(lineNumber, isolate));
- location->Set(v8AtomicString(isolate, "columnNumber"), v8::Integer::New(columnNumber, isolate));
- location->Set(v8AtomicString(isolate, "scriptId"), v8::Integer::New(function->ScriptId(), isolate)->ToString());
+ v8::Local<v8::Object> location = v8::Object::New(isolate);
+ location->Set(v8AtomicString(isolate, "lineNumber"), v8::Integer::New(isolate, lineNumber));
+ location->Set(v8AtomicString(isolate, "columnNumber"), v8::Integer::New(isolate, columnNumber));
+ location->Set(v8AtomicString(isolate, "scriptId"), v8::Integer::New(isolate, function->ScriptId())->ToString());
- v8::Local<v8::Object> result = v8::Object::New();
+ v8::Local<v8::Object> result = v8::Object::New(isolate);
result->Set(v8AtomicString(isolate, "location"), location);
if (!setFunctionName(result, function->GetDisplayName(), isolate)
@@ -241,7 +239,7 @@ void V8InjectedScriptHost::getInternalPropertiesMethodCustom(const v8::FunctionC
v8SetReturnValue(info, debugServer.getInternalProperties(object));
}
-static v8::Handle<v8::Array> getJSListenerFunctions(Document* document, const EventListenerInfo& listenerInfo, v8::Isolate* isolate)
+static v8::Handle<v8::Array> getJSListenerFunctions(ExecutionContext* executionContext, const EventListenerInfo& listenerInfo, v8::Isolate* isolate)
{
v8::Local<v8::Array> result = v8::Array::New(isolate);
size_t handlersCount = listenerInfo.eventListenerVector.size();
@@ -252,7 +250,7 @@ static v8::Handle<v8::Array> getJSListenerFunctions(Document* document, const Ev
continue;
}
V8AbstractEventListener* v8Listener = static_cast<V8AbstractEventListener*>(listener.get());
- v8::Local<v8::Context> context = toV8Context(document, v8Listener->world());
+ v8::Local<v8::Context> context = toV8Context(executionContext, v8Listener->world());
// Hide listeners from other contexts.
if (context != isolate->GetCurrentContext())
continue;
@@ -260,12 +258,12 @@ static v8::Handle<v8::Array> getJSListenerFunctions(Document* document, const Ev
{
// getListenerObject() may cause JS in the event attribute to get compiled, potentially unsuccessfully.
v8::TryCatch block;
- function = v8Listener->getListenerObject(document);
+ function = v8Listener->getListenerObject(executionContext);
if (block.HasCaught())
continue;
}
ASSERT(!function.IsEmpty());
- v8::Local<v8::Object> listenerEntry = v8::Object::New();
+ v8::Local<v8::Object> listenerEntry = v8::Object::New(isolate);
listenerEntry->Set(v8AtomicString(isolate, "listener"), function);
listenerEntry->Set(v8AtomicString(isolate, "useCapture"), v8::Boolean::New(isolate, listenerInfo.eventListenerVector[i].useCapture));
result->Set(v8::Number::New(isolate, outputIndex++), listenerEntry);
@@ -278,20 +276,24 @@ void V8InjectedScriptHost::getEventListenersMethodCustom(const v8::FunctionCallb
if (info.Length() < 1)
return;
+
v8::Local<v8::Value> value = info[0];
- if (!V8Node::hasInstance(value, info.GetIsolate(), worldType(info.GetIsolate())))
- return;
- Node* node = V8Node::toNative(value->ToObject());
- if (!node)
+ EventTarget* target = V8EventTarget::toNativeWithTypeCheck(info.GetIsolate(), value);
+
+ // We need to handle a LocalDOMWindow specially, because a LocalDOMWindow wrapper exists on a prototype chain.
+ if (!target)
+ target = toDOMWindow(value, info.GetIsolate());
+
+ if (!target || !target->executionContext())
return;
InjectedScriptHost* host = V8InjectedScriptHost::toNative(info.Holder());
Vector<EventListenerInfo> listenersArray;
- host->getEventListenersImpl(node, listenersArray);
+ host->getEventListenersImpl(target, listenersArray);
- v8::Local<v8::Object> result = v8::Object::New();
+ v8::Local<v8::Object> result = v8::Object::New(info.GetIsolate());
for (size_t i = 0; i < listenersArray.size(); ++i) {
- v8::Handle<v8::Array> listeners = getJSListenerFunctions(&node->document(), listenersArray[i], info.GetIsolate());
+ v8::Handle<v8::Array> listeners = getJSListenerFunctions(target->executionContext(), listenersArray[i], info.GetIsolate());
if (!listeners->Length())
continue;
AtomicString eventType = listenersArray[i].eventType;
@@ -307,34 +309,10 @@ void V8InjectedScriptHost::inspectMethodCustom(const v8::FunctionCallbackInfo<v8
return;
InjectedScriptHost* host = V8InjectedScriptHost::toNative(info.Holder());
- ScriptValue object(info[0], info.GetIsolate());
- ScriptValue hints(info[1], info.GetIsolate());
- host->inspectImpl(object.toJSONValue(ScriptState::current()), hints.toJSONValue(ScriptState::current()));
-}
-
-void V8InjectedScriptHost::databaseIdMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& info)
-{
- if (info.Length() > 0 && V8Database::hasInstance(info[0], info.GetIsolate(), worldType(info.GetIsolate()))) {
- Database* database = V8Database::toNative(v8::Handle<v8::Object>::Cast(info[0]));
- if (database) {
- InjectedScriptHost* host = V8InjectedScriptHost::toNative(info.Holder()); {
- v8SetReturnValueStringOrUndefined(info, host->databaseIdImpl(database), info.GetIsolate());
- return;
- }
- }
- }
-}
-
-void V8InjectedScriptHost::storageIdMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& info)
-{
- if (info.Length() > 0 && V8Storage::hasInstance(info[0], info.GetIsolate(), worldType(info.GetIsolate()))) {
- Storage* storage = V8Storage::toNative(v8::Handle<v8::Object>::Cast(info[0]));
- if (storage) {
- InjectedScriptHost* host = V8InjectedScriptHost::toNative(info.Holder());
- v8SetReturnValueStringOrUndefined(info, host->storageIdImpl(storage), info.GetIsolate());
- return;
- }
- }
+ ScriptState* scriptState = ScriptState::current(info.GetIsolate());
+ ScriptValue object(scriptState, info[0]);
+ ScriptValue hints(scriptState, info[1]);
+ host->inspectImpl(object.toJSONValue(scriptState), hints.toJSONValue(scriptState));
}
void V8InjectedScriptHost::evaluateMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& info)
@@ -351,7 +329,7 @@ void V8InjectedScriptHost::evaluateMethodCustom(const v8::FunctionCallbackInfo<v
return;
}
- ASSERT(!isolate->GetCurrentContext().IsEmpty());
+ ASSERT(isolate->InContext());
v8::TryCatch tryCatch;
v8::Handle<v8::Value> result = V8ScriptRunner::compileAndRunInternalScript(expression, info.GetIsolate());
if (tryCatch.HasCaught()) {
@@ -445,4 +423,25 @@ void V8InjectedScriptHost::unmonitorFunctionMethodCustom(const v8::FunctionCallb
host->unmonitorFunction(scriptId, lineNumber, columnNumber);
}
+void V8InjectedScriptHost::suppressWarningsAndCallMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& info)
+{
+ if (info.Length() < 2 || !info[0]->IsObject() || !info[1]->IsFunction())
+ return;
+
+ InjectedScriptHost* host = V8InjectedScriptHost::toNative(info.Holder());
+ ScriptDebugServer& debugServer = host->scriptDebugServer();
+ debugServer.muteWarningsAndDeprecations();
+
+ v8::Handle<v8::Object> receiver = v8::Handle<v8::Object>::Cast(info[0]);
+ v8::Handle<v8::Function> function = v8::Handle<v8::Function>::Cast(info[1]);
+ size_t argc = info.Length() - 2;
+ OwnPtr<v8::Handle<v8::Value>[]> argv = adoptArrayPtr(new v8::Handle<v8::Value>[argc]);
+ for (size_t i = 0; i < argc; ++i)
+ argv[i] = info[i + 2];
+
+ v8::Local<v8::Value> result = function->Call(receiver, argc, argv.get());
+ debugServer.unmuteWarningsAndDeprecations();
+ v8SetReturnValue(info, result);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8InjectedScriptManager.cpp b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8InjectedScriptManager.cpp
index fbe5295d1af..fbeffc2fc2a 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8InjectedScriptManager.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8InjectedScriptManager.cpp
@@ -31,17 +31,17 @@
#include "config.h"
#include "core/inspector/InjectedScriptManager.h"
-#include "V8InjectedScriptHost.h"
-#include "V8Window.h"
+#include "bindings/core/v8/V8InjectedScriptHost.h"
+#include "bindings/core/v8/V8Window.h"
#include "bindings/v8/BindingSecurity.h"
#include "bindings/v8/ScopedPersistent.h"
#include "bindings/v8/ScriptDebugServer.h"
-#include "bindings/v8/ScriptObject.h"
+#include "bindings/v8/ScriptValue.h"
#include "bindings/v8/V8Binding.h"
#include "bindings/v8/V8ObjectConstructor.h"
#include "bindings/v8/V8ScriptRunner.h"
#include "core/inspector/InjectedScriptHost.h"
-#include "core/frame/DOMWindow.h"
+#include "core/frame/LocalDOMWindow.h"
#include "wtf/RefPtr.h"
namespace WebCore {
@@ -53,12 +53,12 @@ struct InjectedScriptManager::CallbackData {
static v8::Local<v8::Object> createInjectedScriptHostV8Wrapper(InjectedScriptHost* host, v8::Isolate* isolate)
{
- v8::Local<v8::Function> function = V8InjectedScriptHost::domTemplate(isolate, MainWorld)->GetFunction();
+ v8::Local<v8::Function> function = V8InjectedScriptHost::domTemplate(isolate)->GetFunction();
if (function.IsEmpty()) {
// Return if allocation failed.
return v8::Local<v8::Object>();
}
- v8::Local<v8::Object> instanceTemplate = V8ObjectConstructor::newInstance(function);
+ v8::Local<v8::Object> instanceTemplate = V8ObjectConstructor::newInstance(isolate, function);
if (instanceTemplate.IsEmpty()) {
// Avoid setting the wrapper if allocation failed.
return v8::Local<v8::Object>();
@@ -73,21 +73,18 @@ static v8::Local<v8::Object> createInjectedScriptHostV8Wrapper(InjectedScriptHos
return instanceTemplate;
}
-ScriptObject InjectedScriptManager::createInjectedScript(const String& scriptSource, ScriptState* inspectedScriptState, int id)
+ScriptValue InjectedScriptManager::createInjectedScript(const String& scriptSource, ScriptState* inspectedScriptState, int id)
{
v8::Isolate* isolate = inspectedScriptState->isolate();
- v8::HandleScope handleScope(isolate);
-
- v8::Local<v8::Context> inspectedContext = inspectedScriptState->context();
- v8::Context::Scope contextScope(inspectedContext);
+ ScriptState::Scope scope(inspectedScriptState);
// Call custom code to create InjectedScripHost wrapper specific for the context
// 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(m_injectedScriptHost.get(), inspectedContext->GetIsolate());
+ v8::Local<v8::Object> scriptHostWrapper = createInjectedScriptHostV8Wrapper(m_injectedScriptHost.get(), inspectedScriptState->isolate());
if (scriptHostWrapper.IsEmpty())
- return ScriptObject();
+ return ScriptValue();
// Inject javascript into the context. The compiled script is supposed to evaluate into
// a single anonymous function(it's anonymous to avoid cluttering the global object with
@@ -98,28 +95,24 @@ ScriptObject InjectedScriptManager::createInjectedScript(const String& scriptSou
ASSERT(!value.IsEmpty());
ASSERT(value->IsFunction());
- v8::Local<v8::Object> windowGlobal = inspectedContext->Global();
- v8::Handle<v8::Value> info[] = { scriptHostWrapper, windowGlobal, v8::Number::New(inspectedContext->GetIsolate(), id) };
- v8::Local<v8::Value> injectedScriptValue = V8ScriptRunner::callInternalFunction(v8::Local<v8::Function>::Cast(value), windowGlobal, WTF_ARRAY_LENGTH(info), info, inspectedContext->GetIsolate());
- return ScriptObject(inspectedScriptState, v8::Handle<v8::Object>::Cast(injectedScriptValue));
+ v8::Local<v8::Object> windowGlobal = inspectedScriptState->context()->Global();
+ v8::Handle<v8::Value> info[] = { scriptHostWrapper, windowGlobal, v8::Number::New(inspectedScriptState->isolate(), id) };
+ v8::Local<v8::Value> injectedScriptValue = V8ScriptRunner::callInternalFunction(v8::Local<v8::Function>::Cast(value), windowGlobal, WTF_ARRAY_LENGTH(info), info, inspectedScriptState->isolate());
+ return ScriptValue(inspectedScriptState, injectedScriptValue);
}
bool InjectedScriptManager::canAccessInspectedWindow(ScriptState* scriptState)
{
- v8::HandleScope handleScope(scriptState->isolate());
- v8::Local<v8::Context> context = scriptState->context();
- v8::Local<v8::Object> global = context->Global();
+ ScriptState::Scope scope(scriptState);
+ v8::Local<v8::Object> global = scriptState->context()->Global();
if (global.IsEmpty())
return false;
- v8::Handle<v8::Object> holder = global->FindInstanceInPrototypeChain(V8Window::domTemplate(context->GetIsolate(), MainWorld));
- if (holder.IsEmpty())
- holder = global->FindInstanceInPrototypeChain(V8Window::domTemplate(context->GetIsolate(), IsolatedWorld));
+ v8::Handle<v8::Object> holder = V8Window::findInstanceInPrototypeChain(global, scriptState->isolate());
if (holder.IsEmpty())
return false;
- Frame* frame = V8Window::toNative(holder)->frame();
+ LocalFrame* frame = V8Window::toNative(holder)->frame();
- v8::Context::Scope contextScope(context);
- return BindingSecurity::shouldAllowAccessToFrame(frame, DoNotReportSecurityError);
+ return BindingSecurity::shouldAllowAccessToFrame(scriptState->isolate(), frame, DoNotReportSecurityError);
}
void InjectedScriptManager::setWeakCallback(const v8::WeakCallbackData<v8::Object, InjectedScriptManager::CallbackData>& data)
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8InspectorFrontendHostCustom.cpp b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8InspectorFrontendHostCustom.cpp
index 6fef29ec312..439e9347ee3 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8InspectorFrontendHostCustom.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8InspectorFrontendHostCustom.cpp
@@ -29,9 +29,9 @@
*/
#include "config.h"
-#include "V8InspectorFrontendHost.h"
+#include "bindings/core/v8/V8InspectorFrontendHost.h"
-#include "V8MouseEvent.h"
+#include "bindings/core/v8/V8MouseEvent.h"
#include "bindings/v8/V8Binding.h"
#include "core/inspector/InspectorController.h"
#include "core/inspector/InspectorFrontendClient.h"
@@ -80,7 +80,7 @@ static bool populateContextMenuItems(v8::Local<v8::Array>& itemArray, ContextMen
v8::Local<v8::Array> subItemsArray = v8::Local<v8::Array>::Cast(subItems);
if (!populateContextMenuItems(subItemsArray, subMenu, isolate))
return false;
- V8TRYCATCH_FOR_V8STRINGRESOURCE_RETURN(V8StringResource<WithNullCheck>, labelString, label, false);
+ TOSTRING_DEFAULT(V8StringResource<WithNullCheck>, labelString, label, false);
ContextMenuItem item(SubmenuType,
ContextMenuItemCustomTagNoAction,
labelString,
@@ -88,7 +88,7 @@ static bool populateContextMenuItems(v8::Local<v8::Array>& itemArray, ContextMen
menu.appendItem(item);
} else {
ContextMenuAction typedId = static_cast<ContextMenuAction>(ContextMenuItemBaseCustomTag + id->ToInt32()->Value());
- V8TRYCATCH_FOR_V8STRINGRESOURCE_RETURN(V8StringResource<WithNullCheck>, labelString, label, false);
+ TOSTRING_DEFAULT(V8StringResource<WithNullCheck>, labelString, label, false);
ContextMenuItem menuItem((typeString == "checkbox" ? CheckableActionType : ActionType), typedId, labelString);
if (checked->IsBoolean())
menuItem.setChecked(checked->ToBoolean()->Value());
@@ -143,10 +143,5 @@ void V8InspectorFrontendHost::recordPanelShownMethodCustom(const v8::FunctionCal
histogramEnumeration("DevTools.PanelShown", info, 20);
}
-void V8InspectorFrontendHost::recordSettingChangedMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& info)
-{
- histogramEnumeration("DevTools.SettingChanged", info, 100);
-}
-
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8Int16ArrayCustom.h b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8Int16ArrayCustom.h
index 30f5f5864d4..58aab8bb3ae 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8Int16ArrayCustom.h
+++ b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8Int16ArrayCustom.h
@@ -59,10 +59,6 @@ public:
typedef V8TypedArray<Int16Array> V8Int16Array;
-template<>
-class WrapperTypeTraits<Int16Array> : public TypedArrayWrapperTraits<Int16Array> { };
-
-
inline v8::Handle<v8::Object> wrap(Int16Array* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
{
return V8TypedArray<Int16Array>::wrap(impl, creationContext, isolate);
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8Int32ArrayCustom.h b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8Int32ArrayCustom.h
index bbb4aafc94d..6c29dca3988 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8Int32ArrayCustom.h
+++ b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8Int32ArrayCustom.h
@@ -59,10 +59,6 @@ public:
typedef V8TypedArray<Int32Array> V8Int32Array;
-template<>
-class WrapperTypeTraits<Int32Array> : public TypedArrayWrapperTraits<Int32Array> { };
-
-
inline v8::Handle<v8::Object> wrap(Int32Array* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
{
return V8TypedArray<Int32Array>::wrap(impl, creationContext, isolate);
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8Int8ArrayCustom.h b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8Int8ArrayCustom.h
index 31a9e356ea4..e8783171357 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8Int8ArrayCustom.h
+++ b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8Int8ArrayCustom.h
@@ -59,10 +59,6 @@ public:
typedef V8TypedArray<Int8Array> V8Int8Array;
-template<>
-class WrapperTypeTraits<Int8Array> : public TypedArrayWrapperTraits<Int8Array> { };
-
-
inline v8::Handle<v8::Object> wrap(Int8Array* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
{
return V8TypedArray<Int8Array>::wrap(impl, creationContext, isolate);
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8JavaScriptCallFrameCustom.cpp b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8JavaScriptCallFrameCustom.cpp
index 0f1a60ad709..c379d9a50dc 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8JavaScriptCallFrameCustom.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8JavaScriptCallFrameCustom.cpp
@@ -29,7 +29,7 @@
*/
#include "config.h"
-#include "V8JavaScriptCallFrame.h"
+#include "bindings/core/v8/V8JavaScriptCallFrame.h"
#include "bindings/v8/V8Binding.h"
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8LocationCustom.cpp b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8LocationCustom.cpp
index a9009c9f335..58835d5f127 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8LocationCustom.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8LocationCustom.cpp
@@ -29,7 +29,7 @@
*/
#include "config.h"
-#include "V8Location.h"
+#include "bindings/core/v8/V8Location.h"
namespace WebCore {
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8MIDIOutputCustom.cpp b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8MIDIOutputCustom.cpp
deleted file mode 100644
index fa3b69afea6..00000000000
--- a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8MIDIOutputCustom.cpp
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2013 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 "V8MIDIOutput.h"
-
-#include "V8MIDIAccess.h"
-#include "bindings/v8/V8HiddenPropertyName.h"
-
-namespace WebCore {
-
-v8::Handle<v8::Object> wrap(MIDIOutput* output, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
-{
- ASSERT(output);
- ASSERT(!DOMDataStore::containsWrapper<V8MIDIOutput>(output, isolate));
-
- v8::Handle<v8::Object> wrapper = V8MIDIOutput::createWrapper(output, creationContext, isolate);
-
- if (output->midiAccess())
- V8HiddenPropertyName::setNamedHiddenReference(wrapper, "access", toV8(output->midiAccess(), creationContext, isolate));
-
- return wrapper;
-}
-
-} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8MessageChannelCustom.cpp b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8MessageChannelCustom.cpp
index 67ec60fbd92..d39c588710d 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8MessageChannelCustom.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8MessageChannelCustom.cpp
@@ -29,12 +29,11 @@
*/
#include "config.h"
-#include "V8MessageChannel.h"
+#include "bindings/core/v8/V8MessageChannel.h"
-#include "V8MessagePort.h"
+#include "bindings/core/v8/V8MessagePort.h"
#include "bindings/v8/V8Binding.h"
-#include "bindings/v8/V8HiddenPropertyName.h"
-#include "bindings/v8/V8Utilities.h"
+#include "bindings/v8/V8HiddenValue.h"
#include "core/dom/MessageChannel.h"
#include "core/workers/WorkerGlobalScope.h"
#include "wtf/RefPtr.h"
@@ -43,17 +42,17 @@ namespace WebCore {
void V8MessageChannel::constructorCustom(const v8::FunctionCallbackInfo<v8::Value>& info)
{
- ExecutionContext* context = getExecutionContext();
+ ExecutionContext* context = currentExecutionContext(info.GetIsolate());
- RefPtr<MessageChannel> obj = MessageChannel::create(context);
+ RefPtrWillBeRawPtr<MessageChannel> obj = MessageChannel::create(context);
v8::Local<v8::Object> wrapper = info.Holder();
// 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.
- V8HiddenPropertyName::setNamedHiddenReference(wrapper, "port1", toV8(obj->port1(), info.Holder(), info.GetIsolate()));
- V8HiddenPropertyName::setNamedHiddenReference(wrapper, "port2", toV8(obj->port2(), info.Holder(), info.GetIsolate()));
+ V8HiddenValue::setHiddenValue(info.GetIsolate(), wrapper, V8HiddenValue::port1(info.GetIsolate()), toV8(obj->port1(), info.Holder(), info.GetIsolate()));
+ V8HiddenValue::setHiddenValue(info.GetIsolate(), wrapper, V8HiddenValue::port2(info.GetIsolate()), toV8(obj->port2(), info.Holder(), info.GetIsolate()));
V8DOMWrapper::associateObjectWithWrapper<V8MessageChannel>(obj.release(), &wrapperTypeInfo, wrapper, info.GetIsolate(), WrapperConfiguration::Dependent);
info.GetReturnValue().Set(wrapper);
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8MessageEventCustom.cpp b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8MessageEventCustom.cpp
index 9060e643728..145af08fab3 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8MessageEventCustom.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8MessageEventCustom.cpp
@@ -29,19 +29,50 @@
*/
#include "config.h"
-#include "V8MessageEvent.h"
+#include "bindings/core/v8/V8MessageEvent.h"
-#include "V8Blob.h"
-#include "V8MessagePort.h"
-#include "V8Window.h"
+#include "bindings/core/v8/V8Blob.h"
+#include "bindings/core/v8/V8MessagePort.h"
+#include "bindings/core/v8/V8Window.h"
#include "bindings/v8/SerializedScriptValue.h"
#include "bindings/v8/V8Binding.h"
-#include "bindings/v8/V8HiddenPropertyName.h"
+#include "bindings/v8/V8HiddenValue.h"
#include "bindings/v8/custom/V8ArrayBufferCustom.h"
#include "core/events/MessageEvent.h"
namespace WebCore {
+// Ensures a wrapper is created for the data to return now so that V8 knows how
+// much memory is used via the wrapper. To keep the wrapper alive, it's set to
+// the wrapper of the MessageEvent as a hidden value.
+static void ensureWrapperCreatedAndAssociated(MessageEvent* eventImpl, v8::Handle<v8::Object> eventWrapper, v8::Isolate* isolate)
+{
+ switch (eventImpl->dataType()) {
+ case MessageEvent::DataTypeScriptValue:
+ case MessageEvent::DataTypeSerializedScriptValue:
+ break;
+ case MessageEvent::DataTypeString: {
+ String stringValue = eventImpl->dataAsString();
+ V8HiddenValue::setHiddenValue(isolate, eventWrapper, V8HiddenValue::stringData(isolate), v8String(isolate, stringValue));
+ break;
+ }
+ case MessageEvent::DataTypeBlob:
+ break;
+ case MessageEvent::DataTypeArrayBuffer:
+ V8HiddenValue::setHiddenValue(isolate, eventWrapper, V8HiddenValue::arrayBufferData(isolate), toV8(eventImpl->dataAsArrayBuffer(), eventWrapper, isolate));
+ break;
+ }
+}
+
+v8::Handle<v8::Object> wrap(MessageEvent* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
+{
+ ASSERT(impl);
+ ASSERT(!DOMDataStore::containsWrapper<V8MessageEvent>(impl, isolate));
+ v8::Handle<v8::Object> wrapper = V8MessageEvent::createWrapper(impl, creationContext, isolate);
+ ensureWrapperCreatedAndAssociated(impl, wrapper, isolate);
+ return wrapper;
+}
+
void V8MessageEvent::dataAttributeGetterCustom(const v8::PropertyCallbackInfo<v8::Value>& info)
{
MessageEvent* event = V8MessageEvent::toNative(info.Holder());
@@ -49,12 +80,12 @@ void V8MessageEvent::dataAttributeGetterCustom(const v8::PropertyCallbackInfo<v8
v8::Handle<v8::Value> result;
switch (event->dataType()) {
case MessageEvent::DataTypeScriptValue: {
- result = info.Holder()->GetHiddenValue(V8HiddenPropertyName::data(info.GetIsolate()));
+ result = V8HiddenValue::getHiddenValue(info.GetIsolate(), info.Holder(), V8HiddenValue::data(info.GetIsolate()));
if (result.IsEmpty()) {
if (!event->dataAsSerializedScriptValue()) {
// If we're in an isolated world and the event was created in the main world,
// we need to find the 'data' property on the main world wrapper and clone it.
- v8::Local<v8::Value> mainWorldData = getHiddenValueFromMainWorldWrapper(info.GetIsolate(), event, V8HiddenPropertyName::data(info.GetIsolate()));
+ v8::Local<v8::Value> mainWorldData = V8HiddenValue::getHiddenValueFromMainWorldWrapper(info.GetIsolate(), event, V8HiddenValue::data(info.GetIsolate()));
if (!mainWorldData.IsEmpty())
event->setSerializedData(SerializedScriptValue::createAndSwallowExceptions(mainWorldData, info.GetIsolate()));
}
@@ -76,8 +107,11 @@ void V8MessageEvent::dataAttributeGetterCustom(const v8::PropertyCallbackInfo<v8
break;
case MessageEvent::DataTypeString: {
- String stringValue = event->dataAsString();
- result = v8String(info.GetIsolate(), stringValue);
+ result = V8HiddenValue::getHiddenValue(info.GetIsolate(), info.Holder(), V8HiddenValue::stringData(info.GetIsolate()));
+ if (result.IsEmpty()) {
+ String stringValue = event->dataAsString();
+ result = v8String(info.GetIsolate(), stringValue);
+ }
break;
}
@@ -86,12 +120,14 @@ void V8MessageEvent::dataAttributeGetterCustom(const v8::PropertyCallbackInfo<v8
break;
case MessageEvent::DataTypeArrayBuffer:
- result = toV8(event->dataAsArrayBuffer(), info.Holder(), info.GetIsolate());
+ result = V8HiddenValue::getHiddenValue(info.GetIsolate(), info.Holder(), V8HiddenValue::arrayBufferData(info.GetIsolate()));
+ if (result.IsEmpty())
+ result = toV8(event->dataAsArrayBuffer(), info.Holder(), info.GetIsolate());
break;
}
// Overwrite the data attribute so it returns the cached result in future invocations.
- // This custom handler (dataAccessGetter) will not be called again.
+ // This custom getter handler will not be called again.
v8::PropertyAttribute dataAttr = static_cast<v8::PropertyAttribute>(v8::DontDelete | v8::ReadOnly);
info.Holder()->ForceSet(v8AtomicString(info.GetIsolate(), "data"), result, dataAttr);
v8SetReturnValue(info, result);
@@ -100,41 +136,29 @@ void V8MessageEvent::dataAttributeGetterCustom(const v8::PropertyCallbackInfo<v8
void V8MessageEvent::initMessageEventMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& info)
{
MessageEvent* event = V8MessageEvent::toNative(info.Holder());
- V8TRYCATCH_FOR_V8STRINGRESOURCE_VOID(V8StringResource<>, typeArg, info[0]);
- V8TRYCATCH_VOID(bool, canBubbleArg, info[1]->BooleanValue());
- V8TRYCATCH_VOID(bool, cancelableArg, info[2]->BooleanValue());
+ TOSTRING_VOID(V8StringResource<>, typeArg, info[0]);
+ TONATIVE_VOID(bool, canBubbleArg, info[1]->BooleanValue());
+ TONATIVE_VOID(bool, cancelableArg, info[2]->BooleanValue());
v8::Handle<v8::Value> dataArg = info[3];
- V8TRYCATCH_FOR_V8STRINGRESOURCE_VOID(V8StringResource<>, originArg, info[4]);
- V8TRYCATCH_FOR_V8STRINGRESOURCE_VOID(V8StringResource<>, lastEventIdArg, info[5]);
-
- DOMWindow* sourceArg = 0;
- if (info[6]->IsObject()) {
- v8::Handle<v8::Object> wrapper = v8::Handle<v8::Object>::Cast(info[6]);
- v8::Handle<v8::Object> window = wrapper->FindInstanceInPrototypeChain(V8Window::domTemplate(info.GetIsolate(), worldTypeInMainThread(info.GetIsolate())));
- if (!window.IsEmpty())
- sourceArg = V8Window::toNative(window);
- }
+ TOSTRING_VOID(V8StringResource<>, originArg, info[4]);
+ TOSTRING_VOID(V8StringResource<>, lastEventIdArg, info[5]);
+ LocalDOMWindow* sourceArg = toDOMWindow(info[6], info.GetIsolate());
OwnPtr<MessagePortArray> portArray;
-
const int portArrayIndex = 7;
if (!isUndefinedOrNull(info[portArrayIndex])) {
portArray = adoptPtr(new MessagePortArray);
- if (!getMessagePortArray(info[portArrayIndex], portArrayIndex + 1, *portArray, info.GetIsolate()))
+ bool success = false;
+ *portArray = toRefPtrNativeArray<MessagePort, V8MessagePort>(info[portArrayIndex], portArrayIndex + 1, info.GetIsolate(), &success);
+ if (!success)
return;
}
event->initMessageEvent(typeArg, canBubbleArg, cancelableArg, originArg, lastEventIdArg, sourceArg, portArray.release());
if (!dataArg.IsEmpty()) {
- info.Holder()->SetHiddenValue(V8HiddenPropertyName::data(info.GetIsolate()), dataArg);
- if (isolatedWorldForIsolate(info.GetIsolate()))
+ V8HiddenValue::setHiddenValue(info.GetIsolate(), info.Holder(), V8HiddenValue::data(info.GetIsolate()), dataArg);
+ if (DOMWrapperWorld::current(info.GetIsolate()).isIsolatedWorld())
event->setSerializedData(SerializedScriptValue::createAndSwallowExceptions(dataArg, info.GetIsolate()));
}
}
-void V8MessageEvent::webkitInitMessageEventMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& info)
-{
- initMessageEventMethodCustom(info);
-}
-
-
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8MessagePortCustom.cpp b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8MessagePortCustom.cpp
index f8eb9df2abd..d368989ba93 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8MessagePortCustom.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8MessagePortCustom.cpp
@@ -29,13 +29,12 @@
*/
#include "config.h"
-#include "V8MessagePort.h"
+#include "bindings/core/v8/V8MessagePort.h"
#include "bindings/v8/ExceptionMessages.h"
#include "bindings/v8/ExceptionState.h"
#include "bindings/v8/SerializedScriptValue.h"
#include "bindings/v8/V8Binding.h"
-#include "bindings/v8/V8Utilities.h"
#include "core/dom/MessagePort.h"
#include "wtf/ArrayBuffer.h"
@@ -48,19 +47,14 @@ void V8MessagePort::postMessageMethodCustom(const v8::FunctionCallbackInfo<v8::V
MessagePortArray portArray;
ArrayBufferArray arrayBufferArray;
if (info.Length() > 1) {
- bool notASequence = false;
const int transferablesArgIndex = 1;
- if (!extractTransferables(info[transferablesArgIndex], portArray, arrayBufferArray, notASequence, info.GetIsolate())) {
- if (notASequence) {
- exceptionState.throwTypeError(ExceptionMessages::notAnArrayTypeArgumentOrValue(transferablesArgIndex + 1));
- exceptionState.throwIfNeeded();
- }
+ if (!SerializedScriptValue::extractTransferables(info[transferablesArgIndex], transferablesArgIndex, portArray, arrayBufferArray, exceptionState, info.GetIsolate())) {
+ exceptionState.throwIfNeeded();
return;
}
}
- bool didThrow = false;
- RefPtr<SerializedScriptValue> message = SerializedScriptValue::create(info[0], &portArray, &arrayBufferArray, didThrow, info.GetIsolate());
- if (didThrow)
+ RefPtr<SerializedScriptValue> message = SerializedScriptValue::create(info[0], &portArray, &arrayBufferArray, exceptionState, info.GetIsolate());
+ if (exceptionState.throwIfNeeded())
return;
messagePort->postMessage(message.release(), &portArray, exceptionState);
exceptionState.throwIfNeeded();
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8MutationObserverCustom.cpp b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8MutationObserverCustom.cpp
index f19d3eb52ff..f2e62908d48 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8MutationObserverCustom.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8MutationObserverCustom.cpp
@@ -29,14 +29,14 @@
*/
#include "config.h"
-#include "V8MutationObserver.h"
+#include "bindings/core/v8/V8MutationObserver.h"
#include "bindings/v8/ExceptionMessages.h"
#include "bindings/v8/ExceptionState.h"
#include "bindings/v8/V8Binding.h"
#include "bindings/v8/V8DOMWrapper.h"
+#include "bindings/v8/V8GCController.h"
#include "bindings/v8/V8MutationCallback.h"
-#include "bindings/v8/V8Utilities.h"
#include "core/dom/MutationObserver.h"
namespace WebCore {
@@ -57,14 +57,23 @@ void V8MutationObserver::constructorCustom(const v8::FunctionCallbackInfo<v8::Va
return;
}
- ExecutionContext* context = getExecutionContext();
v8::Handle<v8::Object> wrapper = info.Holder();
- OwnPtr<MutationCallback> callback = V8MutationCallback::create(v8::Handle<v8::Function>::Cast(arg), context, wrapper, info.GetIsolate());
- RefPtr<MutationObserver> observer = MutationObserver::create(callback.release());
+ OwnPtr<MutationCallback> callback = V8MutationCallback::create(v8::Handle<v8::Function>::Cast(arg), wrapper, ScriptState::current(info.GetIsolate()));
+ RefPtrWillBeRawPtr<MutationObserver> observer = MutationObserver::create(callback.release());
V8DOMWrapper::associateObjectWithWrapper<V8MutationObserver>(observer.release(), &wrapperTypeInfo, wrapper, info.GetIsolate(), WrapperConfiguration::Dependent);
info.GetReturnValue().Set(wrapper);
}
+void V8MutationObserver::visitDOMWrapper(void* object, const v8::Persistent<v8::Object>& wrapper, v8::Isolate* isolate)
+{
+ MutationObserver* observer = static_cast<MutationObserver*>(object);
+ HashSet<Node*> observedNodes = observer->getObservedNodes();
+ for (HashSet<Node*>::iterator it = observedNodes.begin(); it != observedNodes.end(); ++it) {
+ v8::UniqueId id(reinterpret_cast<intptr_t>(V8GCController::opaqueRootForGC(*it, isolate)));
+ isolate->SetReferenceFromGroup(id, wrapper);
+ }
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8NodeCustom.cpp b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8NodeCustom.cpp
index 854eb42b1e3..159b31e303b 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8NodeCustom.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8NodeCustom.cpp
@@ -29,22 +29,21 @@
*/
#include "config.h"
-#include "V8Node.h"
-
-#include "V8Attr.h"
-#include "V8CDATASection.h"
-#include "V8Comment.h"
-#include "V8Document.h"
-#include "V8DocumentFragment.h"
-#include "V8DocumentType.h"
-#include "V8Element.h"
-#include "V8Entity.h"
-#include "V8HTMLElement.h"
-#include "V8Notation.h"
-#include "V8ProcessingInstruction.h"
-#include "V8SVGElement.h"
-#include "V8ShadowRoot.h"
-#include "V8Text.h"
+#include "bindings/core/v8/V8Node.h"
+
+#include "bindings/core/v8/V8Attr.h"
+#include "bindings/core/v8/V8CDATASection.h"
+#include "bindings/core/v8/V8Comment.h"
+#include "bindings/core/v8/V8Document.h"
+#include "bindings/core/v8/V8DocumentFragment.h"
+#include "bindings/core/v8/V8DocumentType.h"
+#include "bindings/core/v8/V8Element.h"
+#include "bindings/core/v8/V8HTMLElement.h"
+#include "bindings/core/v8/V8Notation.h"
+#include "bindings/core/v8/V8ProcessingInstruction.h"
+#include "bindings/core/v8/V8SVGElement.h"
+#include "bindings/core/v8/V8ShadowRoot.h"
+#include "bindings/core/v8/V8Text.h"
#include "bindings/v8/ExceptionState.h"
#include "bindings/v8/V8AbstractEventListener.h"
#include "bindings/v8/V8Binding.h"
@@ -62,14 +61,14 @@ namespace WebCore {
void V8Node::insertBeforeMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& info)
{
v8::Handle<v8::Object> holder = info.Holder();
- Node* imp = V8Node::toNative(holder);
+ Node* impl = V8Node::toNative(holder);
CustomElementCallbackDispatcher::CallbackDeliveryScope deliveryScope;
ExceptionState exceptionState(ExceptionState::ExecutionContext, "insertBefore", "Node", info.Holder(), info.GetIsolate());
- Node* newChild = V8Node::hasInstance(info[0], info.GetIsolate(), worldType(info.GetIsolate())) ? V8Node::toNative(v8::Handle<v8::Object>::Cast(info[0])) : 0;
- Node* refChild = V8Node::hasInstance(info[1], info.GetIsolate(), worldType(info.GetIsolate())) ? V8Node::toNative(v8::Handle<v8::Object>::Cast(info[1])) : 0;
- imp->insertBefore(newChild, refChild, exceptionState);
+ Node* newChild = V8Node::toNativeWithTypeCheck(info.GetIsolate(), info[0]);
+ Node* refChild = V8Node::toNativeWithTypeCheck(info.GetIsolate(), info[1]);
+ impl->insertBefore(newChild, refChild, exceptionState);
if (exceptionState.throwIfNeeded())
return;
v8SetReturnValue(info, info[0]);
@@ -78,14 +77,14 @@ void V8Node::insertBeforeMethodCustom(const v8::FunctionCallbackInfo<v8::Value>&
void V8Node::replaceChildMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& info)
{
v8::Handle<v8::Object> holder = info.Holder();
- Node* imp = V8Node::toNative(holder);
+ Node* impl = V8Node::toNative(holder);
CustomElementCallbackDispatcher::CallbackDeliveryScope deliveryScope;
ExceptionState exceptionState(ExceptionState::ExecutionContext, "replaceChild", "Node", info.Holder(), info.GetIsolate());
- Node* newChild = V8Node::hasInstance(info[0], info.GetIsolate(), worldType(info.GetIsolate())) ? V8Node::toNative(v8::Handle<v8::Object>::Cast(info[0])) : 0;
- Node* oldChild = V8Node::hasInstance(info[1], info.GetIsolate(), worldType(info.GetIsolate())) ? V8Node::toNative(v8::Handle<v8::Object>::Cast(info[1])) : 0;
- imp->replaceChild(newChild, oldChild, exceptionState);
+ Node* newChild = V8Node::toNativeWithTypeCheck(info.GetIsolate(), info[0]);
+ Node* oldChild = V8Node::toNativeWithTypeCheck(info.GetIsolate(), info[1]);
+ impl->replaceChild(newChild, oldChild, exceptionState);
if (exceptionState.throwIfNeeded())
return;
v8SetReturnValue(info, info[1]);
@@ -94,13 +93,13 @@ void V8Node::replaceChildMethodCustom(const v8::FunctionCallbackInfo<v8::Value>&
void V8Node::removeChildMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& info)
{
v8::Handle<v8::Object> holder = info.Holder();
- Node* imp = V8Node::toNative(holder);
+ Node* impl = V8Node::toNative(holder);
CustomElementCallbackDispatcher::CallbackDeliveryScope deliveryScope;
ExceptionState exceptionState(ExceptionState::ExecutionContext, "removeChild", "Node", info.Holder(), info.GetIsolate());
- Node* oldChild = V8Node::hasInstance(info[0], info.GetIsolate(), worldType(info.GetIsolate())) ? V8Node::toNative(v8::Handle<v8::Object>::Cast(info[0])) : 0;
- imp->removeChild(oldChild, exceptionState);
+ Node* oldChild = V8Node::toNativeWithTypeCheck(info.GetIsolate(), info[0]);
+ impl->removeChild(oldChild, exceptionState);
if (exceptionState.throwIfNeeded())
return;
v8SetReturnValue(info, info[0]);
@@ -109,13 +108,13 @@ void V8Node::removeChildMethodCustom(const v8::FunctionCallbackInfo<v8::Value>&
void V8Node::appendChildMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& info)
{
v8::Handle<v8::Object> holder = info.Holder();
- Node* imp = V8Node::toNative(holder);
+ Node* impl = V8Node::toNative(holder);
CustomElementCallbackDispatcher::CallbackDeliveryScope deliveryScope;
ExceptionState exceptionState(ExceptionState::ExecutionContext, "appendChild", "Node", info.Holder(), info.GetIsolate());
- Node* newChild = V8Node::hasInstance(info[0], info.GetIsolate(), worldType(info.GetIsolate())) ? V8Node::toNative(v8::Handle<v8::Object>::Cast(info[0])) : 0;
- imp->appendChild(newChild, exceptionState);
+ Node* newChild = V8Node::toNativeWithTypeCheck(info.GetIsolate(), info[0]);
+ impl->appendChild(newChild, exceptionState);
if (exceptionState.throwIfNeeded())
return;
v8SetReturnValue(info, info[0]);
@@ -150,14 +149,8 @@ v8::Handle<v8::Object> wrap(Node* impl, v8::Handle<v8::Object> creationContext,
if (impl->isShadowRoot())
return wrap(toShadowRoot(impl), creationContext, isolate);
return wrap(toDocumentFragment(impl), creationContext, isolate);
- case Node::ENTITY_NODE:
- case Node::NOTATION_NODE:
- // We never create objects of Entity and Notation.
- ASSERT_NOT_REACHED();
- break;
- default:
- break; // ENTITY_REFERENCE_NODE or XPATH_NAMESPACE_NODE
}
+ ASSERT_NOT_REACHED();
return V8Node::createWrapper(impl, creationContext, isolate);
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8OscillatorNodeCustom.cpp b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8OscillatorNodeCustom.cpp
deleted file mode 100644
index 7216a8ec56b..00000000000
--- a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8OscillatorNodeCustom.cpp
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2012, Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. 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"
-#if ENABLE(WEB_AUDIO)
-#include "V8OscillatorNode.h"
-
-#include "bindings/v8/V8Binding.h"
-#include "modules/webaudio/OscillatorNode.h"
-
-namespace WebCore {
-
-void V8OscillatorNode::typeAttributeSetterCustom(v8::Local<v8::Value> value, const v8::PropertyCallbackInfo<void>& info)
-{
- v8::Handle<v8::Object> holder = info.Holder();
- OscillatorNode* imp = V8OscillatorNode::toNative(holder);
-
- if (value->IsNumber()) {
- bool ok = false;
- uint32_t type = toUInt32(value, ok);
- if (!ok || !imp->setType(type))
- throwTypeError("Illegal OscillatorNode type", info.GetIsolate());
- return;
- }
-
- if (value->IsString()) {
- String type = toCoreString(value.As<v8::String>());
- if (type == "sine" || type == "square" || type == "sawtooth" || type == "triangle") {
- imp->setType(type);
- return;
- }
- }
-
- throwTypeError("Illegal OscillatorNode type", info.GetIsolate());
-}
-
-} // namespace WebCore
-
-#endif // ENABLE(WEB_AUDIO)
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8PannerNodeCustom.cpp b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8PannerNodeCustom.cpp
deleted file mode 100644
index 5e10fda34cf..00000000000
--- a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8PannerNodeCustom.cpp
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Copyright (C) 2012, Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. 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"
-#if ENABLE(WEB_AUDIO)
-#include "V8PannerNode.h"
-
-#include "bindings/v8/V8Binding.h"
-#include "modules/webaudio/PannerNode.h"
-
-namespace WebCore {
-
-void V8PannerNode::panningModelAttributeSetterCustom(v8::Local<v8::Value> value, const v8::PropertyCallbackInfo<void>& info)
-{
- PannerNode* imp = V8PannerNode::toNative(info.Holder());
-
- if (value->IsNumber()) {
- bool ok = false;
- uint32_t model = toUInt32(value, ok);
- ASSERT(ok);
- if (!imp->setPanningModel(model))
- throwTypeError("Illegal panningModel", info.GetIsolate());
- return;
- }
-
- if (value->IsString()) {
- String model = toCoreString(value.As<v8::String>());
- if (model == "equalpower" || model == "HRTF" || model == "soundfield") {
- imp->setPanningModel(model);
- return;
- }
- }
-
- throwTypeError("Illegal panningModel", info.GetIsolate());
-}
-
-void V8PannerNode::distanceModelAttributeSetterCustom(v8::Local<v8::Value> value, const v8::PropertyCallbackInfo<void>& info)
-{
- PannerNode* imp = V8PannerNode::toNative(info.Holder());
-
- if (value->IsNumber()) {
- bool ok = false;
- uint32_t model = toUInt32(value, ok);
- ASSERT(ok);
- if (!imp->setDistanceModel(model))
- throwTypeError("Illegal distanceModel", info.GetIsolate());
- return;
- }
-
- if (value->IsString()) {
- String model = toCoreString(value.As<v8::String>());
- if (model == "linear" || model == "inverse" || model == "exponential") {
- imp->setDistanceModel(model);
- return;
- }
- }
-
- throwTypeError("Illegal distanceModel", info.GetIsolate());
-}
-
-} // namespace WebCore
-
-#endif // ENABLE(WEB_AUDIO)
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8PerformanceEntryCustom.cpp b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8PerformanceEntryCustom.cpp
index 15197329bae..6e1d54e0b68 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8PerformanceEntryCustom.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8PerformanceEntryCustom.cpp
@@ -29,11 +29,11 @@
*/
#include "config.h"
-#include "V8PerformanceEntry.h"
+#include "bindings/core/v8/V8PerformanceEntry.h"
-#include "V8PerformanceMark.h"
-#include "V8PerformanceMeasure.h"
-#include "V8PerformanceResourceTiming.h"
+#include "bindings/core/v8/V8PerformanceMark.h"
+#include "bindings/core/v8/V8PerformanceMeasure.h"
+#include "bindings/core/v8/V8PerformanceResourceTiming.h"
#include "core/timing/Performance.h"
#include "core/timing/PerformanceMark.h"
#include "core/timing/PerformanceMeasure.h"
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8PopStateEventCustom.cpp b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8PopStateEventCustom.cpp
index 8a7b790822c..83385ca297f 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8PopStateEventCustom.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8PopStateEventCustom.cpp
@@ -29,11 +29,11 @@
*/
#include "config.h"
-#include "V8PopStateEvent.h"
+#include "bindings/core/v8/V8PopStateEvent.h"
-#include "V8History.h"
+#include "bindings/core/v8/V8History.h"
#include "bindings/v8/SerializedScriptValue.h"
-#include "bindings/v8/V8HiddenPropertyName.h"
+#include "bindings/v8/V8HiddenValue.h"
#include "core/events/PopStateEvent.h"
#include "core/frame/History.h"
@@ -42,13 +42,13 @@ namespace WebCore {
// Save the state value to a hidden attribute in the V8PopStateEvent, and return it, for convenience.
static v8::Handle<v8::Value> cacheState(v8::Handle<v8::Object> popStateEvent, v8::Handle<v8::Value> state, v8::Isolate* isolate)
{
- popStateEvent->SetHiddenValue(V8HiddenPropertyName::state(isolate), state);
+ V8HiddenValue::setHiddenValue(isolate, popStateEvent, V8HiddenValue::state(isolate), state);
return state;
}
void V8PopStateEvent::stateAttributeGetterCustom(const v8::PropertyCallbackInfo<v8::Value>& info)
{
- v8::Handle<v8::Value> result = info.Holder()->GetHiddenValue(V8HiddenPropertyName::state(info.GetIsolate()));
+ v8::Handle<v8::Value> result = V8HiddenValue::getHiddenValue(info.GetIsolate(), info.Holder(), V8HiddenValue::state(info.GetIsolate()));
if (!result.IsEmpty()) {
v8SetReturnValue(info, result);
@@ -61,7 +61,7 @@ void V8PopStateEvent::stateAttributeGetterCustom(const v8::PropertyCallbackInfo<
if (!event->serializedState()) {
// If we're in an isolated world and the event was created in the main world,
// we need to find the 'state' property on the main world wrapper and clone it.
- v8::Local<v8::Value> mainWorldState = getHiddenValueFromMainWorldWrapper(info.GetIsolate(), event, V8HiddenPropertyName::state(info.GetIsolate()));
+ v8::Local<v8::Value> mainWorldState = V8HiddenValue::getHiddenValueFromMainWorldWrapper(info.GetIsolate(), event, V8HiddenValue::state(info.GetIsolate()));
if (!mainWorldState.IsEmpty())
event->setSerializedState(SerializedScriptValue::createAndSwallowExceptions(mainWorldState, info.GetIsolate()));
}
@@ -84,14 +84,14 @@ void V8PopStateEvent::stateAttributeGetterCustom(const v8::PropertyCallbackInfo<
if (isSameState) {
v8::Handle<v8::Object> v8History = toV8(history, info.Holder(), info.GetIsolate()).As<v8::Object>();
if (!history->stateChanged()) {
- result = v8History->GetHiddenValue(V8HiddenPropertyName::state(info.GetIsolate()));
+ result = V8HiddenValue::getHiddenValue(info.GetIsolate(), v8History, V8HiddenValue::state(info.GetIsolate()));
if (!result.IsEmpty()) {
v8SetReturnValue(info, cacheState(info.Holder(), result, info.GetIsolate()));
return;
}
}
result = event->serializedState()->deserialize(info.GetIsolate());
- v8History->SetHiddenValue(V8HiddenPropertyName::state(info.GetIsolate()), result);
+ V8HiddenValue::setHiddenValue(info.GetIsolate(), v8History, V8HiddenValue::state(info.GetIsolate()), result);
} else {
result = event->serializedState()->deserialize(info.GetIsolate());
}
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8PromiseCustom.cpp b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8PromiseCustom.cpp
deleted file mode 100644
index 22580d70da8..00000000000
--- a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8PromiseCustom.cpp
+++ /dev/null
@@ -1,794 +0,0 @@
-/*
- * Copyright (C) 2013 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 "bindings/v8/custom/V8PromiseCustom.h"
-
-#include <v8.h>
-#include "V8Promise.h"
-#include "bindings/v8/DOMRequestState.h"
-#include "bindings/v8/ScopedPersistent.h"
-#include "bindings/v8/ScriptFunctionCall.h"
-#include "bindings/v8/ScriptState.h"
-#include "bindings/v8/V8Binding.h"
-#include "bindings/v8/V8HiddenPropertyName.h"
-#include "bindings/v8/V8PerIsolateData.h"
-#include "bindings/v8/V8ScriptRunner.h"
-#include "bindings/v8/WrapperTypeInfo.h"
-#include "core/dom/Document.h"
-#include "core/dom/ExecutionContextTask.h"
-#include "core/frame/DOMWindow.h"
-#include "core/workers/WorkerGlobalScope.h"
-#include "platform/Task.h"
-#include "wtf/Deque.h"
-#include "wtf/Functional.h"
-#include "wtf/Noncopyable.h"
-#include "wtf/PassOwnPtr.h"
-
-namespace WebCore {
-
-namespace {
-
-v8::Local<v8::ObjectTemplate> cachedObjectTemplate(void* privateTemplateUniqueKey, int internalFieldCount, v8::Isolate* isolate)
-{
- V8PerIsolateData* data = V8PerIsolateData::from(isolate);
- WrapperWorldType currentWorldType = worldType(isolate);
- v8::Handle<v8::FunctionTemplate> functionDescriptor = data->privateTemplateIfExists(currentWorldType, privateTemplateUniqueKey);
- if (!functionDescriptor.IsEmpty())
- return functionDescriptor->InstanceTemplate();
-
- functionDescriptor = v8::FunctionTemplate::New(isolate);
- v8::Local<v8::ObjectTemplate> instanceTemplate = functionDescriptor->InstanceTemplate();
- instanceTemplate->SetInternalFieldCount(internalFieldCount);
- data->setPrivateTemplate(currentWorldType, privateTemplateUniqueKey, functionDescriptor);
- return instanceTemplate;
-}
-
-v8::Local<v8::ObjectTemplate> promiseAllEnvironmentObjectTemplate(v8::Isolate* isolate)
-{
- // This is only for getting a unique pointer which we can pass to privateTemplate.
- static int privateTemplateUniqueKey;
- return cachedObjectTemplate(&privateTemplateUniqueKey, V8PromiseCustom::PromiseAllEnvironmentFieldCount, isolate);
-}
-
-v8::Local<v8::ObjectTemplate> primitiveWrapperObjectTemplate(v8::Isolate* isolate)
-{
- // This is only for getting a unique pointer which we can pass to privateTemplate.
- static int privateTemplateUniqueKey;
- return cachedObjectTemplate(&privateTemplateUniqueKey, V8PromiseCustom::PrimitiveWrapperFieldCount, isolate);
-}
-
-v8::Local<v8::ObjectTemplate> internalObjectTemplate(v8::Isolate* isolate)
-{
- // This is only for getting a unique pointer which we can pass to privateTemplate.
- static int privateTemplateUniqueKey;
- return cachedObjectTemplate(&privateTemplateUniqueKey, V8PromiseCustom::InternalFieldCount, isolate);
-}
-
-void promiseResolveCallback(const v8::FunctionCallbackInfo<v8::Value>& info)
-{
- ASSERT(!info.Data().IsEmpty());
- v8::Local<v8::Object> promise = info.Data().As<v8::Object>();
- v8::Local<v8::Value> result = v8::Undefined(info.GetIsolate());
- if (info.Length() > 0)
- result = info[0];
-
- V8PromiseCustom::resolve(promise, result, info.GetIsolate());
-}
-
-void promiseRejectCallback(const v8::FunctionCallbackInfo<v8::Value>& info)
-{
- ASSERT(!info.Data().IsEmpty());
- v8::Local<v8::Object> promise = info.Data().As<v8::Object>();
- v8::Local<v8::Value> result = v8::Undefined(info.GetIsolate());
- if (info.Length() > 0)
- result = info[0];
-
- V8PromiseCustom::reject(promise, result, info.GetIsolate());
-}
-
-void promiseAllFulfillCallback(const v8::FunctionCallbackInfo<v8::Value>& info)
-{
- v8::Isolate* isolate = info.GetIsolate();
- ASSERT(!info.Data().IsEmpty());
- v8::Local<v8::Object> environment = info.Data().As<v8::Object>();
- v8::Local<v8::Value> result = v8::Undefined(isolate);
- if (info.Length() > 0)
- result = info[0];
-
- v8::Local<v8::Object> promise = environment->GetInternalField(V8PromiseCustom::PromiseAllEnvironmentPromiseIndex).As<v8::Object>();
- v8::Local<v8::Object> countdownWrapper = environment->GetInternalField(V8PromiseCustom::PromiseAllEnvironmentCountdownIndex).As<v8::Object>();
- v8::Local<v8::Integer> index = environment->GetInternalField(V8PromiseCustom::PromiseAllEnvironmentIndexIndex).As<v8::Integer>();
- v8::Local<v8::Array> results = environment->GetInternalField(V8PromiseCustom::PromiseAllEnvironmentResultsIndex).As<v8::Array>();
-
- results->Set(index->Value(), result);
-
- v8::Local<v8::Integer> countdown = countdownWrapper->GetInternalField(V8PromiseCustom::PrimitiveWrapperPrimitiveIndex).As<v8::Integer>();
- ASSERT(countdown->Value() >= 1);
- if (countdown->Value() == 1) {
- V8PromiseCustom::resolve(promise, results, isolate);
- return;
- }
- countdownWrapper->SetInternalField(V8PromiseCustom::PrimitiveWrapperPrimitiveIndex, v8::Integer::New(countdown->Value() - 1, isolate));
-}
-
-v8::Local<v8::Object> promiseAllEnvironment(v8::Handle<v8::Object> promise, v8::Handle<v8::Object> countdownWrapper, int index, v8::Handle<v8::Array> results, v8::Isolate* isolate)
-{
- v8::Local<v8::ObjectTemplate> objectTemplate = promiseAllEnvironmentObjectTemplate(isolate);
- v8::Local<v8::Object> environment = objectTemplate->NewInstance();
-
- environment->SetInternalField(V8PromiseCustom::PromiseAllEnvironmentPromiseIndex, promise);
- environment->SetInternalField(V8PromiseCustom::PromiseAllEnvironmentCountdownIndex, countdownWrapper);
- environment->SetInternalField(V8PromiseCustom::PromiseAllEnvironmentIndexIndex, v8::Integer::New(index, isolate));
- environment->SetInternalField(V8PromiseCustom::PromiseAllEnvironmentResultsIndex, results);
- return environment;
-}
-
-// Clear |internal|'s derived array.
-void clearDerived(v8::Handle<v8::Object> internal, v8::Isolate* isolate)
-{
- internal->SetInternalField(V8PromiseCustom::InternalFulfillCallbackIndex, v8::Array::New(isolate));
- internal->SetInternalField(V8PromiseCustom::InternalRejectCallbackIndex, v8::Array::New(isolate));
- internal->SetInternalField(V8PromiseCustom::InternalDerivedPromiseIndex, v8::Array::New(isolate));
-}
-
-// Add a tuple (|derivedPromise|, |onFulfilled|, |onRejected|) to
-// |internal|'s derived array.
-// |internal| must be a Promise internal object.
-// |derivedPromise| must be a Promise instance.
-// |onFulfilled| and |onRejected| can be an empty value respectively.
-void addToDerived(v8::Handle<v8::Object> internal, v8::Handle<v8::Object> derivedPromise, v8::Handle<v8::Function> onFulfilled, v8::Handle<v8::Function> onRejected, v8::Isolate* isolate)
-{
- v8::Local<v8::Array> fulfillCallbacks = internal->GetInternalField(V8PromiseCustom::InternalFulfillCallbackIndex).As<v8::Array>();
- v8::Local<v8::Array> rejectCallbacks = internal->GetInternalField(V8PromiseCustom::InternalRejectCallbackIndex).As<v8::Array>();
- v8::Local<v8::Array> derivedPromises = internal->GetInternalField(V8PromiseCustom::InternalDerivedPromiseIndex).As<v8::Array>();
-
- if (onFulfilled.IsEmpty()) {
- fulfillCallbacks->Set(fulfillCallbacks->Length(), v8::Undefined(isolate));
- } else {
- fulfillCallbacks->Set(fulfillCallbacks->Length(), onFulfilled);
- }
-
- if (onRejected.IsEmpty()) {
- rejectCallbacks->Set(rejectCallbacks->Length(), v8::Undefined(isolate));
- } else {
- rejectCallbacks->Set(rejectCallbacks->Length(), onRejected);
- }
-
- ASSERT(!derivedPromise.IsEmpty());
- derivedPromises->Set(derivedPromises->Length(), derivedPromise);
-
- // Since they are treated as a tuple,
- // we need to guaranteed that the length of these arrays are same.
- ASSERT(fulfillCallbacks->Length() == rejectCallbacks->Length() && rejectCallbacks->Length() == derivedPromises->Length());
-}
-
-class CallHandlerTask : public ExecutionContextTask {
-public:
- CallHandlerTask(v8::Handle<v8::Object> promise, v8::Handle<v8::Function> handler, v8::Handle<v8::Value> argument, v8::Isolate* isolate, ExecutionContext* context)
- : m_promise(isolate, promise)
- , m_handler(isolate, handler)
- , m_argument(isolate, argument)
- , m_requestState(context)
- {
- ASSERT(!m_promise.isEmpty());
- ASSERT(!m_handler.isEmpty());
- ASSERT(!m_argument.isEmpty());
- }
- virtual ~CallHandlerTask() { }
-
- virtual void performTask(ExecutionContext*) OVERRIDE;
-
-private:
- ScopedPersistent<v8::Object> m_promise;
- ScopedPersistent<v8::Function> m_handler;
- ScopedPersistent<v8::Value> m_argument;
- DOMRequestState m_requestState;
-};
-
-void CallHandlerTask::performTask(ExecutionContext* context)
-{
- ASSERT(context);
- if (context->activeDOMObjectsAreStopped())
- return;
-
- DOMRequestState::Scope scope(m_requestState);
- v8::Isolate* isolate = m_requestState.isolate();
- v8::Handle<v8::Value> info[] = { m_argument.newLocal(isolate) };
- v8::TryCatch trycatch;
- v8::Local<v8::Value> value = V8ScriptRunner::callFunction(m_handler.newLocal(isolate), context, v8::Undefined(isolate), WTF_ARRAY_LENGTH(info), info, isolate);
- if (value.IsEmpty()) {
- V8PromiseCustom::reject(m_promise.newLocal(isolate), trycatch.Exception(), isolate);
- } else {
- V8PromiseCustom::resolve(m_promise.newLocal(isolate), value, isolate);
- }
-}
-
-class UpdateDerivedTask : public ExecutionContextTask {
-public:
- UpdateDerivedTask(v8::Handle<v8::Object> promise, v8::Handle<v8::Function> onFulfilled, v8::Handle<v8::Function> onRejected, v8::Handle<v8::Object> originatorValueObject, v8::Isolate* isolate, ExecutionContext* context)
- : m_promise(isolate, promise)
- , m_onFulfilled(isolate, onFulfilled)
- , m_onRejected(isolate, onRejected)
- , m_originatorValueObject(isolate, originatorValueObject)
- , m_requestState(context)
- {
- ASSERT(!m_promise.isEmpty());
- ASSERT(!m_originatorValueObject.isEmpty());
- }
- virtual ~UpdateDerivedTask() { }
-
- virtual void performTask(ExecutionContext*) OVERRIDE;
-
-private:
- ScopedPersistent<v8::Object> m_promise;
- ScopedPersistent<v8::Function> m_onFulfilled;
- ScopedPersistent<v8::Function> m_onRejected;
- ScopedPersistent<v8::Object> m_originatorValueObject;
- DOMRequestState m_requestState;
-};
-
-void UpdateDerivedTask::performTask(ExecutionContext* context)
-{
- ASSERT(context);
- if (context->activeDOMObjectsAreStopped())
- return;
-
- DOMRequestState::Scope scope(m_requestState);
- v8::Isolate* isolate = m_requestState.isolate();
- v8::Local<v8::Object> originatorValueObject = m_originatorValueObject.newLocal(isolate);
- v8::Local<v8::Value> coercedAlready = originatorValueObject->GetHiddenValue(V8HiddenPropertyName::thenableHiddenPromise(isolate));
- if (!coercedAlready.IsEmpty() && coercedAlready->IsObject()) {
- ASSERT(V8PromiseCustom::isPromise(coercedAlready.As<v8::Object>(), isolate));
- V8PromiseCustom::updateDerivedFromPromise(m_promise.newLocal(isolate), m_onFulfilled.newLocal(isolate), m_onRejected.newLocal(isolate), coercedAlready.As<v8::Object>(), isolate);
- return;
- }
-
- v8::Local<v8::Value> then;
- v8::TryCatch trycatch;
- then = originatorValueObject->Get(v8AtomicString(isolate, "then"));
- if (then.IsEmpty()) {
- // If calling the [[Get]] internal method threw an exception, catch it and run updateDerivedFromReason.
- V8PromiseCustom::updateDerivedFromReason(m_promise.newLocal(isolate), m_onRejected.newLocal(isolate), trycatch.Exception(), isolate);
- return;
- }
-
- if (then->IsFunction()) {
- ASSERT(then->IsObject());
- v8::Local<v8::Object> coerced = V8PromiseCustom::coerceThenable(originatorValueObject, then.As<v8::Function>(), isolate);
- V8PromiseCustom::updateDerivedFromPromise(m_promise.newLocal(isolate), m_onFulfilled.newLocal(isolate), m_onRejected.newLocal(isolate), coerced, isolate);
- return;
- }
-
- V8PromiseCustom::updateDerivedFromValue(m_promise.newLocal(isolate), m_onFulfilled.newLocal(isolate), originatorValueObject, isolate);
-}
-
-// Since Promises state propagation routines are executed recursively, they cause
-// stack overflow.
-// (e.g. UpdateDerived -> UpdateDerivedFromValue -> SetValue ->
-// PropagateToDerived -> UpdateDerived)
-//
-// To fix that, we introduce PromisePropagator. It holds the stack. When
-// propagating the result to the derived tuples, we append the derived tuples
-// to the stack. After that, we drain the stack to propagate the result to
-// the stored tuples.
-//
-// PromisePropagator should be held on the stack and should not be held
-// as other object's member. PromisePropagator holds Derived tuples. Since
-// Derived tuples hold persistent handles to JS objects, retaining
-// PromisePropagator in the heap causes memory leaks.
-//
-class PromisePropagator {
- WTF_MAKE_NONCOPYABLE(PromisePropagator);
-public:
- PromisePropagator() { }
-
- void performPropagation(v8::Isolate*);
-
- void setValue(v8::Handle<v8::Object> promise, v8::Handle<v8::Value>, v8::Isolate*);
- void setReason(v8::Handle<v8::Object> promise, v8::Handle<v8::Value>, v8::Isolate*);
- void propagateToDerived(v8::Handle<v8::Object> promise, v8::Isolate*);
- void updateDerived(v8::Handle<v8::Object> derivedPromise, v8::Handle<v8::Function> onFulfilled, v8::Handle<v8::Function> onRejected, v8::Handle<v8::Object> originator, v8::Isolate*);
- void updateDerivedFromValue(v8::Handle<v8::Object> derivedPromise, v8::Handle<v8::Function> onFulfilled, v8::Handle<v8::Value>, v8::Isolate*);
- void updateDerivedFromReason(v8::Handle<v8::Object> derivedPromise, v8::Handle<v8::Function> onRejected, v8::Handle<v8::Value>, v8::Isolate*);
- void updateDerivedFromPromise(v8::Handle<v8::Object> derivedPromise, v8::Handle<v8::Function> onFulfilled, v8::Handle<v8::Function> onRejected, v8::Handle<v8::Object> promise, v8::Isolate*);
-
-private:
- class Derived {
- WTF_MAKE_NONCOPYABLE(Derived);
- public:
- Derived(v8::Handle<v8::Object> promise, v8::Handle<v8::Function> onFulfilled, v8::Handle<v8::Function> onRejected, v8::Handle<v8::Object> originator, v8::Isolate* isolate)
- : m_promise(isolate, promise)
- , m_onFulfilled(isolate, onFulfilled)
- , m_onRejected(isolate, onRejected)
- , m_originator(isolate, originator)
- {
- ASSERT(!m_promise.isEmpty());
- ASSERT(!m_originator.isEmpty());
- }
-
- static PassOwnPtr<Derived> create(v8::Handle<v8::Object> promise, v8::Handle<v8::Function> onFulfilled, v8::Handle<v8::Function> onRejected, v8::Handle<v8::Object> originator, v8::Isolate* isolate)
- {
- return adoptPtr(new Derived(promise, onFulfilled, onRejected, originator, isolate));
- }
-
- v8::Local<v8::Object> promise(v8::Isolate* isolate) const { return m_promise.newLocal(isolate); }
- v8::Local<v8::Function> onFulfilled(v8::Isolate* isolate) const { return m_onFulfilled.newLocal(isolate); }
- v8::Local<v8::Function> onRejected(v8::Isolate* isolate) const { return m_onRejected.newLocal(isolate); }
- v8::Local<v8::Object> originator(v8::Isolate* isolate) const { return m_originator.newLocal(isolate); }
-
- private:
- ScopedPersistent<v8::Object> m_promise;
- ScopedPersistent<v8::Function> m_onFulfilled;
- ScopedPersistent<v8::Function> m_onRejected;
- ScopedPersistent<v8::Object> m_originator;
- };
-
- Deque<OwnPtr<Derived> > m_derivedStack;
-};
-
-void PromisePropagator::performPropagation(v8::Isolate* isolate)
-{
- while (!m_derivedStack.isEmpty()) {
- v8::HandleScope handleScope(isolate);
- OwnPtr<Derived> derived = m_derivedStack.takeLast();
- updateDerived(derived->promise(isolate), derived->onFulfilled(isolate), derived->onRejected(isolate), derived->originator(isolate), isolate);
- }
-}
-
-void PromisePropagator::setValue(v8::Handle<v8::Object> promise, v8::Handle<v8::Value> value, v8::Isolate* isolate)
-{
- v8::Local<v8::Object> internal = V8PromiseCustom::getInternal(promise);
- ASSERT(V8PromiseCustom::getState(internal) != V8PromiseCustom::Fulfilled && V8PromiseCustom::getState(internal) != V8PromiseCustom::Rejected);
- V8PromiseCustom::setState(internal, V8PromiseCustom::Fulfilled, value, isolate);
- propagateToDerived(promise, isolate);
-}
-
-void PromisePropagator::setReason(v8::Handle<v8::Object> promise, v8::Handle<v8::Value> reason, v8::Isolate* isolate)
-{
- v8::Local<v8::Object> internal = V8PromiseCustom::getInternal(promise);
- ASSERT(V8PromiseCustom::getState(internal) != V8PromiseCustom::Fulfilled && V8PromiseCustom::getState(internal) != V8PromiseCustom::Rejected);
- V8PromiseCustom::setState(internal, V8PromiseCustom::Rejected, reason, isolate);
- propagateToDerived(promise, isolate);
-}
-
-void PromisePropagator::propagateToDerived(v8::Handle<v8::Object> promise, v8::Isolate* isolate)
-{
- v8::Local<v8::Object> internal = V8PromiseCustom::getInternal(promise);
- ASSERT(V8PromiseCustom::getState(internal) == V8PromiseCustom::Fulfilled || V8PromiseCustom::getState(internal) == V8PromiseCustom::Rejected);
- v8::Local<v8::Array> fulfillCallbacks = internal->GetInternalField(V8PromiseCustom::InternalFulfillCallbackIndex).As<v8::Array>();
- v8::Local<v8::Array> rejectCallbacks = internal->GetInternalField(V8PromiseCustom::InternalRejectCallbackIndex).As<v8::Array>();
- v8::Local<v8::Array> derivedPromises = internal->GetInternalField(V8PromiseCustom::InternalDerivedPromiseIndex).As<v8::Array>();
- // Since they are treated as a tuple,
- // we need to guaranteed that the length of these arrays are same.
- ASSERT(fulfillCallbacks->Length() == rejectCallbacks->Length() && rejectCallbacks->Length() == derivedPromises->Length());
-
- // Append Derived tuple to the stack in reverse order.
- for (uint32_t count = 0, length = derivedPromises->Length(); count < length; ++count) {
- uint32_t i = length - count - 1;
- v8::Local<v8::Object> derivedPromise = derivedPromises->Get(i).As<v8::Object>();
-
- v8::Local<v8::Function> onFulfilled, onRejected;
- v8::Local<v8::Value> onFulfilledValue = fulfillCallbacks->Get(i);
- if (onFulfilledValue->IsFunction()) {
- onFulfilled = onFulfilledValue.As<v8::Function>();
- }
- v8::Local<v8::Value> onRejectedValue = rejectCallbacks->Get(i);
- if (onRejectedValue->IsFunction()) {
- onRejected = onRejectedValue.As<v8::Function>();
- }
-
- m_derivedStack.append(Derived::create(derivedPromise, onFulfilled, onRejected, promise, isolate));
- }
- clearDerived(internal, isolate);
-}
-
-void PromisePropagator::updateDerivedFromValue(v8::Handle<v8::Object> derivedPromise, v8::Handle<v8::Function> onFulfilled, v8::Handle<v8::Value> value, v8::Isolate* isolate)
-{
- if (!onFulfilled.IsEmpty()) {
- V8PromiseCustom::callHandler(derivedPromise, onFulfilled, value, isolate);
- } else {
- setValue(derivedPromise, value, isolate);
- }
-}
-
-void PromisePropagator::updateDerivedFromReason(v8::Handle<v8::Object> derivedPromise, v8::Handle<v8::Function> onRejected, v8::Handle<v8::Value> reason, v8::Isolate* isolate)
-{
- if (!onRejected.IsEmpty()) {
- V8PromiseCustom::callHandler(derivedPromise, onRejected, reason, isolate);
- } else {
- setReason(derivedPromise, reason, isolate);
- }
-}
-
-void PromisePropagator::updateDerived(v8::Handle<v8::Object> derivedPromise, v8::Handle<v8::Function> onFulfilled, v8::Handle<v8::Function> onRejected, v8::Handle<v8::Object> originator, v8::Isolate* isolate)
-{
- v8::Local<v8::Object> originatorInternal = V8PromiseCustom::getInternal(originator);
- V8PromiseCustom::PromiseState originatorState = V8PromiseCustom::getState(originatorInternal);
- ASSERT(originatorState == V8PromiseCustom::Fulfilled || originatorState == V8PromiseCustom::Rejected);
- v8::Local<v8::Value> originatorValue = originatorInternal->GetInternalField(V8PromiseCustom::InternalResultIndex);
- if (originatorState == V8PromiseCustom::Fulfilled) {
- if (originatorValue->IsObject()) {
- ExecutionContext* executionContext = getExecutionContext();
- ASSERT(executionContext && executionContext->isContextThread());
- executionContext->postTask(adoptPtr(new UpdateDerivedTask(derivedPromise, onFulfilled, onRejected, originatorValue.As<v8::Object>(), isolate, executionContext)));
- } else {
- updateDerivedFromValue(derivedPromise, onFulfilled, originatorValue, isolate);
- }
- } else {
- updateDerivedFromReason(derivedPromise, onRejected, originatorValue, isolate);
- }
-}
-
-void PromisePropagator::updateDerivedFromPromise(v8::Handle<v8::Object> derivedPromise, v8::Handle<v8::Function> onFulfilled, v8::Handle<v8::Function> onRejected, v8::Handle<v8::Object> promise, v8::Isolate* isolate)
-{
- v8::Local<v8::Object> internal = V8PromiseCustom::getInternal(promise);
- V8PromiseCustom::PromiseState state = V8PromiseCustom::getState(internal);
- if (state == V8PromiseCustom::Fulfilled || state == V8PromiseCustom::Rejected) {
- updateDerived(derivedPromise, onFulfilled, onRejected, promise, isolate);
- } else {
- addToDerived(internal, derivedPromise, onFulfilled, onRejected, isolate);
- }
-}
-
-} // namespace
-
-void V8Promise::constructorCustom(const v8::FunctionCallbackInfo<v8::Value>& info)
-{
- v8SetReturnValue(info, v8::Local<v8::Value>());
- v8::Isolate* isolate = info.GetIsolate();
- if (!info.Length() || !info[0]->IsFunction()) {
- throwTypeError("Promise constructor takes a function argument", isolate);
- return;
- }
- v8::Local<v8::Function> init = info[0].As<v8::Function>();
- v8::Local<v8::Object> promise = V8PromiseCustom::createPromise(info.Holder(), isolate);
- v8::Handle<v8::Value> argv[] = {
- createClosure(promiseResolveCallback, promise, isolate),
- createClosure(promiseRejectCallback, promise, isolate)
- };
- v8::TryCatch trycatch;
- if (V8ScriptRunner::callFunction(init, getExecutionContext(), v8::Undefined(isolate), WTF_ARRAY_LENGTH(argv), argv, isolate).IsEmpty()) {
- // An exception is thrown. Reject the promise if its resolved flag is unset.
- V8PromiseCustom::reject(promise, trycatch.Exception(), isolate);
- }
- v8SetReturnValue(info, promise);
- return;
-}
-
-void V8Promise::thenMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& info)
-{
- v8::Isolate* isolate = info.GetIsolate();
- v8::Local<v8::Function> onFulfilled, onRejected;
- if (info.Length() > 0 && info[0]->IsFunction())
- onFulfilled = info[0].As<v8::Function>();
- if (info.Length() > 1 && info[1]->IsFunction())
- onRejected = info[1].As<v8::Function>();
- v8SetReturnValue(info, V8PromiseCustom::then(info.Holder(), onFulfilled, onRejected, isolate));
-}
-
-void V8Promise::castMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& info)
-{
- v8::Isolate* isolate = info.GetIsolate();
- v8::Local<v8::Value> result = v8::Undefined(isolate);
- if (info.Length() > 0)
- result = info[0];
-
- v8SetReturnValue(info, V8PromiseCustom::toPromise(result, isolate));
-}
-
-void V8Promise::catchMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& info)
-{
- v8::Isolate* isolate = info.GetIsolate();
- v8::Local<v8::Function> onFulfilled, onRejected;
-
- if (info.Length() > 0 && !info[0]->IsUndefined()) {
- if (!info[0]->IsFunction()) {
- v8SetReturnValue(info, throwTypeError("onRejected must be a function or undefined", isolate));
- return;
- }
- onRejected = info[0].As<v8::Function>();
- }
- v8SetReturnValue(info, V8PromiseCustom::then(info.Holder(), onFulfilled, onRejected, isolate));
-}
-
-void V8Promise::resolveMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& info)
-{
- v8::Isolate* isolate = info.GetIsolate();
- v8::Local<v8::Value> result = v8::Undefined(isolate);
- if (info.Length() > 0)
- result = info[0];
-
- v8::Local<v8::Object> promise = V8PromiseCustom::createPromise(info.Holder(), isolate);
- V8PromiseCustom::resolve(promise, result, isolate);
- v8SetReturnValue(info, promise);
-}
-
-void V8Promise::rejectMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& info)
-{
- v8::Isolate* isolate = info.GetIsolate();
- v8::Local<v8::Value> result = v8::Undefined(isolate);
- if (info.Length() > 0)
- result = info[0];
-
- v8::Local<v8::Object> promise = V8PromiseCustom::createPromise(info.Holder(), isolate);
- V8PromiseCustom::reject(promise, result, isolate);
- v8SetReturnValue(info, promise);
-}
-
-void V8Promise::raceMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& info)
-{
- v8::Isolate* isolate = info.GetIsolate();
- v8::Local<v8::Object> promise = V8PromiseCustom::createPromise(info.Holder(), isolate);
-
- if (!info.Length() || !info[0]->IsArray()) {
- v8SetReturnValue(info, promise);
- return;
- }
-
- // FIXME: Now we limit the iterable type to the Array type.
- v8::Local<v8::Array> iterable = info[0].As<v8::Array>();
- v8::Local<v8::Function> onFulfilled = createClosure(promiseResolveCallback, promise, isolate);
- v8::Local<v8::Function> onRejected = createClosure(promiseRejectCallback, promise, isolate);
-
- for (unsigned i = 0, length = iterable->Length(); i < length; ++i) {
- // Array-holes should not be skipped by for-of iteration semantics.
- V8TRYCATCH_VOID(v8::Local<v8::Value>, nextValue, iterable->Get(i));
- v8::Local<v8::Object> nextPromise = V8PromiseCustom::toPromise(nextValue, isolate);
- V8PromiseCustom::then(nextPromise, onFulfilled, onRejected, isolate);
- }
- v8SetReturnValue(info, promise);
-}
-
-void V8Promise::allMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& info)
-{
- v8::Isolate* isolate = info.GetIsolate();
- v8::Local<v8::Object> promise = V8PromiseCustom::createPromise(info.Holder(), isolate);
- v8::Local<v8::Array> results = v8::Array::New(info.GetIsolate());
-
- if (!info.Length() || !info[0]->IsArray()) {
- V8PromiseCustom::resolve(promise, results, isolate);
- v8SetReturnValue(info, promise);
- return;
- }
-
- // FIXME: Now we limit the iterable type to the Array type.
- v8::Local<v8::Array> iterable = info[0].As<v8::Array>();
-
- if (!iterable->Length()) {
- V8PromiseCustom::resolve(promise, results, isolate);
- v8SetReturnValue(info, promise);
- return;
- }
-
- v8::Local<v8::ObjectTemplate> objectTemplate = primitiveWrapperObjectTemplate(isolate);
- v8::Local<v8::Object> countdownWrapper = objectTemplate->NewInstance();
- countdownWrapper->SetInternalField(V8PromiseCustom::PrimitiveWrapperPrimitiveIndex, v8::Integer::New(iterable->Length(), isolate));
-
- v8::Local<v8::Function> onRejected = createClosure(promiseRejectCallback, promise, isolate);
- for (unsigned i = 0, length = iterable->Length(); i < length; ++i) {
- // Array-holes should not be skipped by for-of iteration semantics.
- v8::Local<v8::Object> environment = promiseAllEnvironment(promise, countdownWrapper, i, results, isolate);
- v8::Local<v8::Function> onFulfilled = createClosure(promiseAllFulfillCallback, environment, isolate);
- V8TRYCATCH_VOID(v8::Local<v8::Value>, nextValue, iterable->Get(i));
- v8::Local<v8::Object> nextPromise = V8PromiseCustom::toPromise(nextValue, isolate);
- V8PromiseCustom::then(nextPromise, onFulfilled, onRejected, isolate);
- }
- v8SetReturnValue(info, promise);
-}
-
-//
-// -- V8PromiseCustom --
-v8::Local<v8::Object> V8PromiseCustom::createPromise(v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
-{
- v8::Local<v8::ObjectTemplate> internalTemplate = internalObjectTemplate(isolate);
- v8::Local<v8::Object> internal = internalTemplate->NewInstance();
- v8::Local<v8::Object> promise = V8DOMWrapper::createWrapper(creationContext, &V8Promise::wrapperTypeInfo, 0, isolate);
-
- clearDerived(internal, isolate);
- setState(internal, Pending, v8::Undefined(isolate), isolate);
-
- promise->SetInternalField(v8DOMWrapperObjectIndex, internal);
- return promise;
-}
-
-v8::Local<v8::Object> V8PromiseCustom::getInternal(v8::Handle<v8::Object> promise)
-{
- v8::Local<v8::Value> value = promise->GetInternalField(v8DOMWrapperObjectIndex);
- return value.As<v8::Object>();
-}
-
-V8PromiseCustom::PromiseState V8PromiseCustom::getState(v8::Handle<v8::Object> internal)
-{
- v8::Handle<v8::Value> value = internal->GetInternalField(V8PromiseCustom::InternalStateIndex);
- bool ok = false;
- uint32_t number = toInt32(value, ok);
- ASSERT(ok && (number == Pending || number == Fulfilled || number == Rejected || number == Following));
- return static_cast<PromiseState>(number);
-}
-
-void V8PromiseCustom::setState(v8::Handle<v8::Object> internal, PromiseState state, v8::Handle<v8::Value> value, v8::Isolate* isolate)
-{
- ASSERT(!value.IsEmpty());
- ASSERT(state == Pending || state == Fulfilled || state == Rejected || state == Following);
- internal->SetInternalField(InternalStateIndex, v8::Integer::New(state, isolate));
- internal->SetInternalField(InternalResultIndex, value);
-}
-
-bool V8PromiseCustom::isPromise(v8::Handle<v8::Value> maybePromise, v8::Isolate* isolate)
-{
- WrapperWorldType currentWorldType = worldType(isolate);
- return V8Promise::domTemplate(isolate, currentWorldType)->HasInstance(maybePromise);
-}
-
-v8::Local<v8::Object> V8PromiseCustom::toPromise(v8::Handle<v8::Value> maybePromise, v8::Isolate* isolate)
-{
- // FIXME: Currently we don't check [[PromiseConstructor]] since we limit
- // the creation of the promise objects only from the Blink Promise
- // constructor.
- if (isPromise(maybePromise, isolate))
- return maybePromise.As<v8::Object>();
-
- v8::Local<v8::Object> promise = createPromise(v8::Handle<v8::Object>(), isolate);
- resolve(promise, maybePromise, isolate);
- return promise;
-}
-
-void V8PromiseCustom::resolve(v8::Handle<v8::Object> promise, v8::Handle<v8::Value> result, v8::Isolate* isolate)
-{
- ASSERT(!result.IsEmpty());
- v8::Local<v8::Object> internal = getInternal(promise);
- PromiseState state = getState(internal);
- if (state != Pending)
- return;
-
- if (isPromise(result, isolate)) {
- v8::Local<v8::Object> valuePromise = result.As<v8::Object>();
- v8::Local<v8::Object> valueInternal = getInternal(valuePromise);
- PromiseState valueState = getState(valueInternal);
- if (promise->SameValue(valuePromise)) {
- v8::Local<v8::Value> reason = V8ThrowException::createTypeError("Resolve a promise with itself", isolate);
- setReason(promise, reason, isolate);
- } else if (valueState == Following) {
- v8::Local<v8::Object> valuePromiseFollowing = valueInternal->GetInternalField(InternalResultIndex).As<v8::Object>();
- setState(internal, Following, valuePromiseFollowing, isolate);
- addToDerived(getInternal(valuePromiseFollowing), promise, v8::Handle<v8::Function>(), v8::Handle<v8::Function>(), isolate);
- } else if (valueState == Fulfilled) {
- setValue(promise, valueInternal->GetInternalField(InternalResultIndex), isolate);
- } else if (valueState == Rejected) {
- setReason(promise, valueInternal->GetInternalField(InternalResultIndex), isolate);
- } else {
- ASSERT(valueState == Pending);
- setState(internal, Following, valuePromise, isolate);
- addToDerived(valueInternal, promise, v8::Handle<v8::Function>(), v8::Handle<v8::Function>(), isolate);
- }
- } else {
- setValue(promise, result, isolate);
- }
-}
-
-void V8PromiseCustom::reject(v8::Handle<v8::Object> promise, v8::Handle<v8::Value> reason, v8::Isolate* isolate)
-{
- v8::Local<v8::Object> internal = getInternal(promise);
- PromiseState state = getState(internal);
- if (state != Pending)
- return;
- setReason(promise, reason, isolate);
-}
-
-v8::Local<v8::Object> V8PromiseCustom::then(v8::Handle<v8::Object> promise, v8::Handle<v8::Function> onFulfilled, v8::Handle<v8::Function> onRejected, v8::Isolate* isolate)
-{
- v8::Handle<v8::Object> internal = getInternal(promise);
- while (getState(internal) == Following) {
- promise = internal->GetInternalField(InternalResultIndex).As<v8::Object>();
- internal = getInternal(promise);
- }
- // FIXME: Currently we don't lookup "constructor" property since we limit
- // the creation of the promise objects only from the Blink Promise
- // constructor.
- v8::Local<v8::Object> derivedPromise = createPromise(v8::Handle<v8::Object>(), isolate);
- updateDerivedFromPromise(derivedPromise, onFulfilled, onRejected, promise, isolate);
- return derivedPromise;
-}
-
-void V8PromiseCustom::setValue(v8::Handle<v8::Object> promise, v8::Handle<v8::Value> value, v8::Isolate* isolate)
-{
- PromisePropagator propagator;
- propagator.setValue(promise, value, isolate);
- propagator.performPropagation(isolate);
-}
-
-void V8PromiseCustom::setReason(v8::Handle<v8::Object> promise, v8::Handle<v8::Value> reason, v8::Isolate* isolate)
-{
- PromisePropagator propagator;
- propagator.setReason(promise, reason, isolate);
- propagator.performPropagation(isolate);
-}
-
-void V8PromiseCustom::propagateToDerived(v8::Handle<v8::Object> promise, v8::Isolate* isolate)
-{
- PromisePropagator propagator;
- propagator.propagateToDerived(promise, isolate);
- propagator.performPropagation(isolate);
-}
-
-void V8PromiseCustom::updateDerived(v8::Handle<v8::Object> derivedPromise, v8::Handle<v8::Function> onFulfilled, v8::Handle<v8::Function> onRejected, v8::Handle<v8::Object> originator, v8::Isolate* isolate)
-{
- PromisePropagator propagator;
- propagator.updateDerived(derivedPromise, onFulfilled, onRejected, originator, isolate);
- propagator.performPropagation(isolate);
-}
-
-void V8PromiseCustom::updateDerivedFromValue(v8::Handle<v8::Object> derivedPromise, v8::Handle<v8::Function> onFulfilled, v8::Handle<v8::Value> value, v8::Isolate* isolate)
-{
- PromisePropagator propagator;
- propagator.updateDerivedFromValue(derivedPromise, onFulfilled, value, isolate);
- propagator.performPropagation(isolate);
-}
-
-void V8PromiseCustom::updateDerivedFromReason(v8::Handle<v8::Object> derivedPromise, v8::Handle<v8::Function> onRejected, v8::Handle<v8::Value> reason, v8::Isolate* isolate)
-{
- PromisePropagator propagator;
- propagator.updateDerivedFromReason(derivedPromise, onRejected, reason, isolate);
- propagator.performPropagation(isolate);
-}
-
-void V8PromiseCustom::updateDerivedFromPromise(v8::Handle<v8::Object> derivedPromise, v8::Handle<v8::Function> onFulfilled, v8::Handle<v8::Function> onRejected, v8::Handle<v8::Object> promise, v8::Isolate* isolate)
-{
- PromisePropagator propagator;
- propagator.updateDerivedFromPromise(derivedPromise, onFulfilled, onRejected, promise, isolate);
- propagator.performPropagation(isolate);
-}
-
-v8::Local<v8::Object> V8PromiseCustom::coerceThenable(v8::Handle<v8::Object> thenable, v8::Handle<v8::Function> then, v8::Isolate* isolate)
-{
- ASSERT(!thenable.IsEmpty());
- ASSERT(!then.IsEmpty());
- v8::Local<v8::Object> promise = createPromise(v8::Handle<v8::Object>(), isolate);
- v8::Handle<v8::Value> argv[] = {
- createClosure(promiseResolveCallback, promise, isolate),
- createClosure(promiseRejectCallback, promise, isolate)
- };
- v8::TryCatch trycatch;
- if (V8ScriptRunner::callFunction(then, getExecutionContext(), thenable, WTF_ARRAY_LENGTH(argv), argv, isolate).IsEmpty()) {
- reject(promise, trycatch.Exception(), isolate);
- }
- thenable->SetHiddenValue(V8HiddenPropertyName::thenableHiddenPromise(isolate), promise);
- return promise;
-}
-
-void V8PromiseCustom::callHandler(v8::Handle<v8::Object> promise, v8::Handle<v8::Function> handler, v8::Handle<v8::Value> argument, v8::Isolate* isolate)
-{
- ExecutionContext* executionContext = getExecutionContext();
- ASSERT(executionContext && executionContext->isContextThread());
- executionContext->postTask(adoptPtr(new CallHandlerTask(promise, handler, argument, isolate, executionContext)));
-}
-
-} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8PromiseCustom.h b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8PromiseCustom.h
deleted file mode 100644
index 1751c1e4ae3..00000000000
--- a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8PromiseCustom.h
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Copyright (C) 2013, Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. 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 V8PromiseCustom_h
-#define V8PromiseCustom_h
-
-#include "bindings/v8/WrapperTypeInfo.h"
-
-#include <v8.h>
-
-namespace WebCore {
-
-class V8PromiseCustom {
-public:
- enum InternalFieldIndex {
- InternalStateIndex,
- InternalResultIndex,
- InternalFulfillCallbackIndex,
- InternalRejectCallbackIndex,
- InternalDerivedPromiseIndex,
- InternalFieldCount, // This entry must always be at the bottom.
- };
-
- enum PromiseAllEnvironmentFieldIndex {
- PromiseAllEnvironmentPromiseIndex,
- PromiseAllEnvironmentCountdownIndex,
- PromiseAllEnvironmentIndexIndex,
- PromiseAllEnvironmentResultsIndex,
- PromiseAllEnvironmentFieldCount, // This entry must always be at the bottom.
- };
-
- enum PrimitiveWrapperFieldIndex {
- PrimitiveWrapperPrimitiveIndex,
- PrimitiveWrapperFieldCount, // This entry must always be at the bottom.
- };
-
- enum PromiseState {
- Pending,
- Fulfilled,
- Rejected,
- Following,
- };
-
- static v8::Local<v8::Object> createPromise(v8::Handle<v8::Object> creationContext, v8::Isolate*);
-
- // |promise| must be a Promise instance.
- static v8::Local<v8::Object> getInternal(v8::Handle<v8::Object> promise);
-
- // |internal| must be a Promise internal object.
- static PromiseState getState(v8::Handle<v8::Object> internal);
-
- // |internal| must be a Promise internal object.
- // Set a |promise|'s state and result that correspond to the state.
- static void setState(v8::Handle<v8::Object> internal, PromiseState, v8::Handle<v8::Value>, v8::Isolate*);
-
- // Return true if |maybePromise| is a Promise instance.
- static bool isPromise(v8::Handle<v8::Value> maybePromise, v8::Isolate*);
-
- // Coerces |maybePromise| to a Promise instance.
- static v8::Local<v8::Object> toPromise(v8::Handle<v8::Value> maybePromise, v8::Isolate*);
-
- // |promise| must be a Promise instance.
- static void resolve(v8::Handle<v8::Object> promise, v8::Handle<v8::Value> result, v8::Isolate*);
-
- // |promise| must be a Promise instance.
- static void reject(v8::Handle<v8::Object> promise, v8::Handle<v8::Value> result, v8::Isolate*);
-
- // |promise| must be a Promise instance.
- // |onFulfilled| and |onRejected| can be an empty value respectively.
- // Appends |onFulfilled| and/or |onRejected| handlers to |promise|.
- static v8::Local<v8::Object> then(v8::Handle<v8::Object> promise, v8::Handle<v8::Function> onFulfilled, v8::Handle<v8::Function> onRejected, v8::Isolate*);
-
- // |promise| must be a Promise instance.
- // Set a |promise|'s value and propagate it to derived promises.
- static void setValue(v8::Handle<v8::Object> promise, v8::Handle<v8::Value>, v8::Isolate*);
-
- // |promise| must be a Promise instance.
- // Set a |promise|'s failure reason and propagate it to derived promises.
- static void setReason(v8::Handle<v8::Object> promise, v8::Handle<v8::Value>, v8::Isolate*);
-
- // |promise| must be a Promise instance.
- // Propagate a |promise|'s value or reason to all of its derived promies.
- static void propagateToDerived(v8::Handle<v8::Object> promise, v8::Isolate*);
-
- // |derivedPromise| and |originator| must be a Promise instance.
- // |onFulfilled| and |onRejected| can be an empty value respectively.
- // Propagate |originator|'s state to |derivedPromise|.
- static void updateDerived(v8::Handle<v8::Object> derivedPromise, v8::Handle<v8::Function> onFulfilled, v8::Handle<v8::Function> onRejected, v8::Handle<v8::Object> originator, v8::Isolate*);
-
- // |derivedPromise| must be a Promise instance.
- // Propagate a value to |derivedPromise|.
- static void updateDerivedFromValue(v8::Handle<v8::Object> derivedPromise, v8::Handle<v8::Function> onFulfilled, v8::Handle<v8::Value>, v8::Isolate*);
-
- // |derivedPromise| must be a Promise instance.
- // Propagate a failure reason to |derivedPromise|.
- static void updateDerivedFromReason(v8::Handle<v8::Object> derivedPromise, v8::Handle<v8::Function> onRejected, v8::Handle<v8::Value>, v8::Isolate*);
-
- // |derivedPromise| and |promise| must be a Promise instance.
- // |onFulfilled| and |onRejected| can be an empty value respectively.
- // Propagate |promise|'s state to |derivedPromise|.
- static void updateDerivedFromPromise(v8::Handle<v8::Object> derivedPromise, v8::Handle<v8::Function> onFulfilled, v8::Handle<v8::Function> onRejected, v8::Handle<v8::Object> promise, v8::Isolate*);
-
- // Returns a Promise instance that will be fulfilled or rejected by
- // |thenable|'s result.
- static v8::Local<v8::Object> coerceThenable(v8::Handle<v8::Object> thenable, v8::Handle<v8::Function> then, v8::Isolate*);
-
- // |promise| must be a Promise instance.
- // Applies a transformation to an argument and use it to update derived
- // promies.
- static void callHandler(v8::Handle<v8::Object> promise, v8::Handle<v8::Function> handler, v8::Handle<v8::Value> argument, v8::Isolate*);
-};
-
-} // namespace WebCore
-
-#endif // V8PromiseCustom_h
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8SQLResultSetRowListCustom.cpp b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8SQLResultSetRowListCustom.cpp
index 3c41cb7b9a6..a6fed441759 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8SQLResultSetRowListCustom.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8SQLResultSetRowListCustom.cpp
@@ -29,22 +29,28 @@
*/
#include "config.h"
-#include "V8SQLResultSetRowList.h"
+#include "bindings/modules/v8/V8SQLResultSetRowList.h"
+#include "bindings/v8/ExceptionMessages.h"
+#include "bindings/v8/ExceptionState.h"
#include "bindings/v8/V8Binding.h"
+#include "core/dom/ExceptionCode.h"
#include "modules/webdatabase/SQLResultSetRowList.h"
namespace WebCore {
void V8SQLResultSetRowList::itemMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& info)
{
+ ExceptionState exceptionState(ExceptionState::ExecutionContext, "item", "SQLResultSetRowList", info.Holder(), info.GetIsolate());
if (!info.Length()) {
- throwError(v8SyntaxError, "Item index is required.", info.GetIsolate());
+ exceptionState.throwDOMException(SyntaxError, ExceptionMessages::notEnoughArguments(1, 0));
+ exceptionState.throwIfNeeded();
return;
}
if (!info[0]->IsNumber()) {
- throwTypeError("Item index must be a number.", info.GetIsolate());
+ exceptionState.throwTypeError("The index provided is not a number.");
+ exceptionState.throwIfNeeded();
return;
}
@@ -52,11 +58,12 @@ void V8SQLResultSetRowList::itemMethodCustom(const v8::FunctionCallbackInfo<v8::
unsigned long index = info[0]->IntegerValue();
if (index >= rowList->length()) {
- throwError(v8RangeError, "Item index is out of range.", info.GetIsolate());
+ exceptionState.throwDOMException(IndexSizeError, ExceptionMessages::indexExceedsMaximumBound<unsigned>("index", index, rowList->length()));
+ exceptionState.throwIfNeeded();
return;
}
- v8::Local<v8::Object> item = v8::Object::New();
+ v8::Local<v8::Object> item = v8::Object::New(info.GetIsolate());
unsigned numColumns = rowList->columnNames().size();
unsigned valuesIndex = index * numColumns;
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8SQLTransactionCustom.cpp b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8SQLTransactionCustom.cpp
index 9a314b5f666..45a764ce042 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8SQLTransactionCustom.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8SQLTransactionCustom.cpp
@@ -29,10 +29,11 @@
*/
#include "config.h"
-#include "V8SQLTransaction.h"
+#include "bindings/modules/v8/V8SQLTransaction.h"
-#include "V8SQLStatementCallback.h"
-#include "V8SQLStatementErrorCallback.h"
+#include "bindings/modules/v8/V8SQLStatementCallback.h"
+#include "bindings/modules/v8/V8SQLStatementErrorCallback.h"
+#include "bindings/v8/ExceptionMessages.h"
#include "bindings/v8/ExceptionState.h"
#include "bindings/v8/V8Binding.h"
#include "core/dom/ExceptionCode.h"
@@ -46,69 +47,70 @@ namespace WebCore {
void V8SQLTransaction::executeSqlMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& info)
{
+ ExceptionState exceptionState(ExceptionState::ExecutionContext, "executeSql", "SQLTransaction", info.Holder(), info.GetIsolate());
if (!info.Length()) {
- setDOMException(SyntaxError, info.GetIsolate());
+ exceptionState.throwDOMException(SyntaxError, ExceptionMessages::notEnoughArguments(1, 0));
+ exceptionState.throwIfNeeded();
return;
}
- V8TRYCATCH_FOR_V8STRINGRESOURCE_VOID(V8StringResource<>, statement, info[0]);
+ TOSTRING_VOID(V8StringResource<>, statement, info[0]);
Vector<SQLValue> sqlValues;
if (info.Length() > 1 && !isUndefinedOrNull(info[1])) {
if (!info[1]->IsObject()) {
- setDOMException(TypeMismatchError, info.GetIsolate());
+ exceptionState.throwDOMException(TypeMismatchError, "The 'arguments' (2nd) argument provided is not an object.");
+ exceptionState.throwIfNeeded();
return;
}
uint32_t sqlArgsLength = 0;
v8::Local<v8::Object> sqlArgsObject = info[1]->ToObject();
- V8TRYCATCH_VOID(v8::Local<v8::Value>, length, sqlArgsObject->Get(v8AtomicString(info.GetIsolate(), "length")));
+ TONATIVE_VOID(v8::Local<v8::Value>, length, sqlArgsObject->Get(v8AtomicString(info.GetIsolate(), "length")));
if (isUndefinedOrNull(length))
sqlArgsLength = sqlArgsObject->GetPropertyNames()->Length();
else
sqlArgsLength = length->Uint32Value();
- for (unsigned int i = 0; i < sqlArgsLength; ++i) {
- v8::Handle<v8::Integer> key = v8::Integer::New(i, info.GetIsolate());
- V8TRYCATCH_VOID(v8::Local<v8::Value>, value, sqlArgsObject->Get(key));
+ for (unsigned i = 0; i < sqlArgsLength; ++i) {
+ v8::Handle<v8::Integer> key = v8::Integer::New(info.GetIsolate(), i);
+ TONATIVE_VOID(v8::Local<v8::Value>, value, sqlArgsObject->Get(key));
if (value.IsEmpty() || value->IsNull())
sqlValues.append(SQLValue());
else if (value->IsNumber()) {
- V8TRYCATCH_VOID(double, sqlValue, value->NumberValue());
+ TONATIVE_VOID(double, sqlValue, value->NumberValue());
sqlValues.append(SQLValue(sqlValue));
} else {
- V8TRYCATCH_FOR_V8STRINGRESOURCE_VOID(V8StringResource<>, sqlValue, value);
+ TOSTRING_VOID(V8StringResource<>, sqlValue, value);
sqlValues.append(SQLValue(sqlValue));
}
}
}
SQLTransaction* transaction = V8SQLTransaction::toNative(info.Holder());
-
- ExecutionContext* executionContext = getExecutionContext();
-
OwnPtr<SQLStatementCallback> callback;
if (info.Length() > 2 && !isUndefinedOrNull(info[2])) {
if (!info[2]->IsFunction()) {
- setDOMException(TypeMismatchError, info.GetIsolate());
+ exceptionState.throwDOMException(TypeMismatchError, "The 'callback' (2nd) argument provided is not a function.");
+ exceptionState.throwIfNeeded();
return;
}
- callback = V8SQLStatementCallback::create(v8::Handle<v8::Function>::Cast(info[2]), executionContext);
+ callback = V8SQLStatementCallback::create(v8::Handle<v8::Function>::Cast(info[2]), ScriptState::current(info.GetIsolate()));
}
OwnPtr<SQLStatementErrorCallback> errorCallback;
if (info.Length() > 3 && !isUndefinedOrNull(info[3])) {
if (!info[3]->IsFunction()) {
- setDOMException(TypeMismatchError, info.GetIsolate());
+ exceptionState.throwDOMException(TypeMismatchError, "The 'errorCallback' (3rd) argument provided is not a function.");
+ exceptionState.throwIfNeeded();
return;
}
- errorCallback = V8SQLStatementErrorCallback::create(v8::Handle<v8::Function>::Cast(info[3]), executionContext);
+ errorCallback = V8SQLStatementErrorCallback::create(v8::Handle<v8::Function>::Cast(info[3]), ScriptState::current(info.GetIsolate()));
}
- ExceptionState exceptionState(info.Holder(), info.GetIsolate());
transaction->executeSQL(statement, sqlValues, callback.release(), errorCallback.release(), exceptionState);
exceptionState.throwIfNeeded();
}
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8SQLTransactionSyncCustom.cpp b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8SQLTransactionSyncCustom.cpp
index eaffffa0ca5..9b24721fa41 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8SQLTransactionSyncCustom.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8SQLTransactionSyncCustom.cpp
@@ -29,9 +29,9 @@
*/
#include "config.h"
-#include "V8SQLTransactionSync.h"
+#include "bindings/modules/v8/V8SQLTransactionSync.h"
-#include "V8SQLResultSet.h"
+#include "bindings/modules/v8/V8SQLResultSet.h"
#include "bindings/v8/ExceptionState.h"
#include "bindings/v8/V8Binding.h"
#include "core/dom/ExceptionCode.h"
@@ -46,41 +46,44 @@ namespace WebCore {
void V8SQLTransactionSync::executeSqlMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& info)
{
+ ExceptionState exceptionState(ExceptionState::ExecutionContext, "executeSql", "SQLTransactionSync", info.Holder(), info.GetIsolate());
if (!info.Length()) {
- setDOMException(SyntaxError, info.GetIsolate());
+ exceptionState.throwDOMException(SyntaxError, ExceptionMessages::notEnoughArguments(1, 0));
+ exceptionState.throwIfNeeded();
return;
}
- V8TRYCATCH_FOR_V8STRINGRESOURCE_VOID(V8StringResource<>, statement, info[0]);
+ TOSTRING_VOID(V8StringResource<>, statement, info[0]);
Vector<SQLValue> sqlValues;
if (info.Length() > 1 && !isUndefinedOrNull(info[1])) {
if (!info[1]->IsObject()) {
- setDOMException(TypeMismatchError, info.GetIsolate());
+ exceptionState.throwDOMException(TypeMismatchError, ExceptionMessages::argumentNullOrIncorrectType(1, "DOMString"));
+ exceptionState.throwIfNeeded();
return;
}
uint32_t sqlArgsLength = 0;
v8::Local<v8::Object> sqlArgsObject = info[1]->ToObject();
- V8TRYCATCH_VOID(v8::Local<v8::Value>, length, sqlArgsObject->Get(v8AtomicString(info.GetIsolate(), "length")));
+ TONATIVE_VOID(v8::Local<v8::Value>, length, sqlArgsObject->Get(v8AtomicString(info.GetIsolate(), "length")));
if (isUndefinedOrNull(length))
sqlArgsLength = sqlArgsObject->GetPropertyNames()->Length();
else
sqlArgsLength = length->Uint32Value();
- for (unsigned int i = 0; i < sqlArgsLength; ++i) {
- v8::Handle<v8::Integer> key = v8::Integer::New(i, info.GetIsolate());
- V8TRYCATCH_VOID(v8::Local<v8::Value>, value, sqlArgsObject->Get(key));
+ for (unsigned i = 0; i < sqlArgsLength; ++i) {
+ v8::Handle<v8::Integer> key = v8::Integer::New(info.GetIsolate(), i);
+ TONATIVE_VOID(v8::Local<v8::Value>, value, sqlArgsObject->Get(key));
if (value.IsEmpty() || value->IsNull())
sqlValues.append(SQLValue());
else if (value->IsNumber()) {
- V8TRYCATCH_VOID(double, sqlValue, value->NumberValue());
+ TONATIVE_VOID(double, sqlValue, value->NumberValue());
sqlValues.append(SQLValue(sqlValue));
} else {
- V8TRYCATCH_FOR_V8STRINGRESOURCE_VOID(V8StringResource<>, sqlValue, value);
+ TOSTRING_VOID(V8StringResource<>, sqlValue, value);
sqlValues.append(SQLValue(sqlValue));
}
}
@@ -88,7 +91,6 @@ void V8SQLTransactionSync::executeSqlMethodCustom(const v8::FunctionCallbackInfo
SQLTransactionSync* transaction = V8SQLTransactionSync::toNative(info.Holder());
- ExceptionState exceptionState(info.Holder(), info.GetIsolate());
v8::Handle<v8::Value> result = toV8(transaction->executeSQL(statement, sqlValues, exceptionState), info.Holder(), info.GetIsolate());
if (exceptionState.throwIfNeeded())
return;
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8SVGElementCustom.cpp b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8SVGElementCustom.cpp
index c21247e4d9a..abe89461fad 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8SVGElementCustom.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8SVGElementCustom.cpp
@@ -29,9 +29,9 @@
*/
#include "config.h"
-#include "V8SVGElement.h"
+#include "bindings/core/v8/V8SVGElement.h"
-#include "V8SVGElementWrapperFactory.h"
+#include "core/V8SVGElementWrapperFactory.h" // FIXME: should be bindings/core/v8
namespace WebCore {
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8SVGLengthCustom.cpp b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8SVGLengthCustom.cpp
deleted file mode 100644
index a5a1cfef55b..00000000000
--- a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8SVGLengthCustom.cpp
+++ /dev/null
@@ -1,102 +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 "V8SVGLength.h"
-
-#include "bindings/v8/ExceptionMessages.h"
-#include "bindings/v8/ExceptionState.h"
-#include "bindings/v8/V8Binding.h"
-#include "core/dom/ExceptionCode.h"
-#include "core/svg/SVGLengthContext.h"
-#include "core/svg/properties/SVGPropertyTearOff.h"
-
-namespace WebCore {
-
-void V8SVGLength::valueAttributeGetterCustom(const v8::PropertyCallbackInfo<v8::Value>& info)
-{
- SVGPropertyTearOff<SVGLength>* wrapper = V8SVGLength::toNative(info.Holder());
- SVGLength& imp = wrapper->propertyReference();
- ExceptionState exceptionState(info.Holder(), info.GetIsolate());
- SVGLengthContext lengthContext(wrapper->contextElement());
- float value = imp.value(lengthContext, exceptionState);
- if (exceptionState.throwIfNeeded())
- return;
- v8SetReturnValue(info, value);
-}
-
-void V8SVGLength::valueAttributeSetterCustom(v8::Local<v8::Value> value, const v8::PropertyCallbackInfo<void>& info)
-{
- SVGPropertyTearOff<SVGLength>* wrapper = V8SVGLength::toNative(info.Holder());
- if (wrapper->isReadOnly()) {
- setDOMException(NoModificationAllowedError, info.GetIsolate());
- return;
- }
-
- if (!isUndefinedOrNull(value) && !value->IsNumber() && !value->IsBoolean()) {
- throwUninformativeAndGenericTypeError(info.GetIsolate());
- return;
- }
-
- SVGLength& imp = wrapper->propertyReference();
- ExceptionState exceptionState(info.Holder(), info.GetIsolate());
- SVGLengthContext lengthContext(wrapper->contextElement());
- imp.setValue(static_cast<float>(value->NumberValue()), lengthContext, exceptionState);
- if (exceptionState.throwIfNeeded())
- return;
- wrapper->commitChange();
-}
-
-void V8SVGLength::convertToSpecifiedUnitsMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& info)
-{
- ExceptionState exceptionState(ExceptionState::ExecutionContext, "convertToSpecifiedUnits", "SVGLength", info.Holder(), info.GetIsolate());
- SVGPropertyTearOff<SVGLength>* wrapper = V8SVGLength::toNative(info.Holder());
- if (wrapper->isReadOnly()) {
- exceptionState.throwDOMException(NoModificationAllowedError, "The length is read only.");
- exceptionState.throwIfNeeded();
- return;
- }
-
- if (info.Length() < 1) {
- exceptionState.throwTypeError(ExceptionMessages::notEnoughArguments(1, info.Length()));
- exceptionState.throwIfNeeded();
- return;
- }
-
- SVGLength& imp = wrapper->propertyReference();
- V8TRYCATCH_VOID(int, unitType, toUInt32(info[0]));
- SVGLengthContext lengthContext(wrapper->contextElement());
- imp.convertToSpecifiedUnits(unitType, lengthContext, exceptionState);
- if (exceptionState.throwIfNeeded())
- return;
- wrapper->commitChange();
-}
-
-} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8SVGPathSegCustom.cpp b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8SVGPathSegCustom.cpp
index 77bf679d4f8..8d159757c06 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8SVGPathSegCustom.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8SVGPathSegCustom.cpp
@@ -29,28 +29,28 @@
*/
#include "config.h"
-#include "V8SVGPathSeg.h"
+#include "bindings/core/v8/V8SVGPathSeg.h"
-#include "V8SVGPathSegArcAbs.h"
-#include "V8SVGPathSegArcRel.h"
-#include "V8SVGPathSegClosePath.h"
-#include "V8SVGPathSegCurvetoCubicAbs.h"
-#include "V8SVGPathSegCurvetoCubicRel.h"
-#include "V8SVGPathSegCurvetoCubicSmoothAbs.h"
-#include "V8SVGPathSegCurvetoCubicSmoothRel.h"
-#include "V8SVGPathSegCurvetoQuadraticAbs.h"
-#include "V8SVGPathSegCurvetoQuadraticRel.h"
-#include "V8SVGPathSegCurvetoQuadraticSmoothAbs.h"
-#include "V8SVGPathSegCurvetoQuadraticSmoothRel.h"
-#include "V8SVGPathSegLinetoAbs.h"
-#include "V8SVGPathSegLinetoHorizontalAbs.h"
-#include "V8SVGPathSegLinetoHorizontalRel.h"
-#include "V8SVGPathSegLinetoRel.h"
-#include "V8SVGPathSegLinetoVerticalAbs.h"
-#include "V8SVGPathSegLinetoVerticalRel.h"
-#include "V8SVGPathSegMovetoAbs.h"
-#include "V8SVGPathSegMovetoRel.h"
-#include "V8Window.h"
+#include "bindings/core/v8/V8SVGPathSegArcAbs.h"
+#include "bindings/core/v8/V8SVGPathSegArcRel.h"
+#include "bindings/core/v8/V8SVGPathSegClosePath.h"
+#include "bindings/core/v8/V8SVGPathSegCurvetoCubicAbs.h"
+#include "bindings/core/v8/V8SVGPathSegCurvetoCubicRel.h"
+#include "bindings/core/v8/V8SVGPathSegCurvetoCubicSmoothAbs.h"
+#include "bindings/core/v8/V8SVGPathSegCurvetoCubicSmoothRel.h"
+#include "bindings/core/v8/V8SVGPathSegCurvetoQuadraticAbs.h"
+#include "bindings/core/v8/V8SVGPathSegCurvetoQuadraticRel.h"
+#include "bindings/core/v8/V8SVGPathSegCurvetoQuadraticSmoothAbs.h"
+#include "bindings/core/v8/V8SVGPathSegCurvetoQuadraticSmoothRel.h"
+#include "bindings/core/v8/V8SVGPathSegLinetoAbs.h"
+#include "bindings/core/v8/V8SVGPathSegLinetoHorizontalAbs.h"
+#include "bindings/core/v8/V8SVGPathSegLinetoHorizontalRel.h"
+#include "bindings/core/v8/V8SVGPathSegLinetoRel.h"
+#include "bindings/core/v8/V8SVGPathSegLinetoVerticalAbs.h"
+#include "bindings/core/v8/V8SVGPathSegLinetoVerticalRel.h"
+#include "bindings/core/v8/V8SVGPathSegMovetoAbs.h"
+#include "bindings/core/v8/V8SVGPathSegMovetoRel.h"
+#include "bindings/core/v8/V8Window.h"
#include "bindings/v8/V8DOMWrapper.h"
namespace WebCore {
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8ServiceWorkerCustom.cpp b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8ServiceWorkerCustom.cpp
new file mode 100644
index 00000000000..21337b4f437
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8ServiceWorkerCustom.cpp
@@ -0,0 +1,38 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "bindings/modules/v8/V8ServiceWorker.h"
+
+#include "bindings/v8/ExceptionMessages.h"
+#include "bindings/v8/ExceptionState.h"
+#include "bindings/v8/SerializedScriptValue.h"
+#include "bindings/v8/V8Binding.h"
+#include "core/dom/MessagePort.h"
+#include "modules/serviceworkers/ServiceWorker.h"
+#include "wtf/ArrayBuffer.h"
+
+namespace WebCore {
+
+void V8ServiceWorker::postMessageMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& info)
+{
+ ExceptionState exceptionState(ExceptionState::ExecutionContext, "postMessage", "ServiceWorker", info.Holder(), info.GetIsolate());
+ ServiceWorker* worker = V8ServiceWorker::toNative(info.Holder());
+ MessagePortArray ports;
+ ArrayBufferArray arrayBuffers;
+ if (info.Length() > 1) {
+ const int transferablesArgIndex = 1;
+ if (!SerializedScriptValue::extractTransferables(info[transferablesArgIndex], transferablesArgIndex, ports, arrayBuffers, exceptionState, info.GetIsolate())) {
+ exceptionState.throwIfNeeded();
+ return;
+ }
+ }
+ RefPtr<SerializedScriptValue> message = SerializedScriptValue::create(info[0], &ports, &arrayBuffers, exceptionState, info.GetIsolate());
+ if (exceptionState.throwIfNeeded())
+ return;
+ worker->postMessage(message.release(), &ports, exceptionState);
+ exceptionState.throwIfNeeded();
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8StyleSheetCustom.cpp b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8StyleSheetCustom.cpp
index 39d28a800c6..8705d0783be 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8StyleSheetCustom.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8StyleSheetCustom.cpp
@@ -29,10 +29,10 @@
*/
#include "config.h"
-#include "V8StyleSheet.h"
+#include "bindings/core/v8/V8StyleSheet.h"
-#include "V8CSSStyleSheet.h"
-#include "V8Node.h"
+#include "bindings/core/v8/V8CSSStyleSheet.h"
+#include "bindings/core/v8/V8Node.h"
#include "bindings/v8/V8DOMWrapper.h"
namespace WebCore {
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8SubtleCryptoCustom.cpp b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8SubtleCryptoCustom.cpp
new file mode 100644
index 00000000000..943ad7666a0
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8SubtleCryptoCustom.cpp
@@ -0,0 +1,125 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "bindings/modules/v8/V8SubtleCrypto.h"
+
+#include "bindings/modules/v8/V8Key.h"
+#include "bindings/v8/Dictionary.h"
+#include "bindings/v8/custom/V8ArrayBufferCustom.h"
+#include "bindings/v8/custom/V8ArrayBufferViewCustom.h"
+
+namespace WebCore {
+
+////////////////////////////////////////////////////////////////////////////////
+// Overload resolution for verify()
+// FIXME: needs support for union types http://crbug.com/240176
+////////////////////////////////////////////////////////////////////////////////
+
+// Promise verify(Dictionary algorithm, Key key, ArrayBuffer signature, ArrayBuffer data);
+void verify1Method(const v8::FunctionCallbackInfo<v8::Value>& info)
+{
+ SubtleCrypto* impl = V8SubtleCrypto::toNative(info.Holder());
+ TONATIVE_VOID(Dictionary, algorithm, Dictionary(info[0], info.GetIsolate()));
+ if (!algorithm.isUndefinedOrNull() && !algorithm.isObject()) {
+ throwTypeError(ExceptionMessages::failedToExecute("verify", "SubtleCrypto", "parameter 1 ('algorithm') is not an object."), info.GetIsolate());
+ return;
+ }
+ TONATIVE_VOID(Key*, key, V8Key::toNativeWithTypeCheck(info.GetIsolate(), info[1]));
+ TONATIVE_VOID(ArrayBuffer*, signature, info[2]->IsArrayBuffer() ? V8ArrayBuffer::toNative(v8::Handle<v8::ArrayBuffer>::Cast(info[2])) : 0);
+ TONATIVE_VOID(ArrayBuffer*, data, info[3]->IsArrayBuffer() ? V8ArrayBuffer::toNative(v8::Handle<v8::ArrayBuffer>::Cast(info[3])) : 0);
+ v8SetReturnValue(info, impl->verifySignature(ScriptState::current(info.GetIsolate()), algorithm, key, signature, data).v8Value());
+}
+
+// Promise verify(Dictionary algorithm, Key key, ArrayBuffer signature, ArrayBufferView data);
+void verify2Method(const v8::FunctionCallbackInfo<v8::Value>& info)
+{
+ SubtleCrypto* impl = V8SubtleCrypto::toNative(info.Holder());
+ TONATIVE_VOID(Dictionary, algorithm, Dictionary(info[0], info.GetIsolate()));
+ if (!algorithm.isUndefinedOrNull() && !algorithm.isObject()) {
+ throwTypeError(ExceptionMessages::failedToExecute("verify", "SubtleCrypto", "parameter 1 ('algorithm') is not an object."), info.GetIsolate());
+ return;
+ }
+ TONATIVE_VOID(Key*, key, V8Key::toNativeWithTypeCheck(info.GetIsolate(), info[1]));
+ TONATIVE_VOID(ArrayBuffer*, signature, info[2]->IsArrayBuffer() ? V8ArrayBuffer::toNative(v8::Handle<v8::ArrayBuffer>::Cast(info[2])) : 0);
+ TONATIVE_VOID(ArrayBufferView*, data, info[3]->IsArrayBufferView() ? V8ArrayBufferView::toNative(v8::Handle<v8::ArrayBufferView>::Cast(info[3])) : 0);
+ v8SetReturnValue(info, impl->verifySignature(ScriptState::current(info.GetIsolate()), algorithm, key, signature, data).v8Value());
+}
+
+// Promise verify(Dictionary algorithm, Key key, ArrayBufferView signature, ArrayBuffer data);
+void verify3Method(const v8::FunctionCallbackInfo<v8::Value>& info)
+{
+ SubtleCrypto* impl = V8SubtleCrypto::toNative(info.Holder());
+ TONATIVE_VOID(Dictionary, algorithm, Dictionary(info[0], info.GetIsolate()));
+ if (!algorithm.isUndefinedOrNull() && !algorithm.isObject()) {
+ throwTypeError(ExceptionMessages::failedToExecute("verify", "SubtleCrypto", "parameter 1 ('algorithm') is not an object."), info.GetIsolate());
+ return;
+ }
+ TONATIVE_VOID(Key*, key, V8Key::toNativeWithTypeCheck(info.GetIsolate(), info[1]));
+ TONATIVE_VOID(ArrayBufferView*, signature, info[2]->IsArrayBufferView() ? V8ArrayBufferView::toNative(v8::Handle<v8::ArrayBufferView>::Cast(info[2])) : 0);
+ TONATIVE_VOID(ArrayBuffer*, data, info[3]->IsArrayBuffer() ? V8ArrayBuffer::toNative(v8::Handle<v8::ArrayBuffer>::Cast(info[3])) : 0);
+ v8SetReturnValue(info, impl->verifySignature(ScriptState::current(info.GetIsolate()), algorithm, key, signature, data).v8Value());
+}
+
+// Promise verify(Dictionary algorithm, Key key, ArrayBufferView signature, ArrayBufferView data);
+void verify4Method(const v8::FunctionCallbackInfo<v8::Value>& info)
+{
+ SubtleCrypto* impl = V8SubtleCrypto::toNative(info.Holder());
+ TONATIVE_VOID(Dictionary, algorithm, Dictionary(info[0], info.GetIsolate()));
+ if (!algorithm.isUndefinedOrNull() && !algorithm.isObject()) {
+ throwTypeError(ExceptionMessages::failedToExecute("verify", "SubtleCrypto", "parameter 1 ('algorithm') is not an object."), info.GetIsolate());
+ return;
+ }
+ TONATIVE_VOID(Key*, key, V8Key::toNativeWithTypeCheck(info.GetIsolate(), info[1]));
+ TONATIVE_VOID(ArrayBufferView*, signature, info[2]->IsArrayBufferView() ? V8ArrayBufferView::toNative(v8::Handle<v8::ArrayBufferView>::Cast(info[2])) : 0);
+ TONATIVE_VOID(ArrayBufferView*, data, info[3]->IsArrayBufferView() ? V8ArrayBufferView::toNative(v8::Handle<v8::ArrayBufferView>::Cast(info[3])) : 0);
+ v8SetReturnValue(info, impl->verifySignature(ScriptState::current(info.GetIsolate()), algorithm, key, signature, data).v8Value());
+}
+
+void V8SubtleCrypto::verifyMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& info)
+{
+ v8::Isolate* isolate = info.GetIsolate();
+ ExceptionState exceptionState(ExceptionState::ExecutionContext, "verify", "SubtleCrypto", info.Holder(), isolate);
+ // typedef (ArrayBuffer or ArrayBufferView) CryptoOperationData;
+ //
+ // Promise verify(Dictionary algorithm, Key key,
+ // CryptoOperationData signature,
+ // CryptoOperationData data);
+ switch (info.Length()) {
+ case 4:
+ // Promise verify(Dictionary algorithm, Key key, ArrayBuffer signature, ArrayBuffer data);
+ if (V8ArrayBuffer::hasInstance(info[2], isolate)
+ && V8ArrayBuffer::hasInstance(info[3], isolate)) {
+ verify1Method(info);
+ return;
+ }
+ // Promise verify(Dictionary algorithm, Key key, ArrayBuffer signature, ArrayBufferView data);
+ if (V8ArrayBuffer::hasInstance(info[2], isolate)
+ && V8ArrayBufferView::hasInstance(info[3], isolate)) {
+ verify2Method(info);
+ return;
+ }
+ // Promise verify(Dictionary algorithm, Key key, ArrayBufferView signature, ArrayBuffer data);
+ if (V8ArrayBufferView::hasInstance(info[2], isolate)
+ && V8ArrayBuffer::hasInstance(info[3], isolate)) {
+ verify3Method(info);
+ return;
+ }
+ // Promise verify(Dictionary algorithm, Key key, ArrayBufferView signature, ArrayBufferView data);
+ if (V8ArrayBufferView::hasInstance(info[2], isolate)
+ && V8ArrayBufferView::hasInstance(info[3], isolate)) {
+ verify4Method(info);
+ return;
+ }
+ break;
+ default:
+ throwArityTypeError(exceptionState, "[4]", info.Length());
+ return;
+ break;
+ }
+ exceptionState.throwTypeError("No function was found that matched the signature provided.");
+ exceptionState.throwIfNeeded();
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8TextCustom.cpp b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8TextCustom.cpp
index 478537c3b9f..4ffbadc0d3d 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8TextCustom.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8TextCustom.cpp
@@ -29,9 +29,9 @@
*/
#include "config.h"
-#include "V8Text.h"
+#include "bindings/core/v8/V8Text.h"
-#include "V8CDATASection.h"
+#include "bindings/core/v8/V8CDATASection.h"
#include "core/dom/Node.h"
#include "core/dom/Text.h"
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8TextTrackCueCustom.cpp b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8TextTrackCueCustom.cpp
index 3adef38297e..8d078eb91e9 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8TextTrackCueCustom.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8TextTrackCueCustom.cpp
@@ -28,13 +28,9 @@
*/
#include "config.h"
-#include "V8TextTrackCue.h"
+#include "bindings/core/v8/V8TextTrackCue.h"
-#include "V8VTTCue.h"
-
-#include "bindings/v8/ExceptionMessages.h"
-#include "bindings/v8/ExceptionState.h"
-#include "core/frame/UseCounter.h"
+#include "bindings/core/v8/V8VTTCue.h"
namespace WebCore {
@@ -43,27 +39,4 @@ v8::Handle<v8::Value> toV8(TextTrackCue* impl, v8::Handle<v8::Object> creationCo
return toV8(toVTTCue(impl), creationContext, isolate);
}
-// Custom constructor to make new TextTrackCue(...) return a VTTCue. This is legacy
-// compat, not per spec, and should be removed at the earliest opportunity.
-void V8TextTrackCue::constructorCustom(const v8::FunctionCallbackInfo<v8::Value>& info)
-{
- ExceptionState exceptionState(ExceptionState::ConstructionContext, "TextTrackCue", info.Holder(), info.GetIsolate());
- if (UNLIKELY(info.Length() < 3)) {
- exceptionState.throwTypeError(ExceptionMessages::notEnoughArguments(3, info.Length()));
- exceptionState.throwIfNeeded();
- return;
- }
- V8TRYCATCH_VOID(double, startTime, static_cast<double>(info[0]->NumberValue()));
- V8TRYCATCH_VOID(double, endTime, static_cast<double>(info[1]->NumberValue()));
- V8TRYCATCH_FOR_V8STRINGRESOURCE_VOID(V8StringResource<>, text, info[2]);
-
- Document& document = *toDocument(getExecutionContext());
- UseCounter::count(document, UseCounter::TextTrackCueConstructor);
-
- RefPtr<VTTCue> impl = VTTCue::create(document, startTime, endTime, text);
- v8::Handle<v8::Object> wrapper = wrap(impl.get(), info.Holder(), info.GetIsolate());
-
- v8SetReturnValue(info, wrapper);
-}
-
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8TrackEventCustom.cpp b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8TrackEventCustom.cpp
index aa76cc2c3fd..9c2b04e3c31 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8TrackEventCustom.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8TrackEventCustom.cpp
@@ -29,9 +29,11 @@
*/
#include "config.h"
-#include "V8TrackEvent.h"
+#include "bindings/core/v8/V8TrackEvent.h"
-#include "V8TextTrack.h"
+#include "bindings/core/v8/V8AudioTrack.h"
+#include "bindings/core/v8/V8TextTrack.h"
+#include "bindings/core/v8/V8VideoTrack.h"
#include "core/html/track/TrackBase.h"
#include "core/html/track/TrackEvent.h"
@@ -53,10 +55,12 @@ void V8TrackEvent::trackAttributeGetterCustom(const v8::PropertyCallbackInfo<v8:
return;
case TrackBase::AudioTrack:
+ v8SetReturnValueFast(info, static_cast<AudioTrack*>(track), trackEvent);
+ return;
+
case TrackBase::VideoTrack:
- // This should not happen until VideoTrack and AudioTrack are implemented.
- ASSERT_NOT_REACHED();
- break;
+ v8SetReturnValueFast(info, static_cast<VideoTrack*>(track), trackEvent);
+ return;
}
v8SetReturnValueNull(info);
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8TypedArrayCustom.h b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8TypedArrayCustom.h
index f64f457f2f5..fac7a110e5e 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8TypedArrayCustom.h
+++ b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8TypedArrayCustom.h
@@ -47,17 +47,13 @@ class TypedArrayTraits
template<typename TypedArray>
class V8TypedArray {
public:
- static bool hasInstance(v8::Handle<v8::Value> value, v8::Isolate*, WrapperWorldType)
- {
- return TypedArrayTraits<TypedArray>::IsInstance(value);
- }
-
- static bool hasInstanceInAnyWorld(v8::Handle<v8::Value> value, v8::Isolate*)
+ static bool hasInstance(v8::Handle<v8::Value> value, v8::Isolate*)
{
return TypedArrayTraits<TypedArray>::IsInstance(value);
}
static TypedArray* toNative(v8::Handle<v8::Object>);
+ static TypedArray* toNativeWithTypeCheck(v8::Isolate*, v8::Handle<v8::Value>);
static void derefObject(void*);
static const WrapperTypeInfo wrapperTypeInfo;
static const int internalFieldCount = v8DefaultWrapperInternalFieldCount;
@@ -95,7 +91,7 @@ public:
template<typename CallbackInfo>
static void v8SetReturnValueForMainWorld(const CallbackInfo& info, TypedArray* impl)
{
- ASSERT(worldType(info.GetIsolate()) == MainWorld);
+ ASSERT(DOMWrapperWorld::current(info.GetIsolate()).isMainWorld());
if (UNLIKELY(!impl)) {
v8SetReturnValueNull(info);
return;
@@ -174,12 +170,17 @@ TypedArray* V8TypedArray<TypedArray>::toNative(v8::Handle<v8::Object> object)
return reinterpret_cast<TypedArray*>(typedarrayPtr);
}
+template <typename TypedArray>
+TypedArray* V8TypedArray<TypedArray>::toNativeWithTypeCheck(v8::Isolate* isolate, v8::Handle<v8::Value> value)
+{
+ return V8TypedArray<TypedArray>::hasInstance(value, isolate) ? V8TypedArray<TypedArray>::toNative(v8::Handle<v8::Object>::Cast(value)) : 0;
+}
template <typename TypedArray>
const WrapperTypeInfo V8TypedArray<TypedArray>::wrapperTypeInfo = {
gin::kEmbedderBlink,
0, V8TypedArray<TypedArray>::derefObject,
- 0, 0, 0, 0, 0, WrapperTypeObjectPrototype
+ 0, 0, 0, 0, 0, WrapperTypeObjectPrototype, RefCountedObject
};
template <typename TypedArray>
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8Uint16ArrayCustom.h b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8Uint16ArrayCustom.h
index e692a9cb979..d819d228ece 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8Uint16ArrayCustom.h
+++ b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8Uint16ArrayCustom.h
@@ -59,10 +59,6 @@ public:
typedef V8TypedArray<Uint16Array> V8Uint16Array;
-template<>
-class WrapperTypeTraits<Uint16Array> : public TypedArrayWrapperTraits<Uint16Array> { };
-
-
inline v8::Handle<v8::Object> wrap(Uint16Array* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
{
return V8TypedArray<Uint16Array>::wrap(impl, creationContext, isolate);
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8Uint32ArrayCustom.h b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8Uint32ArrayCustom.h
index 09ee5e990ec..9218135ef73 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8Uint32ArrayCustom.h
+++ b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8Uint32ArrayCustom.h
@@ -59,10 +59,6 @@ public:
typedef V8TypedArray<Uint32Array> V8Uint32Array;
-template<>
-class WrapperTypeTraits<Uint32Array> : public TypedArrayWrapperTraits<Uint32Array> { };
-
-
inline v8::Handle<v8::Object> wrap(Uint32Array* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
{
return V8TypedArray<Uint32Array>::wrap(impl, creationContext, isolate);
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8Uint8ArrayCustom.h b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8Uint8ArrayCustom.h
index 5bcf0045731..7a37501dc64 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8Uint8ArrayCustom.h
+++ b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8Uint8ArrayCustom.h
@@ -59,10 +59,6 @@ public:
typedef V8TypedArray<Uint8Array> V8Uint8Array;
-template<>
-class WrapperTypeTraits<Uint8Array> : public TypedArrayWrapperTraits<Uint8Array> { };
-
-
inline v8::Handle<v8::Object> wrap(Uint8Array* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
{
return V8TypedArray<Uint8Array>::wrap(impl, creationContext, isolate);
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8Uint8ClampedArrayCustom.h b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8Uint8ClampedArrayCustom.h
index 53d938ad4d4..7f936669b8d 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8Uint8ClampedArrayCustom.h
+++ b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8Uint8ClampedArrayCustom.h
@@ -59,10 +59,6 @@ public:
typedef V8TypedArray<Uint8ClampedArray> V8Uint8ClampedArray;
-template<>
-class WrapperTypeTraits<Uint8ClampedArray> : public TypedArrayWrapperTraits<Uint8ClampedArray> { };
-
-
inline v8::Handle<v8::Object> wrap(Uint8ClampedArray* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
{
return V8TypedArray<Uint8ClampedArray>::wrap(impl, creationContext, isolate);
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8WebGLRenderingContextCustom.cpp b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8WebGLRenderingContextCustom.cpp
index 8eb86e9ba86..faa45a3ce42 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8WebGLRenderingContextCustom.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8WebGLRenderingContextCustom.cpp
@@ -29,41 +29,44 @@
*/
#include "config.h"
-#include "V8WebGLRenderingContext.h"
-
-#include "V8ANGLEInstancedArrays.h"
-#include "V8EXTFragDepth.h"
-#include "V8EXTTextureFilterAnisotropic.h"
-#include "V8HTMLCanvasElement.h"
-#include "V8HTMLImageElement.h"
-#include "V8HTMLVideoElement.h"
-#include "V8ImageData.h"
-#include "V8OESElementIndexUint.h"
-#include "V8OESStandardDerivatives.h"
-#include "V8OESTextureFloat.h"
-#include "V8OESTextureFloatLinear.h"
-#include "V8OESTextureHalfFloat.h"
-#include "V8OESTextureHalfFloatLinear.h"
-#include "V8OESVertexArrayObject.h"
-#include "V8WebGLBuffer.h"
-#include "V8WebGLCompressedTextureATC.h"
-#include "V8WebGLCompressedTexturePVRTC.h"
-#include "V8WebGLCompressedTextureS3TC.h"
-#include "V8WebGLDebugRendererInfo.h"
-#include "V8WebGLDebugShaders.h"
-#include "V8WebGLDepthTexture.h"
-#include "V8WebGLDrawBuffers.h"
-#include "V8WebGLFramebuffer.h"
-#include "V8WebGLLoseContext.h"
-#include "V8WebGLProgram.h"
-#include "V8WebGLRenderbuffer.h"
-#include "V8WebGLShader.h"
-#include "V8WebGLTexture.h"
-#include "V8WebGLUniformLocation.h"
-#include "V8WebGLVertexArrayObjectOES.h"
+#include "bindings/core/v8/V8WebGLRenderingContext.h"
+
+#include "bindings/core/v8/V8ANGLEInstancedArrays.h"
+#include "bindings/core/v8/V8EXTBlendMinMax.h"
+#include "bindings/core/v8/V8EXTFragDepth.h"
+#include "bindings/core/v8/V8EXTShaderTextureLOD.h"
+#include "bindings/core/v8/V8EXTTextureFilterAnisotropic.h"
+#include "bindings/core/v8/V8HTMLCanvasElement.h"
+#include "bindings/core/v8/V8HTMLImageElement.h"
+#include "bindings/core/v8/V8HTMLVideoElement.h"
+#include "bindings/core/v8/V8ImageData.h"
+#include "bindings/core/v8/V8OESElementIndexUint.h"
+#include "bindings/core/v8/V8OESStandardDerivatives.h"
+#include "bindings/core/v8/V8OESTextureFloat.h"
+#include "bindings/core/v8/V8OESTextureFloatLinear.h"
+#include "bindings/core/v8/V8OESTextureHalfFloat.h"
+#include "bindings/core/v8/V8OESTextureHalfFloatLinear.h"
+#include "bindings/core/v8/V8OESVertexArrayObject.h"
+#include "bindings/core/v8/V8WebGLBuffer.h"
+#include "bindings/core/v8/V8WebGLCompressedTextureATC.h"
+#include "bindings/core/v8/V8WebGLCompressedTextureETC1.h"
+#include "bindings/core/v8/V8WebGLCompressedTexturePVRTC.h"
+#include "bindings/core/v8/V8WebGLCompressedTextureS3TC.h"
+#include "bindings/core/v8/V8WebGLDebugRendererInfo.h"
+#include "bindings/core/v8/V8WebGLDebugShaders.h"
+#include "bindings/core/v8/V8WebGLDepthTexture.h"
+#include "bindings/core/v8/V8WebGLDrawBuffers.h"
+#include "bindings/core/v8/V8WebGLFramebuffer.h"
+#include "bindings/core/v8/V8WebGLLoseContext.h"
+#include "bindings/core/v8/V8WebGLProgram.h"
+#include "bindings/core/v8/V8WebGLRenderbuffer.h"
+#include "bindings/core/v8/V8WebGLShader.h"
+#include "bindings/core/v8/V8WebGLTexture.h"
+#include "bindings/core/v8/V8WebGLUniformLocation.h"
+#include "bindings/core/v8/V8WebGLVertexArrayObjectOES.h"
#include "bindings/v8/ExceptionMessages.h"
#include "bindings/v8/V8Binding.h"
-#include "bindings/v8/V8HiddenPropertyName.h"
+#include "bindings/v8/V8HiddenValue.h"
#include "bindings/v8/custom/V8ArrayBufferViewCustom.h"
#include "bindings/v8/custom/V8Float32ArrayCustom.h"
#include "bindings/v8/custom/V8Int16ArrayCustom.h"
@@ -81,39 +84,43 @@
namespace WebCore {
// Allocates new storage via fastMalloc.
-// Returns NULL if array failed to convert for any reason.
-static float* jsArrayToFloatArray(v8::Handle<v8::Array> array, uint32_t len)
+// Returns 0 if array failed to convert for any reason.
+static float* jsArrayToFloatArray(v8::Handle<v8::Array> array, uint32_t len, ExceptionState& exceptionState)
{
// Convert the data element-by-element.
- if (len > std::numeric_limits<uint32_t>::max() / sizeof(float))
+ if (len > std::numeric_limits<uint32_t>::max() / sizeof(float)) {
+ exceptionState.throwTypeError("Array length exceeds supported limit.");
return 0;
+ }
float* data = static_cast<float*>(fastMalloc(len * sizeof(float)));
for (uint32_t i = 0; i < len; i++) {
v8::Local<v8::Value> val = array->Get(i);
- if (!val->IsNumber()) {
+ float value = toFloat(val, exceptionState);
+ if (exceptionState.hadException()) {
fastFree(data);
return 0;
}
- data[i] = toFloat(val);
+ data[i] = value;
}
return data;
}
// Allocates new storage via fastMalloc.
-// Returns NULL if array failed to convert for any reason.
-static int* jsArrayToIntArray(v8::Handle<v8::Array> array, uint32_t len)
+// Returns 0 if array failed to convert for any reason.
+static int* jsArrayToIntArray(v8::Handle<v8::Array> array, uint32_t len, ExceptionState& exceptionState)
{
// Convert the data element-by-element.
- if (len > std::numeric_limits<uint32_t>::max() / sizeof(int))
+ if (len > std::numeric_limits<uint32_t>::max() / sizeof(int)) {
+ exceptionState.throwTypeError("Array length exceeds supported limit.");
return 0;
+ }
int* data = static_cast<int*>(fastMalloc(len * sizeof(int)));
for (uint32_t i = 0; i < len; i++) {
v8::Local<v8::Value> val = array->Get(i);
- bool ok;
- int ival = toInt32(val, ok);
- if (!ok) {
+ int ival = toInt32(val, exceptionState);
+ if (exceptionState.hadException()) {
fastFree(data);
return 0;
}
@@ -131,19 +138,19 @@ static v8::Handle<v8::Value> toV8Object(const WebGLGetInfo& args, v8::Handle<v8:
const Vector<bool>& value = args.getBoolArray();
v8::Local<v8::Array> array = v8::Array::New(isolate, value.size());
for (size_t ii = 0; ii < value.size(); ++ii)
- array->Set(v8::Integer::New(ii, isolate), v8Boolean(value[ii], isolate));
+ array->Set(v8::Integer::New(isolate, ii), v8Boolean(value[ii], isolate));
return array;
}
case WebGLGetInfo::kTypeFloat:
return v8::Number::New(isolate, args.getFloat());
case WebGLGetInfo::kTypeInt:
- return v8::Integer::New(args.getInt(), isolate);
+ return v8::Integer::New(isolate, args.getInt());
case WebGLGetInfo::kTypeNull:
return v8::Null(isolate);
case WebGLGetInfo::kTypeString:
return v8String(isolate, args.getString());
case WebGLGetInfo::kTypeUnsignedInt:
- return v8::Integer::NewFromUnsigned(args.getUnsignedInt(), isolate);
+ return v8::Integer::NewFromUnsigned(isolate, args.getUnsignedInt());
case WebGLGetInfo::kTypeWebGLBuffer:
return toV8(args.getWebGLBuffer(), creationContext, isolate);
case WebGLGetInfo::kTypeWebGLFloatArray:
@@ -179,81 +186,96 @@ static v8::Handle<v8::Value> toV8Object(WebGLExtension* extension, v8::Handle<v8
v8::Handle<v8::Value> extensionObject;
const char* referenceName = 0;
switch (extension->name()) {
- case WebGLExtension::ANGLEInstancedArraysName:
+ case ANGLEInstancedArraysName:
extensionObject = toV8(static_cast<ANGLEInstancedArrays*>(extension), contextObject, isolate);
referenceName = "angleInstancedArraysName";
break;
- case WebGLExtension::EXTFragDepthName:
+ case EXTBlendMinMaxName:
+ extensionObject = toV8(static_cast<EXTBlendMinMax*>(extension), contextObject, isolate);
+ referenceName = "extBlendMinMaxName";
+ break;
+ case EXTFragDepthName:
extensionObject = toV8(static_cast<EXTFragDepth*>(extension), contextObject, isolate);
referenceName = "extFragDepthName";
break;
- case WebGLExtension::EXTTextureFilterAnisotropicName:
+ case EXTShaderTextureLODName:
+ extensionObject = toV8(static_cast<EXTShaderTextureLOD*>(extension), contextObject, isolate);
+ referenceName = "extShaderTextureLODName";
+ break;
+ case EXTTextureFilterAnisotropicName:
extensionObject = toV8(static_cast<EXTTextureFilterAnisotropic*>(extension), contextObject, isolate);
referenceName = "extTextureFilterAnisotropicName";
break;
- case WebGLExtension::OESElementIndexUintName:
+ case OESElementIndexUintName:
extensionObject = toV8(static_cast<OESElementIndexUint*>(extension), contextObject, isolate);
referenceName = "oesElementIndexUintName";
break;
- case WebGLExtension::OESStandardDerivativesName:
+ case OESStandardDerivativesName:
extensionObject = toV8(static_cast<OESStandardDerivatives*>(extension), contextObject, isolate);
referenceName = "oesStandardDerivativesName";
break;
- case WebGLExtension::OESTextureFloatName:
+ case OESTextureFloatName:
extensionObject = toV8(static_cast<OESTextureFloat*>(extension), contextObject, isolate);
referenceName = "oesTextureFloatName";
break;
- case WebGLExtension::OESTextureFloatLinearName:
+ case OESTextureFloatLinearName:
extensionObject = toV8(static_cast<OESTextureFloatLinear*>(extension), contextObject, isolate);
referenceName = "oesTextureFloatLinearName";
break;
- case WebGLExtension::OESTextureHalfFloatName:
+ case OESTextureHalfFloatName:
extensionObject = toV8(static_cast<OESTextureHalfFloat*>(extension), contextObject, isolate);
referenceName = "oesTextureHalfFloatName";
break;
- case WebGLExtension::OESTextureHalfFloatLinearName:
+ case OESTextureHalfFloatLinearName:
extensionObject = toV8(static_cast<OESTextureHalfFloatLinear*>(extension), contextObject, isolate);
referenceName = "oesTextureHalfFloatLinearName";
break;
- case WebGLExtension::OESVertexArrayObjectName:
+ case OESVertexArrayObjectName:
extensionObject = toV8(static_cast<OESVertexArrayObject*>(extension), contextObject, isolate);
referenceName = "oesVertexArrayObjectName";
break;
- case WebGLExtension::WebGLCompressedTextureATCName:
+ case WebGLCompressedTextureATCName:
extensionObject = toV8(static_cast<WebGLCompressedTextureATC*>(extension), contextObject, isolate);
referenceName = "webGLCompressedTextureATCName";
break;
- case WebGLExtension::WebGLCompressedTexturePVRTCName:
+ case WebGLCompressedTextureETC1Name:
+ extensionObject = toV8(static_cast<WebGLCompressedTextureETC1*>(extension), contextObject, isolate);
+ referenceName = "webGLCompressedTextureETC1Name";
+ break;
+ case WebGLCompressedTexturePVRTCName:
extensionObject = toV8(static_cast<WebGLCompressedTexturePVRTC*>(extension), contextObject, isolate);
referenceName = "webGLCompressedTexturePVRTCName";
break;
- case WebGLExtension::WebGLCompressedTextureS3TCName:
+ case WebGLCompressedTextureS3TCName:
extensionObject = toV8(static_cast<WebGLCompressedTextureS3TC*>(extension), contextObject, isolate);
referenceName = "webGLCompressedTextureS3TCName";
break;
- case WebGLExtension::WebGLDebugRendererInfoName:
+ case WebGLDebugRendererInfoName:
extensionObject = toV8(static_cast<WebGLDebugRendererInfo*>(extension), contextObject, isolate);
referenceName = "webGLDebugRendererInfoName";
break;
- case WebGLExtension::WebGLDebugShadersName:
+ case WebGLDebugShadersName:
extensionObject = toV8(static_cast<WebGLDebugShaders*>(extension), contextObject, isolate);
referenceName = "webGLDebugShadersName";
break;
- case WebGLExtension::WebGLDepthTextureName:
+ case WebGLDepthTextureName:
extensionObject = toV8(static_cast<WebGLDepthTexture*>(extension), contextObject, isolate);
referenceName = "webGLDepthTextureName";
break;
- case WebGLExtension::WebGLDrawBuffersName:
+ case WebGLDrawBuffersName:
extensionObject = toV8(static_cast<WebGLDrawBuffers*>(extension), contextObject, isolate);
referenceName = "webGLDrawBuffersName";
break;
- case WebGLExtension::WebGLLoseContextName:
+ case WebGLLoseContextName:
extensionObject = toV8(static_cast<WebGLLoseContext*>(extension), contextObject, isolate);
referenceName = "webGLLoseContextName";
break;
+ case WebGLExtensionNameCount:
+ notImplemented();
+ return v8::Undefined(isolate);
}
ASSERT(!extensionObject.IsEmpty());
- V8HiddenPropertyName::setNamedHiddenReference(contextObject, referenceName, extensionObject);
+ V8HiddenValue::setHiddenValue(isolate, contextObject, v8AtomicString(isolate, referenceName), extensionObject);
return extensionObject;
}
@@ -261,16 +283,21 @@ enum ObjectType {
kBuffer, kRenderbuffer, kTexture, kVertexAttrib
};
-static void getObjectParameter(const v8::FunctionCallbackInfo<v8::Value>& info, ObjectType objectType, const char* method)
+static void getObjectParameter(const v8::FunctionCallbackInfo<v8::Value>& info, ObjectType objectType, ExceptionState& exceptionState)
{
if (info.Length() != 2) {
- throwTypeError(ExceptionMessages::failedToExecute(method, "WebGLRenderingContext", ExceptionMessages::notEnoughArguments(2, info.Length())), info.GetIsolate());
+ exceptionState.throwTypeError(ExceptionMessages::notEnoughArguments(2, info.Length()));
+ exceptionState.throwIfNeeded();
return;
}
WebGLRenderingContext* context = V8WebGLRenderingContext::toNative(info.Holder());
- unsigned target = toInt32(info[0]);
- unsigned pname = toInt32(info[1]);
+ unsigned target = toInt32(info[0], exceptionState);
+ if (exceptionState.throwIfNeeded())
+ return;
+ unsigned pname = toInt32(info[1], exceptionState);
+ if (exceptionState.throwIfNeeded())
+ return;
WebGLGetInfo args;
switch (objectType) {
case kBuffer:
@@ -293,15 +320,9 @@ static void getObjectParameter(const v8::FunctionCallbackInfo<v8::Value>& info,
v8SetReturnValue(info, toV8Object(args, info.Holder(), info.GetIsolate()));
}
-static WebGLUniformLocation* toWebGLUniformLocation(v8::Handle<v8::Value> value, bool& ok, v8::Isolate* isolate)
+static WebGLUniformLocation* toWebGLUniformLocation(v8::Handle<v8::Value> value, v8::Isolate* isolate)
{
- ok = false;
- WebGLUniformLocation* location = 0;
- if (V8WebGLUniformLocation::hasInstance(value, isolate, worldType(isolate))) {
- location = V8WebGLUniformLocation::toNative(value->ToObject());
- ok = true;
- }
- return location;
+ return V8WebGLUniformLocation::toNativeWithTypeCheck(isolate, value);
}
enum WhichProgramCall {
@@ -310,17 +331,21 @@ enum WhichProgramCall {
void V8WebGLRenderingContext::getAttachedShadersMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& info)
{
+ ExceptionState exceptionState(ExceptionState::ExecutionContext, "getAttachedShaders", "WebGLRenderingContext", info.Holder(), info.GetIsolate());
if (info.Length() < 1) {
- throwTypeError(ExceptionMessages::failedToExecute("getAttachedShaders", "WebGLRenderingContext", ExceptionMessages::notEnoughArguments(1, info.Length())), info.GetIsolate());
+ exceptionState.throwTypeError(ExceptionMessages::notEnoughArguments(1, info.Length()));
+ exceptionState.throwIfNeeded();
return;
}
+ const int programArgumentIndex = 0;
WebGLRenderingContext* context = V8WebGLRenderingContext::toNative(info.Holder());
- if (info.Length() > 0 && !isUndefinedOrNull(info[0]) && !V8WebGLProgram::hasInstance(info[0], info.GetIsolate(), worldType(info.GetIsolate()))) {
- throwUninformativeAndGenericTypeError(info.GetIsolate());
+ if (info.Length() > 0 && !isUndefinedOrNull(info[programArgumentIndex]) && !V8WebGLProgram::hasInstance(info[programArgumentIndex], info.GetIsolate())) {
+ exceptionState.throwTypeError(ExceptionMessages::argumentNullOrIncorrectType(programArgumentIndex + 1, "WebGLProgram"));
+ exceptionState.throwIfNeeded();
return;
}
- WebGLProgram* program = V8WebGLProgram::hasInstance(info[0], info.GetIsolate(), worldType(info.GetIsolate())) ? V8WebGLProgram::toNative(v8::Handle<v8::Object>::Cast(info[0])) : 0;
+ WebGLProgram* program = V8WebGLProgram::toNativeWithTypeCheck(info.GetIsolate(), info[programArgumentIndex]);
Vector<RefPtr<WebGLShader> > shaders;
bool succeed = context->getAttachedShaders(program, shaders);
if (!succeed) {
@@ -329,136 +354,169 @@ void V8WebGLRenderingContext::getAttachedShadersMethodCustom(const v8::FunctionC
}
v8::Local<v8::Array> array = v8::Array::New(info.GetIsolate(), shaders.size());
for (size_t ii = 0; ii < shaders.size(); ++ii)
- array->Set(v8::Integer::New(ii, info.GetIsolate()), toV8(shaders[ii].get(), info.Holder(), info.GetIsolate()));
+ array->Set(v8::Integer::New(info.GetIsolate(), ii), toV8(shaders[ii].get(), info.Holder(), info.GetIsolate()));
v8SetReturnValue(info, array);
}
void V8WebGLRenderingContext::getBufferParameterMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& info)
{
- getObjectParameter(info, kBuffer, "getBufferParameter");
+ ExceptionState exceptionState(ExceptionState::ExecutionContext, "getBufferParameter", "WebGLRenderingContext", info.Holder(), info.GetIsolate());
+ getObjectParameter(info, kBuffer, exceptionState);
}
void V8WebGLRenderingContext::getExtensionMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& info)
{
- WebGLRenderingContext* imp = V8WebGLRenderingContext::toNative(info.Holder());
+ ExceptionState exceptionState(ExceptionState::ExecutionContext, "getExtension", "WebGLRenderingContext", info.Holder(), info.GetIsolate());
+ WebGLRenderingContext* impl = V8WebGLRenderingContext::toNative(info.Holder());
if (info.Length() < 1) {
- throwTypeError(ExceptionMessages::failedToExecute("getExtension", "WebGLRenderingContext", ExceptionMessages::notEnoughArguments(1, info.Length())), info.GetIsolate());
+ exceptionState.throwTypeError(ExceptionMessages::notEnoughArguments(1, info.Length()));
+ exceptionState.throwIfNeeded();
return;
}
- V8TRYCATCH_FOR_V8STRINGRESOURCE_VOID(V8StringResource<>, name, info[0]);
- RefPtr<WebGLExtension> extension(imp->getExtension(name));
+ TOSTRING_VOID(V8StringResource<>, name, info[0]);
+ RefPtr<WebGLExtension> extension(impl->getExtension(name));
v8SetReturnValue(info, toV8Object(extension.get(), info.Holder(), info.GetIsolate()));
}
void V8WebGLRenderingContext::getFramebufferAttachmentParameterMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& info)
{
+ ExceptionState exceptionState(ExceptionState::ExecutionContext, "getFramebufferAttachmentParameter", "WebGLRenderingContext", info.Holder(), info.GetIsolate());
if (info.Length() != 3) {
- throwTypeError(ExceptionMessages::failedToExecute("getFramebufferAttachmentParameter", "WebGLRenderingContext", ExceptionMessages::notEnoughArguments(3, info.Length())), info.GetIsolate());
+ exceptionState.throwTypeError(ExceptionMessages::notEnoughArguments(3, info.Length()));
+ exceptionState.throwIfNeeded();
return;
}
WebGLRenderingContext* context = V8WebGLRenderingContext::toNative(info.Holder());
unsigned target = toInt32(info[0]);
- unsigned attachment = toInt32(info[1]);
- unsigned pname = toInt32(info[2]);
+ unsigned attachment = toInt32(info[1], exceptionState);
+ if (exceptionState.throwIfNeeded())
+ return;
+ unsigned pname = toInt32(info[2], exceptionState);
+ if (exceptionState.throwIfNeeded())
+ return;
WebGLGetInfo args = context->getFramebufferAttachmentParameter(target, attachment, pname);
v8SetReturnValue(info, toV8Object(args, info.Holder(), info.GetIsolate()));
}
void V8WebGLRenderingContext::getParameterMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& info)
{
+ ExceptionState exceptionState(ExceptionState::ExecutionContext, "getParameter", "WebGLRenderingContext", info.Holder(), info.GetIsolate());
if (info.Length() != 1) {
- throwTypeError(ExceptionMessages::failedToExecute("getParameter", "WebGLRenderingContext", ExceptionMessages::notEnoughArguments(1, info.Length())), info.GetIsolate());
+ exceptionState.throwTypeError(ExceptionMessages::notEnoughArguments(1, info.Length()));
+ exceptionState.throwIfNeeded();
return;
}
WebGLRenderingContext* context = V8WebGLRenderingContext::toNative(info.Holder());
- unsigned pname = toInt32(info[0]);
+ unsigned pname = toInt32(info[0], exceptionState);
+ if (exceptionState.throwIfNeeded())
+ return;
WebGLGetInfo args = context->getParameter(pname);
v8SetReturnValue(info, toV8Object(args, info.Holder(), info.GetIsolate()));
}
void V8WebGLRenderingContext::getProgramParameterMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& info)
{
+ ExceptionState exceptionState(ExceptionState::ExecutionContext, "getProgramParameter", "WebGLRenderingContext", info.Holder(), info.GetIsolate());
if (info.Length() != 2) {
- throwTypeError(ExceptionMessages::failedToExecute("getProgramParameter", "WebGLRenderingContext", ExceptionMessages::notEnoughArguments(2, info.Length())), info.GetIsolate());
+ exceptionState.throwTypeError(ExceptionMessages::notEnoughArguments(2, info.Length()));
+ exceptionState.throwIfNeeded();
return;
}
+ const int programArgumentIndex = 0;
WebGLRenderingContext* context = V8WebGLRenderingContext::toNative(info.Holder());
- if (info.Length() > 0 && !isUndefinedOrNull(info[0]) && !V8WebGLProgram::hasInstance(info[0], info.GetIsolate(), worldType(info.GetIsolate()))) {
- throwUninformativeAndGenericTypeError(info.GetIsolate());
+ if (info.Length() > 0 && !isUndefinedOrNull(info[programArgumentIndex]) && !V8WebGLProgram::hasInstance(info[programArgumentIndex], info.GetIsolate())) {
+ exceptionState.throwTypeError(ExceptionMessages::argumentNullOrIncorrectType(programArgumentIndex + 1, "WebGLProgram"));
+ exceptionState.throwIfNeeded();
return;
}
- WebGLProgram* program = V8WebGLProgram::hasInstance(info[0], info.GetIsolate(), worldType(info.GetIsolate())) ? V8WebGLProgram::toNative(v8::Handle<v8::Object>::Cast(info[0])) : 0;
- unsigned pname = toInt32(info[1]);
+ WebGLProgram* program = V8WebGLProgram::toNativeWithTypeCheck(info.GetIsolate(), info[programArgumentIndex]);
+ unsigned pname = toInt32(info[1], exceptionState);
+ if (exceptionState.throwIfNeeded())
+ return;
WebGLGetInfo args = context->getProgramParameter(program, pname);
v8SetReturnValue(info, toV8Object(args, info.Holder(), info.GetIsolate()));
}
void V8WebGLRenderingContext::getRenderbufferParameterMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& info)
{
- getObjectParameter(info, kRenderbuffer, "getRenderbufferParameter");
+ ExceptionState exceptionState(ExceptionState::ExecutionContext, "getRenderbufferParameter", "WebGLRenderingContext", info.Holder(), info.GetIsolate());
+ getObjectParameter(info, kRenderbuffer, exceptionState);
}
void V8WebGLRenderingContext::getShaderParameterMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& info)
{
+ ExceptionState exceptionState(ExceptionState::ExecutionContext, "getShaderParameter", "WebGLRenderingContext", info.Holder(), info.GetIsolate());
if (info.Length() != 2) {
- throwTypeError(ExceptionMessages::failedToExecute("getShaderParameter", "WebGLRenderingContext", ExceptionMessages::notEnoughArguments(2, info.Length())), info.GetIsolate());
+ exceptionState.throwTypeError(ExceptionMessages::notEnoughArguments(2, info.Length()));
+ exceptionState.throwIfNeeded();
return;
}
+ const int shaderArgumentIndex = 0;
WebGLRenderingContext* context = V8WebGLRenderingContext::toNative(info.Holder());
- if (info.Length() > 0 && !isUndefinedOrNull(info[0]) && !V8WebGLShader::hasInstance(info[0], info.GetIsolate(), worldType(info.GetIsolate()))) {
- throwUninformativeAndGenericTypeError(info.GetIsolate());
+ if (info.Length() > 0 && !isUndefinedOrNull(info[shaderArgumentIndex]) && !V8WebGLShader::hasInstance(info[shaderArgumentIndex], info.GetIsolate())) {
+ exceptionState.throwTypeError(ExceptionMessages::argumentNullOrIncorrectType(shaderArgumentIndex + 1, "WebGLShader"));
+ exceptionState.throwIfNeeded();
return;
}
- WebGLShader* shader = V8WebGLShader::hasInstance(info[0], info.GetIsolate(), worldType(info.GetIsolate())) ? V8WebGLShader::toNative(v8::Handle<v8::Object>::Cast(info[0])) : 0;
- unsigned pname = toInt32(info[1]);
+ WebGLShader* shader = V8WebGLShader::toNativeWithTypeCheck(info.GetIsolate(), info[shaderArgumentIndex]);
+ unsigned pname = toInt32(info[1], exceptionState);
+ if (exceptionState.throwIfNeeded())
+ return;
WebGLGetInfo args = context->getShaderParameter(shader, pname);
v8SetReturnValue(info, toV8Object(args, info.Holder(), info.GetIsolate()));
}
void V8WebGLRenderingContext::getSupportedExtensionsMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& info)
{
- WebGLRenderingContext* imp = V8WebGLRenderingContext::toNative(info.Holder());
- if (imp->isContextLost()) {
+ WebGLRenderingContext* impl = V8WebGLRenderingContext::toNative(info.Holder());
+ if (impl->isContextLost()) {
v8SetReturnValueNull(info);
return;
}
- Vector<String> value = imp->getSupportedExtensions();
+ Vector<String> value = impl->getSupportedExtensions();
v8::Local<v8::Array> array = v8::Array::New(info.GetIsolate(), value.size());
for (size_t ii = 0; ii < value.size(); ++ii)
- array->Set(v8::Integer::New(ii, info.GetIsolate()), v8String(info.GetIsolate(), value[ii]));
+ array->Set(v8::Integer::New(info.GetIsolate(), ii), v8String(info.GetIsolate(), value[ii]));
v8SetReturnValue(info, array);
}
void V8WebGLRenderingContext::getTexParameterMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& info)
{
- getObjectParameter(info, kTexture, "getTexParameter");
+ ExceptionState exceptionState(ExceptionState::ExecutionContext, "getTexParameter", "WebGLRenderingContext", info.Holder(), info.GetIsolate());
+ getObjectParameter(info, kTexture, exceptionState);
}
void V8WebGLRenderingContext::getUniformMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& info)
{
+ ExceptionState exceptionState(ExceptionState::ExecutionContext, "getUniform", "WebGLRenderingContext", info.Holder(), info.GetIsolate());
if (info.Length() != 2) {
- throwTypeError(ExceptionMessages::failedToExecute("getUniform", "WebGLRenderingContext", ExceptionMessages::notEnoughArguments(2, info.Length())), info.GetIsolate());
+ exceptionState.throwTypeError(ExceptionMessages::notEnoughArguments(2, info.Length()));
+ exceptionState.throwIfNeeded();
return;
}
+ const int programArgumentIndex = 0;
WebGLRenderingContext* context = V8WebGLRenderingContext::toNative(info.Holder());
- if (info.Length() > 0 && !isUndefinedOrNull(info[0]) && !V8WebGLProgram::hasInstance(info[0], info.GetIsolate(), worldType(info.GetIsolate()))) {
- throwUninformativeAndGenericTypeError(info.GetIsolate());
+ if (info.Length() > 0 && !isUndefinedOrNull(info[programArgumentIndex]) && !V8WebGLProgram::hasInstance(info[programArgumentIndex], info.GetIsolate())) {
+ exceptionState.throwTypeError(ExceptionMessages::argumentNullOrIncorrectType(programArgumentIndex + 1, "WebGLProgram"));
+ exceptionState.throwIfNeeded();
return;
}
- WebGLProgram* program = V8WebGLProgram::hasInstance(info[0], info.GetIsolate(), worldType(info.GetIsolate())) ? V8WebGLProgram::toNative(v8::Handle<v8::Object>::Cast(info[0])) : 0;
+ WebGLProgram* program = V8WebGLProgram::toNativeWithTypeCheck(info.GetIsolate(), info[programArgumentIndex]);
- if (info.Length() > 1 && !isUndefinedOrNull(info[1]) && !V8WebGLUniformLocation::hasInstance(info[1], info.GetIsolate(), worldType(info.GetIsolate()))) {
- throwUninformativeAndGenericTypeError(info.GetIsolate());
+ const int uniformArgumentIndex = 1;
+ if (info.Length() > 1 && !isUndefinedOrNull(info[uniformArgumentIndex]) && !V8WebGLUniformLocation::hasInstance(info[uniformArgumentIndex], info.GetIsolate())) {
+ exceptionState.throwTypeError(ExceptionMessages::argumentNullOrIncorrectType(uniformArgumentIndex + 1, "WebGLUniformLocation"));
+ exceptionState.throwIfNeeded();
return;
}
- bool ok = false;
- WebGLUniformLocation* location = toWebGLUniformLocation(info[1], ok, info.GetIsolate());
+ const int uniformLocationArgumentIndex = 1;
+ WebGLUniformLocation* location = toWebGLUniformLocation(info[uniformLocationArgumentIndex], info.GetIsolate());
WebGLGetInfo args = context->getUniform(program, location);
v8SetReturnValue(info, toV8Object(args, info.Holder(), info.GetIsolate()));
@@ -466,7 +524,8 @@ void V8WebGLRenderingContext::getUniformMethodCustom(const v8::FunctionCallbackI
void V8WebGLRenderingContext::getVertexAttribMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& info)
{
- getObjectParameter(info, kVertexAttrib, "getVertexAttrib");
+ ExceptionState exceptionState(ExceptionState::ExecutionContext, "getVertexAttrib", "WebGLRenderingContext", info.Holder(), info.GetIsolate());
+ getObjectParameter(info, kVertexAttrib, exceptionState);
}
enum FunctionToCall {
@@ -488,7 +547,7 @@ bool isFunctionToCallForAttribute(FunctionToCall functionToCall)
return false;
}
-static void vertexAttribAndUniformHelperf(const v8::FunctionCallbackInfo<v8::Value>& info, FunctionToCall functionToCall, const char* method)
+static void vertexAttribAndUniformHelperf(const v8::FunctionCallbackInfo<v8::Value>& info, FunctionToCall functionToCall, ExceptionState& exceptionState)
{
// Forms:
// * glUniform1fv(WebGLUniformLocation location, Array data);
@@ -509,29 +568,34 @@ static void vertexAttribAndUniformHelperf(const v8::FunctionCallbackInfo<v8::Val
// * glVertexAttrib4fv(GLint index, Float32Array data);
if (info.Length() != 2) {
- throwTypeError(ExceptionMessages::failedToExecute(method, "WebGLRenderingContext", ExceptionMessages::notEnoughArguments(2, info.Length())), info.GetIsolate());
+ exceptionState.throwTypeError(ExceptionMessages::notEnoughArguments(2, info.Length()));
+ exceptionState.throwIfNeeded();
return;
}
- bool ok = false;
int index = -1;
WebGLUniformLocation* location = 0;
- if (isFunctionToCallForAttribute(functionToCall))
- index = toInt32(info[0]);
- else {
- if (info.Length() > 0 && !isUndefinedOrNull(info[0]) && !V8WebGLUniformLocation::hasInstance(info[0], info.GetIsolate(), worldType(info.GetIsolate()))) {
- throwUninformativeAndGenericTypeError(info.GetIsolate());
+ if (isFunctionToCallForAttribute(functionToCall)) {
+ index = toInt32(info[0], exceptionState);
+ if (exceptionState.throwIfNeeded())
+ return;
+ } else {
+ const int uniformLocationArgumentIndex = 0;
+ if (info.Length() > 0 && !isUndefinedOrNull(info[uniformLocationArgumentIndex]) && !V8WebGLUniformLocation::hasInstance(info[uniformLocationArgumentIndex], info.GetIsolate())) {
+ exceptionState.throwTypeError(ExceptionMessages::argumentNullOrIncorrectType(uniformLocationArgumentIndex + 1, "WebGLUniformLocation"));
+ exceptionState.throwIfNeeded();
return;
}
- location = toWebGLUniformLocation(info[0], ok, info.GetIsolate());
+ location = toWebGLUniformLocation(info[uniformLocationArgumentIndex], info.GetIsolate());
}
WebGLRenderingContext* context = V8WebGLRenderingContext::toNative(info.Holder());
- if (V8Float32Array::hasInstance(info[1], info.GetIsolate(), worldType(info.GetIsolate()))) {
- Float32Array* array = V8Float32Array::toNative(info[1]->ToObject());
- ASSERT(array != NULL);
+ const int indexArrayArgument = 1;
+ if (V8Float32Array::hasInstance(info[indexArrayArgument], info.GetIsolate())) {
+ Float32Array* array = V8Float32Array::toNative(info[indexArrayArgument]->ToObject());
+ ASSERT(array);
switch (functionToCall) {
case kUniform1v: context->uniform1fv(location, array); break;
case kUniform2v: context->uniform2fv(location, array); break;
@@ -546,16 +610,20 @@ static void vertexAttribAndUniformHelperf(const v8::FunctionCallbackInfo<v8::Val
return;
}
- if (info[1].IsEmpty() || !info[1]->IsArray()) {
- throwUninformativeAndGenericTypeError(info.GetIsolate());
+ if (info[indexArrayArgument].IsEmpty() || !info[indexArrayArgument]->IsArray()) {
+ exceptionState.throwTypeError(ExceptionMessages::argumentNullOrIncorrectType(indexArrayArgument + 1, "Array"));
+ exceptionState.throwIfNeeded();
return;
}
v8::Handle<v8::Array> array = v8::Local<v8::Array>::Cast(info[1]);
uint32_t len = array->Length();
- float* data = jsArrayToFloatArray(array, len);
+ float* data = jsArrayToFloatArray(array, len, exceptionState);
+ if (exceptionState.throwIfNeeded())
+ return;
if (!data) {
// FIXME: consider different / better exception type.
- setDOMException(SyntaxError, info.GetIsolate());
+ exceptionState.throwDOMException(SyntaxError, "Failed to convert array argument");
+ exceptionState.throwIfNeeded();
return;
}
switch (functionToCall) {
@@ -572,7 +640,7 @@ static void vertexAttribAndUniformHelperf(const v8::FunctionCallbackInfo<v8::Val
fastFree(data);
}
-static void uniformHelperi(const v8::FunctionCallbackInfo<v8::Value>& info, FunctionToCall functionToCall, const char* method)
+static void uniformHelperi(const v8::FunctionCallbackInfo<v8::Value>& info, FunctionToCall functionToCall, ExceptionState& exceptionState)
{
// Forms:
// * glUniform1iv(GLUniformLocation location, Array data);
@@ -585,21 +653,24 @@ static void uniformHelperi(const v8::FunctionCallbackInfo<v8::Value>& info, Func
// * glUniform4iv(GLUniformLocation location, Int32Array data);
if (info.Length() != 2) {
- throwTypeError(ExceptionMessages::failedToExecute(method, "WebGLRenderingContext", ExceptionMessages::notEnoughArguments(2, info.Length())), info.GetIsolate());
+ exceptionState.throwTypeError(ExceptionMessages::notEnoughArguments(2, info.Length()));
+ exceptionState.throwIfNeeded();
return;
}
+ const int uniformLocationArgumentIndex = 0;
WebGLRenderingContext* context = V8WebGLRenderingContext::toNative(info.Holder());
- if (info.Length() > 0 && !isUndefinedOrNull(info[0]) && !V8WebGLUniformLocation::hasInstance(info[0], info.GetIsolate(), worldType(info.GetIsolate()))) {
- throwUninformativeAndGenericTypeError(info.GetIsolate());
+ if (info.Length() > 0 && !isUndefinedOrNull(info[uniformLocationArgumentIndex]) && !V8WebGLUniformLocation::hasInstance(info[uniformLocationArgumentIndex], info.GetIsolate())) {
+ exceptionState.throwTypeError(ExceptionMessages::argumentNullOrIncorrectType(uniformLocationArgumentIndex + 1, "WebGLUniformLocation"));
+ exceptionState.throwIfNeeded();
return;
}
- bool ok = false;
- WebGLUniformLocation* location = toWebGLUniformLocation(info[0], ok, info.GetIsolate());
+ WebGLUniformLocation* location = toWebGLUniformLocation(info[uniformLocationArgumentIndex], info.GetIsolate());
- if (V8Int32Array::hasInstance(info[1], info.GetIsolate(), worldType(info.GetIsolate()))) {
- Int32Array* array = V8Int32Array::toNative(info[1]->ToObject());
- ASSERT(array != NULL);
+ const int indexArrayArgumentIndex = 1;
+ if (V8Int32Array::hasInstance(info[indexArrayArgumentIndex], info.GetIsolate())) {
+ Int32Array* array = V8Int32Array::toNative(info[indexArrayArgumentIndex]->ToObject());
+ ASSERT(array);
switch (functionToCall) {
case kUniform1v: context->uniform1iv(location, array); break;
case kUniform2v: context->uniform2iv(location, array); break;
@@ -610,16 +681,20 @@ static void uniformHelperi(const v8::FunctionCallbackInfo<v8::Value>& info, Func
return;
}
- if (info[1].IsEmpty() || !info[1]->IsArray()) {
- throwUninformativeAndGenericTypeError(info.GetIsolate());
+ if (info[indexArrayArgumentIndex].IsEmpty() || !info[indexArrayArgumentIndex]->IsArray()) {
+ exceptionState.throwTypeError(ExceptionMessages::argumentNullOrIncorrectType(indexArrayArgumentIndex + 1, "Array"));
+ exceptionState.throwIfNeeded();
return;
}
- v8::Handle<v8::Array> array = v8::Local<v8::Array>::Cast(info[1]);
+ v8::Handle<v8::Array> array = v8::Local<v8::Array>::Cast(info[indexArrayArgumentIndex]);
uint32_t len = array->Length();
- int* data = jsArrayToIntArray(array, len);
+ int* data = jsArrayToIntArray(array, len, exceptionState);
+ if (exceptionState.throwIfNeeded())
+ return;
if (!data) {
// FIXME: consider different / better exception type.
- setDOMException(SyntaxError, info.GetIsolate());
+ exceptionState.throwDOMException(SyntaxError, "Failed to convert array argument");
+ exceptionState.throwIfNeeded();
return;
}
switch (functionToCall) {
@@ -634,45 +709,53 @@ static void uniformHelperi(const v8::FunctionCallbackInfo<v8::Value>& info, Func
void V8WebGLRenderingContext::uniform1fvMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& info)
{
- vertexAttribAndUniformHelperf(info, kUniform1v, "uniform1fv");
+ ExceptionState exceptionState(ExceptionState::ExecutionContext, "uniform1fv", "WebGLRenderingContext", info.Holder(), info.GetIsolate());
+ vertexAttribAndUniformHelperf(info, kUniform1v, exceptionState);
}
void V8WebGLRenderingContext::uniform1ivMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& info)
{
- uniformHelperi(info, kUniform1v, "uniform1iv");
+ ExceptionState exceptionState(ExceptionState::ExecutionContext, "uniform1iv", "WebGLRenderingContext", info.Holder(), info.GetIsolate());
+ uniformHelperi(info, kUniform1v, exceptionState);
}
void V8WebGLRenderingContext::uniform2fvMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& info)
{
- vertexAttribAndUniformHelperf(info, kUniform2v, "uniform2fv");
+ ExceptionState exceptionState(ExceptionState::ExecutionContext, "uniform2fv", "WebGLRenderingContext", info.Holder(), info.GetIsolate());
+ vertexAttribAndUniformHelperf(info, kUniform2v, exceptionState);
}
void V8WebGLRenderingContext::uniform2ivMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& info)
{
- uniformHelperi(info, kUniform2v, "uniform2iv");
+ ExceptionState exceptionState(ExceptionState::ExecutionContext, "uniform2iv", "WebGLRenderingContext", info.Holder(), info.GetIsolate());
+ uniformHelperi(info, kUniform2v, exceptionState);
}
void V8WebGLRenderingContext::uniform3fvMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& info)
{
- vertexAttribAndUniformHelperf(info, kUniform3v, "uniform3fv");
+ ExceptionState exceptionState(ExceptionState::ExecutionContext, "uniform3fv", "WebGLRenderingContext", info.Holder(), info.GetIsolate());
+ vertexAttribAndUniformHelperf(info, kUniform3v, exceptionState);
}
void V8WebGLRenderingContext::uniform3ivMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& info)
{
- uniformHelperi(info, kUniform3v, "uniform3iv");
+ ExceptionState exceptionState(ExceptionState::ExecutionContext, "uniform3iv", "WebGLRenderingContext", info.Holder(), info.GetIsolate());
+ uniformHelperi(info, kUniform3v, exceptionState);
}
void V8WebGLRenderingContext::uniform4fvMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& info)
{
- vertexAttribAndUniformHelperf(info, kUniform4v, "uniform4fv");
+ ExceptionState exceptionState(ExceptionState::ExecutionContext, "uniform4fv", "WebGLRenderingContext", info.Holder(), info.GetIsolate());
+ vertexAttribAndUniformHelperf(info, kUniform4v, exceptionState);
}
void V8WebGLRenderingContext::uniform4ivMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& info)
{
- uniformHelperi(info, kUniform4v, "uniform4iv");
+ ExceptionState exceptionState(ExceptionState::ExecutionContext, "uniform4iv", "WebGLRenderingContext", info.Holder(), info.GetIsolate());
+ uniformHelperi(info, kUniform4v, exceptionState);
}
-static void uniformMatrixHelper(const v8::FunctionCallbackInfo<v8::Value>& info, int matrixSize, const char* method)
+static void uniformMatrixHelper(const v8::FunctionCallbackInfo<v8::Value>& info, int matrixSize, ExceptionState& exceptionState)
{
// Forms:
// * glUniformMatrix2fv(GLint location, GLboolean transpose, Array data);
@@ -684,23 +767,26 @@ static void uniformMatrixHelper(const v8::FunctionCallbackInfo<v8::Value>& info,
//
// FIXME: need to change to accept Float32Array as well.
if (info.Length() != 3) {
- throwTypeError(ExceptionMessages::failedToExecute(method, "WebGLRenderingContext", ExceptionMessages::notEnoughArguments(3, info.Length())), info.GetIsolate());
+ exceptionState.throwTypeError(ExceptionMessages::notEnoughArguments(3, info.Length()));
+ exceptionState.throwIfNeeded();
return;
}
WebGLRenderingContext* context = V8WebGLRenderingContext::toNative(info.Holder());
- if (info.Length() > 0 && !isUndefinedOrNull(info[0]) && !V8WebGLUniformLocation::hasInstance(info[0], info.GetIsolate(), worldType(info.GetIsolate()))) {
- throwUninformativeAndGenericTypeError(info.GetIsolate());
+ const int uniformLocationArgumentIndex = 0;
+ if (info.Length() > 0 && !isUndefinedOrNull(info[uniformLocationArgumentIndex]) && !V8WebGLUniformLocation::hasInstance(info[uniformLocationArgumentIndex], info.GetIsolate())) {
+ exceptionState.throwTypeError(ExceptionMessages::argumentNullOrIncorrectType(uniformLocationArgumentIndex + 1, "WebGLUniformLocation"));
+ exceptionState.throwIfNeeded();
return;
}
- bool ok = false;
- WebGLUniformLocation* location = toWebGLUniformLocation(info[0], ok, info.GetIsolate());
+ WebGLUniformLocation* location = toWebGLUniformLocation(info[uniformLocationArgumentIndex], info.GetIsolate());
bool transpose = info[1]->BooleanValue();
- if (V8Float32Array::hasInstance(info[2], info.GetIsolate(), worldType(info.GetIsolate()))) {
- Float32Array* array = V8Float32Array::toNative(info[2]->ToObject());
- ASSERT(array != NULL);
+ const int arrayArgumentIndex = 2;
+ if (V8Float32Array::hasInstance(info[arrayArgumentIndex], info.GetIsolate())) {
+ Float32Array* array = V8Float32Array::toNative(info[arrayArgumentIndex]->ToObject());
+ ASSERT(array);
switch (matrixSize) {
case 2: context->uniformMatrix2fv(location, transpose, array); break;
case 3: context->uniformMatrix3fv(location, transpose, array); break;
@@ -710,16 +796,20 @@ static void uniformMatrixHelper(const v8::FunctionCallbackInfo<v8::Value>& info,
return;
}
- if (info[2].IsEmpty() || !info[2]->IsArray()) {
- throwUninformativeAndGenericTypeError(info.GetIsolate());
+ if (info[arrayArgumentIndex].IsEmpty() || !info[arrayArgumentIndex]->IsArray()) {
+ exceptionState.throwTypeError(ExceptionMessages::argumentNullOrIncorrectType(arrayArgumentIndex + 1, "Array"));
+ exceptionState.throwIfNeeded();
return;
}
v8::Handle<v8::Array> array = v8::Local<v8::Array>::Cast(info[2]);
uint32_t len = array->Length();
- float* data = jsArrayToFloatArray(array, len);
+ float* data = jsArrayToFloatArray(array, len, exceptionState);
+ if (exceptionState.throwIfNeeded())
+ return;
if (!data) {
// FIXME: consider different / better exception type.
- setDOMException(SyntaxError, info.GetIsolate());
+ exceptionState.throwDOMException(SyntaxError, "failed to convert Array value");
+ exceptionState.throwIfNeeded();
return;
}
switch (matrixSize) {
@@ -733,37 +823,44 @@ static void uniformMatrixHelper(const v8::FunctionCallbackInfo<v8::Value>& info,
void V8WebGLRenderingContext::uniformMatrix2fvMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& info)
{
- uniformMatrixHelper(info, 2, "uniformMatrix2fv");
+ ExceptionState exceptionState(ExceptionState::ExecutionContext, "uniformMatrix2fv", "WebGLRenderingContext", info.Holder(), info.GetIsolate());
+ uniformMatrixHelper(info, 2, exceptionState);
}
void V8WebGLRenderingContext::uniformMatrix3fvMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& info)
{
- uniformMatrixHelper(info, 3, "uniformMatrix3fv");
+ ExceptionState exceptionState(ExceptionState::ExecutionContext, "uniformMatrix3fv", "WebGLRenderingContext", info.Holder(), info.GetIsolate());
+ uniformMatrixHelper(info, 3, exceptionState);
}
void V8WebGLRenderingContext::uniformMatrix4fvMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& info)
{
- uniformMatrixHelper(info, 4, "uniformMatrix4fv");
+ ExceptionState exceptionState(ExceptionState::ExecutionContext, "uniformMatrix4fv", "WebGLRenderingContext", info.Holder(), info.GetIsolate());
+ uniformMatrixHelper(info, 4, exceptionState);
}
void V8WebGLRenderingContext::vertexAttrib1fvMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& info)
{
- vertexAttribAndUniformHelperf(info, kVertexAttrib1v, "vertexAttrib1fv");
+ ExceptionState exceptionState(ExceptionState::ExecutionContext, "vertexAttrib1fv", "WebGLRenderingContext", info.Holder(), info.GetIsolate());
+ vertexAttribAndUniformHelperf(info, kVertexAttrib1v, exceptionState);
}
void V8WebGLRenderingContext::vertexAttrib2fvMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& info)
{
- vertexAttribAndUniformHelperf(info, kVertexAttrib2v, "vertexAttrib2fv");
+ ExceptionState exceptionState(ExceptionState::ExecutionContext, "vertexAttrib2fv", "WebGLRenderingContext", info.Holder(), info.GetIsolate());
+ vertexAttribAndUniformHelperf(info, kVertexAttrib2v, exceptionState);
}
void V8WebGLRenderingContext::vertexAttrib3fvMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& info)
{
- vertexAttribAndUniformHelperf(info, kVertexAttrib3v, "vertexAttrib3fv");
+ ExceptionState exceptionState(ExceptionState::ExecutionContext, "vertexAttrib3fv", "WebGLRenderingContext", info.Holder(), info.GetIsolate());
+ vertexAttribAndUniformHelperf(info, kVertexAttrib3v, exceptionState);
}
void V8WebGLRenderingContext::vertexAttrib4fvMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& info)
{
- vertexAttribAndUniformHelperf(info, kVertexAttrib4v, "vertexAttrib4fv");
+ ExceptionState exceptionState(ExceptionState::ExecutionContext, "vertexAttrib4fv", "WebGLRenderingContext", info.Holder(), info.GetIsolate());
+ vertexAttribAndUniformHelperf(info, kVertexAttrib4v, exceptionState);
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8WebKitPointCustom.cpp b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8WebKitPointCustom.cpp
index 35429f91ffd..e87549ec81f 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8WebKitPointCustom.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8WebKitPointCustom.cpp
@@ -29,7 +29,7 @@
*/
#include "config.h"
-#include "V8WebKitPoint.h"
+#include "bindings/core/v8/V8WebKitPoint.h"
#include "bindings/v8/V8Binding.h"
#include "bindings/v8/V8DOMWrapper.h"
@@ -54,7 +54,7 @@ void V8WebKitPoint::constructorCustom(const v8::FunctionCallbackInfo<v8::Value>&
y = 0;
}
}
- RefPtr<DOMPoint> point = DOMPoint::create(x, y);
+ RefPtrWillBeRawPtr<DOMPoint> point = DOMPoint::create(x, y);
v8::Handle<v8::Object> wrapper = info.Holder();
V8DOMWrapper::associateObjectWithWrapper<V8WebKitPoint>(point.release(), &wrapperTypeInfo, wrapper, info.GetIsolate(), WrapperConfiguration::Dependent);
info.GetReturnValue().Set(wrapper);
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8WindowCustom.cpp b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8WindowCustom.cpp
index 24f19e4fd10..7ab9e529d00 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8WindowCustom.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8WindowCustom.cpp
@@ -29,10 +29,10 @@
*/
#include "config.h"
-#include "V8Window.h"
+#include "bindings/core/v8/V8Window.h"
-#include "V8HTMLCollection.h"
-#include "V8Node.h"
+#include "bindings/core/v8/V8HTMLCollection.h"
+#include "bindings/core/v8/V8Node.h"
#include "bindings/v8/BindingSecurity.h"
#include "bindings/v8/ExceptionMessages.h"
#include "bindings/v8/ExceptionState.h"
@@ -44,8 +44,7 @@
#include "bindings/v8/V8EventListener.h"
#include "bindings/v8/V8EventListenerList.h"
#include "bindings/v8/V8GCForContextDispose.h"
-#include "bindings/v8/V8HiddenPropertyName.h"
-#include "bindings/v8/V8Utilities.h"
+#include "bindings/v8/V8HiddenValue.h"
#include "core/dom/ExceptionCode.h"
#include "core/dom/MessagePort.h"
#include "core/html/HTMLCollection.h"
@@ -53,13 +52,13 @@
#include "core/inspector/ScriptCallStack.h"
#include "core/loader/FrameLoadRequest.h"
#include "core/loader/FrameLoader.h"
-#include "core/frame/ContentSecurityPolicy.h"
#include "core/frame/DOMTimer.h"
-#include "core/frame/DOMWindow.h"
+#include "core/frame/LocalDOMWindow.h"
#include "core/frame/DOMWindowTimers.h"
-#include "core/frame/Frame.h"
#include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
#include "core/frame/Settings.h"
+#include "core/frame/csp/ContentSecurityPolicy.h"
#include "core/storage/Storage.h"
#include "platform/PlatformScreen.h"
#include "platform/graphics/media/MediaPlayer.h"
@@ -71,19 +70,19 @@ namespace WebCore {
// FIXME: There is a lot of duplication with SetTimeoutOrInterval() in V8WorkerGlobalScopeCustom.cpp.
// We should refactor this.
-void WindowSetTimeoutImpl(const v8::FunctionCallbackInfo<v8::Value>& info, bool singleShot, ExceptionState& exceptionState)
+static void windowSetTimeoutImpl(const v8::FunctionCallbackInfo<v8::Value>& info, bool singleShot, ExceptionState& exceptionState)
{
int argumentCount = info.Length();
if (argumentCount < 1)
return;
- DOMWindow* imp = V8Window::toNative(info.Holder());
- if (!imp->document()) {
+ LocalDOMWindow* impl = V8Window::toNative(info.Holder());
+ if (!impl->frame() || !impl->document()) {
exceptionState.throwDOMException(InvalidAccessError, "No script context is available in which to execute the script.");
return;
}
-
+ ScriptState* scriptState = ScriptState::current(info.GetIsolate());
v8::Handle<v8::Value> function = info[0];
String functionString;
if (!function->IsFunction()) {
@@ -105,7 +104,7 @@ void WindowSetTimeoutImpl(const v8::FunctionCallbackInfo<v8::Value>& info, bool
return;
}
- if (!BindingSecurity::shouldAllowAccessToFrame(imp->frame(), exceptionState))
+ if (!BindingSecurity::shouldAllowAccessToFrame(info.GetIsolate(), impl->frame(), exceptionState))
return;
OwnPtr<ScheduledAction> action;
@@ -121,23 +120,23 @@ void WindowSetTimeoutImpl(const v8::FunctionCallbackInfo<v8::Value>& info, bool
}
// params is passed to action, and released in action's destructor
- ASSERT(imp->frame());
- action = adoptPtr(new ScheduledAction(imp->frame()->script().currentWorldContext(), v8::Handle<v8::Function>::Cast(function), paramCount, params.get(), info.GetIsolate()));
+ ASSERT(impl->frame());
+ action = adoptPtr(new ScheduledAction(scriptState, v8::Handle<v8::Function>::Cast(function), paramCount, params.get(), info.GetIsolate()));
} else {
- if (imp->document() && !imp->document()->contentSecurityPolicy()->allowEval()) {
+ if (impl->document() && !impl->document()->contentSecurityPolicy()->allowEval()) {
v8SetReturnValue(info, 0);
return;
}
- ASSERT(imp->frame());
- action = adoptPtr(new ScheduledAction(imp->frame()->script().currentWorldContext(), functionString, KURL(), info.GetIsolate()));
+ ASSERT(impl->frame());
+ action = adoptPtr(new ScheduledAction(scriptState, functionString, KURL(), info.GetIsolate()));
}
int32_t timeout = argumentCount >= 2 ? info[1]->Int32Value() : 0;
int timerId;
if (singleShot)
- timerId = DOMWindowTimers::setTimeout(imp, action.release(), timeout);
+ timerId = DOMWindowTimers::setTimeout(*impl, action.release(), timeout);
else
- timerId = DOMWindowTimers::setInterval(imp, action.release(), timeout);
+ timerId = DOMWindowTimers::setInterval(*impl, action.release(), timeout);
// 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.
@@ -151,24 +150,14 @@ void WindowSetTimeoutImpl(const v8::FunctionCallbackInfo<v8::Value>& info, bool
void V8Window::eventAttributeGetterCustom(const v8::PropertyCallbackInfo<v8::Value>& info)
{
- v8::Handle<v8::Object> holder = info.This()->FindInstanceInPrototypeChain(V8Window::domTemplate(info.GetIsolate(), worldTypeInMainThread(info.GetIsolate())));
- if (holder.IsEmpty())
- return;
-
- Frame* frame = V8Window::toNative(holder)->frame();
+ LocalFrame* frame = V8Window::toNative(info.Holder())->frame();
ExceptionState exceptionState(ExceptionState::GetterContext, "event", "Window", info.Holder(), info.GetIsolate());
- if (!BindingSecurity::shouldAllowAccessToFrame(frame, exceptionState)) {
+ if (!BindingSecurity::shouldAllowAccessToFrame(info.GetIsolate(), frame, exceptionState)) {
exceptionState.throwIfNeeded();
return;
}
- ASSERT(frame);
- v8::Local<v8::Context> context = frame->script().currentWorldContext();
- if (context.IsEmpty())
- return;
-
- v8::Handle<v8::String> eventSymbol = V8HiddenPropertyName::event(info.GetIsolate());
- v8::Handle<v8::Value> jsEvent = context->Global()->GetHiddenValue(eventSymbol);
+ v8::Handle<v8::Value> jsEvent = V8HiddenValue::getHiddenValue(info.GetIsolate(), info.Holder()->CreationContext()->Global(), V8HiddenValue::event(info.GetIsolate()));
if (jsEvent.IsEmpty())
return;
v8SetReturnValue(info, jsEvent);
@@ -176,31 +165,21 @@ void V8Window::eventAttributeGetterCustom(const v8::PropertyCallbackInfo<v8::Val
void V8Window::eventAttributeSetterCustom(v8::Local<v8::Value> value, const v8::PropertyCallbackInfo<void>& info)
{
- v8::Handle<v8::Object> holder = info.This()->FindInstanceInPrototypeChain(V8Window::domTemplate(info.GetIsolate(), worldTypeInMainThread(info.GetIsolate())));
- if (holder.IsEmpty())
- return;
-
- Frame* frame = V8Window::toNative(holder)->frame();
+ LocalFrame* frame = V8Window::toNative(info.Holder())->frame();
ExceptionState exceptionState(ExceptionState::SetterContext, "event", "Window", info.Holder(), info.GetIsolate());
- if (!BindingSecurity::shouldAllowAccessToFrame(frame, exceptionState)) {
+ if (!BindingSecurity::shouldAllowAccessToFrame(info.GetIsolate(), frame, exceptionState)) {
exceptionState.throwIfNeeded();
return;
}
- ASSERT(frame);
- v8::Local<v8::Context> context = frame->script().currentWorldContext();
- if (context.IsEmpty())
- return;
-
- v8::Handle<v8::String> eventSymbol = V8HiddenPropertyName::event(info.GetIsolate());
- context->Global()->SetHiddenValue(eventSymbol, value);
+ V8HiddenValue::setHiddenValue(info.GetIsolate(), info.Holder()->CreationContext()->Global(), V8HiddenValue::event(info.GetIsolate()), value);
}
void V8Window::frameElementAttributeGetterCustom(const v8::PropertyCallbackInfo<v8::Value>& info)
{
- DOMWindow* imp = V8Window::toNative(info.Holder());
+ LocalDOMWindow* impl = V8Window::toNative(info.Holder());
ExceptionState exceptionState(ExceptionState::GetterContext, "frame", "Window", info.Holder(), info.GetIsolate());
- if (!BindingSecurity::shouldAllowAccessToNode(imp->frameElement(), exceptionState)) {
+ if (!BindingSecurity::shouldAllowAccessToNode(info.GetIsolate(), impl->frameElement(), exceptionState)) {
v8SetReturnValueNull(info);
exceptionState.throwIfNeeded();
return;
@@ -208,17 +187,17 @@ void V8Window::frameElementAttributeGetterCustom(const v8::PropertyCallbackInfo<
// The wrapper for an <iframe> should get its prototype from the context of the frame it's in, rather than its own frame.
// So, use its containing document as the creation context when wrapping.
- v8::Handle<v8::Value> creationContext = toV8(&imp->frameElement()->document(), v8::Handle<v8::Object>(), info.GetIsolate());
+ v8::Handle<v8::Value> creationContext = toV8(&impl->frameElement()->document(), info.Holder(), info.GetIsolate());
RELEASE_ASSERT(!creationContext.IsEmpty());
- v8::Handle<v8::Value> wrapper = toV8(imp->frameElement(), v8::Handle<v8::Object>::Cast(creationContext), info.GetIsolate());
+ v8::Handle<v8::Value> wrapper = toV8(impl->frameElement(), v8::Handle<v8::Object>::Cast(creationContext), info.GetIsolate());
v8SetReturnValue(info, wrapper);
}
void V8Window::openerAttributeSetterCustom(v8::Local<v8::Value> value, const v8::PropertyCallbackInfo<void>& info)
{
- DOMWindow* imp = V8Window::toNative(info.Holder());
+ LocalDOMWindow* impl = V8Window::toNative(info.Holder());
ExceptionState exceptionState(ExceptionState::SetterContext, "opener", "Window", info.Holder(), info.GetIsolate());
- if (!BindingSecurity::shouldAllowAccessToFrame(imp->frame(), exceptionState)) {
+ if (!BindingSecurity::shouldAllowAccessToFrame(info.GetIsolate(), impl->frame(), exceptionState)) {
exceptionState.throwIfNeeded();
return;
}
@@ -227,17 +206,18 @@ void V8Window::openerAttributeSetterCustom(v8::Local<v8::Value> value, const v8:
// Have a special handling of null value to behave
// like Firefox. See bug http://b/1224887 & http://b/791706.
if (value->IsNull()) {
- // imp->frame() cannot be null,
+ // impl->frame() cannot be null,
// otherwise, SameOrigin check would have failed.
- ASSERT(imp->frame());
- imp->frame()->loader().setOpener(0);
+ ASSERT(impl->frame());
+ impl->frame()->loader().setOpener(0);
}
// Delete the accessor from this object.
info.Holder()->Delete(v8AtomicString(info.GetIsolate(), "opener"));
// Put property on the front (this) object.
- info.This()->Set(v8AtomicString(info.GetIsolate(), "opener"), value);
+ if (info.This()->IsObject())
+ v8::Handle<v8::Object>::Cast(info.This())->Set(v8AtomicString(info.GetIsolate(), "opener"), value);
}
static bool isLegacyTargetOriginDesignation(v8::Handle<v8::Value> value)
@@ -252,12 +232,15 @@ void V8Window::postMessageMethodCustom(const v8::FunctionCallbackInfo<v8::Value>
{
// None of these need to be RefPtr because info and context are guaranteed
// to hold on to them.
- DOMWindow* window = V8Window::toNative(info.Holder());
- DOMWindow* source = activeDOMWindow();
+ LocalDOMWindow* window = V8Window::toNative(info.Holder());
+ LocalDOMWindow* source = callingDOMWindow(info.GetIsolate());
+
+ ExceptionState exceptionState(ExceptionState::ExecutionContext, "postMessage", "Window", info.Holder(), info.GetIsolate());
// If called directly by WebCore we don't have a calling context.
if (!source) {
- throwUninformativeAndGenericTypeError(info.GetIsolate());
+ exceptionState.throwTypeError("No active calling context exists.");
+ exceptionState.throwIfNeeded();
return;
}
@@ -276,22 +259,17 @@ void V8Window::postMessageMethodCustom(const v8::FunctionCallbackInfo<v8::Value>
targetOriginArgIndex = 2;
transferablesArgIndex = 1;
}
- bool notASequence = false;
- if (!extractTransferables(info[transferablesArgIndex], portArray, arrayBufferArray, notASequence, info.GetIsolate())) {
- if (notASequence)
- throwTypeError(ExceptionMessages::failedToExecute("postMessage", "Window", ExceptionMessages::notAnArrayTypeArgumentOrValue(transferablesArgIndex + 1)), info.GetIsolate());
+ if (!SerializedScriptValue::extractTransferables(info[transferablesArgIndex], transferablesArgIndex, portArray, arrayBufferArray, exceptionState, info.GetIsolate())) {
+ exceptionState.throwIfNeeded();
return;
}
}
- V8TRYCATCH_FOR_V8STRINGRESOURCE_VOID(V8StringResource<WithUndefinedOrNullCheck>, targetOrigin, info[targetOriginArgIndex]);
+ TOSTRING_VOID(V8StringResource<WithUndefinedOrNullCheck>, targetOrigin, info[targetOriginArgIndex]);
- bool didThrow = false;
- RefPtr<SerializedScriptValue> message =
- SerializedScriptValue::create(info[0], &portArray, &arrayBufferArray, didThrow, info.GetIsolate());
- if (didThrow)
+ RefPtr<SerializedScriptValue> message = SerializedScriptValue::create(info[0], &portArray, &arrayBufferArray, exceptionState, info.GetIsolate());
+ if (exceptionState.throwIfNeeded())
return;
- ExceptionState exceptionState(ExceptionState::ExecutionContext, "postMessage", "Window", info.Holder(), info.GetIsolate());
window->postMessage(message.release(), &portArray, targetOrigin, source, exceptionState);
exceptionState.throwIfNeeded();
}
@@ -302,7 +280,7 @@ void V8Window::postMessageMethodCustom(const v8::FunctionCallbackInfo<v8::Value>
// switching context of receiver. I consider it is dangerous.
void V8Window::toStringMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& info)
{
- v8::Handle<v8::Object> domWrapper = info.This()->FindInstanceInPrototypeChain(V8Window::domTemplate(info.GetIsolate(), worldTypeInMainThread(info.GetIsolate())));
+ v8::Handle<v8::Object> domWrapper = V8Window::findInstanceInPrototypeChain(info.This(), info.GetIsolate());
if (domWrapper.IsEmpty()) {
v8SetReturnValue(info, info.This()->ObjectProtoToString());
return;
@@ -312,84 +290,92 @@ void V8Window::toStringMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& i
class DialogHandler {
public:
- explicit DialogHandler(v8::Handle<v8::Value> dialogArguments)
- : m_dialogArguments(dialogArguments)
+ explicit DialogHandler(v8::Handle<v8::Value> dialogArguments, ScriptState* scriptState)
+ : m_scriptState(scriptState)
+ , m_dialogArguments(dialogArguments)
{
}
- void dialogCreated(DOMWindow*, v8::Isolate*);
- v8::Handle<v8::Value> returnValue(v8::Isolate*) const;
+ void dialogCreated(LocalDOMWindow*);
+ v8::Handle<v8::Value> returnValue() const;
private:
+ RefPtr<ScriptState> m_scriptState;
+ RefPtr<ScriptState> m_scriptStateForDialogFrame;
v8::Handle<v8::Value> m_dialogArguments;
- v8::Handle<v8::Context> m_dialogContext;
};
-inline void DialogHandler::dialogCreated(DOMWindow* dialogFrame, v8::Isolate* isolate)
+void DialogHandler::dialogCreated(LocalDOMWindow* dialogFrame)
{
- m_dialogContext = dialogFrame->frame() ? dialogFrame->frame()->script().currentWorldContext() : v8::Local<v8::Context>();
- if (m_dialogContext.IsEmpty())
- return;
if (m_dialogArguments.IsEmpty())
return;
- v8::Context::Scope scope(m_dialogContext);
- m_dialogContext->Global()->Set(v8AtomicString(isolate, "dialogArguments"), m_dialogArguments);
+ v8::Handle<v8::Context> context = toV8Context(dialogFrame->frame(), m_scriptState->world());
+ if (context.IsEmpty())
+ return;
+ m_scriptStateForDialogFrame = ScriptState::from(context);
+
+ ScriptState::Scope scope(m_scriptStateForDialogFrame.get());
+ m_scriptStateForDialogFrame->context()->Global()->Set(v8AtomicString(m_scriptState->isolate(), "dialogArguments"), m_dialogArguments);
}
-inline v8::Handle<v8::Value> DialogHandler::returnValue(v8::Isolate* isolate) const
+v8::Handle<v8::Value> DialogHandler::returnValue() const
{
- if (m_dialogContext.IsEmpty())
- return v8::Undefined(isolate);
- v8::Context::Scope scope(m_dialogContext);
- v8::Handle<v8::Value> returnValue = m_dialogContext->Global()->Get(v8AtomicString(isolate, "returnValue"));
+ if (!m_scriptStateForDialogFrame)
+ return v8Undefined();
+ ASSERT(!m_scriptStateForDialogFrame->contextIsEmpty());
+
+ v8::Isolate* isolate = m_scriptStateForDialogFrame->isolate();
+ v8::EscapableHandleScope handleScope(isolate);
+ ScriptState::Scope scope(m_scriptStateForDialogFrame.get());
+ v8::Local<v8::Value> returnValue = m_scriptStateForDialogFrame->context()->Global()->Get(v8AtomicString(isolate, "returnValue"));
if (returnValue.IsEmpty())
- return v8::Undefined(isolate);
- return returnValue;
+ return v8Undefined();
+ return handleScope.Escape(returnValue);
}
-static void setUpDialog(DOMWindow* dialog, void* handler)
+static void setUpDialog(LocalDOMWindow* dialog, void* handler)
{
- static_cast<DialogHandler*>(handler)->dialogCreated(dialog, v8::Isolate::GetCurrent());
+ static_cast<DialogHandler*>(handler)->dialogCreated(dialog);
}
void V8Window::showModalDialogMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& info)
{
- DOMWindow* impl = V8Window::toNative(info.Holder());
+ LocalDOMWindow* impl = V8Window::toNative(info.Holder());
ExceptionState exceptionState(ExceptionState::ExecutionContext, "showModalDialog", "Window", info.Holder(), info.GetIsolate());
- if (!BindingSecurity::shouldAllowAccessToFrame(impl->frame(), exceptionState)) {
+ if (!BindingSecurity::shouldAllowAccessToFrame(info.GetIsolate(), impl->frame(), exceptionState)) {
exceptionState.throwIfNeeded();
return;
}
- V8TRYCATCH_FOR_V8STRINGRESOURCE_VOID(V8StringResource<WithUndefinedOrNullCheck>, urlString, info[0]);
- DialogHandler handler(info[1]);
- V8TRYCATCH_FOR_V8STRINGRESOURCE_VOID(V8StringResource<WithUndefinedOrNullCheck>, dialogFeaturesString, info[2]);
+ TOSTRING_VOID(V8StringResource<WithUndefinedOrNullCheck>, urlString, info[0]);
+ DialogHandler handler(info[1], ScriptState::current(info.GetIsolate()));
+ TOSTRING_VOID(V8StringResource<WithUndefinedOrNullCheck>, dialogFeaturesString, info[2]);
- impl->showModalDialog(urlString, dialogFeaturesString, activeDOMWindow(), firstDOMWindow(), setUpDialog, &handler);
+ impl->showModalDialog(urlString, dialogFeaturesString, callingDOMWindow(info.GetIsolate()), enteredDOMWindow(info.GetIsolate()), setUpDialog, &handler);
- v8SetReturnValue(info, handler.returnValue(info.GetIsolate()));
+ v8SetReturnValue(info, handler.returnValue());
}
void V8Window::openMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& info)
{
- DOMWindow* impl = V8Window::toNative(info.Holder());
+ LocalDOMWindow* impl = V8Window::toNative(info.Holder());
ExceptionState exceptionState(ExceptionState::ExecutionContext, "open", "Window", info.Holder(), info.GetIsolate());
- if (!BindingSecurity::shouldAllowAccessToFrame(impl->frame(), exceptionState)) {
+ if (!BindingSecurity::shouldAllowAccessToFrame(info.GetIsolate(), impl->frame(), exceptionState)) {
exceptionState.throwIfNeeded();
return;
}
- V8TRYCATCH_FOR_V8STRINGRESOURCE_VOID(V8StringResource<WithUndefinedOrNullCheck>, urlString, info[0]);
+ TOSTRING_VOID(V8StringResource<WithUndefinedOrNullCheck>, urlString, info[0]);
AtomicString frameName;
if (info[1]->IsUndefined() || info[1]->IsNull()) {
frameName = "_blank";
} else {
- V8TRYCATCH_FOR_V8STRINGRESOURCE_VOID(V8StringResource<>, frameNameResource, info[1]);
+ TOSTRING_VOID(V8StringResource<>, frameNameResource, info[1]);
frameName = frameNameResource;
}
- V8TRYCATCH_FOR_V8STRINGRESOURCE_VOID(V8StringResource<WithUndefinedOrNullCheck>, windowFeaturesString, info[2]);
+ TOSTRING_VOID(V8StringResource<WithUndefinedOrNullCheck>, windowFeaturesString, info[2]);
- RefPtr<DOMWindow> openedWindow = impl->open(urlString, frameName, windowFeaturesString, activeDOMWindow(), firstDOMWindow());
+ RefPtrWillBeRawPtr<LocalDOMWindow> openedWindow = impl->open(urlString, frameName, windowFeaturesString, callingDOMWindow(info.GetIsolate()), enteredDOMWindow(info.GetIsolate()));
if (!openedWindow)
return;
@@ -399,11 +385,11 @@ void V8Window::openMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& info)
void V8Window::namedPropertyGetterCustom(v8::Local<v8::String> name, const v8::PropertyCallbackInfo<v8::Value>& info)
{
- DOMWindow* window = V8Window::toNative(info.Holder());
+ LocalDOMWindow* window = V8Window::toNative(info.Holder());
if (!window)
return;
- Frame* frame = window->frame();
+ LocalFrame* frame = window->frame();
// window is detached from a frame.
if (!frame)
return;
@@ -425,7 +411,7 @@ void V8Window::namedPropertyGetterCustom(v8::Local<v8::String> name, const v8::P
if (doc && doc->isHTMLDocument()) {
if (toHTMLDocument(doc)->hasNamedItem(propName) || doc->hasElementWithId(propName.impl())) {
- RefPtr<HTMLCollection> items = doc->windowNamedItems(propName);
+ RefPtrWillBeRawPtr<HTMLCollection> items = doc->windowNamedItems(propName);
if (!items->isEmpty()) {
if (items->hasExactlyOneItem()) {
v8SetReturnValueFast(info, items->item(0), window);
@@ -442,7 +428,7 @@ void V8Window::namedPropertyGetterCustom(v8::Local<v8::String> name, const v8::P
void V8Window::setTimeoutMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& info)
{
ExceptionState exceptionState(ExceptionState::ExecutionContext, "setTimeout", "Window", info.Holder(), info.GetIsolate());
- WindowSetTimeoutImpl(info, true, exceptionState);
+ windowSetTimeoutImpl(info, true, exceptionState);
exceptionState.throwIfNeeded();
}
@@ -450,22 +436,22 @@ void V8Window::setTimeoutMethodCustom(const v8::FunctionCallbackInfo<v8::Value>&
void V8Window::setIntervalMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& info)
{
ExceptionState exceptionState(ExceptionState::ExecutionContext, "setInterval", "Window", info.Holder(), info.GetIsolate());
- WindowSetTimeoutImpl(info, false, exceptionState);
+ windowSetTimeoutImpl(info, false, exceptionState);
exceptionState.throwIfNeeded();
}
bool V8Window::namedSecurityCheckCustom(v8::Local<v8::Object> host, v8::Local<v8::Value> key, v8::AccessType type, v8::Local<v8::Value>)
{
v8::Isolate* isolate = v8::Isolate::GetCurrent();
- v8::Handle<v8::Object> window = host->FindInstanceInPrototypeChain(V8Window::domTemplate(isolate, worldTypeInMainThread(isolate)));
+ v8::Handle<v8::Object> window = V8Window::findInstanceInPrototypeChain(host, isolate);
if (window.IsEmpty())
return false; // the frame is gone.
- DOMWindow* targetWindow = V8Window::toNative(window);
+ LocalDOMWindow* targetWindow = V8Window::toNative(window);
ASSERT(targetWindow);
- Frame* target = targetWindow->frame();
+ LocalFrame* target = targetWindow->frame();
if (!target)
return false;
@@ -494,21 +480,21 @@ bool V8Window::namedSecurityCheckCustom(v8::Local<v8::Object> host, v8::Local<v8
return true;
}
- return BindingSecurity::shouldAllowAccessToFrame(target, DoNotReportSecurityError);
+ return BindingSecurity::shouldAllowAccessToFrame(isolate, target, DoNotReportSecurityError);
}
bool V8Window::indexedSecurityCheckCustom(v8::Local<v8::Object> host, uint32_t index, v8::AccessType type, v8::Local<v8::Value>)
{
v8::Isolate* isolate = v8::Isolate::GetCurrent();
- v8::Handle<v8::Object> window = host->FindInstanceInPrototypeChain(V8Window::domTemplate(isolate, worldTypeInMainThread(isolate)));
+ v8::Handle<v8::Object> window = V8Window::findInstanceInPrototypeChain(host, isolate);
if (window.IsEmpty())
return false;
- DOMWindow* targetWindow = V8Window::toNative(window);
+ LocalDOMWindow* targetWindow = V8Window::toNative(window);
ASSERT(targetWindow);
- Frame* target = targetWindow->frame();
+ LocalFrame* target = targetWindow->frame();
if (!target)
return false;
@@ -516,7 +502,7 @@ bool V8Window::indexedSecurityCheckCustom(v8::Local<v8::Object> host, uint32_t i
if (target->loader().stateMachine()->isDisplayingInitialEmptyDocument())
target->loader().didAccessInitialDocument();
- Frame* childFrame = target->tree().scopedChild(index);
+ Frame* childFrame = target->tree().scopedChild(index);
// Notice that we can't call HasRealNamedProperty for ACCESS_HAS
// because that would generate infinite recursion.
@@ -528,36 +514,22 @@ bool V8Window::indexedSecurityCheckCustom(v8::Local<v8::Object> host, uint32_t i
&& !window->HasRealIndexedProperty(index))
return true;
- return BindingSecurity::shouldAllowAccessToFrame(target, DoNotReportSecurityError);
+ return BindingSecurity::shouldAllowAccessToFrame(isolate, target, DoNotReportSecurityError);
}
-v8::Handle<v8::Value> toV8(DOMWindow* window, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
+v8::Handle<v8::Value> toV8(LocalDOMWindow* window, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
{
- // Notice that we explicitly ignore creationContext because the DOMWindow is its own creationContext.
+ // Notice that we explicitly ignore creationContext because the LocalDOMWindow is its own creationContext.
if (!window)
return v8::Null(isolate);
// Initializes environment of a frame, and return the global object
// of the frame.
- Frame* frame = window->frame();
+ LocalFrame* frame = window->frame();
if (!frame)
return v8Undefined();
- // Special case: Because of executeScriptInIsolatedWorld() one DOMWindow can have
- // multiple contexts and multiple global objects associated with it. When
- // code running in one of those contexts accesses the window object, we
- // want to return the global object associated with that context, not
- // necessarily the first global object associated with that DOMWindow.
- v8::Handle<v8::Context> currentContext = isolate->GetCurrentContext();
- v8::Handle<v8::Object> currentGlobal = currentContext->Global();
- v8::Handle<v8::Object> windowWrapper = currentGlobal->FindInstanceInPrototypeChain(V8Window::domTemplate(isolate, worldTypeInMainThread(isolate)));
- if (!windowWrapper.IsEmpty()) {
- if (V8Window::toNative(windowWrapper) == window)
- return currentGlobal;
- }
-
- // Otherwise, return the global object associated with this frame.
- v8::Handle<v8::Context> context = frame->script().currentWorldContext();
+ v8::Handle<v8::Context> context = toV8Context(frame, DOMWrapperWorld::current(isolate));
if (context.IsEmpty())
return v8Undefined();
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8WorkerCryptoCustom.cpp b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8WorkerCryptoCustom.cpp
deleted file mode 100644
index acf7a114d5a..00000000000
--- a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8WorkerCryptoCustom.cpp
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2013 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 "V8WorkerCrypto.h"
-
-#include "V8Crypto.h"
-
-namespace WebCore {
-
-void V8WorkerCrypto::getRandomValuesMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& info)
-{
- V8Crypto::getRandomValuesMethodCustom(info);
-}
-
-} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8WorkerCustom.cpp b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8WorkerCustom.cpp
index 19440578be3..01a4a822546 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8WorkerCustom.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8WorkerCustom.cpp
@@ -29,13 +29,12 @@
*/
#include "config.h"
-#include "V8Worker.h"
+#include "bindings/core/v8/V8Worker.h"
#include "bindings/v8/ExceptionMessages.h"
#include "bindings/v8/ExceptionState.h"
#include "bindings/v8/SerializedScriptValue.h"
#include "bindings/v8/V8Binding.h"
-#include "bindings/v8/V8Utilities.h"
#include "core/workers/Worker.h"
#include "core/workers/WorkerGlobalScope.h"
#include "wtf/ArrayBuffer.h"
@@ -50,18 +49,13 @@ void V8Worker::postMessageMethodCustom(const v8::FunctionCallbackInfo<v8::Value>
ArrayBufferArray arrayBuffers;
if (info.Length() > 1) {
const int transferablesArgIndex = 1;
- bool notASequence = false;
- if (!extractTransferables(info[transferablesArgIndex], ports, arrayBuffers, notASequence, info.GetIsolate())) {
- if (notASequence) {
- exceptionState.throwTypeError(ExceptionMessages::notAnArrayTypeArgumentOrValue(transferablesArgIndex + 1));
- exceptionState.throwIfNeeded();
- }
+ if (!SerializedScriptValue::extractTransferables(info[transferablesArgIndex], transferablesArgIndex, ports, arrayBuffers, exceptionState, info.GetIsolate())) {
+ exceptionState.throwIfNeeded();
return;
}
}
- bool didThrow = false;
- RefPtr<SerializedScriptValue> message = SerializedScriptValue::create(info[0], &ports, &arrayBuffers, didThrow, info.GetIsolate());
- if (didThrow)
+ RefPtr<SerializedScriptValue> message = SerializedScriptValue::create(info[0], &ports, &arrayBuffers, exceptionState, info.GetIsolate());
+ if (exceptionState.throwIfNeeded())
return;
worker->postMessage(message.release(), &ports, exceptionState);
exceptionState.throwIfNeeded();
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8WorkerGlobalScopeCustom.cpp b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8WorkerGlobalScopeCustom.cpp
index 1863af5992c..ca43934106b 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8WorkerGlobalScopeCustom.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8WorkerGlobalScopeCustom.cpp
@@ -29,27 +29,27 @@
*/
#include "config.h"
-#include "V8WorkerGlobalScope.h"
+#include "bindings/core/v8/V8WorkerGlobalScope.h"
#include "bindings/v8/ExceptionState.h"
#include "bindings/v8/ScheduledAction.h"
#include "bindings/v8/V8Binding.h"
-#include "bindings/v8/V8Utilities.h"
#include "bindings/v8/V8WorkerGlobalScopeEventListener.h"
#include "bindings/v8/WorkerScriptController.h"
#include "core/inspector/ScriptCallStack.h"
-#include "core/frame/ContentSecurityPolicy.h"
#include "core/frame/DOMTimer.h"
#include "core/frame/DOMWindowTimers.h"
+#include "core/frame/csp/ContentSecurityPolicy.h"
#include "core/workers/WorkerGlobalScope.h"
#include "modules/websockets/WebSocket.h"
#include "wtf/OwnPtr.h"
namespace WebCore {
-void SetTimeoutOrInterval(const v8::FunctionCallbackInfo<v8::Value>& info, bool singleShot)
+static void setTimeoutOrInterval(const v8::FunctionCallbackInfo<v8::Value>& info, bool singleShot)
{
WorkerGlobalScope* workerGlobalScope = V8WorkerGlobalScope::toNative(info.Holder());
+ ASSERT(workerGlobalScope);
int argumentCount = info.Length();
if (argumentCount < 1)
@@ -61,8 +61,8 @@ void SetTimeoutOrInterval(const v8::FunctionCallbackInfo<v8::Value>& info, bool
if (!script)
return;
+ ScriptState* scriptState = ScriptState::current(info.GetIsolate());
OwnPtr<ScheduledAction> action;
- v8::Handle<v8::Context> v8Context = script->context();
if (function->IsString()) {
if (ContentSecurityPolicy* policy = workerGlobalScope->contentSecurityPolicy()) {
if (!policy->allowEval()) {
@@ -70,7 +70,7 @@ void SetTimeoutOrInterval(const v8::FunctionCallbackInfo<v8::Value>& info, bool
return;
}
}
- action = adoptPtr(new ScheduledAction(v8Context, toCoreString(function.As<v8::String>()), workerGlobalScope->url(), info.GetIsolate()));
+ action = adoptPtr(new ScheduledAction(scriptState, toCoreString(function.As<v8::String>()), workerGlobalScope->url(), info.GetIsolate()));
} else if (function->IsFunction()) {
size_t paramCount = argumentCount >= 2 ? argumentCount - 2 : 0;
OwnPtr<v8::Local<v8::Value>[]> params;
@@ -80,28 +80,28 @@ void SetTimeoutOrInterval(const v8::FunctionCallbackInfo<v8::Value>& info, bool
params[i] = info[i+2];
}
// ScheduledAction takes ownership of actual params and releases them in its destructor.
- action = adoptPtr(new ScheduledAction(v8Context, v8::Handle<v8::Function>::Cast(function), paramCount, params.get(), info.GetIsolate()));
+ action = adoptPtr(new ScheduledAction(scriptState, v8::Handle<v8::Function>::Cast(function), paramCount, params.get(), info.GetIsolate()));
} else
return;
int32_t timeout = argumentCount >= 2 ? info[1]->Int32Value() : 0;
int timerId;
if (singleShot)
- timerId = DOMWindowTimers::setTimeout(workerGlobalScope, action.release(), timeout);
+ timerId = DOMWindowTimers::setTimeout(*workerGlobalScope, action.release(), timeout);
else
- timerId = DOMWindowTimers::setInterval(workerGlobalScope, action.release(), timeout);
+ timerId = DOMWindowTimers::setInterval(*workerGlobalScope, action.release(), timeout);
v8SetReturnValue(info, timerId);
}
void V8WorkerGlobalScope::setTimeoutMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& info)
{
- return SetTimeoutOrInterval(info, true);
+ return setTimeoutOrInterval(info, true);
}
void V8WorkerGlobalScope::setIntervalMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& info)
{
- return SetTimeoutOrInterval(info, false);
+ return setTimeoutOrInterval(info, false);
}
v8::Handle<v8::Value> toV8(WorkerGlobalScope* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8XMLHttpRequestCustom.cpp b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8XMLHttpRequestCustom.cpp
index 855f64e16bf..8659b65bcff 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8XMLHttpRequestCustom.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8XMLHttpRequestCustom.cpp
@@ -29,17 +29,16 @@
*/
#include "config.h"
-#include "V8XMLHttpRequest.h"
+#include "bindings/core/v8/V8XMLHttpRequest.h"
-#include "V8Blob.h"
-#include "V8Document.h"
-#include "V8FormData.h"
-#include "V8HTMLDocument.h"
-#include "V8Stream.h"
+#include "bindings/core/v8/V8Blob.h"
+#include "bindings/core/v8/V8Document.h"
+#include "bindings/core/v8/V8FormData.h"
+#include "bindings/core/v8/V8HTMLDocument.h"
+#include "bindings/core/v8/V8Stream.h"
#include "bindings/v8/ExceptionMessages.h"
#include "bindings/v8/ExceptionState.h"
#include "bindings/v8/V8Binding.h"
-#include "bindings/v8/V8Utilities.h"
#include "bindings/v8/custom/V8ArrayBufferCustom.h"
#include "bindings/v8/custom/V8ArrayBufferViewCustom.h"
#include "core/dom/Document.h"
@@ -54,15 +53,16 @@ namespace WebCore {
void V8XMLHttpRequest::constructorCustom(const v8::FunctionCallbackInfo<v8::Value>& info)
{
- ExecutionContext* context = getExecutionContext();
+ ExecutionContext* context = currentExecutionContext(info.GetIsolate());
RefPtr<SecurityOrigin> securityOrigin;
if (context->isDocument()) {
- if (DOMWrapperWorld* world = isolatedWorldForEnteredContext(info.GetIsolate()))
- securityOrigin = world->isolatedWorldSecurityOrigin();
+ DOMWrapperWorld& world = DOMWrapperWorld::current(info.GetIsolate());
+ if (world.isIsolatedWorld())
+ securityOrigin = world.isolatedWorldSecurityOrigin();
}
- RefPtr<XMLHttpRequest> xmlHttpRequest = XMLHttpRequest::create(context, securityOrigin);
+ RefPtrWillBeRawPtr<XMLHttpRequest> xmlHttpRequest = XMLHttpRequest::create(context, securityOrigin);
v8::Handle<v8::Object> wrapper = info.Holder();
V8DOMWrapper::associateObjectWithWrapper<V8XMLHttpRequest>(xmlHttpRequest.release(), &wrapperTypeInfo, wrapper, info.GetIsolate(), WrapperConfiguration::Dependent);
@@ -73,10 +73,10 @@ void V8XMLHttpRequest::responseTextAttributeGetterCustom(const v8::PropertyCallb
{
XMLHttpRequest* xmlHttpRequest = V8XMLHttpRequest::toNative(info.Holder());
ExceptionState exceptionState(ExceptionState::GetterContext, "responseText", "XMLHttpRequest", info.Holder(), info.GetIsolate());
- ScriptValue text = xmlHttpRequest->responseText(exceptionState);
+ ScriptString text = xmlHttpRequest->responseText(exceptionState);
if (exceptionState.throwIfNeeded())
return;
- if (text.hasNoValue()) {
+ if (text.isEmpty()) {
v8SetReturnValueString(info, emptyString(), info.GetIsolate());
return;
}
@@ -98,21 +98,18 @@ void V8XMLHttpRequest::responseAttributeGetterCustom(const v8::PropertyCallbackI
v8::Isolate* isolate = info.GetIsolate();
ScriptString jsonSource = xmlHttpRequest->responseJSONSource();
- if (jsonSource.hasNoValue() || !jsonSource.v8Value()->IsString()) {
+ if (jsonSource.isEmpty()) {
v8SetReturnValue(info, v8::Null(isolate));
return;
}
// Catch syntax error.
v8::TryCatch exceptionCatcher;
-
- v8::Handle<v8::Value> json = v8::JSON::Parse(jsonSource.v8Value().As<v8::String>());
-
+ v8::Handle<v8::Value> json = v8::JSON::Parse(jsonSource.v8Value());
if (exceptionCatcher.HasCaught() || json.IsEmpty())
v8SetReturnValue(info, v8::Null(isolate));
else
v8SetReturnValue(info, json);
-
return;
}
@@ -170,20 +167,20 @@ void V8XMLHttpRequest::openMethodCustom(const v8::FunctionCallbackInfo<v8::Value
XMLHttpRequest* xmlHttpRequest = V8XMLHttpRequest::toNative(info.Holder());
- V8TRYCATCH_FOR_V8STRINGRESOURCE_VOID(V8StringResource<>, method, info[0]);
- V8TRYCATCH_FOR_V8STRINGRESOURCE_VOID(V8StringResource<>, urlstring, info[1]);
+ TOSTRING_VOID(V8StringResource<>, method, info[0]);
+ TOSTRING_VOID(V8StringResource<>, urlstring, info[1]);
- ExecutionContext* context = getExecutionContext();
+ ExecutionContext* context = currentExecutionContext(info.GetIsolate());
KURL url = context->completeURL(urlstring);
if (info.Length() >= 3) {
bool async = info[2]->BooleanValue();
if (info.Length() >= 4 && !info[3]->IsUndefined()) {
- V8TRYCATCH_FOR_V8STRINGRESOURCE_VOID(V8StringResource<WithNullCheck>, user, info[3]);
+ TOSTRING_VOID(V8StringResource<WithNullCheck>, user, info[3]);
if (info.Length() >= 5 && !info[4]->IsUndefined()) {
- V8TRYCATCH_FOR_V8STRINGRESOURCE_VOID(V8StringResource<WithNullCheck>, password, info[4]);
+ TOSTRING_VOID(V8StringResource<WithNullCheck>, password, info[4]);
xmlHttpRequest->open(method, url, async, user, password, exceptionState);
} else {
xmlHttpRequest->open(method, url, async, user, exceptionState);
@@ -198,10 +195,10 @@ void V8XMLHttpRequest::openMethodCustom(const v8::FunctionCallbackInfo<v8::Value
exceptionState.throwIfNeeded();
}
-static bool isDocumentType(v8::Handle<v8::Value> value, v8::Isolate* isolate, WrapperWorldType currentWorldType)
+static bool isDocumentType(v8::Handle<v8::Value> value, v8::Isolate* isolate)
{
// FIXME: add other document types.
- return V8Document::hasInstance(value, isolate, currentWorldType) || V8HTMLDocument::hasInstance(value, isolate, currentWorldType);
+ return V8Document::hasInstance(value, isolate) || V8HTMLDocument::hasInstance(value, isolate);
}
void V8XMLHttpRequest::sendMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& info)
@@ -215,36 +212,35 @@ void V8XMLHttpRequest::sendMethodCustom(const v8::FunctionCallbackInfo<v8::Value
xmlHttpRequest->send(exceptionState);
else {
v8::Handle<v8::Value> arg = info[0];
- WrapperWorldType currentWorldType = worldType(info.GetIsolate());
if (isUndefinedOrNull(arg)) {
xmlHttpRequest->send(exceptionState);
- } else if (isDocumentType(arg, info.GetIsolate(), currentWorldType)) {
+ } else if (isDocumentType(arg, info.GetIsolate())) {
v8::Handle<v8::Object> object = v8::Handle<v8::Object>::Cast(arg);
Document* document = V8Document::toNative(object);
ASSERT(document);
xmlHttpRequest->send(document, exceptionState);
- } else if (V8Blob::hasInstance(arg, info.GetIsolate(), currentWorldType)) {
+ } else if (V8Blob::hasInstance(arg, info.GetIsolate())) {
v8::Handle<v8::Object> object = v8::Handle<v8::Object>::Cast(arg);
Blob* blob = V8Blob::toNative(object);
ASSERT(blob);
xmlHttpRequest->send(blob, exceptionState);
- } else if (V8FormData::hasInstance(arg, info.GetIsolate(), currentWorldType)) {
+ } else if (V8FormData::hasInstance(arg, info.GetIsolate())) {
v8::Handle<v8::Object> object = v8::Handle<v8::Object>::Cast(arg);
DOMFormData* domFormData = V8FormData::toNative(object);
ASSERT(domFormData);
xmlHttpRequest->send(domFormData, exceptionState);
- } else if (V8ArrayBuffer::hasInstance(arg, info.GetIsolate(), currentWorldType)) {
+ } else if (V8ArrayBuffer::hasInstance(arg, info.GetIsolate())) {
v8::Handle<v8::Object> object = v8::Handle<v8::Object>::Cast(arg);
ArrayBuffer* arrayBuffer = V8ArrayBuffer::toNative(object);
ASSERT(arrayBuffer);
xmlHttpRequest->send(arrayBuffer, exceptionState);
- } else if (V8ArrayBufferView::hasInstance(arg, info.GetIsolate(), currentWorldType)) {
+ } else if (V8ArrayBufferView::hasInstance(arg, info.GetIsolate())) {
v8::Handle<v8::Object> object = v8::Handle<v8::Object>::Cast(arg);
ArrayBufferView* arrayBufferView = V8ArrayBufferView::toNative(object);
ASSERT(arrayBufferView);
xmlHttpRequest->send(arrayBufferView, exceptionState);
} else {
- V8TRYCATCH_FOR_V8STRINGRESOURCE_VOID(V8StringResource<WithNullCheck>, argString, arg);
+ TOSTRING_VOID(V8StringResource<WithNullCheck>, argString, arg);
xmlHttpRequest->send(argString, exceptionState);
}
}
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8XSLTProcessorCustom.cpp b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8XSLTProcessorCustom.cpp
index 7835310a652..2c7591f1dde 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/custom/V8XSLTProcessorCustom.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/custom/V8XSLTProcessorCustom.cpp
@@ -29,11 +29,11 @@
*/
#include "config.h"
-#include "V8XSLTProcessor.h"
+#include "bindings/core/v8/V8XSLTProcessor.h"
-#include "V8Document.h"
-#include "V8DocumentFragment.h"
-#include "V8Node.h"
+#include "bindings/core/v8/V8Document.h"
+#include "bindings/core/v8/V8DocumentFragment.h"
+#include "bindings/core/v8/V8Node.h"
#include "bindings/v8/V8Binding.h"
#include "core/dom/Document.h"
#include "core/dom/DocumentFragment.h"
@@ -48,12 +48,12 @@ void V8XSLTProcessor::setParameterMethodCustom(const v8::FunctionCallbackInfo<v8
if (isUndefinedOrNull(info[1]) || isUndefinedOrNull(info[2]))
return;
- V8TRYCATCH_FOR_V8STRINGRESOURCE_VOID(V8StringResource<>, namespaceURI, info[0]);
- V8TRYCATCH_FOR_V8STRINGRESOURCE_VOID(V8StringResource<>, localName, info[1]);
- V8TRYCATCH_FOR_V8STRINGRESOURCE_VOID(V8StringResource<>, value, info[2]);
+ TOSTRING_VOID(V8StringResource<>, namespaceURI, info[0]);
+ TOSTRING_VOID(V8StringResource<>, localName, info[1]);
+ TOSTRING_VOID(V8StringResource<>, value, info[2]);
- XSLTProcessor* imp = V8XSLTProcessor::toNative(info.Holder());
- imp->setParameter(namespaceURI, localName, value);
+ XSLTProcessor* impl = V8XSLTProcessor::toNative(info.Holder());
+ impl->setParameter(namespaceURI, localName, value);
}
void V8XSLTProcessor::getParameterMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& info)
@@ -61,11 +61,11 @@ void V8XSLTProcessor::getParameterMethodCustom(const v8::FunctionCallbackInfo<v8
if (isUndefinedOrNull(info[1]))
return;
- V8TRYCATCH_FOR_V8STRINGRESOURCE_VOID(V8StringResource<>, namespaceURI, info[0]);
- V8TRYCATCH_FOR_V8STRINGRESOURCE_VOID(V8StringResource<>, localName, info[1]);
+ TOSTRING_VOID(V8StringResource<>, namespaceURI, info[0]);
+ TOSTRING_VOID(V8StringResource<>, localName, info[1]);
- XSLTProcessor* imp = V8XSLTProcessor::toNative(info.Holder());
- String result = imp->getParameter(namespaceURI, localName);
+ XSLTProcessor* impl = V8XSLTProcessor::toNative(info.Holder());
+ String result = impl->getParameter(namespaceURI, localName);
if (result.isNull())
return;
@@ -77,11 +77,11 @@ void V8XSLTProcessor::removeParameterMethodCustom(const v8::FunctionCallbackInfo
if (isUndefinedOrNull(info[1]))
return;
- V8TRYCATCH_FOR_V8STRINGRESOURCE_VOID(V8StringResource<>, namespaceURI, info[0]);
- V8TRYCATCH_FOR_V8STRINGRESOURCE_VOID(V8StringResource<>, localName, info[1]);
+ TOSTRING_VOID(V8StringResource<>, namespaceURI, info[0]);
+ TOSTRING_VOID(V8StringResource<>, localName, info[1]);
- XSLTProcessor* imp = V8XSLTProcessor::toNative(info.Holder());
- imp->removeParameter(namespaceURI, localName);
+ XSLTProcessor* impl = V8XSLTProcessor::toNative(info.Holder());
+ impl->removeParameter(namespaceURI, localName);
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/custom/custom.gypi b/chromium/third_party/WebKit/Source/bindings/v8/custom/custom.gypi
new file mode 100644
index 00000000000..9d76a6e41ad
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/bindings/v8/custom/custom.gypi
@@ -0,0 +1,92 @@
+# Copyright 2014 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+{
+ 'variables': {
+ 'bindings_v8_custom_files': [
+ 'V8ArrayBufferCustom.cpp',
+ 'V8ArrayBufferCustom.h',
+ 'V8ArrayBufferViewCustom.cpp',
+ 'V8ArrayBufferViewCustom.h',
+ 'V8AudioNodeCustom.cpp',
+ 'V8BlobCustom.cpp',
+ 'V8BlobCustomHelpers.cpp',
+ 'V8BlobCustomHelpers.h',
+ 'V8CSSRuleCustom.cpp',
+ 'V8CSSStyleDeclarationCustom.cpp',
+ 'V8CSSValueCustom.cpp',
+ 'V8CanvasRenderingContext2DCustom.cpp',
+ 'V8ClientCustom.cpp',
+ 'V8CryptoCustom.cpp',
+ 'V8CustomEventCustom.cpp',
+ 'V8CustomSQLStatementErrorCallback.cpp',
+ 'V8CustomXPathNSResolver.cpp',
+ 'V8CustomXPathNSResolver.h',
+ 'V8DataViewCustom.cpp',
+ 'V8DataViewCustom.h',
+ 'V8DedicatedWorkerGlobalScopeCustom.cpp',
+ 'V8DeviceMotionEventCustom.cpp',
+ 'V8DeviceOrientationEventCustom.cpp',
+ 'V8DocumentCustom.cpp',
+ 'V8ElementCustom.cpp',
+ 'V8EntryCustom.cpp',
+ 'V8EntrySyncCustom.cpp',
+ 'V8ErrorEventCustom.cpp',
+ 'V8EventCustom.cpp',
+ 'V8EventTargetCustom.cpp',
+ 'V8FileCustom.cpp',
+ 'V8FileReaderCustom.cpp',
+ 'V8Float32ArrayCustom.h',
+ 'V8Float64ArrayCustom.h',
+ 'V8GeolocationCustom.cpp',
+ 'V8HTMLAllCollectionCustom.cpp',
+ 'V8HTMLCanvasElementCustom.cpp',
+ 'V8HTMLCollectionCustom.cpp',
+ 'V8HTMLDocumentCustom.cpp',
+ 'V8HTMLElementCustom.cpp',
+ 'V8HTMLOptionsCollectionCustom.cpp',
+ 'V8HTMLPlugInElementCustom.cpp',
+ 'V8HistoryCustom.cpp',
+ 'V8ImageDataCustom.cpp',
+ 'V8InjectedScriptHostCustom.cpp',
+ 'V8InjectedScriptManager.cpp',
+ 'V8InspectorFrontendHostCustom.cpp',
+ 'V8Int16ArrayCustom.h',
+ 'V8Int32ArrayCustom.h',
+ 'V8Int8ArrayCustom.h',
+ 'V8JavaScriptCallFrameCustom.cpp',
+ 'V8LocationCustom.cpp',
+ 'V8MessageChannelCustom.cpp',
+ 'V8MessageEventCustom.cpp',
+ 'V8MessagePortCustom.cpp',
+ 'V8MutationObserverCustom.cpp',
+ 'V8NodeCustom.cpp',
+ 'V8PerformanceEntryCustom.cpp',
+ 'V8PopStateEventCustom.cpp',
+ 'V8SQLResultSetRowListCustom.cpp',
+ 'V8SQLTransactionCustom.cpp',
+ 'V8SQLTransactionSyncCustom.cpp',
+ 'V8SVGElementCustom.cpp',
+ 'V8SVGPathSegCustom.cpp',
+ 'V8ServiceWorkerCustom.cpp',
+ 'V8StyleSheetCustom.cpp',
+ 'V8SubtleCryptoCustom.cpp',
+ 'V8TextCustom.cpp',
+ 'V8TextTrackCueCustom.cpp',
+ 'V8TrackEventCustom.cpp',
+ 'V8TypedArrayCustom.h',
+ 'V8Uint16ArrayCustom.h',
+ 'V8Uint32ArrayCustom.h',
+ 'V8Uint8ArrayCustom.h',
+ 'V8Uint8ClampedArrayCustom.h',
+ 'V8WebGLRenderingContextCustom.cpp',
+ 'V8WebKitPointCustom.cpp',
+ 'V8WindowCustom.cpp',
+ 'V8WorkerCustom.cpp',
+ 'V8WorkerGlobalScopeCustom.cpp',
+ 'V8XMLHttpRequestCustom.cpp',
+ 'V8XSLTProcessorCustom.cpp',
+ ],
+ },
+}
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/npruntime.cpp b/chromium/third_party/WebKit/Source/bindings/v8/npruntime.cpp
index d3e1755f100..182845e8810 100644
--- a/chromium/third_party/WebKit/Source/bindings/v8/npruntime.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/v8/npruntime.cpp
@@ -352,7 +352,7 @@ void _NPN_InitializeVariantWithStringCopy(NPVariant* variant, const NPString* va
// The rootObjectMap is a hash table of root objects to a set of
// objects that should be deactivated in sync with the root. A
// root is defined as a top-level owner object. This is used on
-// Frame teardown to deactivate all objects associated
+// LocalFrame teardown to deactivate all objects associated
// with a particular plugin.
typedef WTF::HashSet<NPObject*> NPObjectSet;
@@ -432,7 +432,7 @@ void _NPN_UnregisterObject(NPObject* npObject)
set->remove(sub_object);
liveObjectMap().remove(sub_object);
- // Script objects hold a refernce to their DOMWindow*, which is going away if
+ // Script objects hold a refernce to their LocalDOMWindow*, which is going away if
// we're unregistering the associated owner NPObject. Clear it out.
if (V8NPObject* v8npObject = npObjectToV8NPObject(sub_object))
v8npObject->rootObject = 0;
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/v8.gypi b/chromium/third_party/WebKit/Source/bindings/v8/v8.gypi
new file mode 100644
index 00000000000..a220a63087e
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/bindings/v8/v8.gypi
@@ -0,0 +1,165 @@
+# Copyright 2014 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+{
+ 'includes': [
+ 'custom/custom.gypi',
+ ],
+ 'variables': {
+ 'bindings_v8_dir': '.',
+ 'bindings_v8_files': [
+ '<@(bindings_v8_custom_files)',
+ 'ActiveDOMCallback.cpp',
+ 'ActiveDOMCallback.h',
+ 'ArrayValue.cpp',
+ 'ArrayValue.h',
+ 'BindingSecurity.cpp',
+ 'BindingSecurity.h',
+ 'CallbackPromiseAdapter.h',
+ 'CustomElementBinding.cpp',
+ 'CustomElementBinding.h',
+ 'CustomElementConstructorBuilder.cpp',
+ 'CustomElementConstructorBuilder.h',
+ 'CustomElementWrapper.cpp',
+ 'CustomElementWrapper.h',
+ 'DOMDataStore.cpp',
+ 'DOMDataStore.h',
+ 'DOMWrapperMap.h',
+ 'DOMWrapperWorld.cpp',
+ 'DOMWrapperWorld.h',
+ 'Dictionary.cpp',
+ 'Dictionary.h',
+ 'ExceptionMessages.cpp',
+ 'ExceptionMessages.h',
+ 'ExceptionState.cpp',
+ 'ExceptionState.h',
+ 'ExceptionStatePlaceholder.cpp',
+ 'ExceptionStatePlaceholder.h',
+ 'IDBBindingUtilities.cpp',
+ 'IDBBindingUtilities.h',
+ 'NPV8Object.cpp',
+ 'NPV8Object.h',
+ 'Nullable.h',
+ 'PageScriptDebugServer.cpp',
+ 'PageScriptDebugServer.h',
+ 'RetainedDOMInfo.cpp',
+ 'RetainedDOMInfo.h',
+ 'RetainedObjectInfo.h',
+ 'ScheduledAction.cpp',
+ 'ScheduledAction.h',
+ 'ScopedPersistent.h',
+ 'ScriptCallStackFactory.cpp',
+ 'ScriptCallStackFactory.h',
+ 'ScriptController.cpp',
+ 'ScriptController.h',
+ 'ScriptDebugServer.cpp',
+ 'ScriptDebugServer.h',
+ 'ScriptEventListener.cpp',
+ 'ScriptEventListener.h',
+ 'ScriptFunction.cpp',
+ 'ScriptFunction.h',
+ 'ScriptFunctionCall.cpp',
+ 'ScriptFunctionCall.h',
+ 'ScriptGCEvent.cpp',
+ 'ScriptGCEvent.h',
+ 'ScriptHeapSnapshot.cpp',
+ 'ScriptHeapSnapshot.h',
+ 'ScriptPreprocessor.cpp',
+ 'ScriptPreprocessor.h',
+ 'ScriptProfiler.cpp',
+ 'ScriptProfiler.h',
+ 'ScriptPromise.cpp',
+ 'ScriptPromise.h',
+ 'ScriptPromiseResolver.cpp',
+ 'ScriptPromiseResolver.h',
+ 'ScriptPromiseResolverWithContext.cpp',
+ 'ScriptPromiseResolverWithContext.h',
+ 'ScriptRegexp.cpp',
+ 'ScriptRegexp.h',
+ 'ScriptSourceCode.h',
+ 'ScriptState.cpp',
+ 'ScriptState.h',
+ 'ScriptString.cpp',
+ 'ScriptString.h',
+ 'ScriptValue.cpp',
+ 'ScriptValue.h',
+ 'ScriptWrappable.h',
+ 'SerializedScriptValue.cpp',
+ 'SerializedScriptValue.h',
+ 'SharedPersistent.h',
+ 'V8AbstractEventListener.cpp',
+ 'V8AbstractEventListener.h',
+ 'V8Binding.cpp',
+ 'V8Binding.h',
+ 'V8BindingMacros.h',
+ 'V8Callback.cpp',
+ 'V8Callback.h',
+ 'V8CustomElementLifecycleCallbacks.cpp',
+ 'V8CustomElementLifecycleCallbacks.h',
+ 'V8DOMActivityLogger.cpp',
+ 'V8DOMActivityLogger.h',
+ 'V8DOMConfiguration.cpp',
+ 'V8DOMConfiguration.h',
+ 'V8DOMWrapper.cpp',
+ 'V8DOMWrapper.h',
+ 'V8ErrorHandler.cpp',
+ 'V8ErrorHandler.h',
+ 'V8EventListener.cpp',
+ 'V8EventListener.h',
+ 'V8EventListenerList.cpp',
+ 'V8EventListenerList.h',
+ 'V8GCController.cpp',
+ 'V8GCController.h',
+ 'V8GCForContextDispose.cpp',
+ 'V8GCForContextDispose.h',
+ 'V8HiddenValue.cpp',
+ 'V8HiddenValue.h',
+ 'V8Initializer.cpp',
+ 'V8Initializer.h',
+ 'V8LazyEventListener.cpp',
+ 'V8LazyEventListener.h',
+ 'V8MutationCallback.cpp',
+ 'V8MutationCallback.h',
+ 'V8NPObject.cpp',
+ 'V8NPObject.h',
+ 'V8NPUtils.cpp',
+ 'V8NPUtils.h',
+ 'V8NodeFilterCondition.cpp',
+ 'V8NodeFilterCondition.h',
+ 'V8ObjectConstructor.cpp',
+ 'V8ObjectConstructor.h',
+ 'V8PerContextData.cpp',
+ 'V8PerContextData.h',
+ 'V8PerIsolateData.cpp',
+ 'V8PerIsolateData.h',
+ 'V8RecursionScope.cpp',
+ 'V8RecursionScope.h',
+ 'V8ScriptRunner.cpp',
+ 'V8ScriptRunner.h',
+ 'V8StringResource.cpp',
+ 'V8StringResource.h',
+ 'V8ThrowException.cpp',
+ 'V8ThrowException.h',
+ 'V8ValueCache.cpp',
+ 'V8ValueCache.h',
+ 'V8WindowShell.cpp',
+ 'V8WindowShell.h',
+ 'V8WorkerGlobalScopeEventListener.cpp',
+ 'V8WorkerGlobalScopeEventListener.h',
+ 'WorkerScriptController.cpp',
+ 'WorkerScriptController.h',
+ 'WorkerScriptDebugServer.cpp',
+ 'WorkerScriptDebugServer.h',
+ 'WrapperTypeInfo.h',
+ 'npruntime.cpp',
+ 'npruntime_impl.h',
+ 'npruntime_priv.h',
+ ],
+ 'bindings_v8_unittest_files': [
+ 'IDBBindingUtilitiesTest.cpp',
+ 'ScriptPromiseResolverTest.cpp',
+ 'ScriptPromiseTest.cpp',
+ ],
+ },
+}