| Index: src/pattern-rewriter.cc
|
| diff --git a/src/pattern-rewriter.cc b/src/pattern-rewriter.cc
|
| index 090f85dc9c533ad68fcdb0bff435c7440152194d..e1e3d0b6b95d7b8e5495577df3cdc927c43dcfb7 100644
|
| --- a/src/pattern-rewriter.cc
|
| +++ b/src/pattern-rewriter.cc
|
| @@ -17,19 +17,53 @@ void Parser::PatternRewriter::DeclareAndInitializeVariables(
|
| ZoneList<const AstRawString*>* names, bool* ok) {
|
| PatternRewriter rewriter;
|
|
|
| + rewriter.parser_ = declaration_descriptor->parser;
|
| + rewriter.context_ = BINDING;
|
| rewriter.pattern_ = declaration->pattern;
|
| rewriter.initializer_position_ = declaration->initializer_position;
|
| rewriter.block_ = block;
|
| rewriter.descriptor_ = declaration_descriptor;
|
| rewriter.names_ = names;
|
| rewriter.ok_ = ok;
|
| + rewriter.rhs_ = nullptr;
|
|
|
| rewriter.RecurseIntoSubpattern(rewriter.pattern_, declaration->initializer);
|
| }
|
|
|
|
|
| +Variable* Parser::PatternRewriter::RewriteDestructuringAssignment(
|
| + Parser* parser, Block* block, Expression* pattern, Expression* value,
|
| + Variable* result, bool* ok) {
|
| + PatternRewriter rewriter;
|
| +
|
| + rewriter.parser_ = parser;
|
| + rewriter.context_ = ASSIGNMENT;
|
| + rewriter.pattern_ = pattern;
|
| + rewriter.block_ = block;
|
| + rewriter.descriptor_ = nullptr;
|
| + rewriter.names_ = nullptr;
|
| + rewriter.ok_ = ok;
|
| + rewriter.rhs_ = result;
|
| +
|
| + rewriter.RecurseIntoSubpattern(rewriter.pattern_, value);
|
| + DCHECK_NOT_NULL(rewriter.rhs_);
|
| + return rewriter.rhs_;
|
| +}
|
| +
|
| +
|
| void Parser::PatternRewriter::VisitVariableProxy(VariableProxy* pattern) {
|
| Expression* value = current_value_;
|
| +
|
| + if (context() == ASSIGNMENT) {
|
| + // In an assignment context, simply perform the assignment
|
| + Assignment* assignment = factory()->NewAssignment(
|
| + Token::ASSIGN, pattern, value, pattern->position());
|
| + block_->statements()->Add(
|
| + factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition),
|
| + zone());
|
| + return;
|
| + }
|
| +
|
| descriptor_->scope->RemoveUnresolved(pattern);
|
|
|
| // Declare variable.
|
| @@ -47,7 +81,7 @@ void Parser::PatternRewriter::VisitVariableProxy(VariableProxy* pattern) {
|
| // For let/const declarations in harmony mode, we can also immediately
|
| // pre-resolve the proxy because it resides in the same scope as the
|
| // declaration.
|
| - Parser* parser = descriptor_->parser;
|
| + Parser* parser = parser_;
|
| const AstRawString* name = pattern->raw_name();
|
| VariableProxy* proxy = parser->NewUnresolved(name, descriptor_->mode);
|
| Declaration* declaration = factory()->NewVariableDeclaration(
|
| @@ -213,8 +247,7 @@ void Parser::PatternRewriter::VisitVariableProxy(VariableProxy* pattern) {
|
|
|
|
|
| Variable* Parser::PatternRewriter::CreateTempVar(Expression* value) {
|
| - auto temp = descriptor_->parser->scope_->NewTemporary(
|
| - ast_value_factory()->empty_string());
|
| + auto temp = parser_scope()->NewTemporary(ast_value_factory()->empty_string());
|
| if (value != nullptr) {
|
| auto assignment = factory()->NewAssignment(
|
| Token::ASSIGN, factory()->NewVariableProxy(temp), value,
|
| @@ -230,9 +263,9 @@ Variable* Parser::PatternRewriter::CreateTempVar(Expression* value) {
|
|
|
| void Parser::PatternRewriter::VisitObjectLiteral(ObjectLiteral* pattern) {
|
| auto temp = CreateTempVar(current_value_);
|
| + if (rhs_ == nullptr) rhs_ = temp;
|
|
|
| - block_->statements()->Add(descriptor_->parser->BuildAssertIsCoercible(temp),
|
| - zone());
|
| + block_->statements()->Add(parser_->BuildAssertIsCoercible(temp), zone());
|
|
|
| for (ObjectLiteralProperty* property : *pattern->properties()) {
|
| RecurseIntoSubpattern(
|
| @@ -245,12 +278,18 @@ void Parser::PatternRewriter::VisitObjectLiteral(ObjectLiteral* pattern) {
|
|
|
| void Parser::PatternRewriter::VisitArrayLiteral(ArrayLiteral* node) {
|
| auto temp = CreateTempVar(current_value_);
|
| + if (rhs_ == nullptr) rhs_ = temp;
|
|
|
| - block_->statements()->Add(descriptor_->parser->BuildAssertIsCoercible(temp),
|
| - zone());
|
| + Block* outer_block = block_;
|
|
|
| - auto iterator = CreateTempVar(descriptor_->parser->GetIterator(
|
| - factory()->NewVariableProxy(temp), factory()));
|
| + if (context() == ASSIGNMENT) {
|
| + block_ = factory()->NewBlock(nullptr, 4, false, node->position());
|
| + }
|
| +
|
| + block_->statements()->Add(parser_->BuildAssertIsCoercible(temp), zone());
|
| +
|
| + auto iterator = CreateTempVar(
|
| + parser_->GetIterator(factory()->NewVariableProxy(temp), factory()));
|
| auto done = CreateTempVar(
|
| factory()->NewBooleanLiteral(false, RelocInfo::kNoPosition));
|
| auto result = CreateTempVar();
|
| @@ -269,13 +308,12 @@ void Parser::PatternRewriter::VisitArrayLiteral(ArrayLiteral* node) {
|
| // }
|
| auto next_block =
|
| factory()->NewBlock(nullptr, 2, true, RelocInfo::kNoPosition);
|
| - next_block->statements()->Add(
|
| - factory()->NewExpressionStatement(
|
| - descriptor_->parser->BuildIteratorNextResult(
|
| - factory()->NewVariableProxy(iterator), result,
|
| - RelocInfo::kNoPosition),
|
| - RelocInfo::kNoPosition),
|
| - zone());
|
| + next_block->statements()->Add(factory()->NewExpressionStatement(
|
| + parser_->BuildIteratorNextResult(
|
| + factory()->NewVariableProxy(iterator),
|
| + result, RelocInfo::kNoPosition),
|
| + RelocInfo::kNoPosition),
|
| + zone());
|
|
|
| auto assign_to_done = factory()->NewAssignment(
|
| Token::ASSIGN, factory()->NewVariableProxy(done),
|
| @@ -322,7 +360,7 @@ void Parser::PatternRewriter::VisitArrayLiteral(ArrayLiteral* node) {
|
| empty_exprs,
|
| // Reuse pattern's literal index - it is unused since there is no
|
| // actual literal allocated.
|
| - node->literal_index(), is_strong(descriptor_->parser->language_mode()),
|
| + node->literal_index(), is_strong(parser_->language_mode()),
|
| RelocInfo::kNoPosition));
|
|
|
| auto arguments = new (zone()) ZoneList<Expression*>(2, zone());
|
| @@ -345,6 +383,14 @@ void Parser::PatternRewriter::VisitArrayLiteral(ArrayLiteral* node) {
|
| RecurseIntoSubpattern(spread->expression(),
|
| factory()->NewVariableProxy(array));
|
| }
|
| +
|
| + if (outer_block != block_) {
|
| + DoExpression* work =
|
| + factory()->NewDoExpression(block_, temp, node->position());
|
| + block_ = outer_block;
|
| + block_->statements()->Add(
|
| + factory()->NewExpressionStatement(work, node->position()), zone());
|
| + }
|
| }
|
|
|
|
|
| @@ -353,6 +399,12 @@ void Parser::PatternRewriter::VisitAssignment(Assignment* node) {
|
| // becomes
|
| // temp = <value>;
|
| // <pattern> = temp === undefined ? <init> : temp;
|
| + PatternContext old_context = context();
|
| + if (old_context == INITIALIZER) {
|
| + set_context(ASSIGNMENT);
|
| + } else if (old_context == BINDING) {
|
| + set_context(INITIALIZER);
|
| + }
|
| DCHECK(node->op() == Token::ASSIGN);
|
| auto temp = CreateTempVar(current_value_);
|
| Expression* is_undefined = factory()->NewCompareOperation(
|
| @@ -363,6 +415,20 @@ void Parser::PatternRewriter::VisitAssignment(Assignment* node) {
|
| is_undefined, node->value(), factory()->NewVariableProxy(temp),
|
| RelocInfo::kNoPosition);
|
| RecurseIntoSubpattern(node->target(), value);
|
| + set_context(old_context);
|
| +}
|
| +
|
| +
|
| +// =============== ASSIGNMENT-ONLY =========================
|
| +
|
| +void Parser::PatternRewriter::VisitProperty(v8::internal::Property* pattern) {
|
| + DCHECK(context() == ASSIGNMENT);
|
| + Expression* value = current_value_;
|
| + Assignment* assignment = factory()->NewAssignment(Token::ASSIGN, pattern,
|
| + value, pattern->position());
|
| + block_->statements()->Add(
|
| + factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition),
|
| + zone());
|
| }
|
|
|
|
|
| @@ -403,7 +469,6 @@ NOT_A_PATTERN(IfStatement)
|
| NOT_A_PATTERN(ImportDeclaration)
|
| NOT_A_PATTERN(Literal)
|
| NOT_A_PATTERN(NativeFunctionLiteral)
|
| -NOT_A_PATTERN(Property)
|
| NOT_A_PATTERN(RegExpLiteral)
|
| NOT_A_PATTERN(ReturnStatement)
|
| NOT_A_PATTERN(SloppyBlockFunctionStatement)
|
|
|