V8 API Reference, 7.2.502.16 (for Deno 0.2.4)
builtins-promise-gen.h
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_GEN_H_
6 #define V8_BUILTINS_BUILTINS_PROMISE_GEN_H_
7 
8 #include "src/code-stub-assembler.h"
9 #include "src/contexts.h"
10 #include "src/objects/promise.h"
11 #include "torque-generated/builtins-base-from-dsl-gen.h"
12 #include "torque-generated/builtins-iterator-from-dsl-gen.h"
13 
14 namespace v8 {
15 namespace internal {
16 
17 typedef compiler::CodeAssemblerState CodeAssemblerState;
18 
20  public:
21  enum PromiseResolvingFunctionContextSlot {
22  // The promise which resolve/reject callbacks fulfill.
23  kPromiseSlot = Context::MIN_CONTEXT_SLOTS,
24 
25  // Whether the callback was already invoked.
26  kAlreadyResolvedSlot,
27 
28  // Whether to trigger a debug event or not. Used in catch
29  // prediction.
30  kDebugEventSlot,
31  kPromiseContextLength,
32  };
33 
34  // TODO(bmeurer): Move this to a proper context map in contexts.h?
35  // Similar to the AwaitContext that we introduced for await closures.
36  enum PromiseAllResolveElementContextSlots {
37  // Remaining elements count
38  kPromiseAllResolveElementRemainingSlot = Context::MIN_CONTEXT_SLOTS,
39 
40  // Promise capability from Promise.all
41  kPromiseAllResolveElementCapabilitySlot,
42 
43  // Values array from Promise.all
44  kPromiseAllResolveElementValuesArraySlot,
45 
46  kPromiseAllResolveElementLength
47  };
48 
49  enum FunctionContextSlot {
50  kCapabilitySlot = Context::MIN_CONTEXT_SLOTS,
51 
52  kCapabilitiesContextLength,
53  };
54 
55  // This is used by the Promise.prototype.finally builtin to store
56  // onFinally callback and the Promise constructor.
57  // TODO(gsathya): For native promises we can create a variant of
58  // this without extra space for the constructor to save memory.
59  enum PromiseFinallyContextSlot {
60  kOnFinallySlot = Context::MIN_CONTEXT_SLOTS,
61  kConstructorSlot,
62 
63  kPromiseFinallyContextLength,
64  };
65 
66  // This is used by the ThenFinally and CatchFinally builtins to
67  // store the value to return or reason to throw.
68  enum PromiseValueThunkOrReasonContextSlot {
69  kValueSlot = Context::MIN_CONTEXT_SLOTS,
70 
71  kPromiseValueThunkOrReasonContextLength,
72  };
73 
75  : CodeStubAssembler(state) {}
76  // These allocate and initialize a promise with pending state and
77  // undefined fields.
78  //
79  // This uses undefined as the parent promise for the promise init
80  // hook.
81  Node* AllocateAndInitJSPromise(Node* context);
82  // This uses the given parent as the parent promise for the promise
83  // init hook.
84  Node* AllocateAndInitJSPromise(Node* context, Node* parent);
85 
86  // This allocates and initializes a promise with the given state and
87  // fields.
88  Node* AllocateAndSetJSPromise(Node* context, v8::Promise::PromiseState status,
89  Node* result);
90 
91  Node* AllocatePromiseReaction(Node* next, Node* promise_or_capability,
92  Node* fulfill_handler, Node* reject_handler);
93 
94  Node* AllocatePromiseReactionJobTask(RootIndex map_root_index, Node* context,
95  Node* argument, Node* handler,
96  Node* promise_or_capability);
97  Node* AllocatePromiseReactionJobTask(Node* map, Node* context, Node* argument,
98  Node* handler,
99  Node* promise_or_capability);
100  Node* AllocatePromiseResolveThenableJobTask(Node* promise_to_resolve,
101  Node* then, Node* thenable,
102  Node* context);
103 
104  std::pair<Node*, Node*> CreatePromiseResolvingFunctions(
105  Node* promise, Node* native_context, Node* promise_context);
106 
107  Node* PromiseHasHandler(Node* promise);
108 
109  // Creates the context used by all Promise.all resolve element closures,
110  // together with the values array. Since all closures for a single Promise.all
111  // call use the same context, we need to store the indices for the individual
112  // closures somewhere else (we put them into the identity hash field of the
113  // closures), and we also need to have a separate marker for when the closure
114  // was called already (we slap the native context onto the closure in that
115  // case to mark it's done).
116  Node* CreatePromiseAllResolveElementContext(Node* promise_capability,
117  Node* native_context);
118  Node* CreatePromiseAllResolveElementFunction(Node* context, TNode<Smi> index,
119  Node* native_context);
120 
121  Node* CreatePromiseResolvingFunctionsContext(Node* promise, Node* debug_event,
122  Node* native_context);
123 
124  Node* CreatePromiseGetCapabilitiesExecutorContext(Node* native_context,
125  Node* promise_capability);
126 
127  protected:
128  void PromiseInit(Node* promise);
129 
130  void PromiseSetHasHandler(Node* promise);
131  void PromiseSetHandledHint(Node* promise);
132 
133  void PerformPromiseThen(Node* context, Node* promise, Node* on_fulfilled,
134  Node* on_rejected,
135  Node* result_promise_or_capability);
136 
137  Node* CreatePromiseContext(Node* native_context, int slots);
138 
139  Node* TriggerPromiseReactions(Node* context, Node* promise, Node* result,
140  PromiseReaction::Type type);
141 
142  // We can skip the "resolve" lookup on {constructor} if it's the (initial)
143  // Promise constructor and the Promise.resolve() protector is intact, as
144  // that guards the lookup path for the "resolve" property on the %Promise%
145  // intrinsic object.
146  void BranchIfPromiseResolveLookupChainIntact(Node* native_context,
147  Node* constructor,
148  Label* if_fast, Label* if_slow);
149  void GotoIfNotPromiseResolveLookupChainIntact(Node* native_context,
150  Node* constructor,
151  Label* if_slow);
152 
153  // We can shortcut the SpeciesConstructor on {promise_map} if it's
154  // [[Prototype]] is the (initial) Promise.prototype and the @@species
155  // protector is intact, as that guards the lookup path for the "constructor"
156  // property on JSPromise instances which have the %PromisePrototype%.
157  void BranchIfPromiseSpeciesLookupChainIntact(Node* native_context,
158  Node* promise_map,
159  Label* if_fast, Label* if_slow);
160 
161  // We can skip the "then" lookup on {receiver_map} if it's [[Prototype]]
162  // is the (initial) Promise.prototype and the Promise#then() protector
163  // is intact, as that guards the lookup path for the "then" property
164  // on JSPromise instances which have the (initial) %PromisePrototype%.
165  void BranchIfPromiseThenLookupChainIntact(Node* native_context,
166  Node* receiver_map, Label* if_fast,
167  Label* if_slow);
168 
169  Node* InvokeResolve(Node* native_context, Node* constructor, Node* value,
170  Label* if_exception, Variable* var_exception);
171  template <typename... TArgs>
172  Node* InvokeThen(Node* native_context, Node* receiver, TArgs... args);
173 
174  void BranchIfAccessCheckFailed(Node* context, Node* native_context,
175  Node* promise_constructor, Node* executor,
176  Label* if_noaccess);
177 
178  std::pair<Node*, Node*> CreatePromiseFinallyFunctions(Node* on_finally,
179  Node* constructor,
180  Node* native_context);
181  Node* CreateValueThunkFunction(Node* value, Node* native_context);
182 
183  Node* CreateThrowerFunction(Node* reason, Node* native_context);
184 
185  Node* PerformPromiseAll(
186  Node* context, Node* constructor, Node* capability,
187  const IteratorBuiltinsFromDSLAssembler::IteratorRecord& record,
188  Label* if_exception, Variable* var_exception);
189 
190  void SetForwardingHandlerIfTrue(Node* context, Node* condition,
191  const NodeGenerator& object);
192  inline void SetForwardingHandlerIfTrue(Node* context, Node* condition,
193  Node* object) {
194  return SetForwardingHandlerIfTrue(context, condition,
195  [object]() -> Node* { return object; });
196  }
197  void SetPromiseHandledByIfTrue(Node* context, Node* condition, Node* promise,
198  const NodeGenerator& handled_by);
199 
200  Node* PromiseStatus(Node* promise);
201 
202  void PromiseReactionJob(Node* context, Node* argument, Node* handler,
203  Node* promise_or_capability,
204  PromiseReaction::Type type);
205 
206  Node* IsPromiseStatus(Node* actual, v8::Promise::PromiseState expected);
207  void PromiseSetStatus(Node* promise, v8::Promise::PromiseState status);
208 
209  Node* AllocateJSPromise(Node* context);
210 };
211 
212 } // namespace internal
213 } // namespace v8
214 
215 #endif // V8_BUILTINS_BUILTINS_PROMISE_GEN_H_
Definition: libplatform.h:13
PromiseState
Definition: v8.h:4104