Chromium Code Reviews| 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 |