diff options
author | Lars Knoll <lars.knoll@digia.com> | 2012-10-28 20:33:54 +0100 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@digia.com> | 2012-10-31 12:46:23 +0100 |
commit | 6ace5d1a2b3b1dd9ef1e1223db8298f6c20a9e58 (patch) | |
tree | d5db63688fd213ae9a697050d6b49174b370a27c /qv4codegen.cpp | |
parent | 577cbfa2eed1abe677216f3d57b41a8496ceb18b (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.cpp | 34 |
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; } |