diff options
author | Ulf Hermann <ulf.hermann@qt.io> | 2017-11-01 15:32:30 +0100 |
---|---|---|
committer | Ulf Hermann <ulf.hermann@qt.io> | 2017-11-08 16:27:30 +0000 |
commit | 4d2763e425828ac35c2a03c0e675b83fa8dad668 (patch) | |
tree | 753ef220cf8fe941cc7117140d64fdb5361c802a | |
parent | ba775d50571f8cb445500f0c91ec35b777fa947e (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.cpp | 27 | ||||
-rw-r--r-- | tests/auto/qml/debugger/qv4debugger/tst_qv4debugger.cpp | 11 |
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); |