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 #ifndef ScriptPromiseResolver_h
     32 #define ScriptPromiseResolver_h
     33 
     34 #include "bindings/v8/ScopedPersistent.h"
     35 #include "bindings/v8/ScriptObject.h"
     36 #include "bindings/v8/ScriptState.h"
     37 #include "bindings/v8/ScriptValue.h"
     38 #include "wtf/RefPtr.h"
     39 
     40 #include <v8.h>
     41 
     42 namespace WebCore {
     43 
     44 class ScriptExecutionContext;
     45 
     46 // ScriptPromiseResolver is a class for accessing PromiseResolver methods
     47 // (fulfill / resolve / reject) from C++ world.
     48 // ScriptPromiseResolver holds a Promise and a PromiseResolver.
     49 // All methods of this class must be called from the main thread.
     50 // Here is a typical usage:
     51 //  1. Create a ScriptPromiseResolver.
     52 //  2. Pass the promise object of the holder to a JavaScript program
     53 //     (such as XMLHttpRequest return value).
     54 //  3. Detach the promise object if you no long need it.
     55 //  4. Call fulfill or reject when the operation completes or
     56 //     the operation fails respectively.
     57 //
     58 // Most methods including constructors must be called within a v8 context.
     59 // To use ScriptPromiseResolver out of a v8 context the caller must
     60 // enter a v8 context, for example by using ScriptScope and ScriptState.
     61 //
     62 class ScriptPromiseResolver : public RefCounted<ScriptPromiseResolver> {
     63     WTF_MAKE_NONCOPYABLE(ScriptPromiseResolver);
     64 public:
     65     static PassRefPtr<ScriptPromiseResolver> create(ScriptExecutionContext*);
     66     static PassRefPtr<ScriptPromiseResolver> create();
     67 
     68     // A ScriptPromiseResolver should be fulfilled / resolved / rejected before
     69     // its destruction.
     70     // A ScriptPromiseResolver can be destructed safely without
     71     // entering a v8 context.
     72     ~ScriptPromiseResolver();
     73 
     74     // Detach the promise object and reject the resolver object with undefined.
     75     void detach();
     76 
     77     // Detach the promise object.
     78     void detachPromise() { m_promise.clear(); }
     79 
     80     // Return true if the following conditions are met:
     81     //  - The resolver object is not detached.
     82     //  - The resolver's promise object is in pending state.
     83     //  - The resolver's resolved flag is not set.
     84     bool isPending() const;
     85 
     86     ScriptObject promise()
     87     {
     88         ASSERT(v8::Context::InContext());
     89         return ScriptObject(ScriptState::current(), m_promise.newLocal(m_isolate));
     90     }
     91 
     92     // Fulfill with a C++ object which can be converted to a v8 object by toV8.
     93     template<typename T>
     94     inline void fulfill(PassRefPtr<T>);
     95     // Resolve with a C++ object which can be converted to a v8 object by toV8.
     96     template<typename T>
     97     inline void resolve(PassRefPtr<T>);
     98     // Reject with a C++ object which can be converted to a v8 object by toV8.
     99     template<typename T>
    100     inline void reject(PassRefPtr<T>);
    101 
    102     void fulfill(ScriptValue);
    103     void resolve(ScriptValue);
    104     void reject(ScriptValue);
    105 
    106 private:
    107     ScriptPromiseResolver(v8::Handle<v8::Object> creationContext, v8::Isolate*);
    108     void fulfill(v8::Handle<v8::Value>);
    109     void resolve(v8::Handle<v8::Value>);
    110     void reject(v8::Handle<v8::Value>);
    111 
    112     v8::Isolate* m_isolate;
    113     ScopedPersistent<v8::Object> m_promise;
    114     ScopedPersistent<v8::Object> m_resolver;
    115     bool isPendingInternal() const;
    116 };
    117 
    118 template<typename T>
    119 void ScriptPromiseResolver::fulfill(PassRefPtr<T> value)
    120 {
    121     ASSERT(v8::Context::InContext());
    122     fulfill(toV8(value.get(), v8::Object::New(), m_isolate));
    123 }
    124 
    125 template<typename T>
    126 void ScriptPromiseResolver::resolve(PassRefPtr<T> value)
    127 {
    128     ASSERT(v8::Context::InContext());
    129     resolve(toV8(value.get(), v8::Object::New(), m_isolate));
    130 }
    131 
    132 template<typename T>
    133 void ScriptPromiseResolver::reject(PassRefPtr<T> value)
    134 {
    135     ASSERT(v8::Context::InContext());
    136     reject(toV8(value.get(), v8::Object::New(), m_isolate));
    137 }
    138 
    139 } // namespace WebCore
    140 
    141 
    142 #endif // ScriptPromiseResolver_h
    143