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 PromiseBuiltinsAssembler(CodeAssemblerState * state)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