Chromium Code Reviews| Index: Source/bindings/v8/ScriptPromiseResolverWithContext.cpp |
| diff --git a/Source/bindings/v8/ScriptPromiseResolverWithContext.cpp b/Source/bindings/v8/ScriptPromiseResolverWithContext.cpp |
| index 909a845c44499e7a03d06d172ed33a47202ea49d..738767a98fa09316f138363222df7a6d01a7c21e 100644 |
| --- a/Source/bindings/v8/ScriptPromiseResolverWithContext.cpp |
| +++ b/Source/bindings/v8/ScriptPromiseResolverWithContext.cpp |
| @@ -5,13 +5,36 @@ |
| #include "config.h" |
| #include "bindings/v8/ScriptPromiseResolverWithContext.h" |
| +#include "bindings/v8/V8PerIsolateData.h" |
| + |
| namespace WebCore { |
| +namespace { |
| + |
| +// An empty function that is needed to run microtasks. |
| +void noop(const v8::FunctionCallbackInfo<v8::Value>& info) |
| +{ |
| +} |
| + |
| +v8::Handle<v8::Function> getNoopFunction(v8::Isolate* isolate) |
| +{ |
| + static int key; |
| + V8PerIsolateData* data = V8PerIsolateData::from(isolate); |
| + v8::Handle<v8::FunctionTemplate> functionDescriptor = data->existingDOMTemplate(&key); |
| + if (functionDescriptor.IsEmpty()) { |
| + functionDescriptor = v8::FunctionTemplate::New(isolate, noop); |
| + data->setDOMTemplate(&key, functionDescriptor); |
| + } |
| + return functionDescriptor->GetFunction(); |
| +} |
| + |
| +} // namespace |
| + |
| ScriptPromiseResolverWithContext::ScriptPromiseResolverWithContext(NewScriptState* scriptState) |
| : ActiveDOMObject(scriptState->executionContext()) |
| , m_state(Pending) |
| , m_scriptState(scriptState) |
| - , m_timer(this, &ScriptPromiseResolverWithContext::resolveOrRejectImmediately) |
| + , m_timer(this, &ScriptPromiseResolverWithContext::onTimerFired) |
| , m_resolver(ScriptPromiseResolver::create(m_scriptState->executionContext())) { } |
| void ScriptPromiseResolverWithContext::suspend() |
| @@ -31,20 +54,34 @@ void ScriptPromiseResolverWithContext::stop() |
| clear(); |
| } |
| -void ScriptPromiseResolverWithContext::resolveOrRejectImmediately(Timer<ScriptPromiseResolverWithContext>*) |
| +void ScriptPromiseResolverWithContext::onTimerFired(Timer<ScriptPromiseResolverWithContext>*) |
| +{ |
| + RefPtr<ScriptPromiseResolverWithContext> protect(this); |
| + NewScriptState::Scope scope(m_scriptState.get()); |
| + v8::Isolate* isolate = m_scriptState->isolate(); |
| + resolveOrRejectImmediately(); |
| + |
| + // Call an empty function to run microtasks. |
| + // Create one-element array to make MSVC happy (C2466). |
| + v8::Handle<v8::Value> args[1]; |
| + getNoopFunction(isolate)->Call(v8::Undefined(isolate), 0, args); |
|
yhirano
2014/04/15 08:45:06
I'm wondering if calling v8::V8::RunMicrotasks her
yhirano
2014/04/15 10:33:40
Calling an empty function violates some assertions
|
| +} |
| + |
| +void ScriptPromiseResolverWithContext::resolveOrRejectImmediately() |
| { |
| ASSERT(!executionContext()->activeDOMObjectsAreStopped()); |
| ASSERT(!executionContext()->activeDOMObjectsAreSuspended()); |
| if (m_state == Resolving) { |
| - NewScriptState::Scope scope(m_scriptState.get()); |
| m_resolver->resolve(m_value.newLocal(m_scriptState->isolate())); |
| } else { |
| ASSERT(m_state == Rejecting); |
| - NewScriptState::Scope scope(m_scriptState.get()); |
| m_resolver->reject(m_value.newLocal(m_scriptState->isolate())); |
| } |
| m_state = ResolvedOrRejected; |
| clear(); |
| + |
| + // ref() was called in resolveOrRejected. |
| + deref(); |
| } |
| void ScriptPromiseResolverWithContext::clear() |