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}
This commit is contained in:
adamk 2016-03-07 11:52:12 -08:00 committed by Commit bot
parent d117207a94
commit a8dc2c4781
2 changed files with 80 additions and 115 deletions

View File

@ -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

View File

@ -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,