Index: src/parsing/parser.cc |
diff --git a/src/parsing/parser.cc b/src/parsing/parser.cc |
index 9216b8d959aa05517c58192781275c657bec1be4..40b4decb7203441d32fddcb5ee335824aafae4e4 100644 |
--- a/src/parsing/parser.cc |
+++ b/src/parsing/parser.cc |
@@ -3250,76 +3250,16 @@ 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, |
+ RelocInfo::kNoPosition); |
} 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); |
@@ -3340,6 +3280,71 @@ void Parser::InitializeForEachStatement(ForEachStatement* stmt, |
} |
} |
+void Parser::InitializeForOfStatement(ForOfStatement* for_of, Expression* each, |
+ Expression* iterable, Statement* body, |
+ int iterable_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 = iterable_pos != RelocInfo::kNoPosition |
+ ? iterable_pos |
+ : iterable->position() - 2; |
+ int next_result_pos = iterable_pos != RelocInfo::kNoPosition |
+ ? iterable_pos |
+ : iterable->position() - 1; |
+ |
+ // iterator = iterable[Symbol.iterator]() |
+ assign_iterator = factory()->NewAssignment( |
+ Token::ASSIGN, factory()->NewVariableProxy(iterator), |
+ GetIterator(iterable, factory(), get_iterator_pos), iterable->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, iterable, 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, |
@@ -3744,8 +3749,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(); |
@@ -3843,8 +3847,7 @@ Statement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels, |
// For legacy compat reasons, give for loops similar treatment to |
// if statements in allowing a function declaration for a body |
Statement* body = ParseScopedStatement(NULL, true, CHECK_OK); |
- InitializeForEachStatement(loop, expression, enumerable, body, |
- is_destructuring); |
+ InitializeForEachStatement(loop, expression, enumerable, body); |
Statement* final_loop = loop->IsForOfStatement() |
? FinalizeForOfStatement( |
@@ -5659,45 +5662,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()), |
- 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()); |
- } |
- // 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; |
{ |
@@ -5714,11 +5678,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, spread->expression_position()); |
+ do_block->statements()->Add(loop, zone()); |
} |
} |
// Now, rewind the original array literal to truncate everything from the |