15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/* 25267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) * Copyright (C) 2013 Google Inc. All rights reserved. 35267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) * 45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Redistribution and use in source and binary forms, with or without 55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * modification, are permitted provided that the following conditions are 65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * met: 75267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) * 85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * * Redistributions of source code must retain the above copyright 95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * notice, this list of conditions and the following disclaimer. 105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * * Redistributions in binary form must reproduce the above 115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * copyright notice, this list of conditions and the following disclaimer 125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * in the documentation and/or other materials provided with the 135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * distribution. 145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * * Neither the name of Google Inc. nor the names of its 155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * contributors may be used to endorse or promote products derived from 165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * this software without specific prior written permission. 175267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) * 185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */ 305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 31bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)#include "config.h" 32197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "bindings/core/v8/ScriptPromise.h" 335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 34e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)#include "bindings/core/v8/ExceptionMessages.h" 35e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)#include "bindings/core/v8/ExceptionState.h" 36197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "bindings/core/v8/V8Binding.h" 37e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)#include "bindings/core/v8/V8ThrowException.h" 38d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)#include "core/dom/DOMException.h" 395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 40bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)#include <v8.h> 41926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 42c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink { 435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 44d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)namespace { 45d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) 46d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)struct WithScriptState { 47d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) // Used by ToV8Value<WithScriptState, ScriptState*>. 48d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) static v8::Handle<v8::Object> getCreationContext(ScriptState* scriptState) 49d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) { 50d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) return scriptState->context()->Global(); 51d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) } 52d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)}; 53d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) 54d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)} // namespace 55d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) 56197021e6b966cfb06891637935ef33fff06433d1Ben MurdochScriptPromise::InternalResolver::InternalResolver(ScriptState* scriptState) 57197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch : m_resolver(scriptState, v8::Promise::Resolver::New(scriptState->isolate())) { } 58197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch 59197021e6b966cfb06891637935ef33fff06433d1Ben Murdochv8::Local<v8::Promise> ScriptPromise::InternalResolver::v8Promise() const 60197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch{ 61197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch if (m_resolver.isEmpty()) 62197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch return v8::Local<v8::Promise>(); 63197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch return m_resolver.v8Value().As<v8::Promise::Resolver>()->GetPromise(); 64197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch} 65197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch 66197021e6b966cfb06891637935ef33fff06433d1Ben MurdochScriptPromise ScriptPromise::InternalResolver::promise() const 67197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch{ 68197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch if (m_resolver.isEmpty()) 69197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch return ScriptPromise(); 70197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch return ScriptPromise(m_resolver.scriptState(), v8Promise()); 71197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch} 72197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch 73197021e6b966cfb06891637935ef33fff06433d1Ben Murdochvoid ScriptPromise::InternalResolver::resolve(v8::Local<v8::Value> value) 74197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch{ 75197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch if (m_resolver.isEmpty()) 76197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch return; 77197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch m_resolver.v8Value().As<v8::Promise::Resolver>()->Resolve(value); 78197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch clear(); 79197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch} 80197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch 81197021e6b966cfb06891637935ef33fff06433d1Ben Murdochvoid ScriptPromise::InternalResolver::reject(v8::Local<v8::Value> value) 82197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch{ 83197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch if (m_resolver.isEmpty()) 84197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch return; 85197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch m_resolver.v8Value().As<v8::Promise::Resolver>()->Reject(value); 86197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch clear(); 87197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch} 88197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch 89323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)ScriptPromise::ScriptPromise(ScriptState* scriptState, v8::Handle<v8::Value> value) 90323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) : m_scriptState(scriptState) 91d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){ 9243e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles) if (value.IsEmpty()) 9343e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles) return; 9443e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles) 95d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) if (!value->IsPromise()) { 96323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) m_promise = ScriptValue(scriptState, v8::Handle<v8::Value>()); 97323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) V8ThrowException::throwTypeError("the given value is not a Promise", scriptState->isolate()); 98d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) return; 99d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) } 100323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) m_promise = ScriptValue(scriptState, value); 101d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)} 102d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 1037242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano TucciScriptPromise ScriptPromise::then(v8::Handle<v8::Function> onFulfilled, v8::Handle<v8::Function> onRejected) 10409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles){ 10510f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch if (m_promise.isEmpty()) 10609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) return ScriptPromise(); 10709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 10843e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles) v8::Local<v8::Object> promise = m_promise.v8Value().As<v8::Object>(); 10909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 11043e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles) ASSERT(promise->IsPromise()); 11143e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles) // Return this Promise if no handlers are given. 11243e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles) // In fact it is not the exact bahavior of Promise.prototype.then 11343e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles) // but that is not a problem in this case. 11443e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles) v8::Local<v8::Promise> resultPromise = promise.As<v8::Promise>(); 1157242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci if (!onFulfilled.IsEmpty()) { 1167242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci resultPromise = resultPromise->Then(onFulfilled); 11743e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles) if (resultPromise.IsEmpty()) { 1185d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) // v8::Promise::Then may return an empty value, for example when 11943e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles) // the stack is exhausted. 12043e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles) return ScriptPromise(); 12143e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles) } 12243e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles) } 1237242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci if (!onRejected.IsEmpty()) 1247242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci resultPromise = resultPromise->Catch(onRejected); 12543e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles) 126323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) return ScriptPromise(m_scriptState.get(), resultPromise); 1275267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)} 1285267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) 1295d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)ScriptPromise ScriptPromise::cast(ScriptState* scriptState, const ScriptValue& value) 130bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles){ 1315d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) return ScriptPromise::cast(scriptState, value.v8Value()); 132d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)} 133d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) 134d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)ScriptPromise ScriptPromise::cast(ScriptState* scriptState, v8::Handle<v8::Value> value) 135d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles){ 136d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) if (value.IsEmpty()) 137d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) return ScriptPromise(); 138d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) if (value->IsPromise()) { 139d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) return ScriptPromise(scriptState, value); 14010f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch } 141197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch InternalResolver resolver(scriptState); 142197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch ScriptPromise promise = resolver.promise(); 143197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch resolver.resolve(value); 144d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) return promise; 145d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)} 146d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) 1475d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)ScriptPromise ScriptPromise::reject(ScriptState* scriptState, const ScriptValue& value) 148d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles){ 1495d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) return ScriptPromise::reject(scriptState, value.v8Value()); 150d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)} 151d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) 152d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)ScriptPromise ScriptPromise::reject(ScriptState* scriptState, v8::Handle<v8::Value> value) 153d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles){ 154d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) if (value.IsEmpty()) 155d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) return ScriptPromise(); 156197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch InternalResolver resolver(scriptState); 157197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch ScriptPromise promise = resolver.promise(); 158197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch resolver.reject(value); 159d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) return promise; 160d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)} 161d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) 162d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)ScriptPromise ScriptPromise::rejectWithDOMException(ScriptState* scriptState, PassRefPtrWillBeRawPtr<DOMException> exception) 163d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles){ 164d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) ASSERT(scriptState->isolate()->InContext()); 165197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch return reject(scriptState, V8ValueTraits<PassRefPtrWillBeRawPtr<DOMException> >::toV8Value(exception, scriptState->context()->Global(), scriptState->isolate())); 166bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)} 1675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 168e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)v8::Local<v8::Promise> ScriptPromise::rejectRaw(v8::Isolate* isolate, v8::Handle<v8::Value> value) 169e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles){ 170e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) if (value.IsEmpty()) 171e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) return v8::Local<v8::Promise>(); 172e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) v8::Local<v8::Promise::Resolver> resolver = v8::Promise::Resolver::New(isolate); 173e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) v8::Local<v8::Promise> promise = resolver->GetPromise(); 174e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) resolver->Reject(value); 175e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) return promise; 176e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)} 177e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) 178c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)} // namespace blink 179