aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/compiler/qv4jsir_p.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/qml/compiler/qv4jsir_p.h')
-rw-r--r--src/qml/compiler/qv4jsir_p.h226
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