Index: src/parser.cc |
diff --git a/src/parser.cc b/src/parser.cc |
index 27f7a8200d49c2ab0a54400ddbccdb438eb9c210..fa24bf703bc6f62a039580db9731c0a6ae131c85 100644 |
--- a/src/parser.cc |
+++ b/src/parser.cc |
@@ -2636,6 +2636,78 @@ bool Parser::CheckInOrOf(ForEachStatement::VisitMode* visit_mode) { |
} |
+void Parser::InitializeForEachStatement(ForEachStatement* stmt, |
+ Expression* each, |
+ Expression* subject, |
+ Statement* body) { |
+ ForOfStatement* for_of = stmt->AsForOfStatement(); |
+ |
+ if (for_of != NULL) { |
+ Factory* heap_factory = isolate()->factory(); |
+ Handle<String> iterator_str = heap_factory->InternalizeOneByteString( |
+ STATIC_ASCII_VECTOR(".iterator")); |
+ Handle<String> result_str = heap_factory->InternalizeOneByteString( |
+ STATIC_ASCII_VECTOR(".result")); |
+ Variable* iterator = |
+ top_scope_->DeclarationScope()->NewTemporary(iterator_str); |
+ Variable* result = top_scope_->DeclarationScope()->NewTemporary(result_str); |
+ |
+ Expression* assign_iterator; |
+ Expression* next_result; |
+ Expression* result_done; |
+ Expression* assign_each; |
+ |
+ // var iterator = iterable; |
+ { |
+ Expression* iterator_proxy = factory()->NewVariableProxy(iterator); |
+ assign_iterator = factory()->NewAssignment( |
+ Token::ASSIGN, iterator_proxy, subject, RelocInfo::kNoPosition); |
+ } |
+ |
+ // var result = iterator.next(); |
+ { |
+ Expression* iterator_proxy = factory()->NewVariableProxy(iterator); |
+ Expression* next_literal = |
+ factory()->NewLiteral(heap_factory->next_string()); |
+ Expression* next_property = factory()->NewProperty( |
+ iterator_proxy, next_literal, RelocInfo::kNoPosition); |
+ ZoneList<Expression*>* next_arguments = |
+ new(zone()) ZoneList<Expression*>(0, zone()); |
+ Expression* next_call = factory()->NewCall( |
+ next_property, next_arguments, RelocInfo::kNoPosition); |
+ Expression* result_proxy = factory()->NewVariableProxy(result); |
+ next_result = factory()->NewAssignment( |
+ Token::ASSIGN, result_proxy, next_call, RelocInfo::kNoPosition); |
+ } |
+ |
+ // result.done |
+ { |
+ Expression* done_literal = |
+ factory()->NewLiteral(heap_factory->done_string()); |
+ Expression* result_proxy = factory()->NewVariableProxy(result); |
+ result_done = factory()->NewProperty( |
+ result_proxy, done_literal, RelocInfo::kNoPosition); |
+ } |
+ |
+ // each = result.value |
+ { |
+ Expression* value_literal = |
+ factory()->NewLiteral(heap_factory->value_string()); |
+ Expression* result_proxy = factory()->NewVariableProxy(result); |
+ Expression* result_value = factory()->NewProperty( |
+ result_proxy, value_literal, RelocInfo::kNoPosition); |
+ assign_each = factory()->NewAssignment( |
+ Token::ASSIGN, each, result_value, RelocInfo::kNoPosition); |
+ } |
+ |
+ for_of->Initialize(each, subject, body, |
+ assign_iterator, next_result, result_done, assign_each); |
+ } else { |
+ stmt->Initialize(each, subject, body); |
+ } |
+} |
+ |
+ |
Statement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) { |
// ForStatement :: |
// 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement |
@@ -2670,7 +2742,7 @@ Statement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) { |
VariableProxy* each = |
top_scope_->NewUnresolved(factory(), name, interface); |
Statement* body = ParseStatement(NULL, CHECK_OK); |
- loop->Initialize(each, enumerable, body); |
+ InitializeForEachStatement(loop, each, enumerable, body); |
Block* result = factory()->NewBlock(NULL, 2, false); |
result->AddStatement(variable_statement, zone()); |
result->AddStatement(loop, zone()); |
@@ -2734,7 +2806,7 @@ Statement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) { |
body_block->AddStatement(variable_statement, zone()); |
body_block->AddStatement(assignment_statement, zone()); |
body_block->AddStatement(body, zone()); |
- loop->Initialize(temp_proxy, enumerable, body_block); |
+ InitializeForEachStatement(loop, temp_proxy, enumerable, body_block); |
top_scope_ = saved_scope; |
for_scope->set_end_position(scanner().location().end_pos); |
for_scope = for_scope->FinalizeBlockScope(); |
@@ -2766,7 +2838,7 @@ Statement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) { |
Expect(Token::RPAREN, CHECK_OK); |
Statement* body = ParseStatement(NULL, CHECK_OK); |
- loop->Initialize(expression, enumerable, body); |
+ InitializeForEachStatement(loop, expression, enumerable, body); |
top_scope_ = saved_scope; |
for_scope->set_end_position(scanner().location().end_pos); |
for_scope = for_scope->FinalizeBlockScope(); |