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 : class PromiseBuiltinsAssembler : public CodeStubAssembler {
19 : public:
20 : explicit PromiseBuiltinsAssembler(compiler::CodeAssemblerState* state)
21 3237 : : 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(
51 : Node* promise, Node* native_context, Node* promise_context);
52 :
53 : Node* PromiseHasHandler(Node* promise);
54 :
55 : // Creates the context used by all Promise.all resolve element closures,
56 : // together with the values array. Since all closures for a single Promise.all
57 : // call use the same context, we need to store the indices for the individual
58 : // closures somewhere else (we put them into the identity hash field of the
59 : // closures), and we also need to have a separate marker for when the closure
60 : // was called already (we slap the native context onto the closure in that
61 : // case to mark it's done).
62 : Node* CreatePromiseAllResolveElementContext(Node* promise_capability,
63 : Node* native_context);
64 : Node* CreatePromiseAllResolveElementFunction(Node* context, TNode<Smi> index,
65 : Node* native_context);
66 :
67 : Node* CreatePromiseResolvingFunctionsContext(Node* promise, Node* debug_event,
68 : Node* native_context);
69 :
70 : Node* CreatePromiseGetCapabilitiesExecutorContext(Node* native_context,
71 : Node* promise_capability);
72 :
73 : protected:
74 : void PromiseInit(Node* promise);
75 :
76 : void PromiseSetHasHandler(Node* promise);
77 : void PromiseSetHandledHint(Node* promise);
78 :
79 : void PerformPromiseThen(Node* context, Node* promise, Node* on_fulfilled,
80 : Node* on_rejected,
81 : Node* result_promise_or_capability);
82 :
83 : Node* CreatePromiseContext(Node* native_context, int slots);
84 :
85 : Node* TriggerPromiseReactions(Node* context, Node* promise, Node* result,
86 : PromiseReaction::Type type);
87 :
88 : // We can skip the "resolve" lookup on {constructor} if it's the (initial)
89 : // Promise constructor and the Promise.resolve() protector is intact, as
90 : // that guards the lookup path for the "resolve" property on the %Promise%
91 : // intrinsic object.
92 : void BranchIfPromiseResolveLookupChainIntact(Node* native_context,
93 : Node* constructor,
94 : Label* if_fast, Label* if_slow);
95 : void GotoIfNotPromiseResolveLookupChainIntact(Node* native_context,
96 : Node* constructor,
97 : Label* if_slow);
98 :
99 : // We can shortcut the SpeciesConstructor on {promise_map} if it's
100 : // [[Prototype]] is the (initial) Promise.prototype and the @@species
101 : // protector is intact, as that guards the lookup path for the "constructor"
102 : // property on JSPromise instances which have the %PromisePrototype%.
103 : void BranchIfPromiseSpeciesLookupChainIntact(Node* native_context,
104 : Node* promise_map,
105 : Label* if_fast, Label* if_slow);
106 :
107 : // We can skip the "then" lookup on {receiver_map} if it's [[Prototype]]
108 : // is the (initial) Promise.prototype and the Promise#then() protector
109 : // is intact, as that guards the lookup path for the "then" property
110 : // on JSPromise instances which have the (initial) %PromisePrototype%.
111 : void BranchIfPromiseThenLookupChainIntact(Node* native_context,
112 : Node* receiver_map, Label* if_fast,
113 : Label* if_slow);
114 :
115 : Node* InvokeResolve(Node* native_context, Node* constructor, Node* value,
116 : Label* if_exception, Variable* var_exception);
117 : template <typename... TArgs>
118 : Node* InvokeThen(Node* native_context, Node* receiver, TArgs... args);
119 :
120 : void BranchIfAccessCheckFailed(Node* context, Node* native_context,
121 : Node* promise_constructor, Node* executor,
122 : Label* if_noaccess);
123 :
124 : std::pair<Node*, Node*> CreatePromiseFinallyFunctions(Node* on_finally,
125 : Node* constructor,
126 : Node* native_context);
127 : Node* CreateValueThunkFunction(Node* value, Node* native_context);
128 :
129 : Node* CreateThrowerFunction(Node* reason, Node* native_context);
130 :
131 : Node* PerformPromiseAll(
132 : Node* context, Node* constructor, Node* capability,
133 : const IteratorBuiltinsFromDSLAssembler::IteratorRecord& record,
134 : Label* if_exception, Variable* var_exception);
135 :
136 : void SetForwardingHandlerIfTrue(Node* context, Node* condition,
137 : const NodeGenerator& object);
138 112 : inline void SetForwardingHandlerIfTrue(Node* context, Node* condition,
139 : Node* object) {
140 : return SetForwardingHandlerIfTrue(context, condition,
141 336 : [object]() -> Node* { return object; });
142 : }
143 : void SetPromiseHandledByIfTrue(Node* context, Node* condition, Node* promise,
144 : const NodeGenerator& handled_by);
145 :
146 : Node* PromiseStatus(Node* promise);
147 :
148 : void PromiseReactionJob(Node* context, Node* argument, Node* handler,
149 : Node* promise_or_capability,
150 : PromiseReaction::Type type);
151 :
152 : Node* IsPromiseStatus(Node* actual, v8::Promise::PromiseState expected);
153 : void PromiseSetStatus(Node* promise, v8::Promise::PromiseState status);
154 :
155 : Node* AllocateJSPromise(Node* context);
156 : };
157 :
158 : } // namespace internal
159 : } // namespace v8
160 :
161 : #endif // V8_BUILTINS_BUILTINS_PROMISE_GEN_H_
|