aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2017-11-01 15:32:30 +0100
committerUlf Hermann <ulf.hermann@qt.io>2017-11-08 16:27:30 +0000
commit4d2763e425828ac35c2a03c0e675b83fa8dad668 (patch)
tree753ef220cf8fe941cc7117140d64fdb5361c802a
parentba775d50571f8cb445500f0c91ec35b777fa947e (diff)
Set Jump locations for loops
We don't need them for if/else anymore as there are not block terminators anymore. Change-Id: I1ac384e7176cc35faf28028cd274c63dfaa96146 Reviewed-by: Lars Knoll <lars.knoll@qt.io>
-rw-r--r--src/qml/compiler/qv4codegen.cpp27
-rw-r--r--tests/auto/qml/debugger/qv4debugger/tst_qv4debugger.cpp11
2 files changed, 32 insertions, 6 deletions
diff --git a/src/qml/compiler/qv4codegen.cpp b/src/qml/compiler/qv4codegen.cpp
index 331132de3b..3cee80e977 100644
--- a/src/qml/compiler/qv4codegen.cpp
+++ b/src/qml/compiler/qv4codegen.cpp
@@ -67,6 +67,27 @@ using namespace QV4;
using namespace QV4::Compiler;
using namespace QQmlJS::AST;
+static inline void setJumpOutLocation(QV4::Moth::BytecodeGenerator *bytecodeGenerator,
+ const Statement *body, const SourceLocation &fallback)
+{
+ switch (body->kind) {
+ // Statements where we might never execute the last line.
+ // Use the fallback.
+ case Statement::Kind_ConditionalExpression:
+ case Statement::Kind_ForEachStatement:
+ case Statement::Kind_ForStatement:
+ case Statement::Kind_IfStatement:
+ case Statement::Kind_LocalForEachStatement:
+ case Statement::Kind_LocalForStatement:
+ case Statement::Kind_WhileStatement:
+ bytecodeGenerator->setLocation(fallback);
+ break;
+ default:
+ bytecodeGenerator->setLocation(body->lastSourceLocation());
+ break;
+ }
+}
+
Codegen::Codegen(QV4::Compiler::JSUnitGenerator *jsUnitGenerator, bool strict)
: _module(0)
, _returnAddress(0)
@@ -2261,6 +2282,7 @@ bool Codegen::visit(DoWhileStatement *ast)
ControlFlowLoop flow(this, &end, &cond);
statement(ast->statement);
+ setJumpOutLocation(bytecodeGenerator, ast->statement, ast->semicolonToken);
cond.link();
@@ -2329,6 +2351,7 @@ bool Codegen::visit(ForEachStatement *ast)
BytecodeGenerator::Label body = bytecodeGenerator->label();
statement(ast->statement);
+ setJumpOutLocation(bytecodeGenerator, ast->statement, ast->forToken);
in.link();
@@ -2367,6 +2390,7 @@ bool Codegen::visit(ForStatement *ast)
body.link();
statement(ast->statement);
+ setJumpOutLocation(bytecodeGenerator, ast->statement, ast->forToken);
step.link();
statement(ast->expression);
@@ -2473,6 +2497,7 @@ bool Codegen::visit(LocalForEachStatement *ast)
Reference it = referenceForName(ast->declaration->name.toString(), true).asLValue();
statement(ast->statement);
+ setJumpOutLocation(bytecodeGenerator, ast->statement, ast->forToken);
in.link();
@@ -2509,6 +2534,7 @@ bool Codegen::visit(LocalForStatement *ast)
body.link();
statement(ast->statement);
+ setJumpOutLocation(bytecodeGenerator, ast->statement, ast->forToken);
step.link();
statement(ast->expression);
@@ -2729,6 +2755,7 @@ bool Codegen::visit(WhileStatement *ast)
start.link();
statement(ast->statement);
+ setJumpOutLocation(bytecodeGenerator, ast->statement, ast->whileToken);
bytecodeGenerator->jump().link(cond);
end.link();
diff --git a/tests/auto/qml/debugger/qv4debugger/tst_qv4debugger.cpp b/tests/auto/qml/debugger/qv4debugger/tst_qv4debugger.cpp
index 5162cb55e2..9da4a63ce6 100644
--- a/tests/auto/qml/debugger/qv4debugger/tst_qv4debugger.cpp
+++ b/tests/auto/qml/debugger/qv4debugger/tst_qv4debugger.cpp
@@ -811,13 +811,13 @@ void tst_qv4debugger::lastLineOfConditional_data()
QTest::newRow("do..while {block}") << "do {\n" << "} while (ret < 10);" << 4 << 7;
QTest::newRow("if true {block}") << "if (true) {\n" << "}"
- << 4 << 7;
+ << 4 << 8;
QTest::newRow("if false {block}") << "if (false) {\n" << "}"
<< 2 << 8;
QTest::newRow("if true else {block}") << "if (true) {\n" << "} else {\n ret += 8;\n}"
- << 4 << 7;
+ << 4 << 10;
QTest::newRow("if false else {block}") << "if (false) {\n" << "} else {\n ret += 8;\n}"
- << 8 << 9;
+ << 8 << 10;
QTest::newRow("for statement") << "for (var i = 0; i < 10; ++i)\n" << "" << 4 << 2;
QTest::newRow("for..in statement") << "for (var i in [0, 1, 2, 3, 4])\n" << "" << 4 << 2;
@@ -826,17 +826,16 @@ void tst_qv4debugger::lastLineOfConditional_data()
// For two nested if statements without blocks, we need to map the jump from the inner to the
// outer one on the outer "if". There is just no better place.
- QTest::newRow("if true statement") << "if (true)\n" << "" << 4 << 2;
+ QTest::newRow("if true statement") << "if (true)\n" << "" << 4 << 8;
QTest::newRow("if false statement") << "if (false)\n" << "" << 2 << 8;
// Also two nested ifs without blocks.
- QTest::newRow("if true else statement") << "if (true)\n" << "else\n ret += 8;" << 4 << 2;
+ QTest::newRow("if true else statement") << "if (true)\n" << "else\n ret += 8;" << 4 << 9;
QTest::newRow("if false else statement") << "if (false)\n" << "else\n ret += 8;" << 8 << 9;
}
void tst_qv4debugger::lastLineOfConditional()
{
- QSKIP("fixme");
QFETCH(QString, head);
QFETCH(QString, tail);
QFETCH(int, breakPoint);