Index: Source/bindings/v8/ScriptPromiseResolverWithContext.cpp |
diff --git a/Source/bindings/v8/ScriptPromiseResolverWithContext.cpp b/Source/bindings/v8/ScriptPromiseResolverWithContext.cpp |
index 0678ffcff0684341864e918a297cc72b24ae6ecc..e27f524fe86745a39a80c1a143070757c8c2d9c1 100644 |
--- a/Source/bindings/v8/ScriptPromiseResolverWithContext.cpp |
+++ b/Source/bindings/v8/ScriptPromiseResolverWithContext.cpp |
@@ -5,15 +5,33 @@ |
#include "config.h" |
#include "bindings/v8/ScriptPromiseResolverWithContext.h" |
+#include "bindings/v8/V8PerIsolateData.h" |
+ |
namespace WebCore { |
+class ScriptPromiseResolverWithContext::RetainThis : public RefCounted<RetainThis> { |
+public: |
+ static PassRefPtr<RetainThis> create(ScriptPromiseResolverWithContext* resolver) |
+ { |
+ return adoptRef(new RetainThis(resolver)); |
+ } |
+ |
+private: |
+ RetainThis(ScriptPromiseResolverWithContext* resolver) : m_resolver(resolver) { } |
+ RefPtr<ScriptPromiseResolverWithContext> m_resolver; |
+}; |
+ |
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())) { } |
+ScriptPromiseResolverWithContext::~ScriptPromiseResolverWithContext() |
+{ |
+} |
+ |
void ScriptPromiseResolverWithContext::suspend() |
{ |
m_timer.stop(); |
@@ -31,26 +49,44 @@ 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(); |
+ |
+ v8::V8::RunMicrotasks(isolate); |
+} |
+ |
+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(); |
} |
+void ScriptPromiseResolverWithContext::retainThis() |
+{ |
+ // This creates a cyclic reference intentionally to keep this object |
+ // during waiting for the timer. |
+ // The reference will be cleared in clear(). |
+ m_retainThis = RetainThis::create(this); |
+} |
+ |
void ScriptPromiseResolverWithContext::clear() |
{ |
+ m_state = ResolvedOrRejected; |
m_resolver.clear(); |
m_value.clear(); |
+ m_retainThis.clear(); |
+ // |this| may be deleted here. |
} |
} // namespace WebCore |