aboutsummaryrefslogtreecommitdiffstats
path: root/qv4codegen.cpp
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@digia.com>2012-10-28 20:33:54 +0100
committerSimon Hausmann <simon.hausmann@digia.com>2012-10-31 12:46:23 +0100
commit6ace5d1a2b3b1dd9ef1e1223db8298f6c20a9e58 (patch)
treed5db63688fd213ae9a697050d6b49174b370a27c /qv4codegen.cpp
parent577cbfa2eed1abe677216f3d57b41a8496ceb18b (diff)
Implement the other variant of the 'for in' statement
Change-Id: I90823a97331fd15a8289bab93d7e9c1f34aaa10d Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
Diffstat (limited to 'qv4codegen.cpp')
-rw-r--r--qv4codegen.cpp34
1 files changed, 32 insertions, 2 deletions
diff --git a/qv4codegen.cpp b/qv4codegen.cpp
index 4e9c9cf421..225b43cb3a 100644
--- a/qv4codegen.cpp
+++ b/qv4codegen.cpp
@@ -1663,9 +1663,39 @@ bool Codegen::visit(ExpressionStatement *ast)
return false;
}
-bool Codegen::visit(ForEachStatement *)
+bool Codegen::visit(ForEachStatement *ast)
{
- assert(!"not implemented");
+ IR::BasicBlock *foreachin = _function->newBasicBlock();
+ IR::BasicBlock *foreachbody = _function->newBasicBlock();
+ IR::BasicBlock *foreachend = _function->newBasicBlock();
+
+ enterLoop(ast, foreachend, foreachin);
+
+ int iterator = _block->newTemp();
+ move(_block->TEMP(iterator), *expression(ast->expression));
+ IR::ExprList *args = _function->New<IR::ExprList>();
+ args->init(_block->TEMP(iterator));
+ move(_block->TEMP(iterator), _block->CALL(_block->NAME(IR::Name::builtin_foreach_iterator_object, 0, 0), args));
+
+ _block->JUMP(foreachin);
+
+ _block = foreachbody;
+ int temp = _block->newTemp();
+ move(*expression(ast->initialiser), _block->TEMP(temp));
+ statement(ast->statement);
+ _block->JUMP(foreachin);
+
+ _block = foreachin;
+
+ args = _function->New<IR::ExprList>();
+ args->init(_block->TEMP(iterator));
+ move(_block->TEMP(temp), _block->CALL(_block->NAME(IR::Name::builtin_foreach_next_property_name, 0, 0), args));
+ int null = _block->newTemp();
+ move(_block->TEMP(null), _block->CONST(IR::NullType, 0));
+ cjump(_block->BINOP(IR::OpStrictNotEqual, _block->TEMP(temp), _block->TEMP(null)), foreachbody, foreachend);
+ _block = foreachend;
+
+ leaveLoop();
return false;
}