16f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch// Copyright 2014 The Chromium Authors. All rights reserved. 26f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch// Use of this source code is governed by a BSD-style license that can be 36f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch// found in the LICENSE file. 46f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch 56f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch#include "config.h" 66f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch#include "bindings/v8/ScriptPromiseResolverWithContext.h" 76f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch 8f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)#include "bindings/v8/V8RecursionScope.h" 9f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu 106f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdochnamespace WebCore { 116f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch 12f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo LiuScriptPromiseResolverWithContext::ScriptPromiseResolverWithContext(ScriptState* scriptState) 136f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch : ActiveDOMObject(scriptState->executionContext()) 146f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch , m_state(Pending) 156f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch , m_scriptState(scriptState) 165d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) , m_mode(Default) 17f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu , m_timer(this, &ScriptPromiseResolverWithContext::onTimerFired) 18323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) , m_resolver(ScriptPromiseResolver::create(m_scriptState.get())) 1976c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)#if ASSERTION_ENABLED 2076c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles) , m_isPromiseCalled(false) 2176c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)#endif 22323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles){ 235d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) if (executionContext()->activeDOMObjectsAreStopped()) 245d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) m_state = ResolvedOrRejected; 255d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)} 265d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) 276f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdochvoid ScriptPromiseResolverWithContext::suspend() 286f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch{ 296f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch m_timer.stop(); 306f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch} 316f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch 326f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdochvoid ScriptPromiseResolverWithContext::resume() 336f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch{ 346f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch if (m_state == Resolving || m_state == Rejecting) 356f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch m_timer.startOneShot(0, FROM_HERE); 366f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch} 376f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch 386f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdochvoid ScriptPromiseResolverWithContext::stop() 396f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch{ 406f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch m_timer.stop(); 416f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch clear(); 426f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch} 436f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch 445d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)void ScriptPromiseResolverWithContext::keepAliveWhilePending() 455d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles){ 465d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) if (m_state == ResolvedOrRejected || m_mode == KeepAliveWhilePending) 475d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) return; 485d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) 495d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) // Keep |this| while the promise is Pending. 505d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) // deref() will be called in clear(). 515d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) m_mode = KeepAliveWhilePending; 525d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) ref(); 535d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)} 545d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) 55f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liuvoid ScriptPromiseResolverWithContext::onTimerFired(Timer<ScriptPromiseResolverWithContext>*) 56f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu{ 57f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu ScriptState::Scope scope(m_scriptState.get()); 58f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu resolveOrRejectImmediately(); 59f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu} 60f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu 61f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liuvoid ScriptPromiseResolverWithContext::resolveOrRejectImmediately() 626f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch{ 636f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch ASSERT(!executionContext()->activeDOMObjectsAreStopped()); 646f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch ASSERT(!executionContext()->activeDOMObjectsAreSuspended()); 65f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles) { 66f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles) // FIXME: The V8RecursionScope is only necessary to force microtask delivery for promises 67f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles) // resolved or rejected in workers. It can be removed once worker threads run microtasks 68f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles) // at the end of every task (rather than just the main thread). 69f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles) V8RecursionScope scope(m_scriptState->isolate(), m_scriptState->executionContext()); 70f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles) if (m_state == Resolving) { 71f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles) m_resolver->resolve(m_value.newLocal(m_scriptState->isolate())); 72f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles) } else { 73f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles) ASSERT(m_state == Rejecting); 74f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles) m_resolver->reject(m_value.newLocal(m_scriptState->isolate())); 75f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles) } 766f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch } 776f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch clear(); 786f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch} 796f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch 806f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdochvoid ScriptPromiseResolverWithContext::clear() 816f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch{ 825d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) if (m_state == ResolvedOrRejected) 835d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) return; 84f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu ResolutionState state = m_state; 85f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu m_state = ResolvedOrRejected; 866f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch m_resolver.clear(); 876f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch m_value.clear(); 885d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) if (m_mode == KeepAliveWhilePending) { 8976c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles) // |ref| was called in |keepAliveWhilePending|. 905d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) deref(); 915d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) } 925d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) // |this| may be deleted here, but it is safe to check |state| because 935d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) // it doesn't depend on |this|. When |this| is deleted, |state| can't be 945d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) // |Resolving| nor |Rejecting| and hence |this->deref()| can't be executed. 95f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu if (state == Resolving || state == Rejecting) { 96f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu // |ref| was called in |resolveOrReject|. 97f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu deref(); 98f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu } 996f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch} 1006f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch 1016f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch} // namespace WebCore 102