1 /****************************************************************************
2 **
3 ** Copyright (C) 2016 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 QV4RUNTIMEAPI_P_H
40 #define QV4RUNTIMEAPI_P_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 <private/qv4global_p.h>
54 #include <private/qv4staticvalue_p.h>
55 
56 QT_BEGIN_NAMESPACE
57 
58 namespace QV4 {
59 
60 typedef uint Bool;
61 
62 struct Q_QML_PRIVATE_EXPORT Runtime {
63     typedef ReturnedValue (*UnaryOperation)(const Value &value);
64     typedef ReturnedValue (*BinaryOperation)(const Value &left, const Value &right);
65     typedef ReturnedValue (*BinaryOperationContext)(ExecutionEngine *, const Value &left, const Value &right);
66 
67     enum class Throws { No, Yes };
68     enum class ChangesContext { No, Yes };
69     enum class Pure { No, Yes };
70     enum class LastArgumentIsOutputValue { No, Yes };
71 
72     template<Throws t, ChangesContext c = ChangesContext::No, Pure p = Pure::No,
73              LastArgumentIsOutputValue out = LastArgumentIsOutputValue::No>
74     struct Method
75     {
76         static constexpr bool throws = t == Throws::Yes;
77         static constexpr bool changesContext = c == ChangesContext::Yes;
78         static constexpr bool pure = p == Pure::Yes;
79         static constexpr bool lastArgumentIsOutputValue = out == LastArgumentIsOutputValue::Yes;
80     };
81     using PureMethod = Method<Throws::No, ChangesContext::No, Pure::Yes>;
82     using IteratorMethod = Method<Throws::Yes, ChangesContext::No, Pure::No,
83                                   LastArgumentIsOutputValue::Yes>;
84 
85     /* call */
86     struct Q_QML_PRIVATE_EXPORT CallGlobalLookup : Method<Throws::Yes>
87     {
88         static ReturnedValue call(ExecutionEngine *, uint, Value[], int);
89     };
90     struct Q_QML_PRIVATE_EXPORT CallQmlContextPropertyLookup : Method<Throws::Yes>
91     {
92         static ReturnedValue call(ExecutionEngine *, uint, Value[], int);
93     };
94     struct Q_QML_PRIVATE_EXPORT CallName : Method<Throws::Yes>
95     {
96         static ReturnedValue call(ExecutionEngine *, int, Value[], int);
97     };
98     struct Q_QML_PRIVATE_EXPORT CallProperty : Method<Throws::Yes>
99     {
100         static ReturnedValue call(ExecutionEngine *, const Value &, int, Value[], int);
101     };
102     struct Q_QML_PRIVATE_EXPORT CallPropertyLookup : Method<Throws::Yes>
103     {
104         static ReturnedValue call(ExecutionEngine *, const Value &, uint, Value[], int);
105     };
106     struct Q_QML_PRIVATE_EXPORT CallElement : Method<Throws::Yes>
107     {
108         static ReturnedValue call(ExecutionEngine *, const Value &, const Value &, Value[], int);
109     };
110     struct Q_QML_PRIVATE_EXPORT CallValue : Method<Throws::Yes>
111     {
112         static ReturnedValue call(ExecutionEngine *, const Value &, Value[], int);
113     };
114     struct Q_QML_PRIVATE_EXPORT CallWithReceiver : Method<Throws::Yes>
115     {
116         static ReturnedValue call(ExecutionEngine *, const Value &, const Value &, Value[], int);
117     };
118     struct Q_QML_PRIVATE_EXPORT CallPossiblyDirectEval : Method<Throws::Yes>
119     {
120         static ReturnedValue call(ExecutionEngine *, Value[], int);
121     };
122     struct Q_QML_PRIVATE_EXPORT CallWithSpread : Method<Throws::Yes>
123     {
124         static ReturnedValue call(ExecutionEngine *, const Value &, const Value &, Value[], int);
125     };
126     struct Q_QML_PRIVATE_EXPORT TailCall : Method<Throws::Yes>
127     {
128         static ReturnedValue call(CppStackFrame *, ExecutionEngine *);
129     };
130 
131     /* construct */
132     struct Q_QML_PRIVATE_EXPORT Construct : Method<Throws::Yes>
133     {
134         static ReturnedValue call(ExecutionEngine *, const Value &, const Value &, Value[], int);
135     };
136     struct Q_QML_PRIVATE_EXPORT ConstructWithSpread : Method<Throws::Yes>
137     {
138         static ReturnedValue call(ExecutionEngine *, const Value &, const Value &, Value[], int);
139     };
140 
141     /* load & store */
142     struct Q_QML_PRIVATE_EXPORT StoreNameStrict : Method<Throws::Yes>
143     {
144         static void call(ExecutionEngine *, int, const Value &);
145     };
146     struct Q_QML_PRIVATE_EXPORT StoreNameSloppy : Method<Throws::Yes>
147     {
148         static void call(ExecutionEngine *, int, const Value &);
149     };
150     struct Q_QML_PRIVATE_EXPORT StoreProperty : Method<Throws::Yes>
151     {
152         static void call(ExecutionEngine *, const Value &, int, const Value &);
153     };
154     struct Q_QML_PRIVATE_EXPORT StoreElement : Method<Throws::Yes>
155     {
156         static void call(ExecutionEngine *, const Value &, const Value &, const Value &);
157     };
158     struct Q_QML_PRIVATE_EXPORT LoadProperty : Method<Throws::Yes>
159     {
160         static ReturnedValue call(ExecutionEngine *, const Value &, int);
161     };
162     struct Q_QML_PRIVATE_EXPORT LoadName : Method<Throws::Yes>
163     {
164         static ReturnedValue call(ExecutionEngine *, int);
165     };
166     struct Q_QML_PRIVATE_EXPORT LoadElement : Method<Throws::Yes>
167     {
168         static ReturnedValue call(ExecutionEngine *, const Value &, const Value &);
169     };
170     struct Q_QML_PRIVATE_EXPORT LoadSuperProperty : Method<Throws::Yes>
171     {
172         static ReturnedValue call(ExecutionEngine *, const Value &);
173     };
174     struct Q_QML_PRIVATE_EXPORT StoreSuperProperty : Method<Throws::Yes>
175     {
176         static void call(ExecutionEngine *, const Value &, const Value &);
177     };
178     struct Q_QML_PRIVATE_EXPORT LoadSuperConstructor : Method<Throws::Yes>
179     {
180         static ReturnedValue call(ExecutionEngine *, const Value &);
181     };
182     struct Q_QML_PRIVATE_EXPORT LoadGlobalLookup : Method<Throws::Yes>
183     {
184         static ReturnedValue call(ExecutionEngine *, Function *, int);
185     };
186     struct Q_QML_PRIVATE_EXPORT LoadQmlContextPropertyLookup : Method<Throws::Yes>
187     {
188         static ReturnedValue call(ExecutionEngine *, uint);
189     };
190     struct Q_QML_PRIVATE_EXPORT GetLookup : Method<Throws::Yes>
191     {
192         static ReturnedValue call(ExecutionEngine *, Function *, const Value &, int);
193     };
194     struct Q_QML_PRIVATE_EXPORT SetLookupStrict : Method<Throws::Yes>
195     {
196         static void call(Function *, const Value &, int, const Value &);
197     };
198     struct Q_QML_PRIVATE_EXPORT SetLookupSloppy : Method<Throws::Yes>
199     {
200         static void call(Function *, const Value &, int, const Value &);
201     };
202 
203     /* typeof */
204     struct Q_QML_PRIVATE_EXPORT TypeofValue : PureMethod
205     {
206         static ReturnedValue call(ExecutionEngine *, const Value &);
207     };
208     struct Q_QML_PRIVATE_EXPORT TypeofName : Method<Throws::No>
209     {
210         static ReturnedValue call(ExecutionEngine *, int);
211     };
212 
213     /* delete */
214     struct Q_QML_PRIVATE_EXPORT DeleteProperty_NoThrow : Method<Throws::No>
215     {
216         static Bool call(ExecutionEngine *, const Value &, const Value &);
217     };
218     struct Q_QML_PRIVATE_EXPORT DeleteProperty : Method<Throws::Yes>
219     {
220         static ReturnedValue call(ExecutionEngine *, Function *, const Value &, const Value &);
221     };
222     struct Q_QML_PRIVATE_EXPORT DeleteName_NoThrow : Method<Throws::No>
223     {
224         static Bool call(ExecutionEngine *, int);
225     };
226     struct Q_QML_PRIVATE_EXPORT DeleteName : Method<Throws::Yes>
227     {
228         static ReturnedValue call(ExecutionEngine *, Function *, int);
229     };
230 
231     /* exceptions & scopes */
232     struct Q_QML_PRIVATE_EXPORT ThrowException : Method<Throws::Yes>
233     {
234         static void call(ExecutionEngine *, const Value &);
235     };
236     struct Q_QML_PRIVATE_EXPORT PushCallContext : Method<Throws::No, ChangesContext::Yes>
237     {
238         static void call(CppStackFrame *);
239     };
240     struct Q_QML_PRIVATE_EXPORT PushWithContext : Method<Throws::Yes, ChangesContext::Yes>
241     {
242         static ReturnedValue call(ExecutionEngine *, const Value &);
243     };
244     struct Q_QML_PRIVATE_EXPORT PushCatchContext : Method<Throws::No, ChangesContext::Yes>
245     {
246         static void call(ExecutionEngine *, int, int);
247     };
248     struct Q_QML_PRIVATE_EXPORT PushBlockContext : Method<Throws::No, ChangesContext::Yes>
249     {
250         static void call(ExecutionEngine *, int);
251     };
252     struct Q_QML_PRIVATE_EXPORT CloneBlockContext : Method<Throws::No, ChangesContext::Yes>
253     {
254         static void call(ExecutionEngine *);
255     };
256     struct Q_QML_PRIVATE_EXPORT PushScriptContext : Method<Throws::No, ChangesContext::Yes>
257     {
258         static void call(ExecutionEngine *, int);
259     };
260     struct Q_QML_PRIVATE_EXPORT PopScriptContext : Method<Throws::No, ChangesContext::Yes>
261     {
262         static void call(ExecutionEngine *);
263     };
264     struct Q_QML_PRIVATE_EXPORT ThrowReferenceError : Method<Throws::Yes>
265     {
266         static void call(ExecutionEngine *, int);
267     };
268     struct Q_QML_PRIVATE_EXPORT ThrowOnNullOrUndefined : Method<Throws::Yes>
269     {
270         static void call(ExecutionEngine *, const Value &);
271     };
272 
273     /* closures */
274     struct Q_QML_PRIVATE_EXPORT Closure : Method<Throws::No>
275     {
276         static ReturnedValue call(ExecutionEngine *, int);
277     };
278 
279     /* Function header */
280     struct Q_QML_PRIVATE_EXPORT ConvertThisToObject : Method<Throws::Yes>
281     {
282         static ReturnedValue call(ExecutionEngine *, const Value &);
283     };
284     struct Q_QML_PRIVATE_EXPORT DeclareVar : Method<Throws::Yes>
285     {
286         static void call(ExecutionEngine *, Bool, int);
287     };
288     struct Q_QML_PRIVATE_EXPORT CreateMappedArgumentsObject : Method<Throws::No>
289     {
290         static ReturnedValue call(ExecutionEngine *);
291     };
292     struct Q_QML_PRIVATE_EXPORT CreateUnmappedArgumentsObject : Method<Throws::No>
293     {
294         static ReturnedValue call(ExecutionEngine *);
295     };
296     struct Q_QML_PRIVATE_EXPORT CreateRestParameter : PureMethod
297     {
298         static ReturnedValue call(ExecutionEngine *, int);
299     };
300 
301     /* literals */
302     struct Q_QML_PRIVATE_EXPORT ArrayLiteral : Method<Throws::Yes>
303     {
304         static ReturnedValue call(ExecutionEngine *, Value[], uint);
305     };
306     struct Q_QML_PRIVATE_EXPORT ObjectLiteral : Method<Throws::Yes>
307     {
308         static ReturnedValue call(ExecutionEngine *, int, Value[], int);
309     };
310     struct Q_QML_PRIVATE_EXPORT CreateClass : Method<Throws::Yes>
311     {
312         static ReturnedValue call(ExecutionEngine *, int, const Value &, Value[]);
313     };
314 
315     /* for-in, for-of and array destructuring */
316     struct Q_QML_PRIVATE_EXPORT GetIterator : Method<Throws::Yes>
317     {
318         static ReturnedValue call(ExecutionEngine *, const Value &, int);
319     };
320     struct Q_QML_PRIVATE_EXPORT IteratorNext : IteratorMethod
321     {
322         static ReturnedValue call(ExecutionEngine *, const Value &, Value *);
323     };
324     struct Q_QML_PRIVATE_EXPORT IteratorNextForYieldStar : IteratorMethod
325     {
326         static ReturnedValue call(ExecutionEngine *, const Value &, const Value &, Value *);
327     };
328     struct Q_QML_PRIVATE_EXPORT IteratorClose : Method<Throws::Yes>
329     {
330         static ReturnedValue call(ExecutionEngine *, const Value &, const Value &);
331     };
332     struct Q_QML_PRIVATE_EXPORT DestructureRestElement : Method<Throws::Yes>
333     {
334         static ReturnedValue call(ExecutionEngine *, const Value &);
335     };
336 
337     /* conversions */
338     struct Q_QML_PRIVATE_EXPORT ToObject : Method<Throws::Yes>
339     {
340         static ReturnedValue call(ExecutionEngine *, const Value &);
341     };
342     struct Q_QML_PRIVATE_EXPORT ToBoolean : PureMethod
343     {
344         static Bool call(const Value &);
345     };
346     struct Q_QML_PRIVATE_EXPORT ToNumber : Method<Throws::Yes>
347     {
348         static ReturnedValue call(ExecutionEngine *, const Value &);
349     };
350     /* unary operators */
351     struct Q_QML_PRIVATE_EXPORT UMinus : Method<Throws::Yes>
352     {
353         static ReturnedValue call(const Value &);
354     };
355 
356     /* binary operators */
357     struct Q_QML_PRIVATE_EXPORT Instanceof : Method<Throws::Yes>
358     {
359         static ReturnedValue call(ExecutionEngine *, const Value &, const Value &);
360     };
361     struct Q_QML_PRIVATE_EXPORT In : Method<Throws::Yes>
362     {
363         static ReturnedValue call(ExecutionEngine *, const Value &, const Value &);
364     };
365     struct Q_QML_PRIVATE_EXPORT Add : Method<Throws::Yes>
366     {
367         static ReturnedValue call(ExecutionEngine *, const Value &, const Value &);
368     };
369     struct Q_QML_PRIVATE_EXPORT Sub : Method<Throws::Yes>
370     {
371         static ReturnedValue call(const Value &, const Value &);
372     };
373     struct Q_QML_PRIVATE_EXPORT Mul : Method<Throws::Yes>
374     {
375         static ReturnedValue call(const Value &, const Value &);
376     };
377     struct Q_QML_PRIVATE_EXPORT Div : Method<Throws::Yes>
378     {
379         static ReturnedValue call(const Value &, const Value &);
380     };
381     struct Q_QML_PRIVATE_EXPORT Mod : Method<Throws::Yes>
382     {
383         static ReturnedValue call(const Value &, const Value &);
384     };
385     struct Q_QML_PRIVATE_EXPORT Exp : Method<Throws::Yes>
386     {
387         static ReturnedValue call(const Value &, const Value &);
388     };
389     struct Q_QML_PRIVATE_EXPORT BitAnd : Method<Throws::Yes>
390     {
391         static ReturnedValue call(const Value &, const Value &);
392     };
393     struct Q_QML_PRIVATE_EXPORT BitOr : Method<Throws::Yes>
394     {
395         static ReturnedValue call(const Value &, const Value &);
396     };
397     struct Q_QML_PRIVATE_EXPORT BitXor : Method<Throws::Yes>
398     {
399         static ReturnedValue call(const Value &, const Value &);
400     };
401     struct Q_QML_PRIVATE_EXPORT Shl : Method<Throws::Yes>
402     {
403         static ReturnedValue call(const Value &, const Value &);
404     };
405     struct Q_QML_PRIVATE_EXPORT Shr : Method<Throws::Yes>
406     {
407         static ReturnedValue call(const Value &, const Value &);
408     };
409     struct Q_QML_PRIVATE_EXPORT UShr : Method<Throws::Yes>
410     {
411         static ReturnedValue call(const Value &, const Value &);
412     };
413     struct Q_QML_PRIVATE_EXPORT GreaterThan : Method<Throws::Yes>
414     {
415         static ReturnedValue call(const Value &, const Value &);
416     };
417     struct Q_QML_PRIVATE_EXPORT LessThan : Method<Throws::Yes>
418     {
419         static ReturnedValue call(const Value &, const Value &);
420     };
421     struct Q_QML_PRIVATE_EXPORT GreaterEqual : Method<Throws::Yes>
422     {
423         static ReturnedValue call(const Value &, const Value &);
424     };
425     struct Q_QML_PRIVATE_EXPORT LessEqual : Method<Throws::Yes>
426     {
427         static ReturnedValue call(const Value &, const Value &);
428     };
429     struct Q_QML_PRIVATE_EXPORT Equal : Method<Throws::Yes>
430     {
431         static ReturnedValue call(const Value &, const Value &);
432     };
433     struct Q_QML_PRIVATE_EXPORT NotEqual : Method<Throws::Yes>
434     {
435         static ReturnedValue call(const Value &, const Value &);
436     };
437     struct Q_QML_PRIVATE_EXPORT StrictEqual : Method<Throws::Yes>
438     {
439         static ReturnedValue call(const Value &, const Value &);
440     };
441     struct Q_QML_PRIVATE_EXPORT StrictNotEqual : Method<Throws::Yes>
442     {
443         static ReturnedValue call(const Value &, const Value &);
444     };
445 
446     /* comparisons */
447     struct Q_QML_PRIVATE_EXPORT CompareGreaterThan : Method<Throws::Yes>
448     {
449         static Bool call(const Value &, const Value &);
450     };
451     struct Q_QML_PRIVATE_EXPORT CompareLessThan : Method<Throws::Yes>
452     {
453         static Bool call(const Value &, const Value &);
454     };
455     struct Q_QML_PRIVATE_EXPORT CompareGreaterEqual : Method<Throws::Yes>
456     {
457         static Bool call(const Value &, const Value &);
458     };
459     struct Q_QML_PRIVATE_EXPORT CompareLessEqual : Method<Throws::Yes>
460     {
461         static Bool call(const Value &, const Value &);
462     };
463     struct Q_QML_PRIVATE_EXPORT CompareEqual : Method<Throws::Yes>
464     {
465         static Bool call(const Value &, const Value &);
466     };
467     struct Q_QML_PRIVATE_EXPORT CompareNotEqual : Method<Throws::Yes>
468     {
469         static Bool call(const Value &, const Value &);
470     };
471     struct Q_QML_PRIVATE_EXPORT CompareStrictEqual : Method<Throws::Yes>
472     {
473         static Bool call(const Value &, const Value &);
474     };
475     struct Q_QML_PRIVATE_EXPORT CompareStrictNotEqual : Method<Throws::Yes>
476     {
477         static Bool call(const Value &, const Value &);
478     };
479 
480     struct Q_QML_PRIVATE_EXPORT CompareInstanceof : Method<Throws::Yes>
481     {
482         static Bool call(ExecutionEngine *, const Value &, const Value &);
483     };
484     struct Q_QML_PRIVATE_EXPORT CompareIn : Method<Throws::Yes>
485     {
486         static Bool call(ExecutionEngine *, const Value &, const Value &);
487     };
488 
489     struct Q_QML_PRIVATE_EXPORT RegexpLiteral : PureMethod
490     {
491         static ReturnedValue call(ExecutionEngine *, int);
492     };
493     struct Q_QML_PRIVATE_EXPORT GetTemplateObject : PureMethod
494     {
495         static ReturnedValue call(Function *, int);
496     };
497 
498     struct StackOffsets {
499         static const int tailCall_function   = -1;
500         static const int tailCall_thisObject = -2;
501         static const int tailCall_argv       = -3;
502         static const int tailCall_argc       = -4;
503     };
504 
505     static QHash<const void *, const char *> symbolTable();
506 };
507 
508 static_assert(std::is_standard_layout<Runtime>::value, "Runtime needs to be standard layout in order for us to be able to use offsetof");
509 static_assert(sizeof(Runtime::BinaryOperation) == sizeof(void*), "JIT expects a function pointer to fit into a regular pointer, for cross-compilation offset translation");
510 
511 } // namespace QV4
512 
513 QT_END_NAMESPACE
514 
515 #endif // QV4RUNTIMEAPI_P_H
516