| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "modules/webaudio/AudioWorkletGlobalScope.h" | 5 #include "modules/webaudio/AudioWorkletGlobalScope.h" |
| 6 | 6 |
| 7 #include "bindings/core/v8/Dictionary.h" |
| 8 #include "bindings/core/v8/IDLTypes.h" |
| 9 #include "bindings/core/v8/NativeValueTraitsImpl.h" |
| 7 #include "bindings/core/v8/ToV8ForCore.h" | 10 #include "bindings/core/v8/ToV8ForCore.h" |
| 8 #include "bindings/core/v8/V8BindingForCore.h" | 11 #include "bindings/core/v8/V8BindingForCore.h" |
| 9 #include "bindings/core/v8/WorkerOrWorkletScriptController.h" | 12 #include "bindings/core/v8/WorkerOrWorkletScriptController.h" |
| 13 #include "bindings/modules/v8/V8AudioParamDescriptor.h" |
| 10 #include "core/dom/ExceptionCode.h" | 14 #include "core/dom/ExceptionCode.h" |
| 11 #include "modules/webaudio/AudioBuffer.h" | 15 #include "modules/webaudio/AudioBuffer.h" |
| 16 #include "modules/webaudio/AudioParamDescriptor.h" |
| 12 #include "modules/webaudio/AudioWorkletProcessor.h" | 17 #include "modules/webaudio/AudioWorkletProcessor.h" |
| 13 #include "modules/webaudio/AudioWorkletProcessorDefinition.h" | 18 #include "modules/webaudio/AudioWorkletProcessorDefinition.h" |
| 14 #include "platform/bindings/V8BindingMacros.h" | 19 #include "platform/bindings/V8BindingMacros.h" |
| 15 #include "platform/bindings/V8ObjectConstructor.h" | 20 #include "platform/bindings/V8ObjectConstructor.h" |
| 16 #include "platform/weborigin/SecurityOrigin.h" | 21 #include "platform/weborigin/SecurityOrigin.h" |
| 17 | 22 |
| 18 namespace blink { | 23 namespace blink { |
| 19 | 24 |
| 20 AudioWorkletGlobalScope* AudioWorkletGlobalScope::Create( | 25 AudioWorkletGlobalScope* AudioWorkletGlobalScope::Create( |
| 21 const KURL& url, | 26 const KURL& url, |
| 22 const String& user_agent, | 27 const String& user_agent, |
| 23 PassRefPtr<SecurityOrigin> security_origin, | 28 PassRefPtr<SecurityOrigin> security_origin, |
| 24 v8::Isolate* isolate, | 29 v8::Isolate* isolate, |
| 25 WorkerThread* thread, | 30 WorkerThread* thread, |
| 26 WorkerClients* worker_clients) { | 31 WorkerClients* worker_clients) { |
| 32 LOG(INFO) << "AudioWorkletGlobalScope::RegisterProcessor thread = " |
| 33 << thread; |
| 27 return new AudioWorkletGlobalScope(url, user_agent, | 34 return new AudioWorkletGlobalScope(url, user_agent, |
| 28 std::move(security_origin), isolate, | 35 std::move(security_origin), isolate, |
| 29 thread, worker_clients); | 36 thread, worker_clients); |
| 30 } | 37 } |
| 31 | 38 |
| 32 AudioWorkletGlobalScope::AudioWorkletGlobalScope( | 39 AudioWorkletGlobalScope::AudioWorkletGlobalScope( |
| 33 const KURL& url, | 40 const KURL& url, |
| 34 const String& user_agent, | 41 const String& user_agent, |
| 35 PassRefPtr<SecurityOrigin> security_origin, | 42 PassRefPtr<SecurityOrigin> security_origin, |
| 36 v8::Isolate* isolate, | 43 v8::Isolate* isolate, |
| (...skipping 29 matching lines...) Expand all Loading... |
| 66 } | 73 } |
| 67 | 74 |
| 68 // TODO(hongchan): this is not stated in the spec, but seems necessary. | 75 // TODO(hongchan): this is not stated in the spec, but seems necessary. |
| 69 // https://github.com/WebAudio/web-audio-api/issues/1172 | 76 // https://github.com/WebAudio/web-audio-api/issues/1172 |
| 70 if (name.IsEmpty()) { | 77 if (name.IsEmpty()) { |
| 71 exception_state.ThrowTypeError("The empty string is not a valid name."); | 78 exception_state.ThrowTypeError("The empty string is not a valid name."); |
| 72 return; | 79 return; |
| 73 } | 80 } |
| 74 | 81 |
| 75 v8::Isolate* isolate = ScriptController()->GetScriptState()->GetIsolate(); | 82 v8::Isolate* isolate = ScriptController()->GetScriptState()->GetIsolate(); |
| 76 v8::Local<v8::Context> context = | 83 v8::Local<v8::Context> context = ScriptController()->GetContext(); |
| 77 ScriptController()->GetScriptState()->GetContext(); | |
| 78 | 84 |
| 85 // Get a handle for the class definition (i.e. constructor) |
| 79 if (!class_definition.V8Value()->IsFunction()) { | 86 if (!class_definition.V8Value()->IsFunction()) { |
| 80 exception_state.ThrowTypeError( | 87 exception_state.ThrowTypeError( |
| 81 "The processor definition is neither 'class' nor 'function'."); | 88 "The processor definition is neither 'class' nor 'function'."); |
| 82 return; | 89 return; |
| 83 } | 90 } |
| 84 | 91 |
| 85 v8::Local<v8::Function> class_definition_local = | 92 v8::Local<v8::Function> class_definition_local = |
| 86 class_definition.V8Value().As<v8::Function>(); | 93 v8::Local<v8::Function>::Cast(class_definition.V8Value()); |
| 87 | 94 |
| 95 // Get a handle for |prototype| object out of class definition. |
| 88 v8::Local<v8::Value> prototype_value_local; | 96 v8::Local<v8::Value> prototype_value_local; |
| 89 bool prototype_extracted = | 97 bool prototype_extracted = |
| 90 class_definition_local->Get(context, V8String(isolate, "prototype")) | 98 class_definition_local->Get(context, V8String(isolate, "prototype")) |
| 91 .ToLocal(&prototype_value_local); | 99 .ToLocal(&prototype_value_local); |
| 92 DCHECK(prototype_extracted); | 100 DCHECK(prototype_extracted); |
| 93 | 101 |
| 94 v8::Local<v8::Object> prototype_object_local = | 102 v8::Local<v8::Object> prototype_object_local = |
| 95 prototype_value_local.As<v8::Object>(); | 103 prototype_value_local.As<v8::Object>(); |
| 96 | 104 |
| 105 // Extract |process| function. |
| 97 v8::Local<v8::Value> process_value_local; | 106 v8::Local<v8::Value> process_value_local; |
| 98 bool process_extracted = | 107 bool process_extracted = |
| 99 prototype_object_local->Get(context, V8String(isolate, "process")) | 108 prototype_object_local->Get(context, V8String(isolate, "process")) |
| 100 .ToLocal(&process_value_local); | 109 .ToLocal(&process_value_local); |
| 101 DCHECK(process_extracted); | 110 DCHECK(process_extracted); |
| 102 | 111 |
| 103 if (process_value_local->IsNullOrUndefined()) { | 112 if (process_value_local->IsNullOrUndefined()) { |
| 104 exception_state.ThrowTypeError( | 113 exception_state.ThrowTypeError( |
| 105 "The 'process' function does not exist in the prototype."); | 114 "The 'process' function does not exist in the prototype."); |
| 106 return; | 115 return; |
| (...skipping 23 matching lines...) Expand all Loading... |
| 130 AudioWorkletProcessorDefinition* definition = FindDefinition(name); | 139 AudioWorkletProcessorDefinition* definition = FindDefinition(name); |
| 131 if (!definition) | 140 if (!definition) |
| 132 return nullptr; | 141 return nullptr; |
| 133 | 142 |
| 134 // V8 object instance construction: this construction process is here to make | 143 // V8 object instance construction: this construction process is here to make |
| 135 // the AudioWorkletProcessor class a thin wrapper of V8::Object instance. | 144 // the AudioWorkletProcessor class a thin wrapper of V8::Object instance. |
| 136 v8::Isolate* isolate = ScriptController()->GetScriptState()->GetIsolate(); | 145 v8::Isolate* isolate = ScriptController()->GetScriptState()->GetIsolate(); |
| 137 v8::Local<v8::Object> instance_local; | 146 v8::Local<v8::Object> instance_local; |
| 138 if (!V8ObjectConstructor::NewInstance(isolate, | 147 if (!V8ObjectConstructor::NewInstance(isolate, |
| 139 definition->ConstructorLocal(isolate)) | 148 definition->ConstructorLocal(isolate)) |
| 140 .ToLocal(&instance_local)) { | 149 .ToLocal(&instance_local)) { |
| 141 return nullptr; | 150 return nullptr; |
| 142 } | 151 } |
| 143 | 152 |
| 144 AudioWorkletProcessor* processor = AudioWorkletProcessor::Create(this, name); | 153 AudioWorkletProcessor* processor = |
| 154 AudioWorkletProcessor::Create(this, definition); |
| 145 DCHECK(processor); | 155 DCHECK(processor); |
| 146 | 156 |
| 147 processor->SetInstance(isolate, instance_local); | 157 processor->SetInstance(isolate, instance_local); |
| 148 processor_instances_.push_back(processor); | 158 processor_instances_.push_back(processor); |
| 149 | 159 |
| 150 return processor; | 160 return processor; |
| 151 } | 161 } |
| 152 | 162 |
| 153 bool AudioWorkletGlobalScope::Process(AudioWorkletProcessor* processor, | 163 bool AudioWorkletGlobalScope::Process(AudioWorkletProcessor* processor, |
| 154 AudioBuffer* input_buffer, | 164 AudioBuffer* input_buffer, |
| 155 AudioBuffer* output_buffer) { | 165 AudioBuffer* output_buffer) { |
| 156 CHECK(input_buffer); | 166 CHECK(input_buffer); |
| 157 CHECK(output_buffer); | 167 CHECK(output_buffer); |
| 158 | 168 |
| 159 ScriptState* script_state = ScriptController()->GetScriptState(); | 169 ScriptState* script_state = ScriptController()->GetScriptState(); |
| 170 v8::Isolate* isolate = script_state->GetIsolate(); |
| 171 |
| 160 ScriptState::Scope scope(script_state); | 172 ScriptState::Scope scope(script_state); |
| 161 | 173 |
| 162 v8::Isolate* isolate = script_state->GetIsolate(); | |
| 163 AudioWorkletProcessorDefinition* definition = | 174 AudioWorkletProcessorDefinition* definition = |
| 164 FindDefinition(processor->GetName()); | 175 FindDefinition(processor->GetName()); |
| 165 DCHECK(definition); | 176 DCHECK(definition); |
| 166 | 177 |
| 167 v8::Local<v8::Value> argv[] = { | 178 v8::Local<v8::Value> argv[] = { |
| 168 ToV8(input_buffer, script_state->GetContext()->Global(), isolate), | 179 ToV8(input_buffer, script_state->GetContext()->Global(), isolate), |
| 169 ToV8(output_buffer, script_state->GetContext()->Global(), isolate)}; | 180 ToV8(output_buffer, script_state->GetContext()->Global(), isolate)}; |
| 170 | 181 |
| 171 // TODO(hongchan): Catch exceptions thrown in the process method. The verbose | 182 // TODO(hongchan): Catch exceptions thrown in the process method. The verbose |
| 172 // options forces the TryCatch object to save the exception location. The | 183 // options forces the TryCatch object to save the exception location. The |
| (...skipping 16 matching lines...) Expand all Loading... |
| 189 return processor_definition_map_.at(name); | 200 return processor_definition_map_.at(name); |
| 190 } | 201 } |
| 191 | 202 |
| 192 DEFINE_TRACE(AudioWorkletGlobalScope) { | 203 DEFINE_TRACE(AudioWorkletGlobalScope) { |
| 193 visitor->Trace(processor_definition_map_); | 204 visitor->Trace(processor_definition_map_); |
| 194 visitor->Trace(processor_instances_); | 205 visitor->Trace(processor_instances_); |
| 195 ThreadedWorkletGlobalScope::Trace(visitor); | 206 ThreadedWorkletGlobalScope::Trace(visitor); |
| 196 } | 207 } |
| 197 | 208 |
| 198 } // namespace blink | 209 } // namespace blink |
| OLD | NEW |