diff options
author | Lars Knoll <lars.knoll@qt.io> | 2018-05-04 09:06:39 +0200 |
---|---|---|
committer | Lars Knoll <lars.knoll@qt.io> | 2018-05-04 18:12:57 +0000 |
commit | 798b8d6368dcbcd9b797dad54d87ca0880ad6fb4 (patch) | |
tree | 206dfdead7a6044fbc9b59a4e6c9a0498a38b45a /src/qml/compiler/qv4codegen.cpp | |
parent | d2e7e6ab7fb395e2094295c289a6528ee17f0f0a (diff) | |
download | qtdeclarative-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.cpp | 98 |
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) |