aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/compiler/qv4jsir.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/qml/compiler/qv4jsir.cpp')
-rw-r--r--src/qml/compiler/qv4jsir.cpp395
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";