Commit a8dc2c47 authored by adamk's avatar adamk Committed by Commit bot

Remove duplicated ForOfStatement init code code from RewriteSpreads

Simply call InitializeForOfStatement (split out from InitializeForEachStatement)
instead, which already has all the necessary logic.

As part of this, trade one bool arg (is_destructuring) for an int
(iterable_pos).

Review URL: https://codereview.chromium.org/1740293002

Cr-Commit-Position: refs/heads/master@{#34561}
parent d117207a
......@@ -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
......
......@@ -938,8 +938,10 @@ class Parser : public ParserBase<ParserTraits> {
// Initialize the components of a for-in / for-of statement.
void InitializeForEachStatement(ForEachStatement* stmt, Expression* each,
Expression* subject, Statement* body,
bool is_destructuring);
Expression* subject, Statement* body);
void InitializeForOfStatement(ForOfStatement* stmt, Expression* each,
Expression* iterable, Statement* body,
int iterable_pos);
Statement* DesugarLexicalBindingsInForStatement(
Scope* inner_scope, VariableMode mode,
ZoneList<const AstRawString*>* names, ForStatement* loop, Statement* init,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment