Chromium Code Reviews| Index: src/parsing/parser.cc |
| diff --git a/src/parsing/parser.cc b/src/parsing/parser.cc |
| index 36c966110b2f432202993592a552d3c46bc3e0fb..fdb25e2eeef1468f3f43e6e9c9a4b00b6b82b6bc 100644 |
| --- a/src/parsing/parser.cc |
| +++ b/src/parsing/parser.cc |
| @@ -3257,76 +3257,15 @@ Expression* Parser::BuildIteratorNextResult(Expression* iterator, |
| throw_call, pos); |
| } |
| - |
| void Parser::InitializeForEachStatement(ForEachStatement* stmt, |
| Expression* each, Expression* subject, |
| - Statement* body, |
| - bool is_destructuring) { |
| - DCHECK(!is_destructuring || allow_harmony_destructuring_assignment()); |
| + Statement* body) { |
| ForOfStatement* for_of = stmt->AsForOfStatement(); |
| - |
| if (for_of != NULL) { |
| - Variable* iterator = scope_->NewTemporary( |
| - ast_value_factory()->dot_iterator_string()); |
| - Variable* result = scope_->NewTemporary( |
| - ast_value_factory()->dot_result_string()); |
| - |
| - Expression* assign_iterator; |
| - Expression* next_result; |
| - Expression* result_done; |
| - Expression* assign_each; |
| - |
| - // iterator = subject[Symbol.iterator]() |
| - // Hackily disambiguate o from o.next and o [Symbol.iterator](). |
| - // TODO(verwaest): Come up with a better solution. |
| - assign_iterator = factory()->NewAssignment( |
| - Token::ASSIGN, factory()->NewVariableProxy(iterator), |
| - GetIterator(subject, factory(), subject->position() - 2), |
| - subject->position()); |
| - |
| - // !%_IsJSReceiver(result = iterator.next()) && |
| - // %ThrowIteratorResultNotAnObject(result) |
| - { |
| - // result = iterator.next() |
| - Expression* iterator_proxy = factory()->NewVariableProxy(iterator); |
| - // Hackily disambiguate o from o.next and o [Symbol.iterator](). |
| - // TODO(verwaest): Come up with a better solution. |
| - next_result = BuildIteratorNextResult(iterator_proxy, result, |
| - subject->position() - 1); |
| - } |
| - |
| - // result.done |
| - { |
| - Expression* done_literal = factory()->NewStringLiteral( |
| - ast_value_factory()->done_string(), RelocInfo::kNoPosition); |
| - Expression* result_proxy = factory()->NewVariableProxy(result); |
| - result_done = factory()->NewProperty( |
| - result_proxy, done_literal, RelocInfo::kNoPosition); |
| - } |
| - |
| - // each = result.value |
| - { |
| - Expression* value_literal = factory()->NewStringLiteral( |
| - ast_value_factory()->value_string(), RelocInfo::kNoPosition); |
| - 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); |
| - if (is_destructuring) { |
| - assign_each = PatternRewriter::RewriteDestructuringAssignment( |
| - this, assign_each->AsAssignment(), scope_); |
| - } |
| - } |
| - |
| - for_of->Initialize(each, subject, body, |
| - iterator, |
| - assign_iterator, |
| - next_result, |
| - result_done, |
| - assign_each); |
| + InitializeForOfStatement(for_of, each, subject, body, true); |
| } else { |
| - if (is_destructuring) { |
| + if (each->IsArrayLiteral() || each->IsObjectLiteral()) { |
| + DCHECK(allow_harmony_destructuring_assignment()); |
| Variable* temp = |
| scope_->NewTemporary(ast_value_factory()->empty_string()); |
| VariableProxy* temp_proxy = factory()->NewVariableProxy(temp); |
| @@ -3347,6 +3286,67 @@ void Parser::InitializeForEachStatement(ForEachStatement* stmt, |
| } |
| } |
| +void Parser::InitializeForOfStatement(ForOfStatement* for_of, Expression* each, |
| + Expression* subject, Statement* body, |
| + bool use_position_hack) { |
|
nickie
2016/03/04 14:15:13
As a fix, I suggest that you replace "bool use_pos
|
| + Variable* iterator = |
| + scope_->NewTemporary(ast_value_factory()->dot_iterator_string()); |
| + Variable* result = |
| + scope_->NewTemporary(ast_value_factory()->dot_result_string()); |
| + |
| + Expression* assign_iterator; |
| + Expression* next_result; |
| + Expression* result_done; |
| + Expression* assign_each; |
| + |
| + // Hackily disambiguate o from o.next and o [Symbol.iterator](). |
| + // TODO(verwaest): Come up with a better solution. |
| + int get_iterator_pos = subject->position() - (use_position_hack * 2); |
| + int next_result_pos = subject->position() - (use_position_hack * 1); |
|
nickie
2016/03/04 14:15:13
These two would become:
int get_iterator_pos =
|
| + |
| + // iterator = subject[Symbol.iterator]() |
| + assign_iterator = factory()->NewAssignment( |
| + Token::ASSIGN, factory()->NewVariableProxy(iterator), |
| + GetIterator(subject, factory(), get_iterator_pos), subject->position()); |
| + |
| + // !%_IsJSReceiver(result = iterator.next()) && |
| + // %ThrowIteratorResultNotAnObject(result) |
| + { |
| + // result = iterator.next() |
| + Expression* iterator_proxy = factory()->NewVariableProxy(iterator); |
| + next_result = |
| + BuildIteratorNextResult(iterator_proxy, result, next_result_pos); |
| + } |
| + |
| + // result.done |
| + { |
| + Expression* done_literal = factory()->NewStringLiteral( |
| + ast_value_factory()->done_string(), RelocInfo::kNoPosition); |
| + Expression* result_proxy = factory()->NewVariableProxy(result); |
| + result_done = factory()->NewProperty(result_proxy, done_literal, |
| + RelocInfo::kNoPosition); |
| + } |
| + |
| + // each = result.value |
| + { |
| + Expression* value_literal = factory()->NewStringLiteral( |
| + ast_value_factory()->value_string(), RelocInfo::kNoPosition); |
| + 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); |
| + if (each->IsArrayLiteral() || each->IsObjectLiteral()) { |
| + DCHECK(allow_harmony_destructuring_assignment()); |
| + assign_each = PatternRewriter::RewriteDestructuringAssignment( |
| + this, assign_each->AsAssignment(), scope_); |
| + } |
| + } |
| + |
| + for_of->Initialize(each, subject, body, iterator, assign_iterator, |
| + next_result, result_done, assign_each); |
| +} |
| + |
| Statement* Parser::DesugarLexicalBindingsInForStatement( |
| Scope* inner_scope, VariableMode mode, ZoneList<const AstRawString*>* names, |
| ForStatement* loop, Statement* init, Expression* cond, Statement* next, |
| @@ -3729,8 +3729,7 @@ Statement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels, |
| body_block->statements()->Add(body, zone()); |
| VariableProxy* temp_proxy = |
| factory()->NewVariableProxy(temp, each_beg_pos, each_end_pos); |
| - InitializeForEachStatement(loop, temp_proxy, enumerable, body_block, |
| - false); |
| + InitializeForEachStatement(loop, temp_proxy, enumerable, body_block); |
| } |
| body_scope->set_end_position(scanner()->location().end_pos); |
| body_scope = body_scope->FinalizeBlockScope(); |
| @@ -3838,8 +3837,7 @@ Statement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels, |
| factory()->NewBlock(NULL, 1, false, RelocInfo::kNoPosition); |
| Statement* body = ParseSubStatement(NULL, CHECK_OK); |
| block->statements()->Add(body, zone()); |
| - InitializeForEachStatement(loop, expression, enumerable, block, |
| - is_destructuring); |
| + InitializeForEachStatement(loop, expression, enumerable, block); |
| body_scope->set_end_position(scanner()->location().end_pos); |
| body_scope = body_scope->FinalizeBlockScope(); |
| block->set_scope(body_scope); |
| @@ -5667,45 +5665,6 @@ Expression* Parser::RewriteSpreads(ArrayLiteral* lit) { |
| Variable* each = |
| scope_->NewTemporary(ast_value_factory()->dot_for_string()); |
| Expression* subject = spread->expression(); |
| - Variable* iterator = |
| - scope_->NewTemporary(ast_value_factory()->dot_iterator_string()); |
| - Variable* element = |
| - scope_->NewTemporary(ast_value_factory()->dot_result_string()); |
| - // iterator = subject[Symbol.iterator]() |
| - Expression* assign_iterator = factory()->NewAssignment( |
| - Token::ASSIGN, factory()->NewVariableProxy(iterator), |
| - GetIterator(subject, factory(), spread->expression_position()), |
|
nickie
2016/03/04 14:15:13
There was another tricky point but it was a bit hi
|
| - subject->position()); |
| - // !%_IsJSReceiver(element = iterator.next()) && |
| - // %ThrowIteratorResultNotAnObject(element) |
| - Expression* next_element; |
| - { |
| - // element = iterator.next() |
| - Expression* iterator_proxy = factory()->NewVariableProxy(iterator); |
| - next_element = BuildIteratorNextResult(iterator_proxy, element, |
| - spread->expression_position()); |
|
nickie
2016/03/04 14:15:13
Here too...
|
| - } |
| - // element.done |
| - Expression* element_done; |
| - { |
| - Expression* done_literal = factory()->NewStringLiteral( |
| - ast_value_factory()->done_string(), RelocInfo::kNoPosition); |
| - Expression* element_proxy = factory()->NewVariableProxy(element); |
| - element_done = factory()->NewProperty(element_proxy, done_literal, |
| - RelocInfo::kNoPosition); |
| - } |
| - // each = element.value |
| - Expression* assign_each; |
| - { |
| - Expression* value_literal = factory()->NewStringLiteral( |
| - ast_value_factory()->value_string(), RelocInfo::kNoPosition); |
| - Expression* element_proxy = factory()->NewVariableProxy(element); |
| - Expression* element_value = factory()->NewProperty( |
| - element_proxy, value_literal, RelocInfo::kNoPosition); |
| - assign_each = factory()->NewAssignment( |
| - Token::ASSIGN, factory()->NewVariableProxy(each), element_value, |
| - RelocInfo::kNoPosition); |
| - } |
| // %AppendElement($R, each) |
| Statement* append_body; |
| { |
| @@ -5722,11 +5681,10 @@ Expression* Parser::RewriteSpreads(ArrayLiteral* lit) { |
| // for (each of spread) %AppendElement($R, each) |
| ForEachStatement* loop = factory()->NewForEachStatement( |
| ForEachStatement::ITERATE, nullptr, RelocInfo::kNoPosition); |
| - ForOfStatement* for_of = loop->AsForOfStatement(); |
| - for_of->Initialize(factory()->NewVariableProxy(each), subject, |
| - append_body, iterator, assign_iterator, next_element, |
| - element_done, assign_each); |
| - do_block->statements()->Add(for_of, zone()); |
| + InitializeForOfStatement(loop->AsForOfStatement(), |
| + factory()->NewVariableProxy(each), subject, |
| + append_body); |
| + do_block->statements()->Add(loop, zone()); |
| } |
| } |
| // Now, rewind the original array literal to truncate everything from the |