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() |