Index: Source/bindings/v8/ScriptPromiseResolverWithContext.cpp |
diff --git a/Source/bindings/v8/ScriptPromiseResolverWithContext.cpp b/Source/bindings/v8/ScriptPromiseResolverWithContext.cpp |
index 1a39cac07223f4c777f9d4df80e891041609d0fa..9ee4d584c6c4f5b848721e8d8808824084205820 100644 |
--- a/Source/bindings/v8/ScriptPromiseResolverWithContext.cpp |
+++ b/Source/bindings/v8/ScriptPromiseResolverWithContext.cpp |
@@ -5,10 +5,15 @@ |
#include "config.h" |
#include "bindings/v8/ScriptPromiseResolverWithContext.h" |
+#include "bindings/v8/V8HiddenValue.h" |
#include "bindings/v8/V8RecursionScope.h" |
namespace WebCore { |
+namespace { |
+const char hiddenPropertyName[] = "blink::keepObjectWhilePending"; |
haraken
2014/06/13 14:23:31
Can you use V8HiddenPropertyName::pendingObject? Y
|
+} // namespace |
+ |
ScriptPromiseResolverWithContext::ScriptPromiseResolverWithContext(ScriptState* scriptState) |
: ActiveDOMObject(scriptState->executionContext()) |
, m_state(Pending) |
@@ -18,6 +23,16 @@ ScriptPromiseResolverWithContext::ScriptPromiseResolverWithContext(ScriptState* |
{ |
} |
+ScriptPromiseResolverWithContext::~ScriptPromiseResolverWithContext() |
+{ |
+ if (m_state != ResolvedOrRejected) { |
+ ScriptState::Scope scope(m_scriptState.get()); |
+ unregisterKeptObject(); |
+ reject(v8::Exception::Error(v8::String::NewFromUtf8(m_scriptState->isolate(), |
+ "ScriptPromiseResolverWithContext is destructed without resolve / reject"))); |
+ } |
+} |
+ |
void ScriptPromiseResolverWithContext::suspend() |
{ |
m_timer.stop(); |
@@ -31,6 +46,8 @@ void ScriptPromiseResolverWithContext::resume() |
void ScriptPromiseResolverWithContext::stop() |
{ |
+ ScriptState::Scope scope(m_scriptState.get()); |
+ unregisterKeptObject(); |
m_timer.stop(); |
clear(); |
} |
@@ -46,6 +63,7 @@ void ScriptPromiseResolverWithContext::resolveOrRejectImmediately() |
{ |
ASSERT(!executionContext()->activeDOMObjectsAreStopped()); |
ASSERT(!executionContext()->activeDOMObjectsAreSuspended()); |
+ unregisterKeptObject(); |
haraken
2014/06/13 14:23:31
I think you need to enter ScriptState::Scope befor
|
{ |
// 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 |
@@ -74,4 +92,33 @@ void ScriptPromiseResolverWithContext::clear() |
// |this| may be deleted here. |
} |
+void ScriptPromiseResolverWithContext::keepObjectWhilePendingInternal(v8::Handle<v8::Value> value) |
+{ |
+ if (!m_resolver) |
+ return; |
+ ASSERT(m_scriptState->isolate()->InContext()); |
+ ScriptPromise promise = this->promise(); |
+ if (promise.isEmpty()) |
+ return; |
+ v8::Isolate* isolate = m_scriptState->isolate(); |
+ v8::Local<v8::Promise> v8Promise = promise.v8Value().As<v8::Promise>(); |
+ v8::Local<v8::String> name = v8::String::NewFromUtf8(isolate, hiddenPropertyName); |
+ ASSERT(V8HiddenValue::getHiddenValue(isolate, v8Promise, name).IsEmpty()); |
+ V8HiddenValue::setHiddenValue(isolate, v8Promise, name, value); |
+} |
+ |
+void ScriptPromiseResolverWithContext::unregisterKeptObject() |
+{ |
+ if (!m_resolver) |
+ return; |
+ ASSERT(m_scriptState->isolate()->InContext()); |
+ ScriptPromise promise = this->promise(); |
+ if (promise.isEmpty()) |
+ return; |
+ v8::Isolate* isolate = m_scriptState->isolate(); |
+ v8::Local<v8::Promise> v8Promise = promise.v8Value().As<v8::Promise>(); |
+ v8::Local<v8::String> name = v8::String::NewFromUtf8(isolate, hiddenPropertyName); |
+ V8HiddenValue::deleteHiddenValue(isolate, v8Promise, name); |
+} |
+ |
} // namespace WebCore |