Line data Source code
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/objects/promise.h"
10 : #include "torque-generated/builtins-base-from-dsl-gen.h"
11 : #include "torque-generated/builtins-iterator-from-dsl-gen.h"
12 :
13 : namespace v8 {
14 : namespace internal {
15 :
16 : typedef compiler::CodeAssemblerState CodeAssemblerState;
17 :
18 3228 : class PromiseBuiltinsAssembler : public CodeStubAssembler {
19 : public:
20 3192 : explicit PromiseBuiltinsAssembler(compiler::CodeAssemblerState* state)
21 3228 : : CodeStubAssembler(state) {}
22 : // These allocate and initialize a promise with pending state and
23 : // undefined fields.
24 : //
25 : // This uses undefined as the parent promise for the promise init
26 : // hook.
27 : Node* AllocateAndInitJSPromise(Node* context);
28 : // This uses the given parent as the parent promise for the promise
29 : // init hook.
30 : Node* AllocateAndInitJSPromise(Node* context, Node* parent);
31 :
32 : // This allocates and initializes a promise with the given state and
33 : // fields.
34 : Node* AllocateAndSetJSPromise(Node* context, v8::Promise::PromiseState status,
35 : Node* result);
36 :
37 : Node* AllocatePromiseReaction(Node* next, Node* promise_or_capability,
38 : Node* fulfill_handler, Node* reject_handler);
39 :
40 : Node* AllocatePromiseReactionJobTask(RootIndex map_root_index, Node* context,
41 : Node* argument, Node* handler,
42 : Node* promise_or_capability);
43 : Node* AllocatePromiseReactionJobTask(Node* map, Node* context, Node* argument,
44 : Node* handler,
45 : Node* promise_or_capability);
46 : Node* AllocatePromiseResolveThenableJobTask(Node* promise_to_resolve,
47 : Node* then, Node* thenable,
48 : Node* context);
49 :
50 : std::pair<Node*, Node*> CreatePromiseResolvingFunctions(Node* promise,
51 : Node* debug_event,
52 : Node* native_context);
53 :
54 : Node* PromiseHasHandler(Node* promise);
55 :
56 : // Creates the context used by all Promise.all resolve element closures,
57 : // together with the values array. Since all closures for a single Promise.all
58 : // call use the same context, we need to store the indices for the individual
59 : // closures somewhere else (we put them into the identity hash field of the
60 : // closures), and we also need to have a separate marker for when the closure
61 : // was called already (we slap the native context onto the closure in that
62 : // case to mark it's done).
63 : Node* CreatePromiseAllResolveElementContext(Node* promise_capability,
64 : Node* native_context);
65 : Node* CreatePromiseAllResolveElementFunction(Node* context, TNode<Smi> index,
66 : Node* native_context);
67 :
68 : Node* CreatePromiseResolvingFunctionsContext(Node* promise, Node* debug_event,
69 : Node* native_context);
70 :
71 : Node* CreatePromiseGetCapabilitiesExecutorContext(Node* promise_capability,
72 : Node* native_context);
73 :
74 : protected:
75 : void PromiseInit(Node* promise);
76 :
77 : void PromiseSetHasHandler(Node* promise);
78 : void PromiseSetHandledHint(Node* promise);
79 :
80 : void PerformPromiseThen(Node* context, Node* promise, Node* on_fulfilled,
81 : Node* on_rejected,
82 : Node* result_promise_or_capability);
83 :
84 : Node* CreatePromiseContext(Node* native_context, int slots);
85 :
86 : Node* TriggerPromiseReactions(Node* context, Node* promise, Node* result,
87 : PromiseReaction::Type type);
88 :
89 : // We can skip the "resolve" lookup on {constructor} if it's the (initial)
90 : // Promise constructor and the Promise.resolve() protector is intact, as
91 : // that guards the lookup path for the "resolve" property on the %Promise%
92 : // intrinsic object.
93 : void BranchIfPromiseResolveLookupChainIntact(Node* native_context,
94 : Node* constructor,
95 : Label* if_fast, Label* if_slow);
96 : void GotoIfNotPromiseResolveLookupChainIntact(Node* native_context,
97 : Node* constructor,
98 : Label* if_slow);
99 :
100 : // We can shortcut the SpeciesConstructor on {promise_map} if it's
101 : // [[Prototype]] is the (initial) Promise.prototype and the @@species
102 : // protector is intact, as that guards the lookup path for the "constructor"
103 : // property on JSPromise instances which have the %PromisePrototype%.
104 : void BranchIfPromiseSpeciesLookupChainIntact(Node* native_context,
105 : Node* promise_map,
106 : Label* if_fast, Label* if_slow);
107 :
108 : // We can skip the "then" lookup on {receiver_map} if it's [[Prototype]]
109 : // is the (initial) Promise.prototype and the Promise#then() protector
110 : // is intact, as that guards the lookup path for the "then" property
111 : // on JSPromise instances which have the (initial) %PromisePrototype%.
112 : void BranchIfPromiseThenLookupChainIntact(Node* native_context,
113 : Node* receiver_map, Label* if_fast,
114 : Label* if_slow);
115 :
116 : Node* InvokeResolve(Node* native_context, Node* constructor, Node* value,
117 : Label* if_exception, Variable* var_exception);
118 : template <typename... TArgs>
119 : Node* InvokeThen(Node* native_context, Node* receiver, TArgs... args);
120 :
121 : void BranchIfAccessCheckFailed(Node* context, Node* native_context,
122 : Node* promise_constructor, Node* executor,
123 : Label* if_noaccess);
124 :
125 : std::pair<Node*, Node*> CreatePromiseFinallyFunctions(Node* on_finally,
126 : Node* constructor,
127 : Node* native_context);
128 : Node* CreateValueThunkFunction(Node* value, Node* native_context);
129 :
130 : Node* CreateThrowerFunction(Node* reason, Node* native_context);
131 :
132 : Node* PerformPromiseAll(
133 : Node* context, Node* constructor, Node* capability,
134 : const IteratorBuiltinsFromDSLAssembler::IteratorRecord& record,
135 : Label* if_exception, Variable* var_exception);
136 :
137 : void SetForwardingHandlerIfTrue(Node* context, Node* condition,
138 : const NodeGenerator& object);
139 112 : inline void SetForwardingHandlerIfTrue(Node* context, Node* condition,
140 : Node* object) {
141 224 : return SetForwardingHandlerIfTrue(context, condition,
142 336 : [object]() -> Node* { return object; });
143 : }
144 : void SetPromiseHandledByIfTrue(Node* context, Node* condition, Node* promise,
145 : const NodeGenerator& handled_by);
146 :
147 : Node* PromiseStatus(Node* promise);
148 :
149 : void PromiseReactionJob(Node* context, Node* argument, Node* handler,
150 : Node* promise_or_capability,
151 : PromiseReaction::Type type);
152 :
153 : Node* IsPromiseStatus(Node* actual, v8::Promise::PromiseState expected);
154 : void PromiseSetStatus(Node* promise, v8::Promise::PromiseState status);
155 :
156 : Node* AllocateJSPromise(Node* context);
157 :
158 : void ExtractHandlerContext(Node* handler, Variable* var_context);
159 : };
160 :
161 : } // namespace internal
162 : } // namespace v8
163 :
164 : #endif // V8_BUILTINS_BUILTINS_PROMISE_GEN_H_
|