1 /****************************************************************************
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
6 ** This file is part of the QtDeclarative module of the Qt Toolkit.
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.
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.
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.
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.
40 ****************************************************************************/
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.
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>
63 #include <private/qdeclarativepool_p.h>
64 #include <QtCore/qvarlengtharray.h>
66 // #define DEBUG_IR_STRUCTURE
73 class QDeclarativeType;
75 namespace QDeclarativeJS {
136 AluOp binaryOperator(int op);
150 BoolType = FirstNumberType,
155 Type maxType(IR::Type left, IR::Type right);
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 *) {}
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 *) {}
177 struct Expr: QDeclarativePool::POD {
180 Expr(): type(InvalidType) {}
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;
193 struct ExprList: QDeclarativePool::POD {
197 void init(Expr *expr, ExprList *next = 0)
207 void init(Type type, double value)
213 virtual void accept(ExprVisitor *v) { v->visitConst(this); }
214 virtual Const *asConst() { return this; }
216 virtual void dump(QTextStream &out);
219 struct String: Expr {
222 void init(const QStringRef &value)
224 this->type = StringType;
228 virtual void accept(ExprVisitor *v) { v->visitString(this); }
229 virtual String *asString() { return this; }
231 virtual void dump(QTextStream &out);
232 static QString escape(const QStringRef &s);
237 MathSinBultinFunction,
238 MathCosBultinFunction,
239 MathRoundBultinFunction,
240 MathFloorBultinFunction,
242 MathPIBuiltinConstant
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?
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
267 const QMetaObject *meta;
268 const QDeclarativeType *declarativeType;
269 const QDeclarativeScript::Object *idObject;
271 QDeclarativePropertyData *property;
273 BuiltinSymbol builtin;
277 void init(Name *base, Type type, const QString *id, Symbol symbol, quint32 line, quint32 column);
279 inline bool is(Symbol s) const { return s == symbol; }
280 inline bool isNot(Symbol s) const { return s != symbol; }
282 virtual void accept(ExprVisitor *v) { v->visitName(this); }
283 virtual Name *asName() { return this; }
285 virtual void dump(QTextStream &out);
291 void init(Type type, int index)
297 virtual void accept(ExprVisitor *v) { v->visitTemp(this); }
298 virtual Temp *asTemp() { return this; }
300 virtual void dump(QTextStream &out);
307 void init(AluOp op, Expr *expr)
309 this->typeForOp(op, expr);
314 virtual void accept(ExprVisitor *v) { v->visitUnop(this); }
315 virtual Unop *asUnop() { return this; }
317 virtual void dump(QTextStream &out);
320 static Type typeForOp(AluOp op, Expr *expr);
328 void init(AluOp op, Expr *left, Expr *right)
330 this->type = typeForOp(op, left, right);
336 virtual void accept(ExprVisitor *v) { v->visitBinop(this); }
337 virtual Binop *asBinop() { return this; }
339 virtual void dump(QTextStream &out);
342 static Type typeForOp(AluOp op, Expr *left, Expr *right);
349 void init(Expr *base, ExprList *args)
351 this->type = typeForFunction(base);
356 Expr *onlyArgument() const {
357 if (args && ! args->next)
362 virtual void accept(ExprVisitor *v) { v->visitCall(this); }
363 virtual Call *asCall() { return this; }
365 virtual void dump(QTextStream &out);
368 static Type typeForFunction(Expr *base);
371 struct Stmt: QDeclarativePool::POD {
378 virtual Stmt *asTerminator() { return 0; }
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;
392 void init(Expr *expr)
397 virtual void accept(StmtVisitor *v) { v->visitExp(this); }
398 virtual Exp *asExp() { return this; }
400 virtual void dump(QTextStream &out, Mode);
406 bool isMoveForReturn;
408 void init(Expr *target, Expr *source, bool isMoveForReturn)
410 this->target = target;
411 this->source = source;
412 this->isMoveForReturn = isMoveForReturn;
415 virtual void accept(StmtVisitor *v) { v->visitMove(this); }
416 virtual Move *asMove() { return this; }
418 virtual void dump(QTextStream &out, Mode);
424 void init(BasicBlock *target)
426 this->target = target;
429 virtual Stmt *asTerminator() { return this; }
431 virtual void accept(StmtVisitor *v) { v->visitJump(this); }
432 virtual Jump *asJump() { return this; }
434 virtual void dump(QTextStream &out, Mode mode);
442 void init(Expr *cond, BasicBlock *iftrue, BasicBlock *iffalse)
445 this->iftrue = iftrue;
446 this->iffalse = iffalse;
449 virtual Stmt *asTerminator() { return this; }
451 virtual void accept(StmtVisitor *v) { v->visitCJump(this); }
452 virtual CJump *asCJump() { return this; }
454 virtual void dump(QTextStream &out, Mode mode);
463 void init(Expr *expr, Type type, quint32 line, quint32 column)
468 this->column = column;
471 virtual Stmt *asTerminator() { return this; }
473 virtual void accept(StmtVisitor *v) { v->visitRet(this); }
474 virtual Ret *asRet() { return this; }
476 virtual void dump(QTextStream &out, Mode);
480 QDeclarativePool *pool;
481 QVarLengthArray<BasicBlock *, 8> basicBlocks;
484 Function(QDeclarativePool *pool)
485 : pool(pool), tempCount(0) {}
489 BasicBlock *newBasicBlock();
490 QString *newString(const QString &text);
492 inline BasicBlock *i(BasicBlock *block) { basicBlocks.append(block); return block; }
494 virtual void dump(QTextStream &out);
501 QVarLengthArray<Stmt *, 32> statements;
503 BasicBlock(Function *function, int index): function(function), index(index), offset(-1) {}
506 template <typename Instr> inline Instr i(Instr i) { statements.append(i); return i; }
508 inline bool isEmpty() const {
509 return statements.isEmpty();
512 inline Stmt *terminator() const {
513 if (! statements.isEmpty() && statements.at(statements.size() - 1)->asTerminator() != 0)
514 return statements.at(statements.size() - 1);
518 inline bool isTerminated() const {
519 if (terminator() != 0)
524 Temp *TEMP(Type type, int index);
525 Temp *TEMP(Type type);
527 Expr *CONST(double value);
528 Expr *CONST(Type type, double value);
529 Expr *STRING(const QStringRef &value);
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);
539 Expr *UNOP(AluOp op, Expr *expr);
540 Expr *BINOP(AluOp op, Expr *left, Expr *right);
541 Expr *CALL(Expr *base, ExprList *args);
543 Stmt *EXP(Expr *expr);
544 Stmt *MOVE(Expr *target, Expr *source, bool = false);
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);
550 virtual void dump(QTextStream &out);
553 #ifdef DEBUG_IR_STRUCTURE
554 struct IRDump : public ExprVisitor,
560 void expression(QDeclarativeJS::IR::Expr *);
561 void basicblock(QDeclarativeJS::IR::BasicBlock *);
562 void statement(QDeclarativeJS::IR::Stmt *);
563 void function(QDeclarativeJS::IR::Function *);
566 const char *indent();
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);
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);
590 QByteArray indentData;
596 } // end of namespace IR
598 } // end of namespace QDeclarativeJS