Home | History | Annotate | Download | only in v8
      1 /*
      2  * Copyright (C) 2013 Google Inc. All rights reserved.
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions are
      6  * met:
      7  *
      8  *     * Redistributions of source code must retain the above copyright
      9  * notice, this list of conditions and the following disclaimer.
     10  *     * Redistributions in binary form must reproduce the above
     11  * copyright notice, this list of conditions and the following disclaimer
     12  * in the documentation and/or other materials provided with the
     13  * distribution.
     14  *     * Neither the name of Google Inc. nor the names of its
     15  * contributors may be used to endorse or promote products derived from
     16  * this software without specific prior written permission.
     17  *
     18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     22  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     24  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     29  */
     30 
     31 #include "config.h"
     32 #include "bindings/v8/ScriptPromise.h"
     33 
     34 #include "bindings/v8/ScriptPromiseResolver.h"
     35 #include "bindings/v8/V8Binding.h"
     36 #include "core/dom/DOMException.h"
     37 
     38 #include <v8.h>
     39 
     40 namespace WebCore {
     41 
     42 namespace {
     43 
     44 struct WithScriptState {
     45     // Used by ToV8Value<WithScriptState, ScriptState*>.
     46     static v8::Handle<v8::Object> getCreationContext(ScriptState* scriptState)
     47     {
     48         return scriptState->context()->Global();
     49     }
     50 };
     51 
     52 } // namespace
     53 
     54 ScriptPromise::ScriptPromise(ScriptState* scriptState, v8::Handle<v8::Value> value)
     55     : m_scriptState(scriptState)
     56 {
     57     if (value.IsEmpty())
     58         return;
     59 
     60     if (!value->IsPromise()) {
     61         m_promise = ScriptValue(scriptState, v8::Handle<v8::Value>());
     62         V8ThrowException::throwTypeError("the given value is not a Promise", scriptState->isolate());
     63         return;
     64     }
     65     m_promise = ScriptValue(scriptState, value);
     66 }
     67 
     68 ScriptPromise ScriptPromise::then(PassOwnPtr<ScriptFunction> onFulfilled, PassOwnPtr<ScriptFunction> onRejected)
     69 {
     70     if (m_promise.isEmpty())
     71         return ScriptPromise();
     72 
     73     v8::Local<v8::Object> promise = m_promise.v8Value().As<v8::Object>();
     74     v8::Local<v8::Function> v8OnFulfilled = ScriptFunction::adoptByGarbageCollector(onFulfilled);
     75     v8::Local<v8::Function> v8OnRejected = ScriptFunction::adoptByGarbageCollector(onRejected);
     76 
     77     ASSERT(promise->IsPromise());
     78     // Return this Promise if no handlers are given.
     79     // In fact it is not the exact bahavior of Promise.prototype.then
     80     // but that is not a problem in this case.
     81     v8::Local<v8::Promise> resultPromise = promise.As<v8::Promise>();
     82     if (!v8OnFulfilled.IsEmpty()) {
     83         resultPromise = resultPromise->Then(v8OnFulfilled);
     84         if (resultPromise.IsEmpty()) {
     85             // v8::Promise::Then may return an empty value, for example when
     86             // the stack is exhausted.
     87             return ScriptPromise();
     88         }
     89     }
     90     if (!v8OnRejected.IsEmpty())
     91         resultPromise = resultPromise->Catch(v8OnRejected);
     92 
     93     return ScriptPromise(m_scriptState.get(), resultPromise);
     94 }
     95 
     96 ScriptPromise ScriptPromise::cast(ScriptState* scriptState, const ScriptValue& value)
     97 {
     98     return ScriptPromise::cast(scriptState, value.v8Value());
     99 }
    100 
    101 ScriptPromise ScriptPromise::cast(ScriptState* scriptState, v8::Handle<v8::Value> value)
    102 {
    103     if (value.IsEmpty())
    104         return ScriptPromise();
    105     if (value->IsPromise()) {
    106         return ScriptPromise(scriptState, value);
    107     }
    108     RefPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver::create(scriptState);
    109     ScriptPromise promise = resolver->promise();
    110     resolver->resolve(value);
    111     return promise;
    112 }
    113 
    114 ScriptPromise ScriptPromise::reject(ScriptState* scriptState, const ScriptValue& value)
    115 {
    116     return ScriptPromise::reject(scriptState, value.v8Value());
    117 }
    118 
    119 ScriptPromise ScriptPromise::reject(ScriptState* scriptState, v8::Handle<v8::Value> value)
    120 {
    121     if (value.IsEmpty())
    122         return ScriptPromise();
    123     RefPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver::create(scriptState);
    124     ScriptPromise promise = resolver->promise();
    125     resolver->reject(value);
    126     return promise;
    127 }
    128 
    129 ScriptPromise ScriptPromise::rejectWithDOMException(ScriptState* scriptState, PassRefPtrWillBeRawPtr<DOMException> exception)
    130 {
    131     ASSERT(scriptState->isolate()->InContext());
    132     return reject(scriptState, ToV8Value<WithScriptState, v8::Handle<v8::Object> >::toV8Value(exception, scriptState->context()->Global(), scriptState->isolate()));
    133 }
    134 
    135 } // namespace WebCore
    136