summaryrefslogtreecommitdiff
path: root/src/qml/compiler/qv4codegen.cpp
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2018-05-04 09:06:39 +0200
committerLars Knoll <lars.knoll@qt.io>2018-05-04 18:12:57 +0000
commit798b8d6368dcbcd9b797dad54d87ca0880ad6fb4 (patch)
tree206dfdead7a6044fbc9b59a4e6c9a0498a38b45a /src/qml/compiler/qv4codegen.cpp
parentd2e7e6ab7fb395e2094295c289a6528ee17f0f0a (diff)
downloadqtdeclarative-798b8d6368dcbcd9b797dad54d87ca0880ad6fb4.tar.gz
Unify code paths for the two Foreach variants
They are mostly the same except for initialization. Change-Id: Idd1c0af1fc4fa3e478aeba7a7d45617949a2f239 Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src/qml/compiler/qv4codegen.cpp')
-rw-r--r--src/qml/compiler/qv4codegen.cpp98
1 files changed, 39 insertions, 59 deletions
diff --git a/src/qml/compiler/qv4codegen.cpp b/src/qml/compiler/qv4codegen.cpp
index b0e48bf46d..3e31693593 100644
--- a/src/qml/compiler/qv4codegen.cpp
+++ b/src/qml/compiler/qv4codegen.cpp
@@ -2587,8 +2587,7 @@ bool Codegen::visit(ForEachStatement *ast)
RegisterScope scope(this);
- Reference nextIterObj = Reference::fromStackSlot(this);
- Reference iterObj = Reference::fromStackSlot(this);
+ Reference iterator = Reference::fromStackSlot(this);
Reference expr = expression(ast->expression);
if (hasError)
return true;
@@ -2596,10 +2595,44 @@ bool Codegen::visit(ForEachStatement *ast)
expr.loadInAccumulator();
Instruction::ForeachIteratorObject iteratorObjInstr;
bytecodeGenerator->addInstruction(iteratorObjInstr);
- iterObj.storeConsumeAccumulator();
+ iterator.storeConsumeAccumulator();
Reference lhs = expression(ast->initialiser).asLValue();
+ foreachBody(lhs, ast->statement, ast->forToken, iterator);
+ return false;
+}
+
+bool Codegen::visit(LocalForEachStatement *ast)
+{
+ if (hasError)
+ return true;
+
+ RegisterScope scope(this);
+
+ Reference iterator = Reference::fromStackSlot(this);
+ Reference expr = expression(ast->expression);
+ if (hasError)
+ return true;
+
+ variableDeclaration(ast->declaration);
+
+ expr.loadInAccumulator();
+ Instruction::ForeachIteratorObject iteratorObjInstr;
+ bytecodeGenerator->addInstruction(iteratorObjInstr);
+ iterator.storeConsumeAccumulator();
+
+ Reference lhs = referenceForName(ast->declaration->bindingIdentifier, true).asLValue();
+ foreachBody(lhs, ast->statement, ast->forToken, iterator);
+
+ return false;
+}
+
+void Codegen::foreachBody(const Reference &lhs, Statement *statements, const SourceLocation &forToken, const Reference &iterator)
+{
+ RegisterScope scope(this);
+ Reference nextIterObj = Reference::fromStackSlot(this);
+
BytecodeGenerator::Label in = bytecodeGenerator->newLabel();
BytecodeGenerator::Label end = bytecodeGenerator->newLabel();
@@ -2612,12 +2645,12 @@ bool Codegen::visit(ForEachStatement *ast)
Reference::fromMember(nextIterObj, QStringLiteral("value")).loadInAccumulator();
lhs.storeConsumeAccumulator();
- statement(ast->statement);
- setJumpOutLocation(bytecodeGenerator, ast->statement, ast->forToken);
+ statement(statements);
+ setJumpOutLocation(bytecodeGenerator, statements, forToken);
in.link();
- Reference next = Reference::fromMember(iterObj, QStringLiteral("next"));
+ Reference next = Reference::fromMember(iterator, QStringLiteral("next"));
next.loadInAccumulator();
next = next.asLValue();
Codegen::Arguments args{0, 0};
@@ -2628,8 +2661,6 @@ bool Codegen::visit(ForEachStatement *ast)
bytecodeGenerator->jumpFalse().link(body);
end.link();
-
- return false;
}
bool Codegen::visit(ForStatement *ast)
@@ -2730,57 +2761,6 @@ bool Codegen::visit(LabelledStatement *ast)
return false;
}
-bool Codegen::visit(LocalForEachStatement *ast)
-{
- if (hasError)
- return true;
-
- RegisterScope scope(this);
-
- Reference nextIterObj = Reference::fromStackSlot(this);
- Reference iterObj = Reference::fromStackSlot(this);
- Reference expr = expression(ast->expression);
- if (hasError)
- return true;
-
- variableDeclaration(ast->declaration);
-
- expr.loadInAccumulator();
- Instruction::ForeachIteratorObject iteratorObjInstr;
- bytecodeGenerator->addInstruction(iteratorObjInstr);
- iterObj.storeConsumeAccumulator();
-
- BytecodeGenerator::Label in = bytecodeGenerator->newLabel();
- BytecodeGenerator::Label end = bytecodeGenerator->newLabel();
-
- bytecodeGenerator->jump().link(in);
- ControlFlowLoop flow(this, &end, &in);
-
- BytecodeGenerator::Label body = bytecodeGenerator->label();
-
- Reference it = referenceForName(ast->declaration->bindingIdentifier, true).asLValue();
-
- nextIterObj.loadInAccumulator();
- it.storeConsumeAccumulator();
-
- statement(ast->statement);
- setJumpOutLocation(bytecodeGenerator, ast->statement, ast->forToken);
-
- in.link();
-
- iterObj.loadInAccumulator();
- Instruction::ForeachNextPropertyName nextPropInstr;
- bytecodeGenerator->addInstruction(nextPropInstr);
- nextIterObj.storeConsumeAccumulator();
-
- Reference::fromConst(this, QV4::Encode::null()).loadInAccumulator();
- bytecodeGenerator->jumpStrictNotEqual(nextIterObj.stackSlot(), body);
-
- end.link();
-
- return false;
-}
-
bool Codegen::visit(LocalForStatement *ast)
{
if (hasError)