1 | /**************************************************************************** |
2 | ** |
3 | ** Copyright (C) 2018 The Qt Company Ltd. |
4 | ** Contact: https://www.qt.io/licensing/ |
5 | ** |
6 | ** This file is part of the QtQml module of the Qt Toolkit. |
7 | ** |
8 | ** $QT_BEGIN_LICENSE:LGPL$ |
9 | ** Commercial License Usage |
10 | ** Licensees holding valid commercial Qt licenses may use this file in |
11 | ** accordance with the commercial license agreement provided with the |
12 | ** Software or, alternatively, in accordance with the terms contained in |
13 | ** a written agreement between you and The Qt Company. For licensing terms |
14 | ** and conditions see https://www.qt.io/terms-conditions. For further |
15 | ** information use the contact form at https://www.qt.io/contact-us. |
16 | ** |
17 | ** GNU Lesser General Public License Usage |
18 | ** Alternatively, this file may be used under the terms of the GNU Lesser |
19 | ** General Public License version 3 as published by the Free Software |
20 | ** Foundation and appearing in the file LICENSE.LGPL3 included in the |
21 | ** packaging of this file. Please review the following information to |
22 | ** ensure the GNU Lesser General Public License version 3 requirements |
23 | ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. |
24 | ** |
25 | ** GNU General Public License Usage |
26 | ** Alternatively, this file may be used under the terms of the GNU |
27 | ** General Public License version 2.0 or (at your option) the GNU General |
28 | ** Public license version 3 or any later version approved by the KDE Free |
29 | ** Qt Foundation. The licenses are as published by the Free Software |
30 | ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 |
31 | ** included in the packaging of this file. Please review the following |
32 | ** information to ensure the GNU General Public License requirements will |
33 | ** be met: https://www.gnu.org/licenses/gpl-2.0.html and |
34 | ** https://www.gnu.org/licenses/gpl-3.0.html. |
35 | ** |
36 | ** $QT_END_LICENSE$ |
37 | ** |
38 | ****************************************************************************/ |
39 | #ifndef QV4PROMISEOBJECT_H |
40 | #define QV4PROMISEOBJECT_H |
41 | |
42 | // |
43 | // W A R N I N G |
44 | // ------------- |
45 | // |
46 | // This file is not part of the Qt API. It exists purely as an |
47 | // implementation detail. This header file may change from version to |
48 | // version without notice, or even be removed. |
49 | // |
50 | // We mean it. |
51 | // |
52 | |
53 | #include "qv4object_p.h" |
54 | #include "qv4functionobject_p.h" |
55 | |
56 | QT_BEGIN_NAMESPACE |
57 | |
58 | namespace QV4 { |
59 | |
60 | struct PromiseCapability; |
61 | |
62 | namespace Promise { |
63 | |
64 | struct ReactionEvent; |
65 | struct ResolveThenableEvent; |
66 | |
67 | class ReactionHandler : public QObject |
68 | { |
69 | Q_OBJECT |
70 | |
71 | public: |
72 | ReactionHandler(QObject *parent = nullptr); |
73 | virtual ~ReactionHandler() override; |
74 | |
75 | void addReaction(ExecutionEngine *e, const Value *reaction, const Value *value); |
76 | void addResolveThenable(ExecutionEngine *e, const PromiseObject *promise, const Object *thenable, const FunctionObject *then); |
77 | |
78 | protected: |
79 | void customEvent(QEvent *event) override; |
80 | void executeReaction(ReactionEvent *event); |
81 | void executeResolveThenable(ResolveThenableEvent *event); |
82 | }; |
83 | |
84 | } // Promise |
85 | |
86 | namespace Heap { |
87 | |
88 | struct PromiseCtor : FunctionObject { |
89 | void init(QV4::ExecutionContext *scope); |
90 | }; |
91 | |
92 | #define PromiseObjectMembers(class, Member) \ |
93 | Member(class, HeapValue, HeapValue, resolution) \ |
94 | Member(class, HeapValue, HeapValue, fulfillReactions) \ |
95 | Member(class, HeapValue, HeapValue, rejectReactions) |
96 | |
97 | DECLARE_HEAP_OBJECT(PromiseObject, Object) { |
98 | DECLARE_MARKOBJECTS(PromiseObject) |
99 | void init(ExecutionEngine *e); |
100 | |
101 | enum State { |
102 | Pending, |
103 | Fulfilled, |
104 | Rejected |
105 | }; |
106 | |
107 | void setState(State); |
108 | bool isSettled() const; |
109 | bool isPending() const; |
110 | bool isFulfilled() const; |
111 | bool isRejected() const; |
112 | |
113 | State state; |
114 | |
115 | void triggerFullfillReactions(ExecutionEngine *e); |
116 | void triggerRejectReactions(ExecutionEngine *e); |
117 | }; |
118 | |
119 | #define PromiseCapabilityMembers(class, Member) \ |
120 | Member(class, HeapValue, HeapValue, promise) \ |
121 | Member(class, HeapValue, HeapValue, resolve) \ |
122 | Member(class, HeapValue, HeapValue, reject) |
123 | |
124 | DECLARE_HEAP_OBJECT(PromiseCapability, Object) { |
125 | DECLARE_MARKOBJECTS(PromiseCapability) |
126 | }; |
127 | |
128 | #define PromiseReactionMembers(class, Member) \ |
129 | Member(class, HeapValue, HeapValue, handler) \ |
130 | Member(class, Pointer, PromiseCapability*, capability) |
131 | |
132 | DECLARE_HEAP_OBJECT(PromiseReaction, Object) { |
133 | DECLARE_MARKOBJECTS(PromiseReaction) |
134 | |
135 | static Heap::PromiseReaction *createFulfillReaction(ExecutionEngine* e, const QV4::PromiseCapability *capability, const QV4::FunctionObject *onFulfilled); |
136 | static Heap::PromiseReaction *createRejectReaction(ExecutionEngine* e, const QV4::PromiseCapability *capability, const QV4::FunctionObject *onRejected); |
137 | |
138 | void triggerWithValue(ExecutionEngine *e, const Value *value); |
139 | |
140 | enum Type { |
141 | Function, |
142 | Identity, |
143 | Thrower |
144 | }; |
145 | |
146 | Type type; |
147 | |
148 | friend class ReactionHandler; |
149 | }; |
150 | |
151 | #define CapabilitiesExecutorWrapperMembers(class, Member) \ |
152 | Member(class, Pointer, PromiseCapability*, capabilities) |
153 | |
154 | DECLARE_HEAP_OBJECT(CapabilitiesExecutorWrapper, FunctionObject) { |
155 | DECLARE_MARKOBJECTS(CapabilitiesExecutorWrapper) |
156 | void init(); |
157 | void destroy(); |
158 | }; |
159 | |
160 | #define PromiseExecutionStateMembers(class, Member) \ |
161 | Member(class, HeapValue, HeapValue, values) \ |
162 | Member(class, HeapValue, HeapValue, capability) |
163 | |
164 | DECLARE_HEAP_OBJECT(PromiseExecutionState, FunctionObject) { |
165 | DECLARE_MARKOBJECTS(PromiseExecutionState) |
166 | void init(); |
167 | |
168 | uint index; |
169 | uint remainingElementCount; |
170 | }; |
171 | |
172 | #define ResolveElementWrapperMembers(class, Member) \ |
173 | Member(class, HeapValue, HeapValue, state) |
174 | |
175 | DECLARE_HEAP_OBJECT(ResolveElementWrapper, FunctionObject) { |
176 | DECLARE_MARKOBJECTS(ResolveElementWrapper) |
177 | void init(); |
178 | |
179 | uint index; |
180 | bool alreadyResolved; |
181 | }; |
182 | |
183 | #define ResolveWrapperMembers(class, Member) \ |
184 | Member(class, Pointer, PromiseObject*, promise) |
185 | |
186 | DECLARE_HEAP_OBJECT(ResolveWrapper, FunctionObject) { |
187 | DECLARE_MARKOBJECTS(ResolveWrapper) |
188 | void init(); |
189 | |
190 | bool alreadyResolved; |
191 | }; |
192 | |
193 | #define RejectWrapperMembers(class, Member) \ |
194 | Member(class, Pointer, PromiseObject*, promise) |
195 | |
196 | DECLARE_HEAP_OBJECT(RejectWrapper, FunctionObject) { |
197 | DECLARE_MARKOBJECTS(RejectWrapper) |
198 | void init(); |
199 | |
200 | bool alreadyResolved; |
201 | }; |
202 | |
203 | } // Heap |
204 | |
205 | struct PromiseReaction : Object |
206 | { |
207 | V4_OBJECT2(PromiseReaction, Object) |
208 | }; |
209 | |
210 | struct PromiseCapability : Object |
211 | { |
212 | V4_OBJECT2(PromiseCapability, Object) |
213 | }; |
214 | |
215 | struct PromiseExecutionState : Object |
216 | { |
217 | V4_OBJECT2(PromiseExecutionState, Object) |
218 | }; |
219 | |
220 | struct Q_QML_PRIVATE_EXPORT PromiseObject : Object |
221 | { |
222 | V4_OBJECT2(PromiseObject, Object) |
223 | V4_NEEDS_DESTROY |
224 | V4_PROTOTYPE(promisePrototype) |
225 | }; |
226 | |
227 | struct PromiseCtor: FunctionObject |
228 | { |
229 | V4_OBJECT2(PromiseCtor, FunctionObject) |
230 | |
231 | static ReturnedValue virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc, const Value *); |
232 | static ReturnedValue virtualCall(const FunctionObject *f, const Value *thisObject, const Value *argv, int argc); |
233 | |
234 | static ReturnedValue method_resolve(const FunctionObject *f, const Value *thisObject, const Value *argv, int argc); |
235 | static ReturnedValue method_reject(const FunctionObject *f, const Value *thisObject, const Value *argv, int argc); |
236 | |
237 | static ReturnedValue method_all(const FunctionObject *f, const Value *thisObject, const Value *argv, int argc); |
238 | static ReturnedValue method_race(const FunctionObject *f, const Value *thisObject, const Value *argv, int argc); |
239 | }; |
240 | |
241 | struct PromisePrototype : Object |
242 | { |
243 | void init(ExecutionEngine *engine, Object *ctor); |
244 | |
245 | static ReturnedValue method_then(const FunctionObject *f, const Value *thisObject, const Value *argv, int argc); |
246 | static ReturnedValue method_catch(const FunctionObject *f, const Value *thisObject, const Value *argv, int argc); |
247 | }; |
248 | |
249 | struct CapabilitiesExecutorWrapper: FunctionObject { |
250 | V4_OBJECT2(CapabilitiesExecutorWrapper, FunctionObject) |
251 | |
252 | static ReturnedValue virtualCall(const FunctionObject *f, const Value *thisObject, const Value *argv, int argc); |
253 | }; |
254 | |
255 | struct ResolveElementWrapper : FunctionObject { |
256 | V4_OBJECT2(ResolveElementWrapper, FunctionObject) |
257 | |
258 | static ReturnedValue virtualCall(const FunctionObject *f, const Value *thisObject, const Value *argv, int argc); |
259 | }; |
260 | |
261 | struct ResolveWrapper : FunctionObject { |
262 | V4_OBJECT2(ResolveWrapper, FunctionObject) |
263 | |
264 | static ReturnedValue virtualCall(const FunctionObject *f, const Value *thisObject, const Value *argv, int argc); |
265 | }; |
266 | |
267 | struct RejectWrapper : FunctionObject { |
268 | V4_OBJECT2(RejectWrapper, FunctionObject) |
269 | |
270 | static ReturnedValue virtualCall(const FunctionObject *f, const Value *thisObject, const Value *argv, int argc); |
271 | }; |
272 | |
273 | } // QV4 |
274 | |
275 | QT_END_NAMESPACE |
276 | |
277 | #endif // QV4PROMISEOBJECT_H |
278 | |