diff options
Diffstat (limited to 'src/qml/compiler/qv4jsir_p.h')
-rw-r--r-- | src/qml/compiler/qv4jsir_p.h | 226 |
1 files changed, 147 insertions, 79 deletions
diff --git a/src/qml/compiler/qv4jsir_p.h b/src/qml/compiler/qv4jsir_p.h index 9eff90dd30..fcdcdf9038 100644 --- a/src/qml/compiler/qv4jsir_p.h +++ b/src/qml/compiler/qv4jsir_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the QtQml module of the Qt Toolkit. @@ -108,6 +108,7 @@ struct String; struct RegExp; struct Name; struct Temp; +struct ArgLocal; struct Closure; struct Convert; struct Unop; @@ -210,6 +211,7 @@ struct ExprVisitor { virtual void visitRegExp(RegExp *) = 0; virtual void visitName(Name *) = 0; virtual void visitTemp(Temp *) = 0; + virtual void visitArgLocal(ArgLocal *) = 0; virtual void visitClosure(Closure *) = 0; virtual void visitConvert(Convert *) = 0; virtual void visitUnop(Unop *) = 0; @@ -260,6 +262,7 @@ struct Q_AUTOTEST_EXPORT Expr { virtual RegExp *asRegExp() { return 0; } virtual Name *asName() { return 0; } virtual Temp *asTemp() { return 0; } + virtual ArgLocal *asArgLocal() { return 0; } virtual Closure *asClosure() { return 0; } virtual Convert *asConvert() { return 0; } virtual Unop *asUnop() { return 0; } @@ -268,7 +271,6 @@ struct Q_AUTOTEST_EXPORT Expr { virtual New *asNew() { return 0; } virtual Subscript *asSubscript() { return 0; } virtual Member *asMember() { return 0; } - virtual void dump(QTextStream &out) const = 0; }; struct ExprList { @@ -295,8 +297,6 @@ struct Const: Expr { virtual void accept(ExprVisitor *v) { v->visitConst(this); } virtual Const *asConst() { return this; } - - virtual void dump(QTextStream &out) const; }; struct String: Expr { @@ -309,9 +309,6 @@ struct String: Expr { virtual void accept(ExprVisitor *v) { v->visitString(this); } virtual String *asString() { return this; } - - virtual void dump(QTextStream &out) const; - static QString escape(const QString &s); }; struct RegExp: Expr { @@ -333,8 +330,6 @@ struct RegExp: Expr { virtual void accept(ExprVisitor *v) { v->visitRegExp(this); } virtual RegExp *asRegExp() { return this; } - - virtual void dump(QTextStream &out) const; }; struct Name: Expr { @@ -376,60 +371,85 @@ struct Name: Expr { virtual void accept(ExprVisitor *v) { v->visitName(this); } virtual bool isLValue() { return true; } virtual Name *asName() { return this; } - - virtual void dump(QTextStream &out) const; }; struct Q_AUTOTEST_EXPORT Temp: Expr { enum Kind { - Formal = 0, - ScopedFormal, - Local, - ScopedLocal, + Invalid = 0, VirtualRegister, PhysicalRegister, StackSlot }; - unsigned index; - unsigned scope : 27; // how many scopes outside the current one? - unsigned kind : 3; - unsigned isArgumentsOrEval : 1; - unsigned isReadOnly : 1; + unsigned index : 28; + unsigned kind : 3; + unsigned isReadOnly : 1; // Used when temp is used as base in member expression MemberExpressionResolver memberResolver; - void init(unsigned kind, unsigned index, unsigned scope) - { - Q_ASSERT((kind == ScopedLocal && scope != 0) || - (kind == ScopedFormal && scope != 0) || - (scope == 0)); + Temp() + : index((1 << 28) - 1) + , kind(Invalid) + , isReadOnly(0) + {} + void init(unsigned kind, unsigned index) + { this->kind = kind; this->index = index; - this->scope = scope; - this->isArgumentsOrEval = false; this->isReadOnly = false; } + bool isInvalid() const { return kind == Invalid; } virtual void accept(ExprVisitor *v) { v->visitTemp(this); } virtual bool isLValue() { return !isReadOnly; } virtual Temp *asTemp() { return this; } - - virtual void dump(QTextStream &out) const; }; inline bool operator==(const Temp &t1, const Temp &t2) Q_DECL_NOTHROW -{ return t1.index == t2.index && t1.scope == t2.scope && t1.kind == t2.kind && t1.type == t2.type; } +{ return t1.index == t2.index && t1.kind == t2.kind && t1.type == t2.type; } inline bool operator!=(const Temp &t1, const Temp &t2) Q_DECL_NOTHROW { return !(t1 == t2); } inline uint qHash(const Temp &t, uint seed = 0) Q_DECL_NOTHROW -{ return t.index ^ (t.kind | (t.scope << 3)) ^ seed; } +{ return t.index ^ t.kind ^ seed; } bool operator<(const Temp &t1, const Temp &t2) Q_DECL_NOTHROW; +struct Q_AUTOTEST_EXPORT ArgLocal: Expr { + enum Kind { + Formal = 0, + ScopedFormal, + Local, + ScopedLocal + }; + + unsigned index; + unsigned scope : 29; // how many scopes outside the current one? + unsigned kind : 2; + unsigned isArgumentsOrEval : 1; + + void init(unsigned kind, unsigned index, unsigned scope) + { + Q_ASSERT((kind == ScopedLocal && scope != 0) || + (kind == ScopedFormal && scope != 0) || + (scope == 0)); + + this->kind = kind; + this->index = index; + this->scope = scope; + this->isArgumentsOrEval = false; + } + + virtual void accept(ExprVisitor *v) { v->visitArgLocal(this); } + virtual bool isLValue() { return true; } + virtual ArgLocal *asArgLocal() { return this; } + + bool operator==(const ArgLocal &other) const + { return index == other.index && scope == other.scope && kind == other.kind; } +}; + struct Closure: Expr { int value; // index in _module->functions const QString *functionName; @@ -442,8 +462,6 @@ struct Closure: Expr { virtual void accept(ExprVisitor *v) { v->visitClosure(this); } virtual Closure *asClosure() { return this; } - - virtual void dump(QTextStream &out) const; }; struct Convert: Expr { @@ -457,8 +475,6 @@ struct Convert: Expr { virtual void accept(ExprVisitor *v) { v->visitConvert(this); } virtual Convert *asConvert() { return this; } - - virtual void dump(QTextStream &out) const; }; struct Unop: Expr { @@ -473,8 +489,6 @@ struct Unop: Expr { virtual void accept(ExprVisitor *v) { v->visitUnop(this); } virtual Unop *asUnop() { return this; } - - virtual void dump(QTextStream &out) const; }; struct Binop: Expr { @@ -491,8 +505,6 @@ struct Binop: Expr { virtual void accept(ExprVisitor *v) { v->visitBinop(this); } virtual Binop *asBinop() { return this; } - - virtual void dump(QTextStream &out) const; }; struct Call: Expr { @@ -513,8 +525,6 @@ struct Call: Expr { virtual void accept(ExprVisitor *v) { v->visitCall(this); } virtual Call *asCall() { return this; } - - virtual void dump(QTextStream &out) const; }; struct New: Expr { @@ -535,8 +545,6 @@ struct New: Expr { virtual void accept(ExprVisitor *v) { v->visitNew(this); } virtual New *asNew() { return this; } - - virtual void dump(QTextStream &out) const; }; struct Subscript: Expr { @@ -552,8 +560,6 @@ struct Subscript: Expr { virtual void accept(ExprVisitor *v) { v->visitSubscript(this); } virtual bool isLValue() { return true; } virtual Subscript *asSubscript() { return this; } - - virtual void dump(QTextStream &out) const; }; struct Member: Expr { @@ -562,14 +568,14 @@ struct Member: Expr { UnspecifiedMember, MemberOfEnum, MemberOfQmlScopeObject, - MemberOfQmlContextObject + MemberOfQmlContextObject, + MemberOfSingletonObject }; Expr *base; const QString *name; QQmlPropertyData *property; int attachedPropertiesIdOrEnumValue; // depending on kind - uchar memberIsEnum : 1; uchar freeOfSideEffects : 1; // This is set for example for for QObject properties. All sorts of extra behavior @@ -596,7 +602,6 @@ struct Member: Expr { this->name = name; this->property = property; this->attachedPropertiesIdOrEnumValue = attachedPropertiesIdOrEnumValue; - this->memberIsEnum = false; this->freeOfSideEffects = false; this->inhibitTypeConversionOnWrite = property != 0; this->kind = kind; @@ -605,25 +610,20 @@ struct Member: Expr { virtual void accept(ExprVisitor *v) { v->visitMember(this); } virtual bool isLValue() { return true; } virtual Member *asMember() { return this; } - - virtual void dump(QTextStream &out) const; }; struct Stmt { - enum Mode { - HIR, - MIR - }; - struct Data { QVector<Expr *> incoming; // used by Phi nodes }; + enum { InvalidId = -1 }; + Data *d; - int id; QQmlJS::AST::SourceLocation location; - Stmt(): d(0), id(-1) {} + explicit Stmt(int id): d(0), _id(id) {} + virtual ~Stmt() { #ifdef Q_CC_MSVC @@ -641,7 +641,8 @@ struct Stmt { virtual CJump *asCJump() { return 0; } virtual Ret *asRet() { return 0; } virtual Phi *asPhi() { return 0; } - virtual void dump(QTextStream &out, Mode mode = HIR) = 0; + + int id() const { return _id; } private: // For memory management in BasicBlock friend struct BasicBlock; @@ -649,11 +650,17 @@ private: // For memory management in BasicBlock delete d; d = 0; } + +private: + friend struct Function; + int _id; }; struct Exp: Stmt { Expr *expr; + Exp(int id): Stmt(id) {} + void init(Expr *expr) { this->expr = expr; @@ -662,7 +669,6 @@ struct Exp: Stmt { virtual void accept(StmtVisitor *v) { v->visitExp(this); } virtual Exp *asExp() { return this; } - virtual void dump(QTextStream &out, Mode); }; struct Move: Stmt { @@ -670,6 +676,8 @@ struct Move: Stmt { Expr *source; bool swap; + Move(int id): Stmt(id) {} + void init(Expr *target, Expr *source) { this->target = target; @@ -680,12 +688,13 @@ struct Move: Stmt { virtual void accept(StmtVisitor *v) { v->visitMove(this); } virtual Move *asMove() { return this; } - virtual void dump(QTextStream &out, Mode mode = HIR); }; struct Jump: Stmt { BasicBlock *target; + Jump(int id): Stmt(id) {} + void init(BasicBlock *target) { this->target = target; @@ -695,8 +704,6 @@ struct Jump: Stmt { virtual void accept(StmtVisitor *v) { v->visitJump(this); } virtual Jump *asJump() { return this; } - - virtual void dump(QTextStream &out, Mode mode); }; struct CJump: Stmt { @@ -704,6 +711,8 @@ struct CJump: Stmt { BasicBlock *iftrue; BasicBlock *iffalse; + CJump(int id): Stmt(id) {} + void init(Expr *cond, BasicBlock *iftrue, BasicBlock *iffalse) { this->cond = cond; @@ -715,13 +724,13 @@ struct CJump: Stmt { virtual void accept(StmtVisitor *v) { v->visitCJump(this); } virtual CJump *asCJump() { return this; } - - virtual void dump(QTextStream &out, Mode mode); }; struct Ret: Stmt { Expr *expr; + Ret(int id): Stmt(id) {} + void init(Expr *expr) { this->expr = expr; @@ -731,17 +740,15 @@ struct Ret: Stmt { virtual void accept(StmtVisitor *v) { v->visitRet(this); } virtual Ret *asRet() { return this; } - - virtual void dump(QTextStream &out, Mode); }; struct Phi: Stmt { Temp *targetTemp; + Phi(int id): Stmt(id) {} + virtual void accept(StmtVisitor *v) { v->visitPhi(this); } virtual Phi *asPhi() { return this; } - - virtual void dump(QTextStream &out, Mode mode); }; struct Q_QML_PRIVATE_EXPORT Module { @@ -775,10 +782,10 @@ public: QVector<BasicBlock *> out; QQmlJS::AST::SourceLocation nextLocation; - BasicBlock(Function *function, BasicBlock *containingLoop, BasicBlock *catcher) + BasicBlock(Function *function, BasicBlock *catcher) : function(function) , catchBlock(catcher) - , _containingGroup(containingLoop) + , _containingGroup(0) , _index(-1) , _isExceptionHandler(false) , _groupStart(false) @@ -812,6 +819,7 @@ public: void appendStatement(Stmt *statement); void prependStatement(Stmt *stmt); + void prependStatements(const QVector<Stmt *> &stmts); void insertStatementBefore(Stmt *before, Stmt *newStmt); void insertStatementBefore(int index, Stmt *newStmt); void insertStatementBeforeTerminator(Stmt *stmt); @@ -841,8 +849,8 @@ public: unsigned newTemp(); Temp *TEMP(unsigned kind); - Temp *ARG(unsigned index, unsigned scope); - Temp *LOCAL(unsigned index, unsigned scope); + ArgLocal *ARG(unsigned index, unsigned scope); + ArgLocal *LOCAL(unsigned index, unsigned scope); Expr *CONST(Type type, double value); Expr *STRING(const QString *value); @@ -871,8 +879,6 @@ public: Stmt *CJUMP(Expr *cond, BasicBlock *iftrue, BasicBlock *iffalse); Stmt *RET(Temp *expr); - void dump(QTextStream &out, Stmt::Mode mode = Stmt::HIR); - BasicBlock *containingGroup() const { Q_ASSERT(!isRemoved()); @@ -994,7 +1000,10 @@ struct Function { PropertyDependencyMap contextObjectPropertyDependencies; PropertyDependencyMap scopeObjectPropertyDependencies; - template <typename _Tp> _Tp *New() { return new (pool->allocate(sizeof(_Tp))) _Tp(); } + template <typename T> T *New() { return new (pool->allocate(sizeof(T))) T(); } + template <typename T> T *NewStmt() { + return new (pool->allocate(sizeof(T))) T(getNewStatementId()); + } Function(Module *module, Function *outer, const QString &name); ~Function(); @@ -1004,7 +1013,7 @@ struct Function { DontInsertBlock }; - BasicBlock *newBasicBlock(BasicBlock *containingLoop, BasicBlock *catchBlock, BasicBlockInsertMode mode = InsertBlock); + BasicBlock *newBasicBlock(BasicBlock *catchBlock, BasicBlockInsertMode mode = InsertBlock); const QString *newString(const QString &text); void RECEIVE(const QString &name) { formals.append(newString(name)); } @@ -1024,8 +1033,6 @@ struct Function { int liveBasicBlocksCount() const; - void dump(QTextStream &out, Stmt::Mode mode = Stmt::HIR); - void removeSharedExpressions(); int indexOfArgument(const QStringRef &string) const; @@ -1036,9 +1043,13 @@ struct Function { void setScheduledBlocks(const QVector<BasicBlock *> &scheduled); void renumberBasicBlocks(); + unsigned getNewStatementId() { return _statementCount++; } + unsigned statementCount() const { return _statementCount; } + private: QVector<BasicBlock *> _basicBlocks; QVector<BasicBlock *> *_allBasicBlocks; + unsigned _statementCount; }; class CloneExpr: protected IR::ExprVisitor @@ -1088,12 +1099,20 @@ public: static Temp *cloneTemp(Temp *t, Function *f) { Temp *newTemp = f->New<Temp>(); - newTemp->init(t->kind, t->index, t->scope); + newTemp->init(t->kind, t->index); newTemp->type = t->type; newTemp->memberResolver = t->memberResolver; return newTemp; } + static ArgLocal *cloneArgLocal(ArgLocal *argLocal, Function *f) + { + ArgLocal *newArgLocal = f->New<ArgLocal>(); + newArgLocal->init(argLocal->kind, argLocal->index, argLocal->scope); + newArgLocal->type = argLocal->type; + return newArgLocal; + } + protected: IR::ExprList *clone(IR::ExprList *list); @@ -1102,6 +1121,7 @@ protected: virtual void visitRegExp(RegExp *); virtual void visitName(Name *); virtual void visitTemp(Temp *); + virtual void visitArgLocal(ArgLocal *); virtual void visitClosure(Closure *); virtual void visitConvert(Convert *); virtual void visitUnop(Unop *); @@ -1116,6 +1136,54 @@ private: IR::Expr *cloned; }; +class IRPrinter: public StmtVisitor, public ExprVisitor +{ +public: + IRPrinter(QTextStream *out); + virtual ~IRPrinter(); + + void print(Stmt *s); + void print(Expr *e); + void print(const Expr &e); + + virtual void print(Function *f); + virtual void print(BasicBlock *bb); + + virtual void visitExp(Exp *s); + virtual void visitMove(Move *s); + virtual void visitJump(Jump *s); + virtual void visitCJump(CJump *s); + virtual void visitRet(Ret *s); + virtual void visitPhi(Phi *s); + + virtual void visitConst(Const *e); + virtual void visitString(String *e); + virtual void visitRegExp(RegExp *e); + virtual void visitName(Name *e); + virtual void visitTemp(Temp *e); + virtual void visitArgLocal(ArgLocal *e); + virtual void visitClosure(Closure *e); + virtual void visitConvert(Convert *e); + virtual void visitUnop(Unop *e); + virtual void visitBinop(Binop *e); + virtual void visitCall(Call *e); + virtual void visitNew(New *e); + virtual void visitSubscript(Subscript *e); + virtual void visitMember(Member *e); + + static QString escape(const QString &s); + +protected: + virtual void addStmtNr(Stmt *s); + QString dumpStart(const Expr *e); + const char *dumpEnd(const Expr *e); + void printBlockStart(BasicBlock *bb); + +protected: + QTextStream *out; + bool printElse; +}; + } // end of namespace IR } // end of namespace QV4 |