Home | History | Annotate | Download | only in builtins
      1 // Copyright 2016 the V8 project authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #ifndef V8_BUILTINS_BUILTINS_PROMISE_H_
      6 #define V8_BUILTINS_BUILTINS_PROMISE_H_
      7 
      8 #include "src/code-stub-assembler.h"
      9 #include "src/contexts.h"
     10 
     11 namespace v8 {
     12 namespace internal {
     13 
     14 typedef compiler::Node Node;
     15 typedef CodeStubAssembler::ParameterMode ParameterMode;
     16 typedef compiler::CodeAssemblerState CodeAssemblerState;
     17 
     18 class PromiseBuiltinsAssembler : public CodeStubAssembler {
     19  public:
     20   enum PromiseResolvingFunctionContextSlot {
     21     // Whether the resolve/reject callback was already called.
     22     kAlreadyVisitedSlot = Context::MIN_CONTEXT_SLOTS,
     23 
     24     // The promise which resolve/reject callbacks fulfill.
     25     kPromiseSlot,
     26 
     27     // Whether to trigger a debug event or not. Used in catch
     28     // prediction.
     29     kDebugEventSlot,
     30     kPromiseContextLength,
     31   };
     32 
     33   enum FunctionContextSlot {
     34     kCapabilitySlot = Context::MIN_CONTEXT_SLOTS,
     35 
     36     kCapabilitiesContextLength,
     37   };
     38 
     39   // This is used by the PromiseThenFinally and PromiseCatchFinally
     40   // builtins to store the onFinally in the onFinallySlot.
     41   //
     42   // This is also used by the PromiseValueThunkFinally to store the
     43   // value in the onFinallySlot and PromiseThrowerFinally to store the
     44   // reason in the onFinallySlot.
     45   enum PromiseFinallyContextSlot {
     46     kOnFinallySlot = Context::MIN_CONTEXT_SLOTS,
     47 
     48     kOnFinallyContextLength,
     49   };
     50 
     51   explicit PromiseBuiltinsAssembler(CodeAssemblerState* state)
     52       : CodeStubAssembler(state) {}
     53   // These allocate and initialize a promise with pending state and
     54   // undefined fields.
     55   //
     56   // This uses undefined as the parent promise for the promise init
     57   // hook.
     58   Node* AllocateAndInitJSPromise(Node* context);
     59   // This uses the given parent as the parent promise for the promise
     60   // init hook.
     61   Node* AllocateAndInitJSPromise(Node* context, Node* parent);
     62 
     63   // This allocates and initializes a promise with the given state and
     64   // fields.
     65   Node* AllocateAndSetJSPromise(Node* context, Node* status, Node* result);
     66 
     67   Node* AllocatePromiseResolveThenableJobInfo(Node* result, Node* then,
     68                                               Node* resolve, Node* reject,
     69                                               Node* context);
     70 
     71   std::pair<Node*, Node*> CreatePromiseResolvingFunctions(
     72       Node* promise, Node* native_context, Node* promise_context);
     73 
     74   Node* PromiseHasHandler(Node* promise);
     75 
     76   Node* CreatePromiseResolvingFunctionsContext(Node* promise, Node* debug_event,
     77                                                Node* native_context);
     78 
     79   Node* CreatePromiseGetCapabilitiesExecutorContext(Node* native_context,
     80                                                     Node* promise_capability);
     81 
     82   Node* NewPromiseCapability(Node* context, Node* constructor,
     83                              Node* debug_event = nullptr);
     84 
     85  protected:
     86   void PromiseInit(Node* promise);
     87 
     88   Node* ThrowIfNotJSReceiver(Node* context, Node* value,
     89                              MessageTemplate::Template msg_template,
     90                              const char* method_name = nullptr);
     91 
     92   Node* SpeciesConstructor(Node* context, Node* object,
     93                            Node* default_constructor);
     94 
     95   void PromiseSetHasHandler(Node* promise);
     96   void PromiseSetHandledHint(Node* promise);
     97 
     98   void AppendPromiseCallback(int offset, compiler::Node* promise,
     99                              compiler::Node* value);
    100 
    101   Node* InternalPromiseThen(Node* context, Node* promise, Node* on_resolve,
    102                             Node* on_reject);
    103 
    104   Node* InternalPerformPromiseThen(Node* context, Node* promise,
    105                                    Node* on_resolve, Node* on_reject,
    106                                    Node* deferred_promise,
    107                                    Node* deferred_on_resolve,
    108                                    Node* deferred_on_reject);
    109 
    110   void InternalResolvePromise(Node* context, Node* promise, Node* result);
    111 
    112   void BranchIfFastPath(Node* context, Node* promise, Label* if_isunmodified,
    113                         Label* if_ismodified);
    114 
    115   void BranchIfFastPath(Node* native_context, Node* promise_fun, Node* promise,
    116                         Label* if_isunmodified, Label* if_ismodified);
    117 
    118   Node* CreatePromiseContext(Node* native_context, int slots);
    119   void PromiseFulfill(Node* context, Node* promise, Node* result,
    120                       v8::Promise::PromiseState status);
    121 
    122   void BranchIfAccessCheckFailed(Node* context, Node* native_context,
    123                                  Node* promise_constructor, Node* executor,
    124                                  Label* if_noaccess);
    125 
    126   void InternalPromiseReject(Node* context, Node* promise, Node* value,
    127                              bool debug_event);
    128   void InternalPromiseReject(Node* context, Node* promise, Node* value,
    129                              Node* debug_event);
    130   std::pair<Node*, Node*> CreatePromiseFinallyFunctions(Node* on_finally,
    131                                                         Node* native_context);
    132   Node* CreatePromiseFinallyContext(Node* on_finally, Node* native_context);
    133 
    134   Node* CreateValueThunkFunction(Node* value, Node* native_context);
    135   Node* CreateValueThunkFunctionContext(Node* value, Node* native_context);
    136 
    137   Node* CreateThrowerFunctionContext(Node* reason, Node* native_context);
    138   Node* CreateThrowerFunction(Node* reason, Node* native_context);
    139 
    140  private:
    141   Node* AllocateJSPromise(Node* context);
    142 };
    143 
    144 }  // namespace internal
    145 }  // namespace v8
    146 
    147 #endif  // V8_BUILTINS_BUILTINS_PROMISE_H_
    148