LCOV - code coverage report
Current view: top level - js/src/builtin - Promise.h (source / functions) Hit Total Coverage
Test: output.info Lines: 13 27 48.1 %
Date: 2017-07-14 16:53:18 Functions: 3 10 30.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
       2             :  * vim: set ts=8 sts=4 et sw=4 tw=99:
       3             :  * This Source Code Form is subject to the terms of the Mozilla Public
       4             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       5             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       6             : 
       7             : #ifndef builtin_Promise_h
       8             : #define builtin_Promise_h
       9             : 
      10             : #include "builtin/SelfHostingDefines.h"
      11             : #include "vm/NativeObject.h"
      12             : 
      13             : namespace js {
      14             : 
      15             : enum PromiseSlots {
      16             :     PromiseSlot_Flags = 0,
      17             :     PromiseSlot_ReactionsOrResult,
      18             :     PromiseSlot_RejectFunction,
      19             :     PromiseSlot_AwaitGenerator = PromiseSlot_RejectFunction,
      20             :     PromiseSlot_AllocationSite,
      21             :     PromiseSlot_ResolutionSite,
      22             :     PromiseSlot_AllocationTime,
      23             :     PromiseSlot_ResolutionTime,
      24             :     PromiseSlot_Id,
      25             :     PromiseSlots,
      26             : };
      27             : 
      28             : #define PROMISE_FLAG_RESOLVED  0x1
      29             : #define PROMISE_FLAG_FULFILLED 0x2
      30             : #define PROMISE_FLAG_HANDLED   0x4
      31             : #define PROMISE_FLAG_REPORTED  0x8
      32             : #define PROMISE_FLAG_DEFAULT_RESOLVE_FUNCTION 0x10
      33             : #define PROMISE_FLAG_DEFAULT_REJECT_FUNCTION  0x20
      34             : #define PROMISE_FLAG_ASYNC    0x40
      35             : 
      36             : class AutoSetNewObjectMetadata;
      37             : 
      38             : class PromiseObject : public NativeObject
      39             : {
      40             :   public:
      41             :     static const unsigned RESERVED_SLOTS = PromiseSlots;
      42             :     static const Class class_;
      43             :     static const Class protoClass_;
      44             :     static PromiseObject* create(JSContext* cx, HandleObject executor,
      45             :                                  HandleObject proto = nullptr, bool needsWrapping = false);
      46             : 
      47             :     static PromiseObject* createSkippingExecutor(JSContext* cx);
      48             : 
      49             :     static JSObject* unforgeableResolve(JSContext* cx, HandleValue value);
      50             :     static JSObject* unforgeableReject(JSContext* cx, HandleValue value);
      51             : 
      52        1228 :     JS::PromiseState state() {
      53        1228 :         int32_t flags = getFixedSlot(PromiseSlot_Flags).toInt32();
      54        1228 :         if (!(flags & PROMISE_FLAG_RESOLVED)) {
      55         961 :             MOZ_ASSERT(!(flags & PROMISE_FLAG_FULFILLED));
      56         961 :             return JS::PromiseState::Pending;
      57             :         }
      58         267 :         if (flags & PROMISE_FLAG_FULFILLED)
      59         259 :             return JS::PromiseState::Fulfilled;
      60           8 :         return JS::PromiseState::Rejected;
      61             :     }
      62           0 :     Value value()  {
      63           0 :         MOZ_ASSERT(state() == JS::PromiseState::Fulfilled);
      64           0 :         return getFixedSlot(PromiseSlot_ReactionsOrResult);
      65             :     }
      66           0 :     Value reason() {
      67           0 :         MOZ_ASSERT(state() == JS::PromiseState::Rejected);
      68           0 :         return getFixedSlot(PromiseSlot_ReactionsOrResult);
      69             :     }
      70             : 
      71             :     static MOZ_MUST_USE bool resolve(JSContext* cx, Handle<PromiseObject*> promise,
      72             :                                      HandleValue resolutionValue);
      73             :     static MOZ_MUST_USE bool reject(JSContext* cx, Handle<PromiseObject*> promise,
      74             :                                     HandleValue rejectionValue);
      75             : 
      76             :     static void onSettled(JSContext* cx, Handle<PromiseObject*> promise);
      77             : 
      78           0 :     double allocationTime() { return getFixedSlot(PromiseSlot_AllocationTime).toNumber(); }
      79           0 :     double resolutionTime() { return getFixedSlot(PromiseSlot_ResolutionTime).toNumber(); }
      80         339 :     JSObject* allocationSite() {
      81         339 :         return getFixedSlot(PromiseSlot_AllocationSite).toObjectOrNull();
      82             :     }
      83           0 :     JSObject* resolutionSite() {
      84           0 :         return getFixedSlot(PromiseSlot_ResolutionSite).toObjectOrNull();
      85             :     }
      86             :     double lifetime();
      87           0 :     double timeToResolution() {
      88           0 :         MOZ_ASSERT(state() != JS::PromiseState::Pending);
      89           0 :         return resolutionTime() - allocationTime();
      90             :     }
      91             :     MOZ_MUST_USE bool dependentPromises(JSContext* cx, MutableHandle<GCVector<Value>> values);
      92             :     uint64_t getID();
      93           4 :     bool isUnhandled() {
      94           4 :         MOZ_ASSERT(state() == JS::PromiseState::Rejected);
      95           4 :         return !(getFixedSlot(PromiseSlot_Flags).toInt32() & PROMISE_FLAG_HANDLED);
      96             :     }
      97             :     void markAsReported() {
      98             :         MOZ_ASSERT(isUnhandled());
      99             :         int32_t flags = getFixedSlot(PromiseSlot_Flags).toInt32();
     100             :         setFixedSlot(PromiseSlot_Flags, Int32Value(flags | PROMISE_FLAG_REPORTED));
     101             :     }
     102             : };
     103             : 
     104             : /**
     105             :  * Unforgeable version of the JS builtin Promise.all.
     106             :  *
     107             :  * Takes an AutoObjectVector of Promise objects and returns a promise that's
     108             :  * resolved with an array of resolution values when all those promises have
     109             :  * been resolved, or rejected with the rejection value of the first rejected
     110             :  * promise.
     111             :  *
     112             :  * Asserts that all objects in the `promises` vector are, maybe wrapped,
     113             :  * instances of `Promise` or a subclass of `Promise`.
     114             :  */
     115             : MOZ_MUST_USE JSObject*
     116             : GetWaitForAllPromise(JSContext* cx, const JS::AutoObjectVector& promises);
     117             : 
     118             : /**
     119             :  * Enqueues resolve/reject reactions in the given Promise's reactions lists
     120             :  * as though calling the original value of Promise.prototype.then.
     121             :  *
     122             :  * If the `createDependent` flag is not set, no dependent Promise will be
     123             :  * created. This is used internally to implement DOM functionality.
     124             :  * Note: In this case, the reactions pushed using this function contain a
     125             :  * `promise` field that can contain null. That field is only ever used by
     126             :  * devtools, which have to treat these reactions specially.
     127             :  */
     128             : MOZ_MUST_USE bool
     129             : OriginalPromiseThen(JSContext* cx, Handle<PromiseObject*> promise,
     130             :                     HandleValue onFulfilled, HandleValue onRejected,
     131             :                     MutableHandleObject dependent, bool createDependent);
     132             : 
     133             : 
     134             : MOZ_MUST_USE PromiseObject*
     135             : CreatePromiseObjectForAsync(JSContext* cx, HandleValue generatorVal);
     136             : 
     137             : MOZ_MUST_USE bool
     138             : AsyncFunctionReturned(JSContext* cx, Handle<PromiseObject*> resultPromise, HandleValue value);
     139             : 
     140             : MOZ_MUST_USE bool
     141             : AsyncFunctionThrown(JSContext* cx, Handle<PromiseObject*> resultPromise);
     142             : 
     143             : MOZ_MUST_USE bool
     144             : AsyncFunctionAwait(JSContext* cx, Handle<PromiseObject*> resultPromise, HandleValue value);
     145             : 
     146             : class AsyncGeneratorObject;
     147             : 
     148             : MOZ_MUST_USE bool
     149             : AsyncGeneratorAwait(JSContext* cx, Handle<AsyncGeneratorObject*> asyncGenObj, HandleValue value);
     150             : 
     151             : MOZ_MUST_USE bool
     152             : AsyncGeneratorResolve(JSContext* cx, Handle<AsyncGeneratorObject*> asyncGenObj,
     153             :                       HandleValue value, bool done);
     154             : 
     155             : MOZ_MUST_USE bool
     156             : AsyncGeneratorReject(JSContext* cx, Handle<AsyncGeneratorObject*> asyncGenObj,
     157             :                      HandleValue exception);
     158             : 
     159             : MOZ_MUST_USE bool
     160             : AsyncGeneratorEnqueue(JSContext* cx, HandleValue asyncGenVal, CompletionKind completionKind,
     161             :                       HandleValue completionValue, MutableHandleValue result);
     162             : 
     163             : bool
     164             : AsyncFromSyncIteratorMethod(JSContext* cx, CallArgs& args, CompletionKind completionKind);
     165             : 
     166             : /**
     167             :  * A PromiseTask represents a task that can be dispatched to a helper thread
     168             :  * (via StartPromiseTask), executed (by implementing PromiseTask::execute()),
     169             :  * and then resolved back on the original JSContext owner thread.
     170             :  * Because it contains a PersistentRooted, a PromiseTask will only be destroyed
     171             :  * on the JSContext's owner thread.
     172             :  */
     173             : class PromiseTask : public JS::AsyncTask
     174             : {
     175             :     JSRuntime* runtime_;
     176             :     PersistentRooted<PromiseObject*> promise_;
     177             : 
     178             :     // PromiseTask implements JS::AsyncTask and prevents derived classes from
     179             :     // overriding; derived classes should implement the new pure virtual
     180             :     // functions introduced below. Both of these methods 'delete this'.
     181             :     void finish(JSContext* cx) override final;
     182             :     void cancel(JSContext* cx) override final;
     183             : 
     184             :   protected:
     185             :     // Called by PromiseTask on the JSContext's owner thread after execute()
     186             :     // completes on the helper thread, assuming JS::FinishAsyncTaskCallback
     187             :     // succeeds. After this method returns, the task will be deleted.
     188             :     virtual bool finishPromise(JSContext* cx, Handle<PromiseObject*> promise) = 0;
     189             : 
     190             :   public:
     191             :     PromiseTask(JSContext* cx, Handle<PromiseObject*> promise);
     192             :     ~PromiseTask();
     193           0 :     JSRuntime* runtime() const { return runtime_; }
     194             : 
     195             :     // Called on a helper thread after StartAsyncTask. After execute()
     196             :     // completes, the JS::FinishAsyncTaskCallback will be called. If this fails
     197             :     // the task will be enqueued for deletion at some future point without ever
     198             :     // calling finishPromise().
     199             :     virtual void execute() = 0;
     200             : 
     201             :     // May be called in the absence of helper threads to synchronously execute
     202             :     // and finish a PromiseTask.
     203             :     bool executeAndFinish(JSContext* cx);
     204             : };
     205             : 
     206             : bool
     207             : Promise_static_resolve(JSContext* cx, unsigned argc, Value* vp);
     208             : bool
     209             : Promise_reject(JSContext* cx, unsigned argc, Value* vp);
     210             : bool
     211             : Promise_then(JSContext* cx, unsigned argc, Value* vp);
     212             : 
     213             : } // namespace js
     214             : 
     215             : #endif /* builtin_Promise_h */

Generated by: LCOV version 1.13