aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/compiler/qv4codegen.cpp
diff options
context:
space:
mode:
authorErik Verbruggen <erik.verbruggen@qt.io>2019-02-25 12:09:07 +0100
committerErik Verbruggen <erik.verbruggen@qt.io>2019-03-01 14:33:36 +0000
commit0b9bef199114232f493131a123a1d4559988bc65 (patch)
tree45b3aaa1f5a71625229bea61965a8010f9602704 /src/qml/compiler/qv4codegen.cpp
parent1ede9c24d08efcb8c2f711db100f3a5cb779452c (diff)
V4: Undo rotation of the do-while loop
Previously the generated code looked like this: Jump loop-body loop-condition: acc = condition JumpFalse loop-end loop-body: ... Jump loop-condition loop end: ... This is a problem for anything that analyzes the bytecode in 1 pass from top to bottom: at the point of the loop-condition the state of the interpreter isn't known yet: that state will only be known after analyzing the loop body. The new generated code does not have that problem: loop-body: ... acc = condition JumpTrue loop-body loop-end: ... Change-Id: I16977e9ce1f9377e7bf4d09afc16136ba0111463 Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
Diffstat (limited to 'src/qml/compiler/qv4codegen.cpp')
-rw-r--r--src/qml/compiler/qv4codegen.cpp24
1 files changed, 14 insertions, 10 deletions
diff --git a/src/qml/compiler/qv4codegen.cpp b/src/qml/compiler/qv4codegen.cpp
index 56ff15a78c..fcd93bb600 100644
--- a/src/qml/compiler/qv4codegen.cpp
+++ b/src/qml/compiler/qv4codegen.cpp
@@ -3246,22 +3246,26 @@ bool Codegen::visit(DoWhileStatement *ast)
BytecodeGenerator::Label end = bytecodeGenerator->newLabel();
ControlFlowLoop flow(this, &end, &cond);
- bytecodeGenerator->jump().link(body);
- cond.link();
- bytecodeGenerator->addLoopStart(cond);
-
- if (!AST::cast<TrueLiteral *>(ast->expression)) {
- TailCallBlocker blockTailCalls(this);
- condition(ast->expression, &body, &end, true);
- }
+ // special case that is not a loop:
+ // do {...} while (false)
+ if (!AST::cast<FalseLiteral *>(ast->expression))
+ bytecodeGenerator->addLoopStart(body);
body.link();
statement(ast->statement);
setJumpOutLocation(bytecodeGenerator, ast->statement, ast->semicolonToken);
- if (!AST::cast<FalseLiteral *>(ast->expression))
- bytecodeGenerator->jump().link(cond);
+ cond.link();
+ if (AST::cast<TrueLiteral *>(ast->expression)) {
+ // do {} while (true) -> just jump back to the loop body, no need to generate a condition
+ bytecodeGenerator->jump().link(body);
+ } else if (AST::cast<FalseLiteral *>(ast->expression)) {
+ // do {} while (false) -> fall through, no need to generate a condition
+ } else {
+ TailCallBlocker blockTailCalls(this);
+ condition(ast->expression, &body, &end, false);
+ }
end.link();