diff options
Diffstat (limited to 'src/qml/compiler/qv4jsir.cpp')
-rw-r--r-- | src/qml/compiler/qv4jsir.cpp | 169 |
1 files changed, 152 insertions, 17 deletions
diff --git a/src/qml/compiler/qv4jsir.cpp b/src/qml/compiler/qv4jsir.cpp index efce64bf7a..a067a95104 100644 --- a/src/qml/compiler/qv4jsir.cpp +++ b/src/qml/compiler/qv4jsir.cpp @@ -165,10 +165,12 @@ struct RemoveSharedExpressions: IR::StmtVisitor, IR::ExprVisitor { subexpressions.clear(); - foreach (BasicBlock *block, function->basicBlocks) { + foreach (BasicBlock *block, function->basicBlocks()) { + if (block->isRemoved()) + continue; clone.setBasicBlock(block); - foreach (Stmt *s, block->statements) { + foreach (Stmt *s, block->statements()) { s->accept(this); } } @@ -586,7 +588,7 @@ void Move::dump(QTextStream &out, Mode mode) void Jump::dump(QTextStream &out, Mode mode) { Q_UNUSED(mode); - out << "goto " << 'L' << target->index << ';'; + out << "goto " << 'L' << target->index() << ';'; } void CJump::dump(QTextStream &out, Mode mode) @@ -595,9 +597,9 @@ void CJump::dump(QTextStream &out, Mode mode) out << "if ("; cond->dump(out); if (mode == HIR) - out << ") goto " << 'L' << iftrue->index << "; else goto " << 'L' << iffalse->index << ';'; + out << ") goto " << 'L' << iftrue->index() << "; else goto " << 'L' << iffalse->index() << ';'; else - out << ") goto " << 'L' << iftrue->index << ";"; + out << ") goto " << 'L' << iftrue->index() << ";"; } void Ret::dump(QTextStream &out, Mode) @@ -654,15 +656,37 @@ void Module::setFileName(const QString &name) } } +Function::Function(Module *module, Function *outer, const QString &name) + : module(module) + , pool(&module->pool) + , tempCount(0) + , maxNumberOfArguments(0) + , outer(outer) + , insideWithOrCatch(0) + , hasDirectEval(false) + , usesArgumentsObject(false) + , isStrict(false) + , isNamedExpression(false) + , hasTry(false) + , hasWith(false) + , unused(0) + , line(-1) + , column(-1) + , _allBasicBlocks(0) +{ + this->name = newString(name); + _basicBlocks.reserve(8); +} + Function::~Function() { - // destroy the Stmt::Data blocks manually, because memory pool cleanup won't - // call the Stmt destructors. - foreach (IR::BasicBlock *b, basicBlocks) - foreach (IR::Stmt *s, b->statements) - s->destroyData(); + if (_allBasicBlocks) { + qDeleteAll(*_allBasicBlocks); + delete _allBasicBlocks; + } else { + qDeleteAll(_basicBlocks); + } - qDeleteAll(basicBlocks); pool = 0; module = 0; } @@ -676,7 +700,24 @@ const QString *Function::newString(const QString &text) BasicBlock *Function::newBasicBlock(BasicBlock *containingLoop, BasicBlock *catchBlock, BasicBlockInsertMode mode) { BasicBlock *block = new BasicBlock(this, containingLoop, catchBlock); - return mode == InsertBlock ? insertBasicBlock(block) : block; + return mode == InsertBlock ? addBasicBlock(block) : block; +} + +BasicBlock *Function::addBasicBlock(BasicBlock *block) +{ + Q_ASSERT(block->index() < 0); + block->setIndex(_basicBlocks.size()); + _basicBlocks.append(block); + return block; +} + +int Function::liveBasicBlocksCount() const +{ + int count = 0; + foreach (BasicBlock *bb, basicBlocks()) + if (!bb->isRemoved()) + ++count; + return count; } void Function::dump(QTextStream &out, Stmt::Mode mode) @@ -689,7 +730,7 @@ void Function::dump(QTextStream &out, Stmt::Mode mode) out << "\treceive " << *formal << ';' << endl; foreach (const QString *local, locals) out << "\tlocal " << *local << ';' << endl; - foreach (BasicBlock *bb, basicBlocks) + foreach (BasicBlock *bb, basicBlocks()) bb->dump(out, mode); out << '}' << endl; } @@ -708,13 +749,35 @@ int Function::indexOfArgument(const QStringRef &string) const } return -1; } + +void Function::setScheduledBlocks(const QVector<BasicBlock *> &scheduled) +{ + Q_ASSERT(!_allBasicBlocks); + _allBasicBlocks = new QVector<BasicBlock *>(basicBlocks()); + _basicBlocks = scheduled; +} + +void Function::renumberBasicBlocks() +{ + for (int i = 0, ei = basicBlockCount(); i != ei; ++i) + basicBlock(i)->changeIndex(i); +} + +BasicBlock::~BasicBlock() +{ + foreach (Stmt *s, _statements) + s->destroyData(); +} + unsigned BasicBlock::newTemp() { + Q_ASSERT(!isRemoved()); return function->tempCount++; } Temp *BasicBlock::TEMP(unsigned index) { + Q_ASSERT(!isRemoved()); Temp *e = function->New<Temp>(); e->init(Temp::VirtualRegister, index, 0); return e; @@ -722,6 +785,7 @@ Temp *BasicBlock::TEMP(unsigned index) Temp *BasicBlock::ARG(unsigned index, unsigned scope) { + Q_ASSERT(!isRemoved()); Temp *e = function->New<Temp>(); e->init(scope ? Temp::ScopedFormal : Temp::Formal, index, scope); return e; @@ -729,6 +793,7 @@ Temp *BasicBlock::ARG(unsigned index, unsigned scope) Temp *BasicBlock::LOCAL(unsigned index, unsigned scope) { + Q_ASSERT(!isRemoved()); Temp *e = function->New<Temp>(); e->init(scope ? Temp::ScopedLocal : Temp::Local, index, scope); return e; @@ -736,6 +801,7 @@ Temp *BasicBlock::LOCAL(unsigned index, unsigned scope) Expr *BasicBlock::CONST(Type type, double value) { + Q_ASSERT(!isRemoved()); Const *e = function->New<Const>(); if (type == NumberType) { int ival = (int)value; @@ -756,6 +822,7 @@ Expr *BasicBlock::CONST(Type type, double value) Expr *BasicBlock::STRING(const QString *value) { + Q_ASSERT(!isRemoved()); String *e = function->New<String>(); e->init(value); return e; @@ -763,6 +830,7 @@ Expr *BasicBlock::STRING(const QString *value) Expr *BasicBlock::REGEXP(const QString *value, int flags) { + Q_ASSERT(!isRemoved()); RegExp *e = function->New<RegExp>(); e->init(value, flags); return e; @@ -770,6 +838,7 @@ Expr *BasicBlock::REGEXP(const QString *value, int flags) Name *BasicBlock::NAME(const QString &id, quint32 line, quint32 column) { + Q_ASSERT(!isRemoved()); Name *e = function->New<Name>(); e->init(function->newString(id), line, column); return e; @@ -777,6 +846,7 @@ Name *BasicBlock::NAME(const QString &id, quint32 line, quint32 column) Name *BasicBlock::GLOBALNAME(const QString &id, quint32 line, quint32 column) { + Q_ASSERT(!isRemoved()); Name *e = function->New<Name>(); e->initGlobal(function->newString(id), line, column); return e; @@ -785,6 +855,7 @@ Name *BasicBlock::GLOBALNAME(const QString &id, quint32 line, quint32 column) Name *BasicBlock::NAME(Name::Builtin builtin, quint32 line, quint32 column) { + Q_ASSERT(!isRemoved()); Name *e = function->New<Name>(); e->init(builtin, line, column); return e; @@ -792,6 +863,7 @@ Name *BasicBlock::NAME(Name::Builtin builtin, quint32 line, quint32 column) Closure *BasicBlock::CLOSURE(int functionInModule) { + Q_ASSERT(!isRemoved()); Closure *clos = function->New<Closure>(); clos->init(functionInModule, function->module->functions.at(functionInModule)->name); return clos; @@ -799,6 +871,7 @@ Closure *BasicBlock::CLOSURE(int functionInModule) Expr *BasicBlock::CONVERT(Expr *expr, Type type) { + Q_ASSERT(!isRemoved()); Convert *e = function->New<Convert>(); e->init(expr, type); return e; @@ -806,6 +879,7 @@ Expr *BasicBlock::CONVERT(Expr *expr, Type type) Expr *BasicBlock::UNOP(AluOp op, Expr *expr) { + Q_ASSERT(!isRemoved()); Unop *e = function->New<Unop>(); e->init(op, expr); return e; @@ -813,6 +887,7 @@ Expr *BasicBlock::UNOP(AluOp op, Expr *expr) Expr *BasicBlock::BINOP(AluOp op, Expr *left, Expr *right) { + Q_ASSERT(!isRemoved()); Binop *e = function->New<Binop>(); e->init(op, left, right); return e; @@ -820,6 +895,7 @@ Expr *BasicBlock::BINOP(AluOp op, Expr *left, Expr *right) Expr *BasicBlock::CALL(Expr *base, ExprList *args) { + Q_ASSERT(!isRemoved()); Call *e = function->New<Call>(); e->init(base, args); int argc = 0; @@ -831,6 +907,7 @@ Expr *BasicBlock::CALL(Expr *base, ExprList *args) Expr *BasicBlock::NEW(Expr *base, ExprList *args) { + Q_ASSERT(!isRemoved()); New *e = function->New<New>(); e->init(base, args); return e; @@ -838,6 +915,7 @@ Expr *BasicBlock::NEW(Expr *base, ExprList *args) Expr *BasicBlock::SUBSCRIPT(Expr *base, Expr *index) { + Q_ASSERT(!isRemoved()); Subscript *e = function->New<Subscript>(); e->init(base, index); return e; @@ -845,6 +923,7 @@ Expr *BasicBlock::SUBSCRIPT(Expr *base, Expr *index) Expr *BasicBlock::MEMBER(Expr *base, const QString *name, QQmlPropertyData *property, uchar kind, int attachedPropertiesIdOrEnumValue) { + Q_ASSERT(!isRemoved()); Member*e = function->New<Member>(); e->init(base, name, property, kind, attachedPropertiesIdOrEnumValue); return e; @@ -852,6 +931,7 @@ Expr *BasicBlock::MEMBER(Expr *base, const QString *name, QQmlPropertyData *prop Stmt *BasicBlock::EXP(Expr *expr) { + Q_ASSERT(!isRemoved()); if (isTerminated()) return 0; @@ -863,6 +943,7 @@ Stmt *BasicBlock::EXP(Expr *expr) Stmt *BasicBlock::MOVE(Expr *target, Expr *source) { + Q_ASSERT(!isRemoved()); if (isTerminated()) return 0; @@ -874,6 +955,7 @@ Stmt *BasicBlock::MOVE(Expr *target, Expr *source) Stmt *BasicBlock::JUMP(BasicBlock *target) { + Q_ASSERT(!isRemoved()); if (isTerminated()) return 0; @@ -892,6 +974,7 @@ Stmt *BasicBlock::JUMP(BasicBlock *target) Stmt *BasicBlock::CJUMP(Expr *cond, BasicBlock *iftrue, BasicBlock *iffalse) { + Q_ASSERT(!isRemoved()); if (isTerminated()) return 0; @@ -921,6 +1004,7 @@ Stmt *BasicBlock::CJUMP(Expr *cond, BasicBlock *iftrue, BasicBlock *iffalse) Stmt *BasicBlock::RET(Temp *expr) { + Q_ASSERT(!isRemoved()); if (isTerminated()) return 0; @@ -932,11 +1016,11 @@ Stmt *BasicBlock::RET(Temp *expr) void BasicBlock::dump(QTextStream &out, Stmt::Mode mode) { - out << 'L' << index << ':'; + out << 'L' << index() << ':'; if (catchBlock) - out << " (catchBlock L" << catchBlock->index << ")"; + out << " (catchBlock L" << catchBlock->index() << ")"; out << endl; - foreach (Stmt *s, statements) { + foreach (Stmt *s, statements()) { out << '\t'; s->dump(out, mode); @@ -947,11 +1031,62 @@ void BasicBlock::dump(QTextStream &out, Stmt::Mode mode) } } +void BasicBlock::setStatements(const QVector<Stmt *> &newStatements) +{ + Q_ASSERT(!isRemoved()); + Q_ASSERT(newStatements.size() >= _statements.size()); + _statements = newStatements; +} + void BasicBlock::appendStatement(Stmt *statement) { + Q_ASSERT(!isRemoved()); if (nextLocation.isValid()) statement->location = nextLocation; - statements.append(statement); + _statements.append(statement); +} + +void BasicBlock::prependStatement(Stmt *stmt) +{ + Q_ASSERT(!isRemoved()); + _statements.prepend(stmt); +} + +void BasicBlock::insertStatementBefore(Stmt *before, Stmt *newStmt) +{ + int idx = _statements.indexOf(before); + Q_ASSERT(idx >= 0); + _statements.insert(idx, newStmt); +} + +void BasicBlock::insertStatementBefore(int index, Stmt *newStmt) +{ + Q_ASSERT(index >= 0); + _statements.insert(index, newStmt); +} + +void BasicBlock::insertStatementBeforeTerminator(Stmt *stmt) +{ + Q_ASSERT(!isRemoved()); + _statements.insert(_statements.size() - 1, stmt); +} + +void BasicBlock::replaceStatement(int index, Stmt *newStmt) +{ + Q_ASSERT(!isRemoved()); + _statements[index] = newStmt; +} + +void BasicBlock::removeStatement(Stmt *stmt) +{ + Q_ASSERT(!isRemoved()); + _statements.remove(_statements.indexOf(stmt)); +} + +void BasicBlock::removeStatement(int idx) +{ + Q_ASSERT(!isRemoved()); + _statements.remove(idx); } CloneExpr::CloneExpr(BasicBlock *block) |