| 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();
|
|
|