diff options
Diffstat (limited to 'src/qml/compiler/qv4jsir.cpp')
-rw-r--r-- | src/qml/compiler/qv4jsir.cpp | 395 |
1 files changed, 40 insertions, 355 deletions
diff --git a/src/qml/compiler/qv4jsir.cpp b/src/qml/compiler/qv4jsir.cpp index 685825e8ea..b28db59190 100644 --- a/src/qml/compiler/qv4jsir.cpp +++ b/src/qml/compiler/qv4jsir.cpp @@ -1,31 +1,37 @@ /**************************************************************************** ** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtQml module of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:LGPL21$ +** $QT_BEGIN_LICENSE:LGPL$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. ** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. ** ** $QT_END_LICENSE$ ** @@ -164,12 +170,12 @@ struct RemoveSharedExpressions: IR::StmtVisitor, IR::ExprVisitor subexpressions.clear(); subexpressions.reserve(function->basicBlockCount() * 8); - foreach (BasicBlock *block, function->basicBlocks()) { + for (BasicBlock *block : function->basicBlocks()) { if (block->isRemoved()) continue; clone.setBasicBlock(block); - foreach (Stmt *s, block->statements()) { + for (Stmt *s : block->statements()) { s->accept(this); } } @@ -451,7 +457,7 @@ void Function::removeBasicBlock(BasicBlock *block) int Function::liveBasicBlocksCount() const { int count = 0; - foreach (BasicBlock *bb, basicBlocks()) + for (BasicBlock *bb : basicBlocks()) if (!bb->isRemoved()) ++count; return count; @@ -505,344 +511,23 @@ void Function::setStatementCount(int cnt) _statementCount = cnt; } -BasicBlock::~BasicBlock() -{ - foreach (Stmt *s, _statements) { - Phi *p = s->asPhi(); - if (p) - p->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); - return e; -} - -ArgLocal *BasicBlock::ARG(unsigned index, unsigned scope) -{ - Q_ASSERT(!isRemoved()); - ArgLocal *e = function->New<ArgLocal>(); - e->init(scope ? ArgLocal::ScopedFormal : ArgLocal::Formal, index, scope); - return e; -} - -ArgLocal *BasicBlock::LOCAL(unsigned index, unsigned scope) -{ - Q_ASSERT(!isRemoved()); - ArgLocal *e = function->New<ArgLocal>(); - e->init(scope ? ArgLocal::ScopedLocal : ArgLocal::Local, index, scope); - return e; -} - -Expr *BasicBlock::CONST(Type type, double value) -{ - Q_ASSERT(!isRemoved()); - Const *e = function->New<Const>(); - if (type == NumberType) { - int ival = (int)value; - // +0 != -0, so we need to convert to double when negating 0 - if (ival == value && !(value == 0 && isNegative(value))) - type = SInt32Type; - else - type = DoubleType; - } else if (type == NullType) { - value = 0; - } else if (type == UndefinedType) { - value = qSNaN(); - } - - e->init(type, value); - return e; -} - -Expr *BasicBlock::STRING(const QString *value) -{ - Q_ASSERT(!isRemoved()); - String *e = function->New<String>(); - e->init(value); - return e; -} - -Expr *BasicBlock::REGEXP(const QString *value, int flags) -{ - Q_ASSERT(!isRemoved()); - RegExp *e = function->New<RegExp>(); - e->init(value, flags); - return e; -} - -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; -} - -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; -} - - -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; -} - -Closure *BasicBlock::CLOSURE(int functionInModule) -{ - Q_ASSERT(!isRemoved()); - Closure *clos = function->New<Closure>(); - clos->init(functionInModule, function->module->functions.at(functionInModule)->name); - return clos; -} - -Expr *BasicBlock::CONVERT(Expr *expr, Type type) -{ - Q_ASSERT(!isRemoved()); - Convert *e = function->New<Convert>(); - e->init(expr, type); - return e; -} - -Expr *BasicBlock::UNOP(AluOp op, Expr *expr) -{ - Q_ASSERT(!isRemoved()); - Unop *e = function->New<Unop>(); - e->init(op, expr); - return e; -} - -Expr *BasicBlock::BINOP(AluOp op, Expr *left, Expr *right) -{ - Q_ASSERT(!isRemoved()); - Binop *e = function->New<Binop>(); - e->init(op, left, right); - return e; -} - -Expr *BasicBlock::CALL(Expr *base, ExprList *args) -{ - Q_ASSERT(!isRemoved()); - Call *e = function->New<Call>(); - e->init(base, args); - int argc = 0; - for (ExprList *it = args; it; it = it->next) - ++argc; - function->maxNumberOfArguments = qMax(function->maxNumberOfArguments, argc); - return e; -} - -Expr *BasicBlock::NEW(Expr *base, ExprList *args) -{ - Q_ASSERT(!isRemoved()); - New *e = function->New<New>(); - e->init(base, args); - return e; -} - -Expr *BasicBlock::SUBSCRIPT(Expr *base, Expr *index) -{ - Q_ASSERT(!isRemoved()); - Subscript *e = function->New<Subscript>(); - e->init(base, index); - return e; -} - -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; -} - -Stmt *BasicBlock::EXP(Expr *expr) -{ - Q_ASSERT(!isRemoved()); - if (isTerminated()) - return 0; - - Exp *s = function->NewStmt<Exp>(); - s->init(expr); - appendStatement(s); - return s; -} - -Stmt *BasicBlock::MOVE(Expr *target, Expr *source) -{ - Q_ASSERT(!isRemoved()); - if (isTerminated()) - return 0; - - Move *s = function->NewStmt<Move>(); - s->init(target, source); - appendStatement(s); - return s; -} - -Stmt *BasicBlock::JUMP(BasicBlock *target) -{ - Q_ASSERT(!isRemoved()); - if (isTerminated()) - return 0; - - Jump *s = function->NewStmt<Jump>(); - s->init(target); - appendStatement(s); - - Q_ASSERT(! out.contains(target)); - out.append(target); - - Q_ASSERT(! target->in.contains(this)); - target->in.append(this); - - return s; -} - -Stmt *BasicBlock::CJUMP(Expr *cond, BasicBlock *iftrue, BasicBlock *iffalse) -{ - Q_ASSERT(!isRemoved()); - if (isTerminated()) - return 0; - - if (iftrue == iffalse) { - MOVE(TEMP(newTemp()), cond); - return JUMP(iftrue); - } - - CJump *s = function->NewStmt<CJump>(); - s->init(cond, iftrue, iffalse, this); - appendStatement(s); - - Q_ASSERT(! out.contains(iftrue)); - out.append(iftrue); - - Q_ASSERT(! iftrue->in.contains(this)); - iftrue->in.append(this); - - Q_ASSERT(! out.contains(iffalse)); - out.append(iffalse); - - Q_ASSERT(! iffalse->in.contains(this)); - iffalse->in.append(this); - - return s; -} - -Stmt *BasicBlock::RET(Expr *expr) -{ - Q_ASSERT(!isRemoved()); - if (isTerminated()) - return 0; - - Ret *s = function->NewStmt<Ret>(); - s->init(expr); - appendStatement(s); - return s; -} - void BasicBlock::setStatements(const QVector<Stmt *> &newStatements) { Q_ASSERT(!isRemoved()); Q_ASSERT(newStatements.size() >= _statements.size()); - // FIXME: this gets quite inefficient for large basic-blocks, so this function/case should be re-worked. - foreach (Stmt *s, _statements) { - Phi *p = s->asPhi(); - if (!p) - continue; - - if (!newStatements.contains(p)) - p->destroyData(); + for (Stmt *s : qAsConst(_statements)) { + if (Phi *p = s->asPhi()) { + if (!newStatements.contains(p)) { + // phi-node was not copied over, so: + p->destroyData(); + } + } else { + break; + } } _statements = newStatements; } -void BasicBlock::appendStatement(Stmt *statement) -{ - Q_ASSERT(!isRemoved()); - if (nextLocation.startLine) - statement->location = nextLocation; - _statements.append(statement); -} - -void BasicBlock::prependStatement(Stmt *stmt) -{ - Q_ASSERT(!isRemoved()); - _statements.prepend(stmt); -} - -void BasicBlock::prependStatements(const QVector<Stmt *> &stmts) -{ - Q_ASSERT(!isRemoved()); - QVector<Stmt *> newStmts = stmts; - newStmts += _statements; - _statements = newStmts; -} - -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()); - Phi *p = _statements[index]->asPhi(); - if (p) - p->destroyData(); - _statements[index] = newStmt; -} - -void BasicBlock::removeStatement(Stmt *stmt) -{ - Q_ASSERT(!isRemoved()); - Phi *p = stmt->asPhi(); - if (p) - p->destroyData(); - _statements.remove(_statements.indexOf(stmt)); -} - -void BasicBlock::removeStatement(int idx) -{ - Q_ASSERT(!isRemoved()); - Phi *p = _statements[idx]->asPhi(); - if (p) - p->destroyData(); - _statements.remove(idx); -} - CloneExpr::CloneExpr(BasicBlock *block) : block(block), cloned(0) { @@ -978,11 +663,11 @@ void IRPrinter::print(Function *f) *out << ')' << endl << '{' << endl; - foreach (const QString *local, f->locals) + for (const QString *local : qAsConst(f->locals)) *out << " local var " << *local << endl; bool needsSeperator = !f->locals.isEmpty(); - foreach (BasicBlock *bb, f->basicBlocks()) { + for (BasicBlock *bb : f->basicBlocks()) { if (bb->isRemoved()) continue; @@ -1000,7 +685,7 @@ void IRPrinter::print(BasicBlock *bb) std::swap(currentBB, bb); printBlockStart(); - foreach (Stmt *s, currentBB->statements()) { + for (Stmt *s : currentBB->statements()) { if (!s) continue; @@ -1078,13 +763,13 @@ void IRPrinter::visitPhi(Phi *s) s->targetTemp->accept(this); *out << " = phi "; - for (int i = 0, ei = s->d->incoming.size(); i < ei; ++i) { + for (int i = 0, ei = s->incoming.size(); i < ei; ++i) { if (i > 0) *out << ", "; if (currentBB) *out << 'L' << currentBB->in.at(i)->index() << ": "; - if (s->d->incoming[i]) - s->d->incoming[i]->accept(this); + if (s->incoming[i]) + s->incoming[i]->accept(this); } } @@ -1139,7 +824,7 @@ void IRPrinter::visitRegExp(RegExp *e) void IRPrinter::visitName(Name *e) { if (e->id) { - if (*e->id != QStringLiteral("this")) + if (*e->id != QLatin1String("this")) *out << '.'; *out << *e->id; } else { @@ -1315,7 +1000,7 @@ void IRPrinter::printBlockStart() *out << str; *out << "; predecessors:"; - foreach (BasicBlock *in, currentBB->in) + for (BasicBlock *in : qAsConst(currentBB->in)) *out << " L" << in->index(); if (currentBB->in.isEmpty()) *out << " none"; |