| Index: src/pattern-rewriter.cc | 
| diff --git a/src/pattern-rewriter.cc b/src/pattern-rewriter.cc | 
| deleted file mode 100644 | 
| index e5231155687b7b2826881537777938a85078e721..0000000000000000000000000000000000000000 | 
| --- a/src/pattern-rewriter.cc | 
| +++ /dev/null | 
| @@ -1,435 +0,0 @@ | 
| -// Copyright 2015 the V8 project authors. All rights reserved. | 
| -// Use of this source code is governed by a BSD-style license that can be | 
| -// found in the LICENSE file. | 
| - | 
| -#include "src/ast.h" | 
| -#include "src/messages.h" | 
| -#include "src/parameter-initializer-rewriter.h" | 
| -#include "src/parser.h" | 
| - | 
| -namespace v8 { | 
| - | 
| -namespace internal { | 
| - | 
| - | 
| -void Parser::PatternRewriter::DeclareAndInitializeVariables( | 
| -    Block* block, const DeclarationDescriptor* declaration_descriptor, | 
| -    const DeclarationParsingResult::Declaration* declaration, | 
| -    ZoneList<const AstRawString*>* names, bool* ok) { | 
| -  PatternRewriter rewriter; | 
| - | 
| -  rewriter.pattern_ = declaration->pattern; | 
| -  rewriter.initializer_position_ = declaration->initializer_position; | 
| -  rewriter.block_ = block; | 
| -  rewriter.descriptor_ = declaration_descriptor; | 
| -  rewriter.names_ = names; | 
| -  rewriter.ok_ = ok; | 
| - | 
| -  rewriter.RecurseIntoSubpattern(rewriter.pattern_, declaration->initializer); | 
| -} | 
| - | 
| - | 
| -void Parser::PatternRewriter::VisitVariableProxy(VariableProxy* pattern) { | 
| -  Expression* value = current_value_; | 
| -  descriptor_->scope->RemoveUnresolved(pattern); | 
| - | 
| -  // Declare variable. | 
| -  // Note that we *always* must treat the initial value via a separate init | 
| -  // assignment for variables and constants because the value must be assigned | 
| -  // when the variable is encountered in the source. But the variable/constant | 
| -  // is declared (and set to 'undefined') upon entering the function within | 
| -  // which the variable or constant is declared. Only function variables have | 
| -  // an initial value in the declaration (because they are initialized upon | 
| -  // entering the function). | 
| -  // | 
| -  // If we have a legacy const declaration, in an inner scope, the proxy | 
| -  // is always bound to the declared variable (independent of possibly | 
| -  // surrounding 'with' statements). | 
| -  // 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; | 
| -  const AstRawString* name = pattern->raw_name(); | 
| -  VariableProxy* proxy = parser->NewUnresolved(name, descriptor_->mode); | 
| -  Declaration* declaration = factory()->NewVariableDeclaration( | 
| -      proxy, descriptor_->mode, descriptor_->scope, | 
| -      descriptor_->declaration_pos); | 
| -  Variable* var = parser->Declare(declaration, descriptor_->declaration_kind, | 
| -                                  descriptor_->mode != VAR, ok_, | 
| -                                  descriptor_->hoist_scope); | 
| -  if (!*ok_) return; | 
| -  DCHECK_NOT_NULL(var); | 
| -  DCHECK(!proxy->is_resolved() || proxy->var() == var); | 
| -  var->set_initializer_position(initializer_position_); | 
| - | 
| -  DCHECK(initializer_position_ != RelocInfo::kNoPosition); | 
| - | 
| -  if (descriptor_->declaration_scope->num_var_or_const() > | 
| -      kMaxNumFunctionLocals) { | 
| -    parser->ReportMessage(MessageTemplate::kTooManyVariables); | 
| -    *ok_ = false; | 
| -    return; | 
| -  } | 
| -  if (names_) { | 
| -    names_->Add(name, zone()); | 
| -  } | 
| - | 
| -  // Initialize variables if needed. A | 
| -  // declaration of the form: | 
| -  // | 
| -  //    var v = x; | 
| -  // | 
| -  // is syntactic sugar for: | 
| -  // | 
| -  //    var v; v = x; | 
| -  // | 
| -  // In particular, we need to re-lookup 'v' (in scope_, not | 
| -  // declaration_scope) as it may be a different 'v' than the 'v' in the | 
| -  // declaration (e.g., if we are inside a 'with' statement or 'catch' | 
| -  // block). | 
| -  // | 
| -  // However, note that const declarations are different! A const | 
| -  // declaration of the form: | 
| -  // | 
| -  //   const c = x; | 
| -  // | 
| -  // is *not* syntactic sugar for: | 
| -  // | 
| -  //   const c; c = x; | 
| -  // | 
| -  // The "variable" c initialized to x is the same as the declared | 
| -  // one - there is no re-lookup (see the last parameter of the | 
| -  // Declare() call above). | 
| -  Scope* initialization_scope = descriptor_->is_const | 
| -                                    ? descriptor_->declaration_scope | 
| -                                    : descriptor_->scope; | 
| - | 
| - | 
| -  // Global variable declarations must be compiled in a specific | 
| -  // way. When the script containing the global variable declaration | 
| -  // is entered, the global variable must be declared, so that if it | 
| -  // doesn't exist (on the global object itself, see ES5 errata) it | 
| -  // gets created with an initial undefined value. This is handled | 
| -  // by the declarations part of the function representing the | 
| -  // top-level global code; see Runtime::DeclareGlobalVariable. If | 
| -  // it already exists (in the object or in a prototype), it is | 
| -  // *not* touched until the variable declaration statement is | 
| -  // executed. | 
| -  // | 
| -  // Executing the variable declaration statement will always | 
| -  // guarantee to give the global object an own property. | 
| -  // This way, global variable declarations can shadow | 
| -  // properties in the prototype chain, but only after the variable | 
| -  // declaration statement has been executed. This is important in | 
| -  // browsers where the global object (window) has lots of | 
| -  // properties defined in prototype objects. | 
| -  if (initialization_scope->is_script_scope() && | 
| -      !IsLexicalVariableMode(descriptor_->mode)) { | 
| -    // Compute the arguments for the runtime | 
| -    // call.test-parsing/InitializedDeclarationsInStrictForOfError | 
| -    ZoneList<Expression*>* arguments = | 
| -        new (zone()) ZoneList<Expression*>(3, zone()); | 
| -    // We have at least 1 parameter. | 
| -    arguments->Add( | 
| -        factory()->NewStringLiteral(name, descriptor_->declaration_pos), | 
| -        zone()); | 
| -    CallRuntime* initialize; | 
| - | 
| -    if (descriptor_->is_const) { | 
| -      arguments->Add(value, zone()); | 
| -      value = NULL;  // zap the value to avoid the unnecessary assignment | 
| - | 
| -      // Construct the call to Runtime_InitializeConstGlobal | 
| -      // and add it to the initialization statement block. | 
| -      // Note that the function does different things depending on | 
| -      // the number of arguments (1 or 2). | 
| -      initialize = | 
| -          factory()->NewCallRuntime(Runtime::kInitializeConstGlobal, arguments, | 
| -                                    descriptor_->initialization_pos); | 
| -    } else { | 
| -      // Add language mode. | 
| -      // We may want to pass singleton to avoid Literal allocations. | 
| -      LanguageMode language_mode = initialization_scope->language_mode(); | 
| -      arguments->Add(factory()->NewNumberLiteral(language_mode, | 
| -                                                 descriptor_->declaration_pos), | 
| -                     zone()); | 
| - | 
| -      // Be careful not to assign a value to the global variable if | 
| -      // we're in a with. The initialization value should not | 
| -      // necessarily be stored in the global object in that case, | 
| -      // which is why we need to generate a separate assignment node. | 
| -      if (value != NULL && !descriptor_->scope->inside_with()) { | 
| -        arguments->Add(value, zone()); | 
| -        value = NULL;  // zap the value to avoid the unnecessary assignment | 
| -        // Construct the call to Runtime_InitializeVarGlobal | 
| -        // and add it to the initialization statement block. | 
| -        initialize = | 
| -            factory()->NewCallRuntime(Runtime::kInitializeVarGlobal, arguments, | 
| -                                      descriptor_->declaration_pos); | 
| -      } else { | 
| -        initialize = NULL; | 
| -      } | 
| -    } | 
| - | 
| -    if (initialize != NULL) { | 
| -      block_->statements()->Add( | 
| -          factory()->NewExpressionStatement(initialize, RelocInfo::kNoPosition), | 
| -          zone()); | 
| -    } | 
| -  } else if (value != nullptr && (descriptor_->mode == CONST_LEGACY || | 
| -                                  IsLexicalVariableMode(descriptor_->mode))) { | 
| -    // Constant initializations always assign to the declared constant which | 
| -    // is always at the function scope level. This is only relevant for | 
| -    // dynamically looked-up variables and constants (the | 
| -    // start context for constant lookups is always the function context, | 
| -    // while it is the top context for var declared variables). Sigh... | 
| -    // For 'let' and 'const' declared variables in harmony mode the | 
| -    // initialization also always assigns to the declared variable. | 
| -    DCHECK_NOT_NULL(proxy); | 
| -    DCHECK_NOT_NULL(proxy->var()); | 
| -    DCHECK_NOT_NULL(value); | 
| -    Assignment* assignment = factory()->NewAssignment( | 
| -        Token::INIT, proxy, value, descriptor_->initialization_pos); | 
| -    block_->statements()->Add( | 
| -        factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition), | 
| -        zone()); | 
| -    value = NULL; | 
| -  } | 
| - | 
| -  // Add an assignment node to the initialization statement block if we still | 
| -  // have a pending initialization value. | 
| -  if (value != NULL) { | 
| -    DCHECK(descriptor_->mode == VAR); | 
| -    // 'var' initializations are simply assignments (with all the consequences | 
| -    // if they are inside a 'with' statement - they may change a 'with' object | 
| -    // property). | 
| -    VariableProxy* proxy = initialization_scope->NewUnresolved(factory(), name); | 
| -    Assignment* assignment = factory()->NewAssignment( | 
| -        Token::INIT, proxy, value, descriptor_->initialization_pos); | 
| -    block_->statements()->Add( | 
| -        factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition), | 
| -        zone()); | 
| -  } | 
| -} | 
| - | 
| - | 
| -Variable* Parser::PatternRewriter::CreateTempVar(Expression* value) { | 
| -  auto temp = descriptor_->parser->scope_->NewTemporary( | 
| -      ast_value_factory()->empty_string()); | 
| -  if (value != nullptr) { | 
| -    auto assignment = factory()->NewAssignment( | 
| -        Token::ASSIGN, factory()->NewVariableProxy(temp), value, | 
| -        RelocInfo::kNoPosition); | 
| - | 
| -    block_->statements()->Add( | 
| -        factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition), | 
| -        zone()); | 
| -  } | 
| -  return temp; | 
| -} | 
| - | 
| - | 
| -void Parser::PatternRewriter::VisitObjectLiteral(ObjectLiteral* pattern) { | 
| -  auto temp = CreateTempVar(current_value_); | 
| - | 
| -  block_->statements()->Add(descriptor_->parser->BuildAssertIsCoercible(temp), | 
| -                            zone()); | 
| - | 
| -  for (ObjectLiteralProperty* property : *pattern->properties()) { | 
| -    RecurseIntoSubpattern( | 
| -        property->value(), | 
| -        factory()->NewProperty(factory()->NewVariableProxy(temp), | 
| -                               property->key(), RelocInfo::kNoPosition)); | 
| -  } | 
| -} | 
| - | 
| - | 
| -void Parser::PatternRewriter::VisitArrayLiteral(ArrayLiteral* node) { | 
| -  auto temp = CreateTempVar(current_value_); | 
| - | 
| -  block_->statements()->Add(descriptor_->parser->BuildAssertIsCoercible(temp), | 
| -                            zone()); | 
| - | 
| -  auto iterator = CreateTempVar(descriptor_->parser->GetIterator( | 
| -      factory()->NewVariableProxy(temp), factory())); | 
| -  auto done = CreateTempVar( | 
| -      factory()->NewBooleanLiteral(false, RelocInfo::kNoPosition)); | 
| -  auto result = CreateTempVar(); | 
| -  auto v = CreateTempVar(); | 
| - | 
| -  Spread* spread = nullptr; | 
| -  for (Expression* value : *node->values()) { | 
| -    if (value->IsSpread()) { | 
| -      spread = value->AsSpread(); | 
| -      break; | 
| -    } | 
| - | 
| -    // if (!done) { | 
| -    //   result = IteratorNext(iterator); | 
| -    //   v = (done = result.done) ? undefined : result.value; | 
| -    // } | 
| -    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()); | 
| - | 
| -    auto assign_to_done = factory()->NewAssignment( | 
| -        Token::ASSIGN, factory()->NewVariableProxy(done), | 
| -        factory()->NewProperty( | 
| -            factory()->NewVariableProxy(result), | 
| -            factory()->NewStringLiteral(ast_value_factory()->done_string(), | 
| -                                        RelocInfo::kNoPosition), | 
| -            RelocInfo::kNoPosition), | 
| -        RelocInfo::kNoPosition); | 
| -    auto next_value = factory()->NewConditional( | 
| -        assign_to_done, factory()->NewUndefinedLiteral(RelocInfo::kNoPosition), | 
| -        factory()->NewProperty( | 
| -            factory()->NewVariableProxy(result), | 
| -            factory()->NewStringLiteral(ast_value_factory()->value_string(), | 
| -                                        RelocInfo::kNoPosition), | 
| -            RelocInfo::kNoPosition), | 
| -        RelocInfo::kNoPosition); | 
| -    next_block->statements()->Add( | 
| -        factory()->NewExpressionStatement( | 
| -            factory()->NewAssignment(Token::ASSIGN, | 
| -                                     factory()->NewVariableProxy(v), next_value, | 
| -                                     RelocInfo::kNoPosition), | 
| -            RelocInfo::kNoPosition), | 
| -        zone()); | 
| - | 
| -    auto if_statement = factory()->NewIfStatement( | 
| -        factory()->NewUnaryOperation(Token::NOT, | 
| -                                     factory()->NewVariableProxy(done), | 
| -                                     RelocInfo::kNoPosition), | 
| -        next_block, factory()->NewEmptyStatement(RelocInfo::kNoPosition), | 
| -        RelocInfo::kNoPosition); | 
| -    block_->statements()->Add(if_statement, zone()); | 
| - | 
| -    if (!(value->IsLiteral() && value->AsLiteral()->raw_value()->IsTheHole())) { | 
| -      RecurseIntoSubpattern(value, factory()->NewVariableProxy(v)); | 
| -    } | 
| -  } | 
| - | 
| -  if (spread != nullptr) { | 
| -    // array = []; | 
| -    // if (!done) %concat_iterable_to_array(array, iterator); | 
| -    auto empty_exprs = new (zone()) ZoneList<Expression*>(0, zone()); | 
| -    auto array = CreateTempVar(factory()->NewArrayLiteral( | 
| -        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()), | 
| -        RelocInfo::kNoPosition)); | 
| - | 
| -    auto arguments = new (zone()) ZoneList<Expression*>(2, zone()); | 
| -    arguments->Add(factory()->NewVariableProxy(array), zone()); | 
| -    arguments->Add(factory()->NewVariableProxy(iterator), zone()); | 
| -    auto spread_into_array_call = | 
| -        factory()->NewCallRuntime(Context::CONCAT_ITERABLE_TO_ARRAY_INDEX, | 
| -                                  arguments, RelocInfo::kNoPosition); | 
| - | 
| -    auto if_statement = factory()->NewIfStatement( | 
| -        factory()->NewUnaryOperation(Token::NOT, | 
| -                                     factory()->NewVariableProxy(done), | 
| -                                     RelocInfo::kNoPosition), | 
| -        factory()->NewExpressionStatement(spread_into_array_call, | 
| -                                          RelocInfo::kNoPosition), | 
| -        factory()->NewEmptyStatement(RelocInfo::kNoPosition), | 
| -        RelocInfo::kNoPosition); | 
| -    block_->statements()->Add(if_statement, zone()); | 
| - | 
| -    RecurseIntoSubpattern(spread->expression(), | 
| -                          factory()->NewVariableProxy(array)); | 
| -  } | 
| -} | 
| - | 
| - | 
| -void Parser::PatternRewriter::VisitAssignment(Assignment* node) { | 
| -  // let {<pattern> = <init>} = <value> | 
| -  //   becomes | 
| -  // temp = <value>; | 
| -  // <pattern> = temp === undefined ? <init> : temp; | 
| -  DCHECK(node->op() == Token::ASSIGN); | 
| -  auto temp = CreateTempVar(current_value_); | 
| -  Expression* is_undefined = factory()->NewCompareOperation( | 
| -      Token::EQ_STRICT, factory()->NewVariableProxy(temp), | 
| -      factory()->NewUndefinedLiteral(RelocInfo::kNoPosition), | 
| -      RelocInfo::kNoPosition); | 
| -  Expression* initializer = node->value(); | 
| -  if (descriptor_->declaration_kind == DeclarationDescriptor::PARAMETER && | 
| -      descriptor_->scope->is_arrow_scope()) { | 
| -    // TODO(adamk): Only call this if necessary. | 
| -    RewriteParameterInitializerScope( | 
| -        descriptor_->parser->stack_limit(), initializer, | 
| -        descriptor_->scope->outer_scope(), descriptor_->scope); | 
| -  } | 
| -  Expression* value = factory()->NewConditional( | 
| -      is_undefined, initializer, factory()->NewVariableProxy(temp), | 
| -      RelocInfo::kNoPosition); | 
| -  RecurseIntoSubpattern(node->target(), value); | 
| -} | 
| - | 
| - | 
| -// =============== UNREACHABLE ============================= | 
| - | 
| -void Parser::PatternRewriter::Visit(AstNode* node) { UNREACHABLE(); } | 
| - | 
| -#define NOT_A_PATTERN(Node)                                        \ | 
| -  void Parser::PatternRewriter::Visit##Node(v8::internal::Node*) { \ | 
| -    UNREACHABLE();                                                 \ | 
| -  } | 
| - | 
| -NOT_A_PATTERN(BinaryOperation) | 
| -NOT_A_PATTERN(Block) | 
| -NOT_A_PATTERN(BreakStatement) | 
| -NOT_A_PATTERN(Call) | 
| -NOT_A_PATTERN(CallNew) | 
| -NOT_A_PATTERN(CallRuntime) | 
| -NOT_A_PATTERN(CaseClause) | 
| -NOT_A_PATTERN(ClassLiteral) | 
| -NOT_A_PATTERN(CompareOperation) | 
| -NOT_A_PATTERN(Conditional) | 
| -NOT_A_PATTERN(ContinueStatement) | 
| -NOT_A_PATTERN(CountOperation) | 
| -NOT_A_PATTERN(DebuggerStatement) | 
| -NOT_A_PATTERN(DoExpression) | 
| -NOT_A_PATTERN(DoWhileStatement) | 
| -NOT_A_PATTERN(EmptyStatement) | 
| -NOT_A_PATTERN(EmptyParentheses) | 
| -NOT_A_PATTERN(ExportDeclaration) | 
| -NOT_A_PATTERN(ExpressionStatement) | 
| -NOT_A_PATTERN(ForInStatement) | 
| -NOT_A_PATTERN(ForOfStatement) | 
| -NOT_A_PATTERN(ForStatement) | 
| -NOT_A_PATTERN(FunctionDeclaration) | 
| -NOT_A_PATTERN(FunctionLiteral) | 
| -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) | 
| -NOT_A_PATTERN(Spread) | 
| -NOT_A_PATTERN(SuperPropertyReference) | 
| -NOT_A_PATTERN(SuperCallReference) | 
| -NOT_A_PATTERN(SwitchStatement) | 
| -NOT_A_PATTERN(ThisFunction) | 
| -NOT_A_PATTERN(Throw) | 
| -NOT_A_PATTERN(TryCatchStatement) | 
| -NOT_A_PATTERN(TryFinallyStatement) | 
| -NOT_A_PATTERN(UnaryOperation) | 
| -NOT_A_PATTERN(VariableDeclaration) | 
| -NOT_A_PATTERN(WhileStatement) | 
| -NOT_A_PATTERN(WithStatement) | 
| -NOT_A_PATTERN(Yield) | 
| - | 
| -#undef NOT_A_PATTERN | 
| -}  // namespace internal | 
| -}  // namespace v8 | 
|  |