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