void ScriptPromisePropertyBase::resolveOrReject(State targetState) { ASSERT(executionContext()); ASSERT(m_state == Pending); ASSERT(targetState == Resolved || targetState == Rejected); m_state = targetState; v8::HandleScope handleScope(m_isolate); size_t i = 0; while (i < m_wrappers.size()) { const OwnPtr<ScopedPersistent<v8::Object> >& persistent = m_wrappers[i]; if (persistent->isEmpty()) { // wrapper has died. // Since v8 GC can run during the iteration and clear the reference, // we can't move this check out of the loop. m_wrappers.remove(i); continue; } v8::Local<v8::Object> wrapper = persistent->newLocal(m_isolate); ScriptState::Scope scope(ScriptState::from(wrapper->CreationContext())); v8::Local<v8::Promise::Resolver> resolver = V8HiddenValue::getHiddenValue(m_isolate, wrapper, resolverName()).As<v8::Promise::Resolver>(); V8HiddenValue::deleteHiddenValue(m_isolate, wrapper, resolverName()); resolveOrRejectInternal(resolver); ++i; } }
void ScriptPromisePropertyBase::clearWrappers() { v8::HandleScope handleScope(m_isolate); for (WeakPersistentSet::iterator i = m_wrappers.begin(); i != m_wrappers.end(); ++i) { v8::Local<v8::Object> wrapper = (*i)->newLocal(m_isolate); if (!wrapper.IsEmpty()) { wrapper->DeleteHiddenValue(resolverName()); wrapper->DeleteHiddenValue(promiseName()); } } m_wrappers.clear(); }
void ScriptPromisePropertyBase::clearWrappers() { checkThis(); checkWrappers(); v8::HandleScope handleScope(m_isolate); for (WeakPersistentSet::iterator i = m_wrappers.begin(); i != m_wrappers.end(); ++i) { v8::Local<v8::Object> wrapper = (*i)->newLocal(m_isolate); if (!wrapper.IsEmpty()) { ScriptState* scriptState = ScriptState::from(wrapper->CreationContext()); V8HiddenValue::deleteHiddenValue(scriptState, wrapper, resolverName()); V8HiddenValue::deleteHiddenValue(scriptState, wrapper, promiseName()); } } m_wrappers.clear(); }
ScriptPromise ScriptPromisePropertyBase::promise(DOMWrapperWorld& world) { if (!getExecutionContext()) return ScriptPromise(); v8::HandleScope handleScope(m_isolate); v8::Local<v8::Context> context = toV8Context(getExecutionContext(), world); if (context.IsEmpty()) return ScriptPromise(); ScriptState* scriptState = ScriptState::from(context); ScriptState::Scope scope(scriptState); v8::Local<v8::Object> wrapper = ensureHolderWrapper(scriptState); ASSERT(wrapper->CreationContext() == context); v8::Local<v8::Value> cachedPromise = V8HiddenValue::getHiddenValue(scriptState, wrapper, promiseName()); if (!cachedPromise.IsEmpty() && cachedPromise->IsPromise()) return ScriptPromise(scriptState, cachedPromise); // Create and cache the Promise v8::Local<v8::Promise::Resolver> resolver; if (!v8::Promise::Resolver::New(context).ToLocal(&resolver)) return ScriptPromise(); v8::Local<v8::Promise> promise = resolver->GetPromise(); V8HiddenValue::setHiddenValue(scriptState, wrapper, promiseName(), promise); switch (m_state) { case Pending: // Cache the resolver too V8HiddenValue::setHiddenValue(scriptState, wrapper, resolverName(), resolver); break; case Resolved: case Rejected: resolveOrRejectInternal(resolver); break; } return ScriptPromise(scriptState, promise); }