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