Remove QtQuick1 elements from qtdeclarative
[profile/ivi/qtdeclarative.git] / src / declarative / qml / v4 / qv4ir_p.h
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
5 **
6 ** This file is part of the QtDeclarative module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
16 **
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
20 **
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
28 **
29 ** Other Usage
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
32 **
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #ifndef QV4IR_P_H
43 #define QV4IR_P_H
44
45 //
46 //  W A R N I N G
47 //  -------------
48 //
49 // This file is not part of the Qt API.  It exists purely as an
50 // implementation detail.  This header file may change from version to
51 // version without notice, or even be removed.
52 //
53 // We mean it.
54 //
55
56 #include <private/qdeclarativejsast_p.h>
57 #include <private/qdeclarativejsengine_p.h>
58 #include <private/qdeclarativescript_p.h>
59 #include <private/qdeclarativeimport_p.h>
60 #include <private/qdeclarativeengine_p.h>
61 #include <private/qv4compiler_p.h>
62
63 #include <private/qdeclarativepool_p.h>
64 #include <QtCore/qvarlengtharray.h>
65
66 // #define DEBUG_IR_STRUCTURE
67
68 QT_BEGIN_HEADER
69
70 QT_BEGIN_NAMESPACE
71
72 class QTextStream;
73 class QDeclarativeType;
74
75 namespace QDeclarativeJS {
76
77 namespace IR {
78
79 struct BasicBlock;
80 struct Function;
81
82 struct Stmt;
83 struct Expr;
84
85 // expressions
86 struct Const;
87 struct String;
88 struct Name;
89 struct Temp;
90 struct Unop;
91 struct Binop;
92 struct Call;
93
94 // statements
95 struct Exp;
96 struct Move;
97 struct Jump;
98 struct CJump;
99 struct Ret;
100
101 enum AluOp {
102     OpInvalid = 0,
103
104     OpIfTrue,
105     OpNot,
106     OpUMinus,
107     OpUPlus,
108     OpCompl,
109
110     OpBitAnd,
111     OpBitOr,
112     OpBitXor,
113
114     OpAdd,
115     OpSub,
116     OpMul,
117     OpDiv,
118     OpMod,
119
120     OpLShift,
121     OpRShift,
122     OpURShift,
123
124     OpGt,
125     OpLt,
126     OpGe,
127     OpLe,
128     OpEqual,
129     OpNotEqual,
130     OpStrictEqual,
131     OpStrictNotEqual,
132
133     OpAnd,
134     OpOr
135 };
136 AluOp binaryOperator(int op);
137
138 enum Type {
139     InvalidType,
140     UndefinedType,
141     NullType,
142     VoidType,
143     StringType,
144     UrlType,
145     SGAnchorLineType,
146     AttachType,
147     ObjectType,
148
149     FirstNumberType,
150     BoolType = FirstNumberType,
151     IntType,
152     RealType,
153     RealNaNType
154 };
155 Type maxType(IR::Type left, IR::Type right);
156
157 struct ExprVisitor {
158     virtual ~ExprVisitor() {}
159     virtual void visitConst(Const *) {}
160     virtual void visitString(String *) {}
161     virtual void visitName(Name *) {}
162     virtual void visitTemp(Temp *) {}
163     virtual void visitUnop(Unop *) {}
164     virtual void visitBinop(Binop *) {}
165     virtual void visitCall(Call *) {}
166 };
167
168 struct StmtVisitor {
169     virtual ~StmtVisitor() {}
170     virtual void visitExp(Exp *) {}
171     virtual void visitMove(Move *) {}
172     virtual void visitJump(Jump *) {}
173     virtual void visitCJump(CJump *) {}
174     virtual void visitRet(Ret *) {}
175 };
176
177 struct Expr: QDeclarativePool::POD {
178     Type type;
179
180     Expr(): type(InvalidType) {}
181     virtual ~Expr() {}
182     virtual void accept(ExprVisitor *) = 0;
183     virtual Const *asConst() { return 0; }
184     virtual String *asString() { return 0; }
185     virtual Name *asName() { return 0; }
186     virtual Temp *asTemp() { return 0; }
187     virtual Unop *asUnop() { return 0; }
188     virtual Binop *asBinop() { return 0; }
189     virtual Call *asCall() { return 0; }
190     virtual void dump(QTextStream &out) = 0;
191 };
192
193 struct ExprList: QDeclarativePool::POD {
194     Expr *expr;
195     ExprList *next;
196
197     void init(Expr *expr, ExprList *next = 0)
198     {
199         this->expr = expr;
200         this->next = next;
201     }
202 };
203
204 struct Const: Expr {
205     double value;
206
207     void init(Type type, double value)
208     {
209         this->type = type;
210         this->value = value;
211     }
212
213     virtual void accept(ExprVisitor *v) { v->visitConst(this); }
214     virtual Const *asConst() { return this; }
215
216     virtual void dump(QTextStream &out);
217 };
218
219 struct String: Expr {
220     QStringRef value;
221
222     void init(const QStringRef &value)
223     {
224         this->type = StringType;
225         this->value = value;
226     }
227
228     virtual void accept(ExprVisitor *v) { v->visitString(this); }
229     virtual String *asString() { return this; }
230
231     virtual void dump(QTextStream &out);
232     static QString escape(const QStringRef &s);
233 };
234
235 enum BuiltinSymbol {
236     NoBuiltinSymbol,
237     MathSinBultinFunction,
238     MathCosBultinFunction,
239     MathRoundBultinFunction,
240     MathFloorBultinFunction,
241
242     MathPIBuiltinConstant
243 };
244
245 struct Name: Expr {
246     enum Symbol {
247         Unbound,
248         IdObject,      // This is a load of a id object.  Storage will always be IdStorage
249         AttachType,    // This is a load of an attached object 
250         Object,        // XXX what is this for?
251         Property,      // This is a load of a regular property
252         Slot           // XXX what is this for?
253     };
254
255     enum Storage {
256         MemberStorage, // This is a property of a previously fetched object
257         IdStorage,     // This is a load of a id object.  Symbol will always be IdObject
258         RootStorage,   // This is a property of the root object
259         ScopeStorage   // This is a property of the scope object
260     };
261
262     Name *base;
263     const QString *id;
264     Symbol symbol;
265     union {
266         void *ptr;
267         const QMetaObject *meta;
268         const QDeclarativeType *declarativeType;
269         const QDeclarativeScript::Object *idObject;
270     };
271     QDeclarativePropertyData *property;
272     Storage storage;
273     BuiltinSymbol builtin;
274     quint32 line;
275     quint32 column;
276
277     void init(Name *base, Type type, const QString *id, Symbol symbol, quint32 line, quint32 column);
278
279     inline bool is(Symbol s) const { return s == symbol; }
280     inline bool isNot(Symbol s) const { return s != symbol; }
281
282     virtual void accept(ExprVisitor *v) { v->visitName(this); }
283     virtual Name *asName() { return this; }
284
285     virtual void dump(QTextStream &out);
286 };
287
288 struct Temp: Expr {
289     int index;
290
291     void init(Type type, int index)
292     {
293         this->type = type;
294         this->index = index;
295     }
296
297     virtual void accept(ExprVisitor *v) { v->visitTemp(this); }
298     virtual Temp *asTemp() { return this; }
299
300     virtual void dump(QTextStream &out);
301 };
302
303 struct Unop: Expr {
304     AluOp op;
305     Expr *expr;
306
307     void init(AluOp op, Expr *expr)
308     {
309         this->typeForOp(op, expr);
310         this->op = op;
311         this->expr = expr;
312     }
313
314     virtual void accept(ExprVisitor *v) { v->visitUnop(this); }
315     virtual Unop *asUnop() { return this; }
316
317     virtual void dump(QTextStream &out);
318
319 private:
320     static Type typeForOp(AluOp op, Expr *expr);
321 };
322
323 struct Binop: Expr {
324     AluOp op;
325     Expr *left;
326     Expr *right;
327
328     void init(AluOp op, Expr *left, Expr *right)
329     {
330         this->type = typeForOp(op, left, right);
331         this->op = op;
332         this->left = left;
333         this->right = right;
334     }
335
336     virtual void accept(ExprVisitor *v) { v->visitBinop(this); }
337     virtual Binop *asBinop() { return this; }
338
339     virtual void dump(QTextStream &out);
340
341 private:
342     static Type typeForOp(AluOp op, Expr *left, Expr *right);
343 };
344
345 struct Call: Expr {
346     Expr *base;
347     ExprList *args;
348
349     void init(Expr *base, ExprList *args)
350     {
351         this->type = typeForFunction(base);
352         this->base = base;
353         this->args = args;
354     }
355
356     Expr *onlyArgument() const {
357         if (args && ! args->next)
358             return args->expr;
359         return 0;
360     }
361
362     virtual void accept(ExprVisitor *v) { v->visitCall(this); }
363     virtual Call *asCall() { return this; }
364
365     virtual void dump(QTextStream &out);
366
367 private:
368     static Type typeForFunction(Expr *base);
369 };
370
371 struct Stmt: QDeclarativePool::POD {
372     enum Mode {
373         HIR,
374         MIR
375     };
376
377     virtual ~Stmt() {}
378     virtual Stmt *asTerminator() { return 0; }
379
380     virtual void accept(StmtVisitor *) = 0;
381     virtual Exp *asExp() { return 0; }
382     virtual Move *asMove() { return 0; }
383     virtual Jump *asJump() { return 0; }
384     virtual CJump *asCJump() { return 0; }
385     virtual Ret *asRet() { return 0; }
386     virtual void dump(QTextStream &out, Mode mode = HIR) = 0;
387 };
388
389 struct Exp: Stmt {
390     Expr *expr;
391
392     void init(Expr *expr)
393     {
394         this->expr = expr;
395     }
396
397     virtual void accept(StmtVisitor *v) { v->visitExp(this); }
398     virtual Exp *asExp() { return this; }
399
400     virtual void dump(QTextStream &out, Mode);
401 };
402
403 struct Move: Stmt {
404     Expr *target;
405     Expr *source;
406     bool isMoveForReturn;
407
408     void init(Expr *target, Expr *source, bool isMoveForReturn)
409     {
410         this->target = target;
411         this->source = source;
412         this->isMoveForReturn = isMoveForReturn;
413     }
414
415     virtual void accept(StmtVisitor *v) { v->visitMove(this); }
416     virtual Move *asMove() { return this; }
417
418     virtual void dump(QTextStream &out, Mode);
419 };
420
421 struct Jump: Stmt {
422     BasicBlock *target;
423
424     void init(BasicBlock *target)
425     {
426         this->target = target;
427     }
428
429     virtual Stmt *asTerminator() { return this; }
430
431     virtual void accept(StmtVisitor *v) { v->visitJump(this); }
432     virtual Jump *asJump() { return this; }
433
434     virtual void dump(QTextStream &out, Mode mode);
435 };
436
437 struct CJump: Stmt {
438     Expr *cond;
439     BasicBlock *iftrue;
440     BasicBlock *iffalse;
441
442     void init(Expr *cond, BasicBlock *iftrue, BasicBlock *iffalse)
443     {
444         this->cond = cond;
445         this->iftrue = iftrue;
446         this->iffalse = iffalse;
447     }
448
449     virtual Stmt *asTerminator() { return this; }
450
451     virtual void accept(StmtVisitor *v) { v->visitCJump(this); }
452     virtual CJump *asCJump() { return this; }
453
454     virtual void dump(QTextStream &out, Mode mode);
455 };
456
457 struct Ret: Stmt {
458     Expr *expr;
459     Type type;
460     quint32 line;
461     quint32 column;
462
463     void init(Expr *expr, Type type, quint32 line, quint32 column)
464     {
465         this->expr = expr;
466         this->type = type;
467         this->line = line;
468         this->column = column;
469     }
470
471     virtual Stmt *asTerminator() { return this; }
472
473     virtual void accept(StmtVisitor *v) { v->visitRet(this); }
474     virtual Ret *asRet() { return this; }
475
476     virtual void dump(QTextStream &out, Mode);
477 };
478
479 struct Function {
480     QDeclarativePool *pool;
481     QVarLengthArray<BasicBlock *, 8> basicBlocks;
482     int tempCount;
483
484     Function(QDeclarativePool *pool)
485       : pool(pool), tempCount(0) {}
486
487     ~Function();
488
489     BasicBlock *newBasicBlock();
490     QString *newString(const QString &text);
491
492     inline BasicBlock *i(BasicBlock *block) { basicBlocks.append(block); return block; }
493
494     virtual void dump(QTextStream &out);
495 };
496
497 struct BasicBlock {
498     Function *function;
499     int index;
500     int offset;
501     QVarLengthArray<Stmt *, 32> statements;
502
503     BasicBlock(Function *function, int index): function(function), index(index), offset(-1) {}
504     ~BasicBlock() {}
505
506     template <typename Instr> inline Instr i(Instr i) { statements.append(i); return i; }
507
508     inline bool isEmpty() const {
509         return statements.isEmpty();
510     }
511
512     inline Stmt *terminator() const {
513         if (! statements.isEmpty() && statements.at(statements.size() - 1)->asTerminator() != 0)
514             return statements.at(statements.size() - 1);
515         return 0;
516     }
517
518     inline bool isTerminated() const {
519         if (terminator() != 0)
520             return true;
521         return false;
522     }
523
524     Temp *TEMP(Type type, int index);
525     Temp *TEMP(Type type);
526
527     Expr *CONST(double value);
528     Expr *CONST(Type type, double value);
529     Expr *STRING(const QStringRef &value);
530
531     Name *NAME(const QString &id, quint32 line, quint32 column);
532     Name *NAME(Name *base, const QString &id, quint32 line, quint32 column);
533     Name *SYMBOL(Type type, const QString &id, const QMetaObject *meta, QDeclarativePropertyData *property, Name::Storage storage, quint32 line, quint32 column);
534     Name *SYMBOL(Name *base, Type type, const QString &id, const QMetaObject *meta, QDeclarativePropertyData *property, quint32 line, quint32 column);
535     Name *SYMBOL(Name *base, Type type, const QString &id, const QMetaObject *meta, QDeclarativePropertyData *property, Name::Storage storage, quint32 line, quint32 column);
536     Name *ID_OBJECT(const QString &id, const QDeclarativeScript::Object *object, quint32 line, quint32 column);
537     Name *ATTACH_TYPE(const QString &id, const QDeclarativeType *attachType, Name::Storage storage, quint32 line, quint32 column);
538
539     Expr *UNOP(AluOp op, Expr *expr);
540     Expr *BINOP(AluOp op, Expr *left, Expr *right);
541     Expr *CALL(Expr *base, ExprList *args);
542
543     Stmt *EXP(Expr *expr);
544     Stmt *MOVE(Expr *target, Expr *source, bool = false);
545
546     Stmt *JUMP(BasicBlock *target);
547     Stmt *CJUMP(Expr *cond, BasicBlock *iftrue, BasicBlock *iffalse);
548     Stmt *RET(Expr *expr, Type type, quint32 line, quint32 column);
549
550     virtual void dump(QTextStream &out);
551 };
552
553 #ifdef DEBUG_IR_STRUCTURE
554 struct IRDump : public ExprVisitor,
555                 public StmtVisitor 
556 {
557 public:
558     IRDump();
559
560     void expression(QDeclarativeJS::IR::Expr *);
561     void basicblock(QDeclarativeJS::IR::BasicBlock *);
562     void statement(QDeclarativeJS::IR::Stmt *);
563     void function(QDeclarativeJS::IR::Function *);
564 protected:
565
566     const char *indent();
567
568     //
569     // expressions
570     //
571     virtual void visitConst(QDeclarativeJS::IR::Const *e);
572     virtual void visitString(QDeclarativeJS::IR::String *e);
573     virtual void visitName(QDeclarativeJS::IR::Name *e);
574     virtual void visitTemp(QDeclarativeJS::IR::Temp *e);
575     virtual void visitUnop(QDeclarativeJS::IR::Unop *e);
576     virtual void visitBinop(QDeclarativeJS::IR::Binop *e);
577     virtual void visitCall(QDeclarativeJS::IR::Call *e);
578
579     //
580     // statements
581     //
582     virtual void visitExp(QDeclarativeJS::IR::Exp *s);
583     virtual void visitMove(QDeclarativeJS::IR::Move *s);
584     virtual void visitJump(QDeclarativeJS::IR::Jump *s);
585     virtual void visitCJump(QDeclarativeJS::IR::CJump *s);
586     virtual void visitRet(QDeclarativeJS::IR::Ret *s);
587
588 private:
589     int indentSize;
590     QByteArray indentData;
591     void inc();
592     void dec();
593 };
594 #endif
595
596 } // end of namespace IR
597
598 } // end of namespace QDeclarativeJS
599
600 QT_END_NAMESPACE
601
602 QT_END_HEADER
603
604 #endif // QV4IR_P_H