LCOV - code coverage report
Current view: top level - src/parsing - parser.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 1695 1775 95.5 %
Date: 2017-04-26 Functions: 105 116 90.5 %

          Line data    Source code
       1             : // Copyright 2012 the V8 project authors. All rights reserved.
       2             : // Use of this source code is governed by a BSD-style license that can be
       3             : // found in the LICENSE file.
       4             : 
       5             : #include "src/parsing/parser.h"
       6             : 
       7             : #include <memory>
       8             : 
       9             : #include "src/api.h"
      10             : #include "src/ast/ast-expression-rewriter.h"
      11             : #include "src/ast/ast-function-literal-id-reindexer.h"
      12             : #include "src/ast/ast-traversal-visitor.h"
      13             : #include "src/ast/ast.h"
      14             : #include "src/bailout-reason.h"
      15             : #include "src/base/platform/platform.h"
      16             : #include "src/char-predicates-inl.h"
      17             : #include "src/messages.h"
      18             : #include "src/objects-inl.h"
      19             : #include "src/parsing/duplicate-finder.h"
      20             : #include "src/parsing/parameter-initializer-rewriter.h"
      21             : #include "src/parsing/parse-info.h"
      22             : #include "src/parsing/rewriter.h"
      23             : #include "src/parsing/scanner-character-streams.h"
      24             : #include "src/runtime/runtime.h"
      25             : #include "src/string-stream.h"
      26             : #include "src/tracing/trace-event.h"
      27             : 
      28             : namespace v8 {
      29             : namespace internal {
      30             : 
      31        1330 : ScriptData::ScriptData(const byte* data, int length)
      32        1330 :     : owns_data_(false), rejected_(false), data_(data), length_(length) {
      33        2660 :   if (!IsAligned(reinterpret_cast<intptr_t>(data), kPointerAlignment)) {
      34           4 :     byte* copy = NewArray<byte>(length);
      35             :     DCHECK(IsAligned(reinterpret_cast<intptr_t>(copy), kPointerAlignment));
      36           4 :     CopyBytes(copy, data, length);
      37           4 :     data_ = copy;
      38             :     AcquireDataOwnership();
      39             :   }
      40        1330 : }
      41             : 
      42         276 : FunctionEntry ParseData::GetFunctionEntry(int start) {
      43             :   // The current pre-data entry must be a FunctionEntry with the given
      44             :   // start position.
      45         414 :   if ((function_index_ + FunctionEntry::kSize <= Length()) &&
      46         138 :       (static_cast<int>(Data()[function_index_]) == start)) {
      47             :     int index = function_index_;
      48         126 :     function_index_ += FunctionEntry::kSize;
      49         126 :     Vector<unsigned> subvector(&(Data()[index]), FunctionEntry::kSize);
      50         126 :     return FunctionEntry(subvector);
      51             :   }
      52          12 :   return FunctionEntry();
      53             : }
      54             : 
      55             : 
      56          36 : int ParseData::FunctionCount() {
      57             :   int functions_size = FunctionsSize();
      58          36 :   if (functions_size < 0) return 0;
      59          36 :   if (functions_size % FunctionEntry::kSize != 0) return 0;
      60          36 :   return functions_size / FunctionEntry::kSize;
      61             : }
      62             : 
      63             : 
      64         114 : bool ParseData::IsSane() {
      65         228 :   if (!IsAligned(script_data_->length(), sizeof(unsigned))) return false;
      66             :   // Check that the header data is valid and doesn't specify
      67             :   // point to positions outside the store.
      68             :   int data_length = Length();
      69         114 :   if (data_length < PreparseDataConstants::kHeaderSize) return false;
      70         114 :   if (Magic() != PreparseDataConstants::kMagicNumber) return false;
      71         108 :   if (Version() != PreparseDataConstants::kCurrentVersion) return false;
      72             :   // Check that the space allocated for function entries is sane.
      73             :   int functions_size = FunctionsSize();
      74         108 :   if (functions_size < 0) return false;
      75         108 :   if (functions_size % FunctionEntry::kSize != 0) return false;
      76             :   // Check that the total size has room for header and function entries.
      77             :   int minimum_size =
      78         108 :       PreparseDataConstants::kHeaderSize + functions_size;
      79         108 :   if (data_length < minimum_size) return false;
      80         108 :   return true;
      81             : }
      82             : 
      83             : 
      84          72 : void ParseData::Initialize() {
      85             :   // Prepares state for use.
      86             :   int data_length = Length();
      87          72 :   if (data_length >= PreparseDataConstants::kHeaderSize) {
      88          72 :     function_index_ = PreparseDataConstants::kHeaderSize;
      89             :   }
      90           6 : }
      91             : 
      92             : 
      93           0 : unsigned ParseData::Magic() {
      94         114 :   return Data()[PreparseDataConstants::kMagicOffset];
      95             : }
      96             : 
      97             : 
      98           0 : unsigned ParseData::Version() {
      99         108 :   return Data()[PreparseDataConstants::kVersionOffset];
     100             : }
     101             : 
     102             : 
     103          36 : int ParseData::FunctionsSize() {
     104         144 :   return static_cast<int>(Data()[PreparseDataConstants::kFunctionsSizeOffset]);
     105             : }
     106             : 
     107             : // Helper for putting parts of the parse results into a temporary zone when
     108             : // parsing inner function bodies.
     109             : class DiscardableZoneScope {
     110             :  public:
     111     7562020 :   DiscardableZoneScope(Parser* parser, Zone* temp_zone, bool use_temp_zone)
     112             :       : ast_node_factory_scope_(parser->factory(), temp_zone, use_temp_zone),
     113             :         fni_(parser->ast_value_factory_, temp_zone),
     114             :         parser_(parser),
     115             :         prev_fni_(parser->fni_),
     116             :         prev_zone_(parser->zone_),
     117             :         prev_allow_lazy_(parser->allow_lazy_),
     118    15124040 :         prev_temp_zoned_(parser->temp_zoned_) {
     119     7562028 :     if (use_temp_zone) {
     120             :       DCHECK(!parser_->temp_zoned_);
     121     1403478 :       parser_->allow_lazy_ = false;
     122     1403478 :       parser_->temp_zoned_ = true;
     123     1403478 :       parser_->fni_ = &fni_;
     124     1403478 :       parser_->zone_ = temp_zone;
     125     1403478 :       if (parser_->reusable_preparser_ != nullptr) {
     126     1011643 :         parser_->reusable_preparser_->zone_ = temp_zone;
     127             :         parser_->reusable_preparser_->factory()->set_zone(temp_zone);
     128             :       }
     129             :     }
     130     7562028 :   }
     131     7562065 :   void Reset() {
     132     7562065 :     parser_->fni_ = prev_fni_;
     133     7562065 :     parser_->zone_ = prev_zone_;
     134     7562065 :     parser_->allow_lazy_ = prev_allow_lazy_;
     135     7562065 :     parser_->temp_zoned_ = prev_temp_zoned_;
     136     7562065 :     if (parser_->reusable_preparser_ != nullptr) {
     137     2778811 :       parser_->reusable_preparser_->zone_ = prev_zone_;
     138             :       parser_->reusable_preparser_->factory()->set_zone(prev_zone_);
     139             :     }
     140             :     ast_node_factory_scope_.Reset();
     141     7562065 :   }
     142     7562022 :   ~DiscardableZoneScope() { Reset(); }
     143             : 
     144             :  private:
     145             :   AstNodeFactory::BodyScope ast_node_factory_scope_;
     146             :   FuncNameInferrer fni_;
     147             :   Parser* parser_;
     148             :   FuncNameInferrer* prev_fni_;
     149             :   Zone* prev_zone_;
     150             :   bool prev_allow_lazy_;
     151             :   bool prev_temp_zoned_;
     152             : 
     153             :   DISALLOW_COPY_AND_ASSIGN(DiscardableZoneScope);
     154             : };
     155             : 
     156     2263423 : void Parser::SetCachedData(ParseInfo* info) {
     157             :   DCHECK_NULL(cached_parse_data_);
     158     2263351 :   if (consume_cached_parse_data()) {
     159          72 :     if (allow_lazy_) {
     160          72 :       cached_parse_data_ = ParseData::FromCachedData(*info->cached_data());
     161     2263423 :       if (cached_parse_data_ != nullptr) return;
     162             :     }
     163           6 :     compile_options_ = ScriptCompiler::kNoCompileOptions;
     164             :   }
     165             : }
     166             : 
     167       87041 : FunctionLiteral* Parser::DefaultConstructor(const AstRawString* name,
     168             :                                             bool call_super, int pos,
     169             :                                             int end_pos) {
     170             :   int expected_property_count = -1;
     171             :   const int parameter_count = 0;
     172      323723 :   if (name == nullptr) name = ast_value_factory()->empty_string();
     173             : 
     174             :   FunctionKind kind = call_super ? FunctionKind::kDefaultDerivedConstructor
     175       87041 :                                  : FunctionKind::kDefaultBaseConstructor;
     176       87041 :   DeclarationScope* function_scope = NewFunctionScope(kind);
     177       87041 :   SetLanguageMode(function_scope, STRICT);
     178             :   // Set start and end position to the same value
     179             :   function_scope->set_start_position(pos);
     180             :   function_scope->set_end_position(pos);
     181             :   ZoneList<Statement*>* body = NULL;
     182             : 
     183             :   {
     184       87041 :     FunctionState function_state(&function_state_, &scope_, function_scope);
     185             : 
     186       87041 :     body = new (zone()) ZoneList<Statement*>(call_super ? 2 : 1, zone());
     187       87041 :     if (call_super) {
     188             :       // Create a SuperCallReference and handle in BytecodeGenerator.
     189       15650 :       auto constructor_args_name = ast_value_factory()->empty_string();
     190             :       bool is_duplicate;
     191             :       bool is_rest = true;
     192             :       bool is_optional = false;
     193             :       Variable* constructor_args = function_scope->DeclareParameter(
     194             :           constructor_args_name, TEMPORARY, is_optional, is_rest, &is_duplicate,
     195       15650 :           ast_value_factory(), pos);
     196             : 
     197             :       ZoneList<Expression*>* args =
     198       15650 :           new (zone()) ZoneList<Expression*>(1, zone());
     199             :       Spread* spread_args = factory()->NewSpread(
     200       31300 :           factory()->NewVariableProxy(constructor_args), pos, pos);
     201             : 
     202             :       args->Add(spread_args, zone());
     203       15650 :       Expression* super_call_ref = NewSuperCallReference(pos);
     204       15650 :       Expression* call = factory()->NewCall(super_call_ref, args, pos);
     205       15650 :       body->Add(factory()->NewReturnStatement(call, pos), zone());
     206             :     }
     207             : 
     208       87041 :     expected_property_count = function_state.expected_property_count();
     209             :   }
     210             : 
     211             :   FunctionLiteral* function_literal = factory()->NewFunctionLiteral(
     212             :       name, function_scope, body, expected_property_count, parameter_count,
     213             :       parameter_count, FunctionLiteral::kNoDuplicateParameters,
     214             :       FunctionLiteral::kAnonymousExpression, default_eager_compile_hint(), pos,
     215       87041 :       true, GetNextFunctionLiteralId());
     216             : 
     217       87041 :   return function_literal;
     218             : }
     219             : 
     220             : // ----------------------------------------------------------------------------
     221             : // The CHECK_OK macro is a convenient macro to enforce error
     222             : // handling for functions that may fail (by returning !*ok).
     223             : //
     224             : // CAUTION: This macro appends extra statements after a call,
     225             : // thus it must never be used where only a single statement
     226             : // is correct (e.g. an if statement branch w/o braces)!
     227             : 
     228             : #define CHECK_OK_VALUE(x) ok); \
     229             :   if (!*ok) return x;          \
     230             :   ((void)0
     231             : #define DUMMY )  // to make indentation work
     232             : #undef DUMMY
     233             : 
     234             : #define CHECK_OK CHECK_OK_VALUE(nullptr)
     235             : #define CHECK_OK_VOID CHECK_OK_VALUE(this->Void())
     236             : 
     237             : #define CHECK_FAILED /**/); \
     238             :   if (failed_) return nullptr;  \
     239             :   ((void)0
     240             : #define DUMMY )  // to make indentation work
     241             : #undef DUMMY
     242             : 
     243             : // ----------------------------------------------------------------------------
     244             : // Implementation of Parser
     245             : 
     246    12609988 : bool Parser::ShortcutNumericLiteralBinaryExpression(Expression** x,
     247             :                                                     Expression* y,
     248             :                                                     Token::Value op, int pos) {
     249    31163432 :   if ((*x)->AsLiteral() && (*x)->AsLiteral()->raw_value()->IsNumber() &&
     250    15103570 :       y->AsLiteral() && y->AsLiteral()->raw_value()->IsNumber()) {
     251     1447518 :     double x_val = (*x)->AsLiteral()->raw_value()->AsNumber();
     252     1447518 :     double y_val = y->AsLiteral()->raw_value()->AsNumber();
     253     1447518 :     bool x_has_dot = (*x)->AsLiteral()->raw_value()->ContainsDot();
     254      723759 :     bool y_has_dot = y->AsLiteral()->raw_value()->ContainsDot();
     255      723759 :     bool has_dot = x_has_dot || y_has_dot;
     256      723759 :     switch (op) {
     257             :       case Token::ADD:
     258       24837 :         *x = factory()->NewNumberLiteral(x_val + y_val, pos, has_dot);
     259       24837 :         return true;
     260             :       case Token::SUB:
     261        1777 :         *x = factory()->NewNumberLiteral(x_val - y_val, pos, has_dot);
     262        1777 :         return true;
     263             :       case Token::MUL:
     264      356884 :         *x = factory()->NewNumberLiteral(x_val * y_val, pos, has_dot);
     265      356884 :         return true;
     266             :       case Token::DIV:
     267        6219 :         *x = factory()->NewNumberLiteral(x_val / y_val, pos, has_dot);
     268        6219 :         return true;
     269             :       case Token::BIT_OR: {
     270       82369 :         int value = DoubleToInt32(x_val) | DoubleToInt32(y_val);
     271       82369 :         *x = factory()->NewNumberLiteral(value, pos, has_dot);
     272       82369 :         return true;
     273             :       }
     274             :       case Token::BIT_AND: {
     275         570 :         int value = DoubleToInt32(x_val) & DoubleToInt32(y_val);
     276         570 :         *x = factory()->NewNumberLiteral(value, pos, has_dot);
     277         570 :         return true;
     278             :       }
     279             :       case Token::BIT_XOR: {
     280         332 :         int value = DoubleToInt32(x_val) ^ DoubleToInt32(y_val);
     281         332 :         *x = factory()->NewNumberLiteral(value, pos, has_dot);
     282         332 :         return true;
     283             :       }
     284             :       case Token::SHL: {
     285      225798 :         int value = DoubleToInt32(x_val) << (DoubleToInt32(y_val) & 0x1f);
     286      225798 :         *x = factory()->NewNumberLiteral(value, pos, has_dot);
     287      225798 :         return true;
     288             :       }
     289             :       case Token::SHR: {
     290         677 :         uint32_t shift = DoubleToInt32(y_val) & 0x1f;
     291         677 :         uint32_t value = DoubleToUint32(x_val) >> shift;
     292         677 :         *x = factory()->NewNumberLiteral(value, pos, has_dot);
     293         677 :         return true;
     294             :       }
     295             :       case Token::SAR: {
     296        8810 :         uint32_t shift = DoubleToInt32(y_val) & 0x1f;
     297        8810 :         int value = ArithmeticShiftRight(DoubleToInt32(x_val), shift);
     298        8810 :         *x = factory()->NewNumberLiteral(value, pos, has_dot);
     299        8810 :         return true;
     300             :       }
     301             :       case Token::EXP: {
     302         428 :         double value = Pow(x_val, y_val);
     303         428 :         int int_value = static_cast<int>(value);
     304             :         *x = factory()->NewNumberLiteral(
     305         633 :             int_value == value && value != -0.0 ? int_value : value, pos,
     306        1284 :             has_dot);
     307         428 :         return true;
     308             :       }
     309             :       default:
     310             :         break;
     311             :     }
     312             :   }
     313             :   return false;
     314             : }
     315             : 
     316     3151268 : Expression* Parser::BuildUnaryExpression(Expression* expression,
     317             :                                          Token::Value op, int pos) {
     318             :   DCHECK(expression != NULL);
     319     3151268 :   if (expression->IsLiteral()) {
     320     2520810 :     const AstValue* literal = expression->AsLiteral()->raw_value();
     321     1260405 :     if (op == Token::NOT) {
     322             :       // Convert the literal to a boolean condition and negate it.
     323         411 :       bool condition = literal->BooleanValue();
     324         411 :       return factory()->NewBooleanLiteral(!condition, pos);
     325     1259994 :     } else if (literal->IsNumber()) {
     326             :       // Compute some expressions involving only number literals.
     327     1258916 :       double value = literal->AsNumber();
     328             :       bool has_dot = literal->ContainsDot();
     329     1258916 :       switch (op) {
     330             :         case Token::ADD:
     331             :           return expression;
     332             :         case Token::SUB:
     333      722832 :           return factory()->NewNumberLiteral(-value, pos, has_dot);
     334             :         case Token::BIT_NOT:
     335         828 :           return factory()->NewNumberLiteral(~DoubleToInt32(value), pos,
     336        1656 :                                              has_dot);
     337             :         default:
     338             :           break;
     339             :       }
     340             :     }
     341             :   }
     342             :   // Desugar '+foo' => 'foo*1'
     343     2424918 :   if (op == Token::ADD) {
     344             :     return factory()->NewBinaryOperation(
     345       68519 :         Token::MUL, expression, factory()->NewNumberLiteral(1, pos, true), pos);
     346             :   }
     347             :   // The same idea for '-foo' => 'foo*(-1)'.
     348     2356399 :   if (op == Token::SUB) {
     349             :     return factory()->NewBinaryOperation(
     350       41410 :         Token::MUL, expression, factory()->NewNumberLiteral(-1, pos), pos);
     351             :   }
     352             :   // ...and one more time for '~foo' => 'foo^(~0)'.
     353     2314989 :   if (op == Token::BIT_NOT) {
     354             :     return factory()->NewBinaryOperation(
     355        7474 :         Token::BIT_XOR, expression, factory()->NewNumberLiteral(~0, pos), pos);
     356             :   }
     357     4615031 :   return factory()->NewUnaryOperation(op, expression, pos);
     358             : }
     359             : 
     360       41204 : Expression* Parser::BuildIteratorResult(Expression* value, bool done) {
     361             :   int pos = kNoSourcePosition;
     362             : 
     363      123612 :   if (value == nullptr) value = factory()->NewUndefinedLiteral(pos);
     364             : 
     365       41204 :   auto args = new (zone()) ZoneList<Expression*>(2, zone());
     366             :   args->Add(value, zone());
     367       41204 :   args->Add(factory()->NewBooleanLiteral(done, pos), zone());
     368             : 
     369             :   return factory()->NewCallRuntime(Runtime::kInlineCreateIterResultObject, args,
     370       41204 :                                    pos);
     371             : }
     372             : 
     373      381382 : Expression* Parser::NewThrowError(Runtime::FunctionId id,
     374             :                                   MessageTemplate::Template message,
     375             :                                   const AstRawString* arg, int pos) {
     376     1144146 :   ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(2, zone());
     377      381382 :   args->Add(factory()->NewSmiLiteral(message, pos), zone());
     378      381382 :   args->Add(factory()->NewStringLiteral(arg, pos), zone());
     379      381382 :   CallRuntime* call_constructor = factory()->NewCallRuntime(id, args, pos);
     380      762764 :   return factory()->NewThrow(call_constructor, pos);
     381             : }
     382             : 
     383        6119 : Expression* Parser::NewSuperPropertyReference(int pos) {
     384             :   // this_function[home_object_symbol]
     385             :   VariableProxy* this_function_proxy =
     386        6119 :       NewUnresolved(ast_value_factory()->this_function_string(), pos);
     387             :   Expression* home_object_symbol_literal = factory()->NewSymbolLiteral(
     388        6119 :       AstSymbol::kHomeObjectSymbol, kNoSourcePosition);
     389             :   Expression* home_object = factory()->NewProperty(
     390        6119 :       this_function_proxy, home_object_symbol_literal, pos);
     391             :   return factory()->NewSuperPropertyReference(
     392       18357 :       ThisExpression(pos)->AsVariableProxy(), home_object, pos);
     393             : }
     394             : 
     395       21195 : Expression* Parser::NewSuperCallReference(int pos) {
     396             :   VariableProxy* new_target_proxy =
     397       42390 :       NewUnresolved(ast_value_factory()->new_target_string(), pos);
     398             :   VariableProxy* this_function_proxy =
     399       21195 :       NewUnresolved(ast_value_factory()->this_function_string(), pos);
     400             :   return factory()->NewSuperCallReference(
     401             :       ThisExpression(pos)->AsVariableProxy(), new_target_proxy,
     402       63585 :       this_function_proxy, pos);
     403             : }
     404             : 
     405       25292 : Expression* Parser::NewTargetExpression(int pos) {
     406       25292 :   auto proxy = NewUnresolved(ast_value_factory()->new_target_string(), pos);
     407             :   proxy->set_is_new_target();
     408       25292 :   return proxy;
     409             : }
     410             : 
     411        2641 : Expression* Parser::FunctionSentExpression(int pos) {
     412             :   // We desugar function.sent into %_GeneratorGetInputOrDebugPos(generator).
     413        7923 :   ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(1, zone());
     414             :   VariableProxy* generator =
     415        5282 :       factory()->NewVariableProxy(function_state_->generator_object_variable());
     416             :   args->Add(generator, zone());
     417             :   return factory()->NewCallRuntime(Runtime::kInlineGeneratorGetInputOrDebugPos,
     418        2641 :                                    args, pos);
     419             : }
     420             : 
     421    31910582 : Literal* Parser::ExpressionFromLiteral(Token::Value token, int pos) {
     422    31910582 :   switch (token) {
     423             :     case Token::NULL_LITERAL:
     424    32241978 :       return factory()->NewNullLiteral(pos);
     425             :     case Token::TRUE_LITERAL:
     426      626092 :       return factory()->NewBooleanLiteral(true, pos);
     427             :     case Token::FALSE_LITERAL:
     428      787877 :       return factory()->NewBooleanLiteral(false, pos);
     429             :     case Token::SMI: {
     430    28080761 :       uint32_t value = scanner()->smi_value();
     431    28080761 :       return factory()->NewSmiLiteral(value, pos);
     432             :     }
     433             :     case Token::NUMBER: {
     434     1745359 :       bool has_dot = scanner()->ContainsDot();
     435     1745359 :       double value = scanner()->DoubleValue();
     436     1745359 :       return factory()->NewNumberLiteral(value, pos, has_dot);
     437             :     }
     438             :     default:
     439             :       DCHECK(false);
     440             :   }
     441             :   return NULL;
     442             : }
     443             : 
     444             : void Parser::MarkTailPosition(Expression* expression) {
     445       10304 :   expression->MarkTail();
     446             : }
     447             : 
     448             : Expression* Parser::NewV8Intrinsic(const AstRawString* name,
     449             :                                    ZoneList<Expression*>* args, int pos,
     450             :                                    bool* ok) {
     451     2231180 :   if (extension_ != nullptr) {
     452             :     // The extension structures are only accessible while parsing the
     453             :     // very first time, not when reparsing because of lazy compilation.
     454           6 :     GetClosureScope()->ForceEagerCompilation();
     455             :   }
     456             : 
     457             :   DCHECK(name->is_one_byte());
     458             :   const Runtime::Function* function =
     459     2231180 :       Runtime::FunctionForName(name->raw_data(), name->length());
     460             : 
     461     2231180 :   if (function != nullptr) {
     462             :     // Check for possible name clash.
     463             :     DCHECK_EQ(Context::kNotFound,
     464             :               Context::IntrinsicIndexForName(name->raw_data(), name->length()));
     465             :     // Check for built-in IS_VAR macro.
     466     1989254 :     if (function->function_id == Runtime::kIS_VAR) {
     467             :       DCHECK_EQ(Runtime::RUNTIME, function->intrinsic_type);
     468             :       // %IS_VAR(x) evaluates to x if x is a variable,
     469             :       // leads to a parse error otherwise.  Could be implemented as an
     470             :       // inline function %_IS_VAR(x) to eliminate this special case.
     471     1737612 :       if (args->length() == 1 && args->at(0)->AsVariableProxy() != nullptr) {
     472       21680 :         return args->at(0);
     473             :       } else {
     474           0 :         ReportMessage(MessageTemplate::kNotIsvar);
     475           0 :         *ok = false;
     476             :         return nullptr;
     477             :       }
     478             :     }
     479             : 
     480             :     // Check that the expected number of arguments are being passed.
     481     3661826 :     if (function->nargs != -1 && function->nargs != args->length()) {
     482           0 :       ReportMessage(MessageTemplate::kRuntimeWrongNumArgs);
     483           0 :       *ok = false;
     484             :       return nullptr;
     485             :     }
     486             : 
     487     1967574 :     return factory()->NewCallRuntime(function, args, pos);
     488             :   }
     489             : 
     490             :   int context_index =
     491      241926 :       Context::IntrinsicIndexForName(name->raw_data(), name->length());
     492             : 
     493             :   // Check that the function is defined.
     494      241926 :   if (context_index == Context::kNotFound) {
     495          75 :     ReportMessage(MessageTemplate::kNotDefined, name);
     496          75 :     *ok = false;
     497             :     return nullptr;
     498             :   }
     499             : 
     500      241851 :   return factory()->NewCallRuntime(context_index, args, pos);
     501             : }
     502             : 
     503    27711683 : Parser::Parser(ParseInfo* info)
     504             :     : ParserBase<Parser>(info->zone(), &scanner_, info->stack_limit(),
     505             :                          info->extension(), info->ast_value_factory(),
     506             :                          info->runtime_call_stats(),
     507             :                          info->preparsed_scope_data(), true),
     508             :       scanner_(info->unicode_cache()),
     509             :       reusable_preparser_(nullptr),
     510             :       mode_(PARSE_EAGERLY),  // Lazy mode must be set explicitly.
     511             :       target_stack_(nullptr),
     512             :       compile_options_(info->compile_options()),
     513             :       cached_parse_data_(nullptr),
     514             :       total_preparse_skipped_(0),
     515             :       temp_zoned_(false),
     516             :       log_(nullptr),
     517    24861392 :       parameters_end_pos_(info->parameters_end_pos()) {
     518             :   // Even though we were passed ParseInfo, we should not store it in
     519             :   // Parser - this makes sure that Isolate is not accidentally accessed via
     520             :   // ParseInfo during background parsing.
     521             :   DCHECK(!info->script().is_null() || info->source_stream() != nullptr ||
     522             :          info->character_stream() != nullptr);
     523             :   // Determine if functions can be lazily compiled. This is necessary to
     524             :   // allow some of our builtin JS files to be lazily compiled. These
     525             :   // builtins cannot be handled lazily by the parser, since we have to know
     526             :   // if a function uses the special natives syntax, which is something the
     527             :   // parser records.
     528             :   // If the debugger requests compilation for break points, we cannot be
     529             :   // aggressive about lazy compilation, because it might trigger compilation
     530             :   // of functions without an outer context when setting a breakpoint through
     531             :   // Debug::FindSharedFunctionInfoInScript
     532     7142918 :   bool can_compile_lazily = FLAG_lazy && !info->is_debug();
     533             : 
     534             :   // Consider compiling eagerly when targeting the code cache.
     535     3571939 :   can_compile_lazily &= !(FLAG_serialize_eager && info->will_serialize());
     536             : 
     537             :   set_default_eager_compile_hint(can_compile_lazily
     538             :                                      ? FunctionLiteral::kShouldLazyCompile
     539     3571936 :                                      : FunctionLiteral::kShouldEagerCompile);
     540     9684761 :   allow_lazy_ = FLAG_lazy && info->allow_lazy_parsing() && !info->is_native() &&
     541     6417499 :                 info->extension() == nullptr && can_compile_lazily;
     542     5776605 :   set_allow_natives(FLAG_allow_natives_syntax || info->is_native());
     543     3590705 :   set_allow_tailcalls(FLAG_harmony_tailcalls && !info->is_native() &&
     544             :                       info->is_tail_call_elimination_enabled());
     545     3571936 :   set_allow_harmony_do_expressions(FLAG_harmony_do_expressions);
     546     3571936 :   set_allow_harmony_function_sent(FLAG_harmony_function_sent);
     547     3571936 :   set_allow_harmony_restrictive_generators(FLAG_harmony_restrictive_generators);
     548     3571936 :   set_allow_harmony_trailing_commas(FLAG_harmony_trailing_commas);
     549     3571936 :   set_allow_harmony_class_fields(FLAG_harmony_class_fields);
     550     3571936 :   set_allow_harmony_object_rest_spread(FLAG_harmony_object_rest_spread);
     551     3571936 :   set_allow_harmony_dynamic_import(FLAG_harmony_dynamic_import);
     552     3571936 :   set_allow_harmony_async_iteration(FLAG_harmony_async_iteration);
     553     3571936 :   set_allow_harmony_template_escapes(FLAG_harmony_template_escapes);
     554   142877089 :   for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount;
     555             :        ++feature) {
     556   139305153 :     use_counts_[feature] = 0;
     557             :   }
     558     3571936 :   if (info->ast_value_factory() == NULL) {
     559             :     // info takes ownership of AstValueFactory.
     560             :     info->set_ast_value_factory(new AstValueFactory(
     561     3429773 :         zone(), info->ast_string_constants(), info->hash_seed()));
     562             :     info->set_ast_value_factory_owned();
     563     3429793 :     ast_value_factory_ = info->ast_value_factory();
     564             :     ast_node_factory_.set_ast_value_factory(ast_value_factory_);
     565             :   }
     566     3571956 : }
     567             : 
     568     3567735 : void Parser::DeserializeScopeChain(
     569             :     ParseInfo* info, MaybeHandle<ScopeInfo> maybe_outer_scope_info) {
     570             :   // TODO(wingo): Add an outer SCRIPT_SCOPE corresponding to the native
     571             :   // context, which will have the "this" binding for script scopes.
     572     6967193 :   DeclarationScope* script_scope = NewScriptScope();
     573             :   info->set_script_scope(script_scope);
     574             :   Scope* scope = script_scope;
     575             :   Handle<ScopeInfo> outer_scope_info;
     576     3567716 :   if (maybe_outer_scope_info.ToHandle(&outer_scope_info)) {
     577             :     DCHECK(ThreadId::Current().Equals(
     578             :         outer_scope_info->GetIsolate()->thread_id()));
     579             :     scope = Scope::DeserializeScopeChain(
     580             :         zone(), *outer_scope_info, script_scope, ast_value_factory(),
     581     1699729 :         Scope::DeserializationMode::kScopesOnly);
     582             :     DCHECK(!info->is_module() || scope->is_module_scope());
     583             :   }
     584     3567716 :   original_scope_ = scope;
     585     3567716 : }
     586             : 
     587     9053534 : FunctionLiteral* Parser::ParseProgram(Isolate* isolate, ParseInfo* info) {
     588             :   // TODO(bmeurer): We temporarily need to pass allow_nesting = true here,
     589             :   // see comment for HistogramTimerScope class.
     590             : 
     591             :   // It's OK to use the Isolate & counters here, since this function is only
     592             :   // called in the main thread.
     593             :   DCHECK(parsing_on_main_thread_);
     594             :   RuntimeCallTimerScope runtime_timer(
     595             :       runtime_call_stats_, info->is_eval() ? &RuntimeCallStats::ParseEval
     596     2263349 :                                            : &RuntimeCallStats::ParseProgram);
     597     6790060 :   TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.ParseProgram");
     598             :   Handle<String> source(String::cast(info->script()->source()));
     599     2263352 :   isolate->counters()->total_parse_size()->Increment(source->length());
     600             :   base::ElapsedTimer timer;
     601     2263354 :   if (FLAG_trace_parse) {
     602             :     timer.Start();
     603             :   }
     604     4526707 :   fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone());
     605             : 
     606             :   // Initialize parser state.
     607     2263352 :   ParserLogger logger;
     608             : 
     609     2263355 :   if (produce_cached_parse_data()) {
     610         138 :     if (allow_lazy_) {
     611         138 :       log_ = &logger;
     612             :     } else {
     613           0 :       compile_options_ = ScriptCompiler::kNoCompileOptions;
     614             :     }
     615     2263217 :   } else if (consume_cached_parse_data()) {
     616          66 :     cached_parse_data_->Initialize();
     617             :   }
     618             : 
     619     2263355 :   DeserializeScopeChain(info, info->maybe_outer_scope_info());
     620             : 
     621     2263345 :   source = String::Flatten(source);
     622             :   FunctionLiteral* result;
     623             : 
     624             :   {
     625     2263344 :     std::unique_ptr<Utf16CharacterStream> stream(ScannerStream::For(source));
     626     2263354 :     if (FLAG_use_parse_tasks) {
     627             :       // FIXME(wiktorg) make it useful for something
     628             :       // TODO(wiktorg) make preparser work also with modules
     629           0 :       if (!info->is_module()) {
     630           0 :         scanner_.Initialize(stream.get());
     631             :         // NOTE: Some features will be double counted - once here and one more
     632             :         //  time while being fully parsed by a parse task.
     633             :         PreParser::PreParseResult result =
     634           0 :             reusable_preparser()->PreParseProgram(false, use_counts_);
     635           0 :         if (result == PreParser::kPreParseStackOverflow) {
     636             :           set_stack_overflow();
     637             :           return nullptr;
     638             :         }
     639           0 :         stream->Seek(0);
     640             :       }
     641             :     }
     642     2263354 :     scanner_.Initialize(stream.get());
     643     2263351 :     result = DoParseProgram(info);
     644             :   }
     645             :   if (result != NULL) {
     646             :     DCHECK_EQ(scanner_.peek_location().beg_pos, source->length());
     647             :   }
     648     2263353 :   HandleSourceURLComments(isolate, info->script());
     649             : 
     650     2263349 :   if (FLAG_trace_parse && result != nullptr) {
     651           0 :     double ms = timer.Elapsed().InMillisecondsF();
     652           0 :     if (info->is_eval()) {
     653           0 :       PrintF("[parsing eval");
     654           0 :     } else if (info->script()->name()->IsString()) {
     655             :       String* name = String::cast(info->script()->name());
     656           0 :       std::unique_ptr<char[]> name_chars = name->ToCString();
     657           0 :       PrintF("[parsing script: %s", name_chars.get());
     658             :     } else {
     659           0 :       PrintF("[parsing script");
     660             :     }
     661           0 :     PrintF(" - took %0.3f ms]\n", ms);
     662             :   }
     663     2263340 :   if (produce_cached_parse_data() && result != nullptr) {
     664         138 :     *info->cached_data() = logger.GetScriptData();
     665             :   }
     666     2263340 :   log_ = nullptr;
     667     2263340 :   return result;
     668             : }
     669             : 
     670             : 
     671     2281272 : FunctionLiteral* Parser::DoParseProgram(ParseInfo* info) {
     672             :   // Note that this function can be called from the main thread or from a
     673             :   // background thread. We should not access anything Isolate / heap dependent
     674             :   // via ParseInfo, and also not pass it forward.
     675             :   DCHECK_NULL(scope_);
     676             :   DCHECK_NULL(target_stack_);
     677             : 
     678     2263486 :   ParsingModeScope mode(this, allow_lazy_ ? PARSE_LAZILY : PARSE_EAGERLY);
     679    11632563 :   ResetFunctionLiteralId();
     680             :   DCHECK(info->function_literal_id() == FunctionLiteral::kIdTypeTopLevel ||
     681             :          info->function_literal_id() == FunctionLiteral::kIdTypeInvalid);
     682             : 
     683             :   FunctionLiteral* result = NULL;
     684             :   {
     685     2263486 :     Scope* outer = original_scope_;
     686             :     DCHECK_NOT_NULL(outer);
     687     2263486 :     parsing_module_ = info->is_module();
     688     2263486 :     if (info->is_eval()) {
     689     1400404 :       outer = NewEvalScope(outer);
     690      863082 :     } else if (parsing_module_) {
     691             :       DCHECK_EQ(outer, info->script_scope());
     692       17786 :       outer = NewModuleScope(info->script_scope());
     693             :     }
     694             : 
     695     2263486 :     DeclarationScope* scope = outer->AsDeclarationScope();
     696             : 
     697             :     scope->set_start_position(0);
     698             : 
     699     2263480 :     FunctionState function_state(&function_state_, &scope_, scope);
     700             : 
     701     2263485 :     ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16, zone());
     702     2263470 :     bool ok = true;
     703             :     int beg_pos = scanner()->location().beg_pos;
     704     2263470 :     if (parsing_module_) {
     705             :       // Declare the special module parameter.
     706       17786 :       auto name = ast_value_factory()->empty_string();
     707             :       bool is_duplicate;
     708             :       bool is_rest = false;
     709             :       bool is_optional = false;
     710             :       auto var =
     711             :           scope->DeclareParameter(name, VAR, is_optional, is_rest,
     712       17786 :                                   &is_duplicate, ast_value_factory(), beg_pos);
     713             :       DCHECK(!is_duplicate);
     714             :       var->AllocateTo(VariableLocation::PARAMETER, 0);
     715             : 
     716       17786 :       PrepareGeneratorVariables();
     717             :       Expression* initial_yield =
     718       17786 :           BuildInitialYield(kNoSourcePosition, kGeneratorFunction);
     719             :       body->Add(
     720       17786 :           factory()->NewExpressionStatement(initial_yield, kNoSourcePosition),
     721             :           zone());
     722             : 
     723       17786 :       ParseModuleItemList(body, &ok);
     724       25244 :       ok = ok &&
     725             :            module()->Validate(this->scope()->AsModuleScope(),
     726       40160 :                               &pending_error_handler_, zone());
     727             :     } else {
     728             :       // Don't count the mode in the use counters--give the program a chance
     729             :       // to enable script-wide strict mode below.
     730             :       this->scope()->SetLanguageMode(info->language_mode());
     731     2245684 :       ParseStatementList(body, Token::EOS, &ok);
     732             :     }
     733             : 
     734             :     // The parser will peek but not consume EOS.  Our scope logically goes all
     735             :     // the way to the EOS, though.
     736             :     scope->set_end_position(scanner()->peek_location().beg_pos);
     737             : 
     738     4172862 :     if (ok && is_strict(language_mode())) {
     739      282474 :       CheckStrictOctalLiteral(beg_pos, scanner()->location().end_pos, &ok);
     740             :     }
     741     4172517 :     if (ok && is_sloppy(language_mode())) {
     742             :       // TODO(littledan): Function bindings on the global object that modify
     743             :       // pre-existing bindings should be made writable, enumerable and
     744             :       // nonconfigurable if possible, whereas this code will leave attributes
     745             :       // unchanged if the property already exists.
     746     1626909 :       InsertSloppyBlockFunctionVarBindings(scope);
     747             :     }
     748     2263479 :     if (ok) {
     749     1909038 :       CheckConflictingVarDeclarations(scope, &ok);
     750             :     }
     751             : 
     752     4147331 :     if (ok && info->parse_restriction() == ONLY_SINGLE_FUNCTION_LITERAL) {
     753     1371087 :       if (body->length() != 1 ||
     754     1371072 :           !body->at(0)->IsExpressionStatement() ||
     755             :           !body->at(0)->AsExpressionStatement()->
     756      914038 :               expression()->IsFunctionLiteral()) {
     757          30 :         ReportMessage(MessageTemplate::kSingleFunctionLiteral);
     758          30 :         ok = false;
     759             :       }
     760             :     }
     761             : 
     762     2263479 :     if (ok) {
     763             :       RewriteDestructuringAssignments();
     764     1883814 :       int parameter_count = parsing_module_ ? 1 : 0;
     765             :       result = factory()->NewScriptOrEvalFunctionLiteral(
     766             :           scope, body, function_state.expected_property_count(),
     767     1883814 :           parameter_count);
     768             :     }
     769             :   }
     770             : 
     771             :   info->set_max_function_literal_id(GetLastFunctionLiteralId());
     772             : 
     773             :   // Make sure the target stack is empty.
     774             :   DCHECK(target_stack_ == NULL);
     775             : 
     776     2263486 :   return result;
     777             : }
     778             : 
     779     3912656 : FunctionLiteral* Parser::ParseFunction(Isolate* isolate, ParseInfo* info) {
     780             :   // It's OK to use the Isolate & counters here, since this function is only
     781             :   // called in the main thread.
     782             :   DCHECK(parsing_on_main_thread_);
     783             :   RuntimeCallTimerScope runtime_timer(runtime_call_stats_,
     784     1304219 :                                       &RuntimeCallStats::ParseFunction);
     785     3912657 :   TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.ParseFunction");
     786             :   Handle<String> source(String::cast(info->script()->source()));
     787     1304219 :   isolate->counters()->total_parse_size()->Increment(source->length());
     788             :   base::ElapsedTimer timer;
     789     1304219 :   if (FLAG_trace_parse) {
     790             :     timer.Start();
     791             :   }
     792             :   Handle<SharedFunctionInfo> shared_info = info->shared_info();
     793     1304219 :   DeserializeScopeChain(info, info->maybe_outer_scope_info());
     794     1304218 :   if (info->asm_function_scope()) {
     795       11262 :     original_scope_ = info->asm_function_scope();
     796     1304219 :     factory()->set_zone(info->zone());
     797             :   } else {
     798             :     DCHECK_EQ(factory()->zone(), info->zone());
     799             :   }
     800             : 
     801             :   // Initialize parser state.
     802     1304218 :   source = String::Flatten(source);
     803             :   FunctionLiteral* result;
     804             :   {
     805             :     std::unique_ptr<Utf16CharacterStream> stream(ScannerStream::For(
     806     1304219 :         source, shared_info->start_position(), shared_info->end_position()));
     807             :     Handle<String> name(String::cast(shared_info->name()));
     808     1304219 :     scanner_.Initialize(stream.get());
     809     1304219 :     info->set_function_name(ast_value_factory()->GetString(name));
     810     1304218 :     result = DoParseFunction(info);
     811     1304218 :     if (result != nullptr) {
     812     1297591 :       Handle<String> inferred_name(shared_info->inferred_name());
     813             :       result->set_inferred_name(inferred_name);
     814             :     }
     815             :   }
     816             : 
     817     1304219 :   if (FLAG_trace_parse && result != NULL) {
     818           0 :     double ms = timer.Elapsed().InMillisecondsF();
     819             :     // We need to make sure that the debug-name is available.
     820           0 :     ast_value_factory()->Internalize(isolate);
     821           0 :     std::unique_ptr<char[]> name_chars = result->debug_name()->ToCString();
     822           0 :     PrintF("[parsing function: %s - took %0.3f ms]\n", name_chars.get(), ms);
     823             :   }
     824     1304219 :   return result;
     825             : }
     826             : 
     827     1304247 : static FunctionLiteral::FunctionType ComputeFunctionType(ParseInfo* info) {
     828     1304247 :   if (info->is_declaration()) {
     829             :     return FunctionLiteral::kDeclaration;
     830      655180 :   } else if (info->is_named_expression()) {
     831             :     return FunctionLiteral::kNamedExpression;
     832     1560950 :   } else if (IsConciseMethod(info->function_kind()) ||
     833      460762 :              IsAccessorFunction(info->function_kind())) {
     834             :     return FunctionLiteral::kAccessorOrMethod;
     835             :   }
     836      453256 :   return FunctionLiteral::kAnonymousExpression;
     837             : }
     838             : 
     839     2774948 : FunctionLiteral* Parser::DoParseFunction(ParseInfo* info) {
     840             :   const AstRawString* raw_name = info->function_name();
     841             :   FunctionNameValidity function_name_validity = kSkipFunctionNameCheck;
     842     1304246 :   if (!raw_name) {
     843           1 :     bool ok = true;
     844     1409504 :     if (peek() == Token::LPAREN) {
     845             :       const AstRawString* variable_name;
     846             :       impl()->GetDefaultStrings(&raw_name, &variable_name);
     847             :     } else {
     848           0 :       bool is_strict_reserved = true;
     849           0 :       raw_name = ParseIdentifierOrStrictReservedWord(info->function_kind(),
     850           0 :                                                      &is_strict_reserved, &ok);
     851           0 :       if (!ok) return nullptr;
     852             :       function_name_validity = is_strict_reserved
     853             :                                    ? kFunctionNameIsStrictReserved
     854           0 :                                    : kFunctionNameValidityUnknown;
     855             :     }
     856             :   }
     857             : 
     858             :   DCHECK_NOT_NULL(raw_name);
     859             :   DCHECK_NULL(scope_);
     860             :   DCHECK_NULL(target_stack_);
     861             : 
     862             :   DCHECK(ast_value_factory());
     863     1304246 :   fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone());
     864     1304247 :   fni_->PushEnclosingName(raw_name);
     865             : 
     866             :   ResetFunctionLiteralId();
     867             :   DCHECK_LT(0, info->function_literal_id());
     868     1304247 :   SkipFunctionLiterals(info->function_literal_id() - 1);
     869             : 
     870             :   ParsingModeScope parsing_mode(this, PARSE_EAGERLY);
     871             : 
     872             :   // Place holder for the result.
     873             :   FunctionLiteral* result = nullptr;
     874             : 
     875             :   {
     876             :     // Parse the function literal.
     877     1304247 :     Scope* outer = original_scope_;
     878     1304247 :     DeclarationScope* outer_function = outer->GetClosureScope();
     879             :     DCHECK(outer);
     880     1304247 :     FunctionState function_state(&function_state_, &scope_, outer_function);
     881             :     BlockState block_state(&scope_, outer);
     882             :     DCHECK(is_sloppy(outer->language_mode()) ||
     883             :            is_strict(info->language_mode()));
     884     1304247 :     FunctionLiteral::FunctionType function_type = ComputeFunctionType(info);
     885     1304247 :     FunctionKind kind = info->function_kind();
     886     1304247 :     bool ok = true;
     887             : 
     888     1304247 :     if (IsArrowFunction(kind)) {
     889       53051 :       if (IsAsyncFunction(kind)) {
     890             :         DCHECK(!scanner()->HasAnyLineTerminatorAfterNext());
     891        1137 :         if (!Check(Token::ASYNC)) {
     892           1 :           CHECK(stack_overflow());
     893         155 :           return nullptr;
     894             :         }
     895        2244 :         if (!(peek_any_identifier() || peek() == Token::LPAREN)) {
     896         154 :           CHECK(stack_overflow());
     897             :           return nullptr;
     898             :         }
     899             :       }
     900             : 
     901             :       // TODO(adamk): We should construct this scope from the ScopeInfo.
     902       52897 :       DeclarationScope* scope = NewFunctionScope(kind);
     903             : 
     904             :       // This bit only needs to be explicitly set because we're
     905             :       // not passing the ScopeInfo to the Scope constructor.
     906       52897 :       SetLanguageMode(scope, info->language_mode());
     907             : 
     908             :       scope->set_start_position(info->start_position());
     909       52897 :       ExpressionClassifier formals_classifier(this);
     910             :       ParserFormalParameters formals(scope);
     911             :       int rewritable_length =
     912       52897 :           function_state.destructuring_assignments_to_rewrite().length();
     913             :       {
     914             :         // Parsing patterns as variable reference expression creates
     915             :         // NewUnresolved references in current scope. Enter arrow function
     916             :         // scope for formal parameter parsing.
     917             :         BlockState block_state(&scope_, scope);
     918       52897 :         if (Check(Token::LPAREN)) {
     919             :           // '(' StrictFormalParameters ')'
     920       42968 :           ParseFormalParameterList(&formals, &ok);
     921       42968 :           if (ok) ok = Check(Token::RPAREN);
     922             :         } else {
     923             :           // BindingIdentifier
     924        9929 :           ParseFormalParameter(&formals, &ok);
     925        9929 :           if (ok) DeclareFormalParameters(formals.scope, formals.params);
     926             :         }
     927             :       }
     928             : 
     929       52897 :       if (ok) {
     930       52793 :         if (GetLastFunctionLiteralId() != info->function_literal_id() - 1) {
     931             :           // If there were FunctionLiterals in the parameters, we need to
     932             :           // renumber them to shift down so the next function literal id for
     933             :           // the arrow function is the one requested.
     934             :           AstFunctionLiteralIdReindexer reindexer(
     935             :               stack_limit_,
     936         299 :               (info->function_literal_id() - 1) - GetLastFunctionLiteralId());
     937        1000 :           for (auto p : formals.params) {
     938         402 :             if (p->pattern != nullptr) reindexer.Reindex(p->pattern);
     939         402 :             if (p->initializer != nullptr) reindexer.Reindex(p->initializer);
     940             :           }
     941             :           ResetFunctionLiteralId();
     942         598 :           SkipFunctionLiterals(info->function_literal_id() - 1);
     943             :         }
     944             : 
     945             :         // Pass `accept_IN=true` to ParseArrowFunctionLiteral --- This should
     946             :         // not be observable, or else the preparser would have failed.
     947             :         Expression* expression =
     948       52793 :             ParseArrowFunctionLiteral(true, formals, rewritable_length, &ok);
     949       52793 :         if (ok) {
     950             :           // Scanning must end at the same position that was recorded
     951             :           // previously. If not, parsing has been interrupted due to a stack
     952             :           // overflow, at which point the partially parsed arrow function
     953             :           // concise body happens to be a valid expression. This is a problem
     954             :           // only for arrow functions with single expression bodies, since there
     955             :           // is no end token such as "}" for normal functions.
     956       52309 :           if (scanner()->location().end_pos == info->end_position()) {
     957             :             // The pre-parser saw an arrow function here, so the full parser
     958             :             // must produce a FunctionLiteral.
     959             :             DCHECK(expression->IsFunctionLiteral());
     960       52309 :             result = expression->AsFunctionLiteral();
     961             :             // Rewrite destructuring assignments in the parameters. (The ones
     962             :             // inside the function body are rewritten by
     963             :             // ParseArrowFunctionLiteral.)
     964             :             RewriteDestructuringAssignments();
     965             :           } else {
     966           0 :             ok = false;
     967             :           }
     968             :         }
     969             :       }
     970     1251196 :     } else if (IsDefaultConstructor(kind)) {
     971             :       DCHECK_EQ(scope(), outer);
     972             :       result = DefaultConstructor(raw_name, IsDerivedConstructor(kind),
     973        8157 :                                   info->start_position(), info->end_position());
     974             :     } else {
     975             :       result = ParseFunctionLiteral(
     976             :           raw_name, Scanner::Location::invalid(), function_name_validity, kind,
     977     1243039 :           kNoSourcePosition, function_type, info->language_mode(), &ok);
     978             :     }
     979             :     // Make sure the results agree.
     980             :     DCHECK(ok == (result != nullptr));
     981             :   }
     982             : 
     983             :   // Make sure the target stack is empty.
     984             :   DCHECK_NULL(target_stack_);
     985             :   DCHECK_IMPLIES(result,
     986             :                  info->function_literal_id() == result->function_literal_id());
     987     1304092 :   return result;
     988             : }
     989             : 
     990      101084 : Statement* Parser::ParseModuleItem(bool* ok) {
     991             :   // ecma262/#prod-ModuleItem
     992             :   // ModuleItem :
     993             :   //    ImportDeclaration
     994             :   //    ExportDeclaration
     995             :   //    StatementListItem
     996             : 
     997        2289 :   Token::Value next = peek();
     998             : 
     999      101084 :   if (next == Token::EXPORT) {
    1000        2103 :     return ParseExportDeclaration(ok);
    1001             :   }
    1002             : 
    1003             :   // We must be careful not to parse a dynamic import expression as an import
    1004             :   // declaration.
    1005      200251 :   if (next == Token::IMPORT &&
    1006         690 :       (!allow_harmony_dynamic_import() || PeekAhead() != Token::LPAREN)) {
    1007        1941 :     ParseImportDeclaration(CHECK_OK);
    1008        1614 :     return factory()->NewEmptyStatement(kNoSourcePosition);
    1009             :   }
    1010             : 
    1011       97040 :   return ParseStatementListItem(ok);
    1012             : }
    1013             : 
    1014             : 
    1015       17786 : void Parser::ParseModuleItemList(ZoneList<Statement*>* body, bool* ok) {
    1016             :   // ecma262/#prod-Module
    1017             :   // Module :
    1018             :   //    ModuleBody?
    1019             :   //
    1020             :   // ecma262/#prod-ModuleItemList
    1021             :   // ModuleBody :
    1022             :   //    ModuleItem*
    1023             : 
    1024             :   DCHECK(scope()->is_module_scope());
    1025      126328 :   while (peek() != Token::EOS) {
    1026      118870 :     Statement* stat = ParseModuleItem(CHECK_OK_VOID);
    1027       90756 :     if (stat && !stat->IsEmpty()) {
    1028       72136 :       body->Add(stat, zone());
    1029             :     }
    1030             :   }
    1031             : }
    1032             : 
    1033             : 
    1034        1073 : const AstRawString* Parser::ParseModuleSpecifier(bool* ok) {
    1035             :   // ModuleSpecifier :
    1036             :   //    StringLiteral
    1037             : 
    1038        1073 :   Expect(Token::STRING, CHECK_OK);
    1039        1055 :   return GetSymbol();
    1040             : }
    1041             : 
    1042             : 
    1043         575 : void Parser::ParseExportClause(ZoneList<const AstRawString*>* export_names,
    1044             :                                ZoneList<Scanner::Location>* export_locations,
    1045             :                                ZoneList<const AstRawString*>* local_names,
    1046             :                                Scanner::Location* reserved_loc, bool* ok) {
    1047             :   // ExportClause :
    1048             :   //   '{' '}'
    1049             :   //   '{' ExportsList '}'
    1050             :   //   '{' ExportsList ',' '}'
    1051             :   //
    1052             :   // ExportsList :
    1053             :   //   ExportSpecifier
    1054             :   //   ExportsList ',' ExportSpecifier
    1055             :   //
    1056             :   // ExportSpecifier :
    1057             :   //   IdentifierName
    1058             :   //   IdentifierName 'as' IdentifierName
    1059             : 
    1060        3262 :   Expect(Token::LBRACE, CHECK_OK_VOID);
    1061             : 
    1062             :   Token::Value name_tok;
    1063         676 :   while ((name_tok = peek()) != Token::RBRACE) {
    1064             :     // Keep track of the first reserved word encountered in case our
    1065             :     // caller needs to report an error.
    1066        1230 :     if (!reserved_loc->IsValid() &&
    1067         615 :         !Token::IsIdentifier(name_tok, STRICT, false, parsing_module_)) {
    1068          81 :       *reserved_loc = scanner()->location();
    1069             :     }
    1070         663 :     const AstRawString* local_name = ParseIdentifierName(CHECK_OK_VOID);
    1071             :     const AstRawString* export_name = NULL;
    1072         591 :     Scanner::Location location = scanner()->location();
    1073         591 :     if (CheckContextualKeyword(Token::AS)) {
    1074         290 :       export_name = ParseIdentifierName(CHECK_OK_VOID);
    1075             :       // Set the location to the whole "a as b" string, so that it makes sense
    1076             :       // both for errors due to "a" and for errors due to "b".
    1077         278 :       location.end_pos = scanner()->location().end_pos;
    1078             :     }
    1079         579 :     if (export_name == NULL) {
    1080             :       export_name = local_name;
    1081             :     }
    1082             :     export_names->Add(export_name, zone());
    1083             :     local_names->Add(local_name, zone());
    1084             :     export_locations->Add(location, zone());
    1085         579 :     if (peek() == Token::RBRACE) break;
    1086         113 :     Expect(Token::COMMA, CHECK_OK_VOID);
    1087             :   }
    1088             : 
    1089         527 :   Expect(Token::RBRACE, CHECK_OK_VOID);
    1090             : }
    1091             : 
    1092             : 
    1093         804 : ZoneList<const Parser::NamedImport*>* Parser::ParseNamedImports(
    1094             :     int pos, bool* ok) {
    1095             :   // NamedImports :
    1096             :   //   '{' '}'
    1097             :   //   '{' ImportsList '}'
    1098             :   //   '{' ImportsList ',' '}'
    1099             :   //
    1100             :   // ImportsList :
    1101             :   //   ImportSpecifier
    1102             :   //   ImportsList ',' ImportSpecifier
    1103             :   //
    1104             :   // ImportSpecifier :
    1105             :   //   BindingIdentifier
    1106             :   //   IdentifierName 'as' BindingIdentifier
    1107             : 
    1108        4777 :   Expect(Token::LBRACE, CHECK_OK);
    1109             : 
    1110         804 :   auto result = new (zone()) ZoneList<const NamedImport*>(1, zone());
    1111        1729 :   while (peek() != Token::RBRACE) {
    1112         893 :     const AstRawString* import_name = ParseIdentifierName(CHECK_OK);
    1113             :     const AstRawString* local_name = import_name;
    1114             :     Scanner::Location location = scanner()->location();
    1115             :     // In the presence of 'as', the left-side of the 'as' can
    1116             :     // be any IdentifierName. But without 'as', it must be a valid
    1117             :     // BindingIdentifier.
    1118         827 :     if (CheckContextualKeyword(Token::AS)) {
    1119         374 :       local_name = ParseIdentifierName(CHECK_OK);
    1120             :     }
    1121         827 :     if (!Token::IsIdentifier(scanner()->current_token(), STRICT, false,
    1122        1654 :                              parsing_module_)) {
    1123          36 :       *ok = false;
    1124          36 :       ReportMessage(MessageTemplate::kUnexpectedReserved);
    1125          36 :       return nullptr;
    1126         791 :     } else if (IsEvalOrArguments(local_name)) {
    1127          18 :       *ok = false;
    1128          18 :       ReportMessage(MessageTemplate::kStrictEvalArguments);
    1129          18 :       return nullptr;
    1130             :     }
    1131             : 
    1132             :     DeclareVariable(local_name, CONST, kNeedsInitialization, position(),
    1133         773 :                     CHECK_OK);
    1134             : 
    1135             :     NamedImport* import =
    1136             :         new (zone()) NamedImport(import_name, local_name, location);
    1137             :     result->Add(import, zone());
    1138             : 
    1139         773 :     if (peek() == Token::RBRACE) break;
    1140         169 :     Expect(Token::COMMA, CHECK_OK);
    1141             :   }
    1142             : 
    1143         636 :   Expect(Token::RBRACE, CHECK_OK);
    1144         636 :   return result;
    1145             : }
    1146             : 
    1147             : 
    1148        1941 : void Parser::ParseImportDeclaration(bool* ok) {
    1149             :   // ImportDeclaration :
    1150             :   //   'import' ImportClause 'from' ModuleSpecifier ';'
    1151             :   //   'import' ModuleSpecifier ';'
    1152             :   //
    1153             :   // ImportClause :
    1154             :   //   ImportedDefaultBinding
    1155             :   //   NameSpaceImport
    1156             :   //   NamedImports
    1157             :   //   ImportedDefaultBinding ',' NameSpaceImport
    1158             :   //   ImportedDefaultBinding ',' NamedImports
    1159             :   //
    1160             :   // NameSpaceImport :
    1161             :   //   '*' 'as' ImportedBinding
    1162             : 
    1163        2998 :   int pos = peek_position();
    1164        3164 :   Expect(Token::IMPORT, CHECK_OK_VOID);
    1165             : 
    1166             :   Token::Value tok = peek();
    1167             : 
    1168             :   // 'import' ModuleSpecifier ';'
    1169        1941 :   if (tok == Token::STRING) {
    1170          89 :     const AstRawString* module_specifier = ParseModuleSpecifier(CHECK_OK_VOID);
    1171          89 :     ExpectSemicolon(CHECK_OK_VOID);
    1172          89 :     module()->AddEmptyImport(module_specifier);
    1173          89 :     return;
    1174             :   }
    1175             : 
    1176             :   // Parse ImportedDefaultBinding if present.
    1177             :   const AstRawString* import_default_binding = nullptr;
    1178             :   Scanner::Location import_default_binding_loc;
    1179        1852 :   if (tok != Token::MUL && tok != Token::LBRACE) {
    1180             :     import_default_binding =
    1181         926 :         ParseIdentifier(kDontAllowRestrictedIdentifiers, CHECK_OK_VOID);
    1182          86 :     import_default_binding_loc = scanner()->location();
    1183             :     DeclareVariable(import_default_binding, CONST, kNeedsInitialization, pos,
    1184          86 :                     CHECK_OK_VOID);
    1185             :   }
    1186             : 
    1187             :   // Parse NameSpaceImport or NamedImports if present.
    1188             :   const AstRawString* module_namespace_binding = nullptr;
    1189             :   Scanner::Location module_namespace_binding_loc;
    1190             :   const ZoneList<const NamedImport*>* named_imports = nullptr;
    1191        1012 :   if (import_default_binding == nullptr || Check(Token::COMMA)) {
    1192         950 :     switch (peek()) {
    1193             :       case Token::MUL: {
    1194         134 :         Consume(Token::MUL);
    1195         134 :         ExpectContextualKeyword(Token::AS, CHECK_OK_VOID);
    1196             :         module_namespace_binding =
    1197         134 :             ParseIdentifier(kDontAllowRestrictedIdentifiers, CHECK_OK_VOID);
    1198         134 :         module_namespace_binding_loc = scanner()->location();
    1199             :         DeclareVariable(module_namespace_binding, CONST, kCreatedInitialized,
    1200         134 :                         pos, CHECK_OK_VOID);
    1201             :         break;
    1202             :       }
    1203             : 
    1204             :       case Token::LBRACE:
    1205         804 :         named_imports = ParseNamedImports(pos, CHECK_OK_VOID);
    1206             :         break;
    1207             : 
    1208             :       default:
    1209          12 :         *ok = false;
    1210          12 :         ReportUnexpectedToken(scanner()->current_token());
    1211          12 :         return;
    1212             :     }
    1213             :   }
    1214             : 
    1215         832 :   ExpectContextualKeyword(Token::FROM, CHECK_OK_VOID);
    1216         724 :   const AstRawString* module_specifier = ParseModuleSpecifier(CHECK_OK_VOID);
    1217         718 :   ExpectSemicolon(CHECK_OK_VOID);
    1218             : 
    1219             :   // Now that we have all the information, we can make the appropriate
    1220             :   // declarations.
    1221             : 
    1222             :   // TODO(neis): Would prefer to call DeclareVariable for each case below rather
    1223             :   // than above and in ParseNamedImports, but then a possible error message
    1224             :   // would point to the wrong location.  Maybe have a DeclareAt version of
    1225             :   // Declare that takes a location?
    1226             : 
    1227         718 :   if (module_namespace_binding != nullptr) {
    1228             :     module()->AddStarImport(module_namespace_binding, module_specifier,
    1229         116 :                             module_namespace_binding_loc, zone());
    1230             :   }
    1231             : 
    1232         718 :   if (import_default_binding != nullptr) {
    1233             :     module()->AddImport(ast_value_factory()->default_string(),
    1234             :                         import_default_binding, module_specifier,
    1235         112 :                         import_default_binding_loc, zone());
    1236             :   }
    1237             : 
    1238         718 :   if (named_imports != nullptr) {
    1239        1749 :     if (named_imports->length() == 0) {
    1240          20 :       module()->AddEmptyImport(module_specifier);
    1241             :     } else {
    1242        1844 :       for (int i = 0; i < named_imports->length(); ++i) {
    1243         653 :         const NamedImport* import = named_imports->at(i);
    1244             :         module()->AddImport(import->import_name, import->local_name,
    1245        1306 :                             module_specifier, import->location, zone());
    1246             :       }
    1247             :     }
    1248             :   }
    1249             : }
    1250             : 
    1251             : 
    1252         450 : Statement* Parser::ParseExportDefault(bool* ok) {
    1253             :   //  Supports the following productions, starting after the 'default' token:
    1254             :   //    'export' 'default' HoistableDeclaration
    1255             :   //    'export' 'default' ClassDeclaration
    1256             :   //    'export' 'default' AssignmentExpression[In] ';'
    1257             : 
    1258        2387 :   Expect(Token::DEFAULT, CHECK_OK);
    1259         450 :   Scanner::Location default_loc = scanner()->location();
    1260             : 
    1261         450 :   ZoneList<const AstRawString*> local_names(1, zone());
    1262             :   Statement* result = nullptr;
    1263         450 :   switch (peek()) {
    1264             :     case Token::FUNCTION:
    1265          79 :       result = ParseHoistableDeclaration(&local_names, true, CHECK_OK);
    1266             :       break;
    1267             : 
    1268             :     case Token::CLASS:
    1269          52 :       Consume(Token::CLASS);
    1270          52 :       result = ParseClassDeclaration(&local_names, true, CHECK_OK);
    1271             :       break;
    1272             : 
    1273             :     case Token::ASYNC:
    1274         144 :       if (PeekAhead() == Token::FUNCTION &&
    1275             :           !scanner()->HasAnyLineTerminatorAfterNext()) {
    1276          72 :         Consume(Token::ASYNC);
    1277          72 :         result = ParseAsyncFunctionDeclaration(&local_names, true, CHECK_OK);
    1278             :         break;
    1279             :       }
    1280             :     /* falls through */
    1281             : 
    1282             :     default: {
    1283             :       int pos = position();
    1284         247 :       ExpressionClassifier classifier(this);
    1285         247 :       Expression* value = ParseAssignmentExpression(true, CHECK_OK);
    1286         199 :       RewriteNonPattern(CHECK_OK);
    1287         398 :       SetFunctionName(value, ast_value_factory()->default_string());
    1288             : 
    1289             :       const AstRawString* local_name =
    1290         199 :           ast_value_factory()->star_default_star_string();
    1291             :       local_names.Add(local_name, zone());
    1292             : 
    1293             :       // It's fine to declare this as CONST because the user has no way of
    1294             :       // writing to it.
    1295         597 :       Declaration* decl = DeclareVariable(local_name, CONST, pos, CHECK_OK);
    1296         199 :       decl->proxy()->var()->set_initializer_position(position());
    1297             : 
    1298             :       Assignment* assignment = factory()->NewAssignment(
    1299         199 :           Token::INIT, decl->proxy(), value, kNoSourcePosition);
    1300             :       result = IgnoreCompletion(
    1301         199 :           factory()->NewExpressionStatement(assignment, kNoSourcePosition));
    1302             : 
    1303         199 :       ExpectSemicolon(CHECK_OK);
    1304             :       break;
    1305             :     }
    1306             :   }
    1307             : 
    1308             :   DCHECK_EQ(local_names.length(), 1);
    1309             :   module()->AddExport(local_names.first(),
    1310             :                       ast_value_factory()->default_string(), default_loc,
    1311        1116 :                       zone());
    1312             : 
    1313             :   DCHECK_NOT_NULL(result);
    1314         372 :   return result;
    1315             : }
    1316             : 
    1317        2103 : Statement* Parser::ParseExportDeclaration(bool* ok) {
    1318             :   // ExportDeclaration:
    1319             :   //    'export' '*' 'from' ModuleSpecifier ';'
    1320             :   //    'export' ExportClause ('from' ModuleSpecifier)? ';'
    1321             :   //    'export' VariableStatement
    1322             :   //    'export' Declaration
    1323             :   //    'export' 'default' ... (handled in ParseExportDefault)
    1324             : 
    1325        8414 :   Expect(Token::EXPORT, CHECK_OK);
    1326             :   int pos = position();
    1327             : 
    1328             :   Statement* result = nullptr;
    1329        2103 :   ZoneList<const AstRawString*> names(1, zone());
    1330        2103 :   Scanner::Location loc = scanner()->peek_location();
    1331        2103 :   switch (peek()) {
    1332             :     case Token::DEFAULT:
    1333         450 :       return ParseExportDefault(ok);
    1334             : 
    1335             :     case Token::MUL: {
    1336         134 :       Consume(Token::MUL);
    1337         134 :       loc = scanner()->location();
    1338         134 :       ExpectContextualKeyword(Token::FROM, CHECK_OK);
    1339         128 :       const AstRawString* module_specifier = ParseModuleSpecifier(CHECK_OK);
    1340         122 :       ExpectSemicolon(CHECK_OK);
    1341         122 :       module()->AddStarExport(module_specifier, loc, zone());
    1342         244 :       return factory()->NewEmptyStatement(pos);
    1343             :     }
    1344             : 
    1345             :     case Token::LBRACE: {
    1346             :       // There are two cases here:
    1347             :       //
    1348             :       // 'export' ExportClause ';'
    1349             :       // and
    1350             :       // 'export' ExportClause FromClause ';'
    1351             :       //
    1352             :       // In the first case, the exported identifiers in ExportClause must
    1353             :       // not be reserved words, while in the latter they may be. We
    1354             :       // pass in a location that gets filled with the first reserved word
    1355             :       // encountered, and then throw a SyntaxError if we are in the
    1356             :       // non-FromClause case.
    1357         575 :       Scanner::Location reserved_loc = Scanner::Location::invalid();
    1358         575 :       ZoneList<const AstRawString*> export_names(1, zone());
    1359         575 :       ZoneList<Scanner::Location> export_locations(1, zone());
    1360         575 :       ZoneList<const AstRawString*> original_names(1, zone());
    1361             :       ParseExportClause(&export_names, &export_locations, &original_names,
    1362         575 :                         &reserved_loc, CHECK_OK);
    1363             :       const AstRawString* module_specifier = nullptr;
    1364         527 :       if (CheckContextualKeyword(Token::FROM)) {
    1365         132 :         module_specifier = ParseModuleSpecifier(CHECK_OK);
    1366         395 :       } else if (reserved_loc.IsValid()) {
    1367             :         // No FromClause, so reserved words are invalid in ExportClause.
    1368          12 :         *ok = false;
    1369             :         ReportMessageAt(reserved_loc, MessageTemplate::kUnexpectedReserved);
    1370             :         return nullptr;
    1371             :       }
    1372         509 :       ExpectSemicolon(CHECK_OK);
    1373         509 :       const int length = export_names.length();
    1374             :       DCHECK_EQ(length, original_names.length());
    1375             :       DCHECK_EQ(length, export_locations.length());
    1376         509 :       if (module_specifier == nullptr) {
    1377         425 :         for (int i = 0; i < length; ++i) {
    1378         850 :           module()->AddExport(original_names[i], export_names[i],
    1379        1700 :                               export_locations[i], zone());
    1380             :         }
    1381         126 :       } else if (length == 0) {
    1382          35 :         module()->AddEmptyImport(module_specifier);
    1383             :       } else {
    1384         112 :         for (int i = 0; i < length; ++i) {
    1385         224 :           module()->AddExport(original_names[i], export_names[i],
    1386         448 :                               module_specifier, export_locations[i], zone());
    1387             :         }
    1388             :       }
    1389        1018 :       return factory()->NewEmptyStatement(pos);
    1390             :     }
    1391             : 
    1392             :     case Token::FUNCTION:
    1393         332 :       result = ParseHoistableDeclaration(&names, false, CHECK_OK);
    1394             :       break;
    1395             : 
    1396             :     case Token::CLASS:
    1397          39 :       Consume(Token::CLASS);
    1398          39 :       result = ParseClassDeclaration(&names, false, CHECK_OK);
    1399             :       break;
    1400             : 
    1401             :     case Token::VAR:
    1402             :     case Token::LET:
    1403             :     case Token::CONST:
    1404         465 :       result = ParseVariableStatement(kStatementListItem, &names, CHECK_OK);
    1405             :       break;
    1406             : 
    1407             :     case Token::ASYNC:
    1408             :       // TODO(neis): Why don't we have the same check here as in
    1409             :       // ParseStatementListItem?
    1410         102 :       Consume(Token::ASYNC);
    1411         102 :       result = ParseAsyncFunctionDeclaration(&names, false, CHECK_OK);
    1412             :       break;
    1413             : 
    1414             :     default:
    1415           6 :       *ok = false;
    1416           6 :       ReportUnexpectedToken(scanner()->current_token());
    1417           6 :       return nullptr;
    1418             :   }
    1419         842 :   loc.end_pos = scanner()->location().end_pos;
    1420             : 
    1421             :   ModuleDescriptor* descriptor = module();
    1422        1684 :   for (int i = 0; i < names.length(); ++i) {
    1423        1684 :     descriptor->AddExport(names[i], names[i], loc, zone());
    1424             :   }
    1425             : 
    1426             :   DCHECK_NOT_NULL(result);
    1427             :   return result;
    1428             : }
    1429             : 
    1430    86686319 : VariableProxy* Parser::NewUnresolved(const AstRawString* name, int begin_pos,
    1431             :                                      VariableKind kind) {
    1432    86760120 :   return scope()->NewUnresolved(factory(), name, begin_pos, kind);
    1433             : }
    1434             : 
    1435           0 : VariableProxy* Parser::NewUnresolved(const AstRawString* name) {
    1436       35407 :   return scope()->NewUnresolved(factory(), name, scanner()->location().beg_pos);
    1437             : }
    1438             : 
    1439       56856 : Declaration* Parser::DeclareVariable(const AstRawString* name,
    1440             :                                      VariableMode mode, int pos, bool* ok) {
    1441             :   return DeclareVariable(name, mode, Variable::DefaultInitializationFlag(mode),
    1442      170455 :                          pos, ok);
    1443             : }
    1444             : 
    1445      171448 : Declaration* Parser::DeclareVariable(const AstRawString* name,
    1446             :                                      VariableMode mode, InitializationFlag init,
    1447             :                                      int pos, bool* ok) {
    1448             :   DCHECK_NOT_NULL(name);
    1449             :   VariableProxy* proxy = factory()->NewVariableProxy(
    1450      514344 :       name, NORMAL_VARIABLE, scanner()->location().beg_pos);
    1451             :   Declaration* declaration =
    1452      171448 :       factory()->NewVariableDeclaration(proxy, this->scope(), pos);
    1453             :   Declare(declaration, DeclarationDescriptor::NORMAL, mode, init, ok, nullptr,
    1454      171448 :           scanner()->location().end_pos);
    1455      171448 :   if (!*ok) return nullptr;
    1456      165960 :   return declaration;
    1457             : }
    1458             : 
    1459    16574958 : Variable* Parser::Declare(Declaration* declaration,
    1460             :                           DeclarationDescriptor::Kind declaration_kind,
    1461             :                           VariableMode mode, InitializationFlag init, bool* ok,
    1462             :                           Scope* scope, int var_end_pos) {
    1463    16419892 :   if (scope == nullptr) {
    1464    32838306 :     scope = this->scope();
    1465             :   }
    1466    16419892 :   bool sloppy_mode_block_scope_function_redefinition = false;
    1467             :   Variable* variable = scope->DeclareVariable(
    1468             :       declaration, mode, init, allow_harmony_restrictive_generators(),
    1469    16419892 :       &sloppy_mode_block_scope_function_redefinition, ok);
    1470    16419895 :   if (!*ok) {
    1471             :     // If we only have the start position of a proxy, we can't highlight the
    1472             :     // whole variable name.  Pretend its length is 1 so that we highlight at
    1473             :     // least the first character.
    1474             :     Scanner::Location loc(declaration->proxy()->position(),
    1475             :                           var_end_pos != kNoSourcePosition
    1476             :                               ? var_end_pos
    1477      235343 :                               : declaration->proxy()->position() + 1);
    1478       80277 :     if (declaration_kind == DeclarationDescriptor::NORMAL) {
    1479             :       ReportMessageAt(loc, MessageTemplate::kVarRedeclaration,
    1480             :                       declaration->proxy()->raw_name());
    1481             :     } else {
    1482             :       ReportMessageAt(loc, MessageTemplate::kParamDupe);
    1483             :     }
    1484             :     return nullptr;
    1485             :   }
    1486    16339618 :   if (sloppy_mode_block_scope_function_redefinition) {
    1487         238 :     ++use_counts_[v8::Isolate::kSloppyModeBlockScopedFunctionRedefinition];
    1488             :   }
    1489    16339618 :   return variable;
    1490             : }
    1491             : 
    1492      720937 : Block* Parser::BuildInitializationBlock(
    1493             :     DeclarationParsingResult* parsing_result,
    1494             :     ZoneList<const AstRawString*>* names, bool* ok) {
    1495             :   Block* result = factory()->NewBlock(
    1496      720937 :       NULL, 1, true, parsing_result->descriptor.declaration_pos);
    1497     2189319 :   for (auto declaration : parsing_result->declarations) {
    1498             :     PatternRewriter::DeclareAndInitializeVariables(
    1499             :         this, result, &(parsing_result->descriptor), &declaration, names,
    1500      747473 :         CHECK_OK);
    1501             :   }
    1502      720909 :   return result;
    1503             : }
    1504             : 
    1505           0 : void Parser::DeclareAndInitializeVariables(
    1506             :     Block* block, const DeclarationDescriptor* declaration_descriptor,
    1507             :     const DeclarationParsingResult::Declaration* declaration,
    1508             :     ZoneList<const AstRawString*>* names, bool* ok) {
    1509             :   DCHECK_NOT_NULL(block);
    1510             :   PatternRewriter::DeclareAndInitializeVariables(
    1511    13356511 :       this, block, declaration_descriptor, declaration, names, ok);
    1512           0 : }
    1513             : 
    1514     1752082 : Statement* Parser::DeclareFunction(const AstRawString* variable_name,
    1515             :                                    FunctionLiteral* function, VariableMode mode,
    1516             :                                    int pos, bool is_sloppy_block_function,
    1517             :                                    ZoneList<const AstRawString*>* names,
    1518             :                                    bool* ok) {
    1519             :   VariableProxy* proxy =
    1520     3515224 :       factory()->NewVariableProxy(variable_name, NORMAL_VARIABLE);
    1521             : 
    1522             :   Declaration* declaration =
    1523     1752082 :       factory()->NewFunctionDeclaration(proxy, function, scope(), pos);
    1524             :   Declare(declaration, DeclarationDescriptor::NORMAL, mode, kCreatedInitialized,
    1525     1752082 :           CHECK_OK);
    1526     1749516 :   if (names) names->Add(variable_name, zone());
    1527     1749516 :   if (is_sloppy_block_function) {
    1528             :     SloppyBlockFunctionStatement* statement =
    1529       10583 :         factory()->NewSloppyBlockFunctionStatement();
    1530             :     GetDeclarationScope()->DeclareSloppyBlockFunction(variable_name, scope(),
    1531       10583 :                                                       statement);
    1532       10583 :     return statement;
    1533             :   }
    1534     3477866 :   return factory()->NewEmptyStatement(kNoSourcePosition);
    1535             : }
    1536             : 
    1537             : Statement* Parser::DeclareClass(const AstRawString* variable_name,
    1538             :                                 Expression* value,
    1539             :                                 ZoneList<const AstRawString*>* names,
    1540             :                                 int class_token_pos, int end_pos, bool* ok) {
    1541       96760 :   Declaration* decl =
    1542       53868 :       DeclareVariable(variable_name, LET, class_token_pos, CHECK_OK);
    1543       48380 :   decl->proxy()->var()->set_initializer_position(end_pos);
    1544       48380 :   if (names) names->Add(variable_name, zone());
    1545             : 
    1546       48380 :   Assignment* assignment = factory()->NewAssignment(Token::INIT, decl->proxy(),
    1547       48380 :                                                     value, class_token_pos);
    1548             :   return IgnoreCompletion(
    1549       48380 :       factory()->NewExpressionStatement(assignment, kNoSourcePosition));
    1550             : }
    1551             : 
    1552             : Statement* Parser::DeclareNative(const AstRawString* name, int pos, bool* ok) {
    1553             :   // Make sure that the function containing the native declaration
    1554             :   // isn't lazily compiled. The extension structures are only
    1555             :   // accessible while parsing the first time not when reparsing
    1556             :   // because of lazy compilation.
    1557        2988 :   GetClosureScope()->ForceEagerCompilation();
    1558             : 
    1559             :   // TODO(1240846): It's weird that native function declarations are
    1560             :   // introduced dynamically when we meet their declarations, whereas
    1561             :   // other functions are set up when entering the surrounding scope.
    1562        5976 :   Declaration* decl = DeclareVariable(name, VAR, pos, CHECK_OK);
    1563             :   NativeFunctionLiteral* lit =
    1564        2988 :       factory()->NewNativeFunctionLiteral(name, extension_, kNoSourcePosition);
    1565             :   return factory()->NewExpressionStatement(
    1566        2988 :       factory()->NewAssignment(Token::INIT, decl->proxy(), lit,
    1567        2988 :                                kNoSourcePosition),
    1568        2988 :       pos);
    1569             : }
    1570             : 
    1571       25158 : ZoneList<const AstRawString*>* Parser::DeclareLabel(
    1572             :     ZoneList<const AstRawString*>* labels, VariableProxy* var, bool* ok) {
    1573             :   DCHECK(IsIdentifier(var));
    1574             :   const AstRawString* label = var->raw_name();
    1575             :   // TODO(1240780): We don't check for redeclaration of labels
    1576             :   // during preparsing since keeping track of the set of active
    1577             :   // labels requires nontrivial changes to the way scopes are
    1578             :   // structured.  However, these are probably changes we want to
    1579             :   // make later anyway so we should go back and fix this then.
    1580       25158 :   if (ContainsLabel(labels, label) || TargetStackContainsLabel(label)) {
    1581       75133 :     ReportMessage(MessageTemplate::kLabelRedeclaration, label);
    1582           0 :     *ok = false;
    1583           0 :     return nullptr;
    1584             :   }
    1585       25158 :   if (labels == nullptr) {
    1586       24817 :     labels = new (zone()) ZoneList<const AstRawString*>(1, zone());
    1587             :   }
    1588             :   labels->Add(label, zone());
    1589             :   // Remove the "ghost" variable that turned out to be a label
    1590             :   // from the top scope. This way, we don't try to resolve it
    1591             :   // during the scope processing.
    1592       25158 :   scope()->RemoveUnresolved(var);
    1593       25158 :   return labels;
    1594             : }
    1595             : 
    1596           0 : bool Parser::ContainsLabel(ZoneList<const AstRawString*>* labels,
    1597             :                            const AstRawString* label) {
    1598             :   DCHECK_NOT_NULL(label);
    1599      142162 :   if (labels != nullptr) {
    1600       54460 :     for (int i = labels->length(); i-- > 0;) {
    1601       25337 :       if (labels->at(i) == label) return true;
    1602             :     }
    1603             :   }
    1604             :   return false;
    1605             : }
    1606             : 
    1607             : Block* Parser::IgnoreCompletion(Statement* statement) {
    1608      652628 :   Block* block = factory()->NewBlock(nullptr, 1, true, kNoSourcePosition);
    1609      652628 :   block->statements()->Add(statement, zone());
    1610             :   return block;
    1611             : }
    1612             : 
    1613     5379147 : Expression* Parser::RewriteReturn(Expression* return_value, int pos) {
    1614    10758303 :   if (IsDerivedConstructor(function_state_->kind())) {
    1615             :     // For subclass constructors we need to return this in case of undefined;
    1616             :     // other primitive values trigger an exception in the ConstructStub.
    1617             :     //
    1618             :     //   return expr;
    1619             :     //
    1620             :     // Is rewritten as:
    1621             :     //
    1622             :     //   return (temp = expr) === undefined ? this : temp;
    1623             : 
    1624             :     // temp = expr
    1625         874 :     Variable* temp = NewTemporary(ast_value_factory()->empty_string());
    1626             :     Assignment* assign = factory()->NewAssignment(
    1627        1748 :         Token::ASSIGN, factory()->NewVariableProxy(temp), return_value, pos);
    1628             : 
    1629             :     // temp === undefined
    1630             :     Expression* is_undefined = factory()->NewCompareOperation(
    1631             :         Token::EQ_STRICT, assign,
    1632         874 :         factory()->NewUndefinedLiteral(kNoSourcePosition), pos);
    1633             : 
    1634             :     // is_undefined ? this : temp
    1635             :     return_value =
    1636             :         factory()->NewConditional(is_undefined, ThisExpression(pos),
    1637        1748 :                                   factory()->NewVariableProxy(temp), pos);
    1638             :   }
    1639     5379156 :   return return_value;
    1640             : }
    1641             : 
    1642         760 : Expression* Parser::RewriteDoExpression(Block* body, int pos, bool* ok) {
    1643        1520 :   Variable* result = NewTemporary(ast_value_factory()->dot_result_string());
    1644         760 :   DoExpression* expr = factory()->NewDoExpression(body, result, pos);
    1645         760 :   if (!Rewriter::Rewrite(this, GetClosureScope(), expr, ast_value_factory())) {
    1646           0 :     *ok = false;
    1647           0 :     return nullptr;
    1648             :   }
    1649             :   return expr;
    1650             : }
    1651             : 
    1652       89081 : Statement* Parser::RewriteSwitchStatement(Expression* tag,
    1653             :                                           SwitchStatement* switch_statement,
    1654             :                                           ZoneList<CaseClause*>* cases,
    1655             :                                           Scope* scope) {
    1656             :   // In order to get the CaseClauses to execute in their own lexical scope,
    1657             :   // but without requiring downstream code to have special scope handling
    1658             :   // code for switch statements, desugar into blocks as follows:
    1659             :   // {  // To group the statements--harmless to evaluate Expression in scope
    1660             :   //   .tag_variable = Expression;
    1661             :   //   {  // To give CaseClauses a scope
    1662             :   //     switch (.tag_variable) { CaseClause* }
    1663             :   //   }
    1664             :   // }
    1665             : 
    1666      445405 :   Block* switch_block = factory()->NewBlock(NULL, 2, false, kNoSourcePosition);
    1667             : 
    1668             :   Variable* tag_variable =
    1669       89081 :       NewTemporary(ast_value_factory()->dot_switch_tag_string());
    1670             :   Assignment* tag_assign = factory()->NewAssignment(
    1671       89081 :       Token::ASSIGN, factory()->NewVariableProxy(tag_variable), tag,
    1672      178162 :       tag->position());
    1673             :   Statement* tag_statement =
    1674       89081 :       factory()->NewExpressionStatement(tag_assign, kNoSourcePosition);
    1675             :   switch_block->statements()->Add(tag_statement, zone());
    1676             : 
    1677             :   // make statement: undefined;
    1678             :   // This is needed so the tag isn't returned as the value, in case the switch
    1679             :   // statements don't have a value.
    1680             :   switch_block->statements()->Add(
    1681             :       factory()->NewExpressionStatement(
    1682       89081 :           factory()->NewUndefinedLiteral(kNoSourcePosition), kNoSourcePosition),
    1683             :       zone());
    1684             : 
    1685       89081 :   Expression* tag_read = factory()->NewVariableProxy(tag_variable);
    1686             :   switch_statement->Initialize(tag_read, cases);
    1687       89081 :   Block* cases_block = factory()->NewBlock(NULL, 1, false, kNoSourcePosition);
    1688             :   cases_block->statements()->Add(switch_statement, zone());
    1689             :   cases_block->set_scope(scope);
    1690             :   DCHECK_IMPLIES(scope != nullptr,
    1691             :                  switch_statement->position() >= scope->start_position());
    1692             :   DCHECK_IMPLIES(scope != nullptr,
    1693             :                  switch_statement->position() < scope->end_position());
    1694             :   switch_block->statements()->Add(cases_block, zone());
    1695       89081 :   return switch_block;
    1696             : }
    1697             : 
    1698      285737 : void Parser::RewriteCatchPattern(CatchInfo* catch_info, bool* ok) {
    1699      285737 :   if (catch_info->name == nullptr) {
    1700             :     DCHECK_NOT_NULL(catch_info->pattern);
    1701      298715 :     catch_info->name = ast_value_factory()->dot_catch_string();
    1702             :   }
    1703             :   Variable* catch_variable =
    1704      285737 :       catch_info->scope->DeclareLocal(catch_info->name, VAR);
    1705      285737 :   if (catch_info->pattern != nullptr) {
    1706             :     DeclarationDescriptor descriptor;
    1707        4326 :     descriptor.declaration_kind = DeclarationDescriptor::NORMAL;
    1708        4326 :     descriptor.scope = scope();
    1709        4326 :     descriptor.mode = LET;
    1710        4326 :     descriptor.declaration_pos = catch_info->pattern->position();
    1711        4326 :     descriptor.initialization_pos = catch_info->pattern->position();
    1712             : 
    1713             :     // Initializer position for variables declared by the pattern.
    1714             :     const int initializer_position = position();
    1715             : 
    1716             :     DeclarationParsingResult::Declaration decl(
    1717             :         catch_info->pattern, initializer_position,
    1718        8652 :         factory()->NewVariableProxy(catch_variable));
    1719             : 
    1720             :     catch_info->init_block =
    1721        4326 :         factory()->NewBlock(nullptr, 8, true, kNoSourcePosition);
    1722             :     PatternRewriter::DeclareAndInitializeVariables(
    1723             :         this, catch_info->init_block, &descriptor, &decl,
    1724        4326 :         &catch_info->bound_names, ok);
    1725             :   } else {
    1726      281411 :     catch_info->bound_names.Add(catch_info->name, zone());
    1727             :   }
    1728      285737 : }
    1729             : 
    1730      285238 : void Parser::ValidateCatchBlock(const CatchInfo& catch_info, bool* ok) {
    1731             :   // Check for `catch(e) { let e; }` and similar errors.
    1732      285238 :   Scope* inner_block_scope = catch_info.inner_block->scope();
    1733      285238 :   if (inner_block_scope != nullptr) {
    1734         532 :     Declaration* decl = inner_block_scope->CheckLexDeclarationsConflictingWith(
    1735        1619 :         catch_info.bound_names);
    1736        1619 :     if (decl != nullptr) {
    1737             :       const AstRawString* name = decl->proxy()->raw_name();
    1738         532 :       int position = decl->proxy()->position();
    1739             :       Scanner::Location location =
    1740             :           position == kNoSourcePosition
    1741             :               ? Scanner::Location::invalid()
    1742         532 :               : Scanner::Location(position, position + 1);
    1743             :       ReportMessageAt(location, MessageTemplate::kVarRedeclaration, name);
    1744         532 :       *ok = false;
    1745             :     }
    1746             :   }
    1747      285238 : }
    1748             : 
    1749      296564 : Statement* Parser::RewriteTryStatement(Block* try_block, Block* catch_block,
    1750             :                                        Block* finally_block,
    1751             :                                        const CatchInfo& catch_info, int pos) {
    1752             :   // Simplify the AST nodes by converting:
    1753             :   //   'try B0 catch B1 finally B2'
    1754             :   // to:
    1755             :   //   'try { try B0 catch B1 } finally B2'
    1756             : 
    1757      296564 :   if (catch_block != nullptr && finally_block != nullptr) {
    1758             :     // If we have both, create an inner try/catch.
    1759             :     DCHECK_NOT_NULL(catch_info.scope);
    1760             :     TryCatchStatement* statement;
    1761             :     statement = factory()->NewTryCatchStatement(try_block, catch_info.scope,
    1762        2106 :                                                 catch_block, kNoSourcePosition);
    1763             : 
    1764        1053 :     try_block = factory()->NewBlock(nullptr, 1, false, kNoSourcePosition);
    1765             :     try_block->statements()->Add(statement, zone());
    1766             :     catch_block = nullptr;  // Clear to indicate it's been handled.
    1767             :   }
    1768             : 
    1769      296564 :   if (catch_block != nullptr) {
    1770             :     // For a try-catch construct append return expressions from the catch block
    1771             :     // to the list of return expressions.
    1772      283653 :     function_state_->tail_call_expressions().Append(
    1773      567306 :         catch_info.tail_call_expressions);
    1774             : 
    1775             :     DCHECK_NULL(finally_block);
    1776             :     DCHECK_NOT_NULL(catch_info.scope);
    1777             :     return factory()->NewTryCatchStatement(try_block, catch_info.scope,
    1778      567306 :                                            catch_block, pos);
    1779             :   } else {
    1780             :     DCHECK_NOT_NULL(finally_block);
    1781       25822 :     return factory()->NewTryFinallyStatement(try_block, finally_block, pos);
    1782             :   }
    1783             : }
    1784             : 
    1785       47797 : void Parser::ParseAndRewriteGeneratorFunctionBody(int pos, FunctionKind kind,
    1786             :                                                   ZoneList<Statement*>* body,
    1787             :                                                   bool* ok) {
    1788             :   // For ES6 Generators, we produce:
    1789             :   //
    1790             :   // try { InitialYield; ...body...; return {value: undefined, done: true} }
    1791             :   // finally { %_GeneratorClose(generator) }
    1792             :   //
    1793             :   // For ES2017 Async Generators, we produce:
    1794             :   //
    1795             :   // try {
    1796             :   //   InitialYield;
    1797             :   //   ...body...;
    1798             :   //   return undefined; // See comment below
    1799             :   // } catch (.catch) {
    1800             :   //   %AsyncGeneratorReject(generator, .catch);
    1801             :   // } finally {
    1802             :   //   %_GeneratorClose(generator);
    1803             :   // }
    1804             :   //
    1805             :   // - InitialYield yields the actual generator object.
    1806             :   // - Any return statement inside the body will have its argument wrapped
    1807             :   //   in an iterator result object with a "done" property set to `true`.
    1808             :   // - If the generator terminates for whatever reason, we must close it.
    1809             :   //   Hence the finally clause.
    1810             :   // - BytecodeGenerator performs special handling for ReturnStatements in
    1811             :   //   async generator functions, resolving the appropriate Promise with an
    1812             :   //   "done" iterator result object containing a Promise-unwrapped value.
    1813             : 
    1814      342334 :   Block* try_block = factory()->NewBlock(nullptr, 3, false, kNoSourcePosition);
    1815       47797 :   Expression* initial_yield = BuildInitialYield(pos, kind);
    1816             :   try_block->statements()->Add(
    1817       47797 :       factory()->NewExpressionStatement(initial_yield, kNoSourcePosition),
    1818             :       zone());
    1819       47797 :   ParseStatementList(try_block->statements(), Token::RBRACE, ok);
    1820       95594 :   if (!*ok) return;
    1821             : 
    1822       35067 :   if (IsAsyncGeneratorFunction(kind)) {
    1823             :     // Don't create iterator result for async generators, as the resume methods
    1824             :     // will create it.
    1825             :     Statement* final_return = BuildReturnStatement(
    1826       14281 :         factory()->NewUndefinedLiteral(kNoSourcePosition), kNoSourcePosition);
    1827             :     try_block->statements()->Add(final_return, zone());
    1828             : 
    1829             :     // For AsyncGenerators, a top-level catch block will reject the Promise.
    1830             :     Scope* catch_scope = NewHiddenCatchScopeWithParent(scope());
    1831             : 
    1832       14281 :     ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(2, zone());
    1833             :     args->Add(factory()->NewVariableProxy(
    1834       28562 :                   function_state_->generator_object_variable()),
    1835             :               zone());
    1836       14281 :     args->Add(factory()->NewVariableProxy(catch_scope->catch_variable()),
    1837             :               zone());
    1838             : 
    1839             :     Expression* call = factory()->NewCallRuntime(
    1840       14281 :         Runtime::kInlineAsyncGeneratorReject, args, kNoSourcePosition);
    1841             :     Block* catch_block = IgnoreCompletion(
    1842       14281 :         factory()->NewReturnStatement(call, kNoSourcePosition));
    1843             : 
    1844             :     TryStatement* try_catch = factory()->NewTryCatchStatementForAsyncAwait(
    1845       14281 :         try_block, catch_scope, catch_block, kNoSourcePosition);
    1846             : 
    1847       14281 :     try_block = factory()->NewBlock(nullptr, 1, false, kNoSourcePosition);
    1848             :     try_block->statements()->Add(try_catch, zone());
    1849             :   } else {
    1850             :     Statement* final_return = factory()->NewReturnStatement(
    1851       20786 :         BuildIteratorResult(nullptr, true), kNoSourcePosition);
    1852             :     try_block->statements()->Add(final_return, zone());
    1853             :   }
    1854             : 
    1855             :   Block* finally_block =
    1856       35067 :       factory()->NewBlock(nullptr, 1, false, kNoSourcePosition);
    1857       35067 :   ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(1, zone());
    1858             :   VariableProxy* call_proxy =
    1859       70134 :       factory()->NewVariableProxy(function_state_->generator_object_variable());
    1860             :   args->Add(call_proxy, zone());
    1861             :   Expression* call = factory()->NewCallRuntime(Runtime::kInlineGeneratorClose,
    1862       35067 :                                                args, kNoSourcePosition);
    1863             :   finally_block->statements()->Add(
    1864       35067 :       factory()->NewExpressionStatement(call, kNoSourcePosition), zone());
    1865             : 
    1866             :   body->Add(factory()->NewTryFinallyStatement(try_block, finally_block,
    1867       35067 :                                               kNoSourcePosition),
    1868             :             zone());
    1869             : }
    1870             : 
    1871     6207141 : void Parser::CreateFunctionNameAssignment(
    1872             :     const AstRawString* function_name, int pos,
    1873             :     FunctionLiteral::FunctionType function_type,
    1874             :     DeclarationScope* function_scope, ZoneList<Statement*>* result, int index) {
    1875     6207141 :   if (function_type == FunctionLiteral::kNamedExpression) {
    1876      938869 :     StatementT statement = factory()->NewEmptyStatement(kNoSourcePosition);
    1877      938871 :     if (function_scope->LookupLocal(function_name) == nullptr) {
    1878             :       // Now that we know the language mode, we can create the const assignment
    1879             :       // in the previously reserved spot.
    1880             :       DCHECK_EQ(function_scope, scope());
    1881      938707 :       Variable* fvar = function_scope->DeclareFunctionVar(function_name);
    1882      938711 :       VariableProxy* fproxy = factory()->NewVariableProxy(fvar);
    1883             :       statement = factory()->NewExpressionStatement(
    1884             :           factory()->NewAssignment(Token::INIT, fproxy,
    1885      938695 :                                    factory()->NewThisFunction(pos),
    1886      938700 :                                    kNoSourcePosition),
    1887      938702 :           kNoSourcePosition);
    1888             :     }
    1889      938866 :     result->Set(index, statement);
    1890             :   }
    1891     6207138 : }
    1892             : 
    1893             : // [if (IteratorType == kNormal)]
    1894             : //     !%_IsJSReceiver(result = iterator.next()) &&
    1895             : //         %ThrowIteratorResultNotAnObject(result)
    1896             : // [else if (IteratorType == kAsync)]
    1897             : //     !%_IsJSReceiver(result = Await(iterator.next())) &&
    1898             : //         %ThrowIteratorResultNotAnObject(result)
    1899             : // [endif]
    1900      241558 : Expression* Parser::BuildIteratorNextResult(Expression* iterator,
    1901             :                                             Variable* result, IteratorType type,
    1902             :                                             int pos) {
    1903             :   Expression* next_literal = factory()->NewStringLiteral(
    1904     1690906 :       ast_value_factory()->next_string(), kNoSourcePosition);
    1905             :   Expression* next_property =
    1906      241558 :       factory()->NewProperty(iterator, next_literal, kNoSourcePosition);
    1907             :   ZoneList<Expression*>* next_arguments =
    1908      241558 :       new (zone()) ZoneList<Expression*>(0, zone());
    1909             :   Expression* next_call =
    1910      241558 :       factory()->NewCall(next_property, next_arguments, pos);
    1911      241558 :   if (type == IteratorType::kAsync) {
    1912             :     next_call = RewriteAwaitExpression(next_call, pos);
    1913             :   }
    1914      241558 :   Expression* result_proxy = factory()->NewVariableProxy(result);
    1915             :   Expression* left =
    1916      241558 :       factory()->NewAssignment(Token::ASSIGN, result_proxy, next_call, pos);
    1917             : 
    1918             :   // %_IsJSReceiver(...)
    1919             :   ZoneList<Expression*>* is_spec_object_args =
    1920      241558 :       new (zone()) ZoneList<Expression*>(1, zone());
    1921             :   is_spec_object_args->Add(left, zone());
    1922             :   Expression* is_spec_object_call = factory()->NewCallRuntime(
    1923      241558 :       Runtime::kInlineIsJSReceiver, is_spec_object_args, pos);
    1924             : 
    1925             :   // %ThrowIteratorResultNotAnObject(result)
    1926      241558 :   Expression* result_proxy_again = factory()->NewVariableProxy(result);
    1927             :   ZoneList<Expression*>* throw_arguments =
    1928      241558 :       new (zone()) ZoneList<Expression*>(1, zone());
    1929             :   throw_arguments->Add(result_proxy_again, zone());
    1930             :   Expression* throw_call = factory()->NewCallRuntime(
    1931      241558 :       Runtime::kThrowIteratorResultNotAnObject, throw_arguments, pos);
    1932             : 
    1933             :   return factory()->NewBinaryOperation(
    1934             :       Token::AND,
    1935      241558 :       factory()->NewUnaryOperation(Token::NOT, is_spec_object_call, pos),
    1936      241558 :       throw_call, pos);
    1937             : }
    1938             : 
    1939      168751 : Statement* Parser::InitializeForEachStatement(ForEachStatement* stmt,
    1940             :                                               Expression* each,
    1941             :                                               Expression* subject,
    1942             :                                               Statement* body,
    1943             :                                               int each_keyword_pos) {
    1944      168751 :   ForOfStatement* for_of = stmt->AsForOfStatement();
    1945      168751 :   if (for_of != NULL) {
    1946             :     const bool finalize = true;
    1947             :     return InitializeForOfStatement(for_of, each, subject, body, finalize,
    1948      103480 :                                     IteratorType::kNormal, each_keyword_pos);
    1949             :   } else {
    1950      127566 :     if (each->IsArrayLiteral() || each->IsObjectLiteral()) {
    1951       26616 :       Variable* temp = NewTemporary(ast_value_factory()->empty_string());
    1952        6654 :       VariableProxy* temp_proxy = factory()->NewVariableProxy(temp);
    1953             :       Expression* assign_each = PatternRewriter::RewriteDestructuringAssignment(
    1954             :           this, factory()->NewAssignment(Token::ASSIGN, each, temp_proxy,
    1955             :                                          kNoSourcePosition),
    1956        6654 :           scope());
    1957        6654 :       auto block = factory()->NewBlock(nullptr, 2, false, kNoSourcePosition);
    1958             :       block->statements()->Add(
    1959        6654 :           factory()->NewExpressionStatement(assign_each, kNoSourcePosition),
    1960             :           zone());
    1961             :       block->statements()->Add(body, zone());
    1962             :       body = block;
    1963        6654 :       each = factory()->NewVariableProxy(temp);
    1964             :     }
    1965             :     MarkExpressionAsAssigned(each);
    1966             :     stmt->AsForInStatement()->Initialize(each, subject, body);
    1967             :   }
    1968       65271 :   return stmt;
    1969             : }
    1970             : 
    1971             : // Special case for legacy for
    1972             : //
    1973             : //    for (var x = initializer in enumerable) body
    1974             : //
    1975             : // An initialization block of the form
    1976             : //
    1977             : //    {
    1978             : //      x = initializer;
    1979             : //    }
    1980             : //
    1981             : // is returned in this case.  It has reserved space for two statements,
    1982             : // so that (later on during parsing), the equivalent of
    1983             : //
    1984             : //   for (x in enumerable) body
    1985             : //
    1986             : // is added as a second statement to it.
    1987      112037 : Block* Parser::RewriteForVarInLegacy(const ForInfo& for_info) {
    1988             :   const DeclarationParsingResult::Declaration& decl =
    1989      112037 :       for_info.parsing_result.declarations[0];
    1990      277679 :   if (!IsLexicalVariableMode(for_info.parsing_result.descriptor.mode) &&
    1991      163771 :       decl.pattern->IsVariableProxy() && decl.initializer != nullptr) {
    1992         149 :     ++use_counts_[v8::Isolate::kForInInitializer];
    1993         149 :     const AstRawString* name = decl.pattern->AsVariableProxy()->raw_name();
    1994             :     VariableProxy* single_var = NewUnresolved(name);
    1995             :     Block* init_block = factory()->NewBlock(
    1996         149 :         nullptr, 2, true, for_info.parsing_result.descriptor.declaration_pos);
    1997             :     init_block->statements()->Add(
    1998             :         factory()->NewExpressionStatement(
    1999             :             factory()->NewAssignment(Token::ASSIGN, single_var,
    2000         149 :                                      decl.initializer, kNoSourcePosition),
    2001         149 :             kNoSourcePosition),
    2002             :         zone());
    2003         149 :     return init_block;
    2004             :   }
    2005             :   return nullptr;
    2006             : }
    2007             : 
    2008             : // Rewrite a for-in/of statement of the form
    2009             : //
    2010             : //   for (let/const/var x in/of e) b
    2011             : //
    2012             : // into
    2013             : //
    2014             : //   {
    2015             : //     <let x' be a temporary variable>
    2016             : //     for (x' in/of e) {
    2017             : //       let/const/var x;
    2018             : //       x = x';
    2019             : //       b;
    2020             : //     }
    2021             : //     let x;  // for TDZ
    2022             : //   }
    2023      128173 : void Parser::DesugarBindingInForEachStatement(ForInfo* for_info,
    2024             :                                               Block** body_block,
    2025             :                                               Expression** each_variable,
    2026             :                                               bool* ok) {
    2027             :   DCHECK(for_info->parsing_result.declarations.length() == 1);
    2028             :   DeclarationParsingResult::Declaration& decl =
    2029      128173 :       for_info->parsing_result.declarations[0];
    2030      284931 :   Variable* temp = NewTemporary(ast_value_factory()->dot_for_string());
    2031             :   auto each_initialization_block =
    2032      128173 :       factory()->NewBlock(nullptr, 1, true, kNoSourcePosition);
    2033             :   {
    2034      128173 :     auto descriptor = for_info->parsing_result.descriptor;
    2035      128173 :     descriptor.declaration_pos = kNoSourcePosition;
    2036      128173 :     descriptor.initialization_pos = kNoSourcePosition;
    2037      256346 :     decl.initializer = factory()->NewVariableProxy(temp);
    2038             : 
    2039             :     bool is_for_var_of =
    2040      220629 :         for_info->mode == ForEachStatement::ITERATE &&
    2041       92456 :         for_info->parsing_result.descriptor.mode == VariableMode::VAR;
    2042             :     bool collect_names =
    2043      256346 :         IsLexicalVariableMode(for_info->parsing_result.descriptor.mode) ||
    2044             :         is_for_var_of;
    2045             : 
    2046             :     PatternRewriter::DeclareAndInitializeVariables(
    2047             :         this, each_initialization_block, &descriptor, &decl,
    2048      128355 :         collect_names ? &for_info->bound_names : nullptr, CHECK_OK_VOID);
    2049             : 
    2050             :     // Annex B.3.5 prohibits the form
    2051             :     // `try {} catch(e) { for (var e of {}); }`
    2052             :     // So if we are parsing a statement like `for (var ... of ...)`
    2053             :     // we need to walk up the scope chain and look for catch scopes
    2054             :     // which have a simple binding, then compare their binding against
    2055             :     // all of the names declared in the init of the for-of we're
    2056             :     // parsing.
    2057      128173 :     if (is_for_var_of) {
    2058      140296 :       Scope* catch_scope = scope();
    2059      224411 :       while (catch_scope != nullptr && !catch_scope->is_declaration_scope()) {
    2060       70239 :         if (catch_scope->is_catch_scope()) {
    2061         668 :           auto name = catch_scope->catch_variable()->raw_name();
    2062             :           // If it's a simple binding and the name is declared in the for loop.
    2063        1682 :           if (name != ast_value_factory()->dot_catch_string() &&
    2064         346 :               for_info->bound_names.Contains(name)) {
    2065             :             ReportMessageAt(for_info->parsing_result.bindings_loc,
    2066             :                             MessageTemplate::kVarRedeclaration, name);
    2067         182 :             *ok = false;
    2068             :             return;
    2069             :           }
    2070             :         }
    2071             :         catch_scope = catch_scope->outer_scope();
    2072             :       }
    2073             :     }
    2074             :   }
    2075             : 
    2076      127991 :   *body_block = factory()->NewBlock(nullptr, 3, false, kNoSourcePosition);
    2077             :   (*body_block)->statements()->Add(each_initialization_block, zone());
    2078      255982 :   *each_variable = factory()->NewVariableProxy(temp, for_info->position);
    2079             : }
    2080             : 
    2081             : // Create a TDZ for any lexically-bound names in for in/of statements.
    2082      127991 : Block* Parser::CreateForEachStatementTDZ(Block* init_block,
    2083             :                                          const ForInfo& for_info, bool* ok) {
    2084      255982 :   if (IsLexicalVariableMode(for_info.parsing_result.descriptor.mode)) {
    2085             :     DCHECK_NULL(init_block);
    2086             : 
    2087      151443 :     init_block = factory()->NewBlock(nullptr, 1, false, kNoSourcePosition);
    2088             : 
    2089      302886 :     for (int i = 0; i < for_info.bound_names.length(); ++i) {
    2090             :       // TODO(adamk): This needs to be some sort of special
    2091             :       // INTERNAL variable that's invisible to the debugger
    2092             :       // but visible to everything else.
    2093      309813 :       Declaration* tdz_decl = DeclareVariable(for_info.bound_names[i], LET,
    2094      158370 :                                               kNoSourcePosition, CHECK_OK);
    2095       79185 :       tdz_decl->proxy()->var()->set_initializer_position(position());
    2096             :     }
    2097             :   }
    2098      127991 :   return init_block;
    2099             : }
    2100             : 
    2101      133899 : Statement* Parser::InitializeForOfStatement(
    2102             :     ForOfStatement* for_of, Expression* each, Expression* iterable,
    2103             :     Statement* body, bool finalize, IteratorType type, int next_result_pos) {
    2104             :   // Create the auxiliary expressions needed for iterating over the iterable,
    2105             :   // and initialize the given ForOfStatement with them.
    2106             :   // If finalize is true, also instrument the loop with code that performs the
    2107             :   // proper ES6 iterator finalization.  In that case, the result is not
    2108             :   // immediately a ForOfStatement.
    2109             :   const int nopos = kNoSourcePosition;
    2110     1325369 :   auto avfactory = ast_value_factory();
    2111             : 
    2112             :   Variable* iterator = NewTemporary(avfactory->dot_iterator_string());
    2113             :   Variable* result = NewTemporary(avfactory->dot_result_string());
    2114             :   Variable* completion = NewTemporary(avfactory->empty_string());
    2115             : 
    2116             :   // iterator = GetIterator(iterable, type)
    2117             :   Expression* assign_iterator;
    2118             :   {
    2119             :     assign_iterator = factory()->NewAssignment(
    2120      133899 :         Token::ASSIGN, factory()->NewVariableProxy(iterator),
    2121      133899 :         factory()->NewGetIterator(iterable, type, iterable->position()),
    2122      267798 :         iterable->position());
    2123             :   }
    2124             : 
    2125             :   // [if (IteratorType == kNormal)]
    2126             :   //     !%_IsJSReceiver(result = iterator.next()) &&
    2127             :   //         %ThrowIteratorResultNotAnObject(result)
    2128             :   // [else if (IteratorType == kAsync)]
    2129             :   //     !%_IsJSReceiver(result = Await(iterator.next())) &&
    2130             :   //         %ThrowIteratorResultNotAnObject(result)
    2131             :   // [endif]
    2132             :   Expression* next_result;
    2133             :   {
    2134      133899 :     Expression* iterator_proxy = factory()->NewVariableProxy(iterator);
    2135             :     next_result =
    2136      133899 :         BuildIteratorNextResult(iterator_proxy, result, type, next_result_pos);
    2137             :   }
    2138             : 
    2139             :   // result.done
    2140             :   Expression* result_done;
    2141             :   {
    2142             :     Expression* done_literal = factory()->NewStringLiteral(
    2143      267798 :         ast_value_factory()->done_string(), kNoSourcePosition);
    2144      133899 :     Expression* result_proxy = factory()->NewVariableProxy(result);
    2145             :     result_done =
    2146      133899 :         factory()->NewProperty(result_proxy, done_literal, kNoSourcePosition);
    2147             :   }
    2148             : 
    2149             :   // result.value
    2150             :   Expression* result_value;
    2151             :   {
    2152             :     Expression* value_literal =
    2153      133899 :         factory()->NewStringLiteral(avfactory->value_string(), nopos);
    2154      133899 :     Expression* result_proxy = factory()->NewVariableProxy(result);
    2155      133899 :     result_value = factory()->NewProperty(result_proxy, value_literal, nopos);
    2156             :   }
    2157             : 
    2158             :   // {{completion = kAbruptCompletion;}}
    2159             :   Statement* set_completion_abrupt;
    2160      133899 :   if (finalize) {
    2161      128502 :     Expression* proxy = factory()->NewVariableProxy(completion);
    2162             :     Expression* assignment = factory()->NewAssignment(
    2163             :         Token::ASSIGN, proxy,
    2164      128502 :         factory()->NewSmiLiteral(Parser::kAbruptCompletion, nopos), nopos);
    2165             : 
    2166             :     set_completion_abrupt =
    2167      128502 :         IgnoreCompletion(factory()->NewExpressionStatement(assignment, nopos));
    2168             :   }
    2169             : 
    2170             :   // do { let tmp = #result_value; #set_completion_abrupt; tmp }
    2171             :   // Expression* result_value (gets overwritten)
    2172      133899 :   if (finalize) {
    2173             :     Variable* var_tmp = NewTemporary(avfactory->empty_string());
    2174      128502 :     Expression* tmp = factory()->NewVariableProxy(var_tmp);
    2175             :     Expression* assignment =
    2176      128502 :         factory()->NewAssignment(Token::ASSIGN, tmp, result_value, nopos);
    2177             : 
    2178      128502 :     Block* block = factory()->NewBlock(nullptr, 2, false, nopos);
    2179             :     block->statements()->Add(
    2180      128502 :         factory()->NewExpressionStatement(assignment, nopos), zone());
    2181             :     block->statements()->Add(set_completion_abrupt, zone());
    2182             : 
    2183      128502 :     result_value = factory()->NewDoExpression(block, var_tmp, nopos);
    2184             :   }
    2185             : 
    2186             :   // each = #result_value;
    2187             :   Expression* assign_each;
    2188             :   {
    2189             :     assign_each =
    2190      133899 :         factory()->NewAssignment(Token::ASSIGN, each, result_value, nopos);
    2191      263328 :     if (each->IsArrayLiteral() || each->IsObjectLiteral()) {
    2192             :       assign_each = PatternRewriter::RewriteDestructuringAssignment(
    2193       26728 :           this, assign_each->AsAssignment(), scope());
    2194             :     }
    2195             :   }
    2196             : 
    2197             :   // {{completion = kNormalCompletion;}}
    2198             :   Statement* set_completion_normal;
    2199      133899 :   if (finalize) {
    2200      128502 :     Expression* proxy = factory()->NewVariableProxy(completion);
    2201             :     Expression* assignment = factory()->NewAssignment(
    2202             :         Token::ASSIGN, proxy,
    2203      128502 :         factory()->NewSmiLiteral(Parser::kNormalCompletion, nopos), nopos);
    2204             : 
    2205             :     set_completion_normal =
    2206      128502 :         IgnoreCompletion(factory()->NewExpressionStatement(assignment, nopos));
    2207             :   }
    2208             : 
    2209             :   // { #loop-body; #set_completion_normal }
    2210             :   // Statement* body (gets overwritten)
    2211      133899 :   if (finalize) {
    2212      128502 :     Block* block = factory()->NewBlock(nullptr, 2, false, nopos);
    2213             :     block->statements()->Add(body, zone());
    2214             :     block->statements()->Add(set_completion_normal, zone());
    2215             :     body = block;
    2216             :   }
    2217             : 
    2218             :   for_of->Initialize(body, iterator, assign_iterator, next_result, result_done,
    2219             :                      assign_each);
    2220             :   return finalize ? FinalizeForOfStatement(for_of, completion, type, nopos)
    2221      133899 :                   : for_of;
    2222             : }
    2223             : 
    2224       25291 : Statement* Parser::DesugarLexicalBindingsInForStatement(
    2225             :     ForStatement* loop, Statement* init, Expression* cond, Statement* next,
    2226             :     Statement* body, Scope* inner_scope, const ForInfo& for_info, bool* ok) {
    2227             :   // ES6 13.7.4.8 specifies that on each loop iteration the let variables are
    2228             :   // copied into a new environment.  Moreover, the "next" statement must be
    2229             :   // evaluated not in the environment of the just completed iteration but in
    2230             :   // that of the upcoming one.  We achieve this with the following desugaring.
    2231             :   // Extra care is needed to preserve the completion value of the original loop.
    2232             :   //
    2233             :   // We are given a for statement of the form
    2234             :   //
    2235             :   //  labels: for (let/const x = i; cond; next) body
    2236             :   //
    2237             :   // and rewrite it as follows.  Here we write {{ ... }} for init-blocks, ie.,
    2238             :   // blocks whose ignore_completion_value_ flag is set.
    2239             :   //
    2240             :   //  {
    2241             :   //    let/const x = i;
    2242             :   //    temp_x = x;
    2243             :   //    first = 1;
    2244             :   //    undefined;
    2245             :   //    outer: for (;;) {
    2246             :   //      let/const x = temp_x;
    2247             :   //      {{ if (first == 1) {
    2248             :   //           first = 0;
    2249             :   //         } else {
    2250             :   //           next;
    2251             :   //         }
    2252             :   //         flag = 1;
    2253             :   //         if (!cond) break;
    2254             :   //      }}
    2255             :   //      labels: for (; flag == 1; flag = 0, temp_x = x) {
    2256             :   //        body
    2257             :   //      }
    2258             :   //      {{ if (flag == 1)  // Body used break.
    2259             :   //           break;
    2260             :   //      }}
    2261             :   //    }
    2262             :   //  }
    2263             : 
    2264             :   DCHECK(for_info.bound_names.length() > 0);
    2265      736566 :   ZoneList<Variable*> temps(for_info.bound_names.length(), zone());
    2266             : 
    2267             :   Block* outer_block = factory()->NewBlock(
    2268       25291 :       nullptr, for_info.bound_names.length() + 4, false, kNoSourcePosition);
    2269             : 
    2270             :   // Add statement: let/const x = i.
    2271             :   outer_block->statements()->Add(init, zone());
    2272             : 
    2273       25291 :   const AstRawString* temp_name = ast_value_factory()->dot_for_string();
    2274             : 
    2275             :   // For each lexical variable x:
    2276             :   //   make statement: temp_x = x.
    2277      119012 :   for (int i = 0; i < for_info.bound_names.length(); i++) {
    2278       34215 :     VariableProxy* proxy = NewUnresolved(for_info.bound_names[i]);
    2279             :     Variable* temp = NewTemporary(temp_name);
    2280       34215 :     VariableProxy* temp_proxy = factory()->NewVariableProxy(temp);
    2281             :     Assignment* assignment = factory()->NewAssignment(Token::ASSIGN, temp_proxy,
    2282       34215 :                                                       proxy, kNoSourcePosition);
    2283             :     Statement* assignment_statement =
    2284       34215 :         factory()->NewExpressionStatement(assignment, kNoSourcePosition);
    2285             :     outer_block->statements()->Add(assignment_statement, zone());
    2286             :     temps.Add(temp, zone());
    2287             :   }
    2288             : 
    2289             :   Variable* first = NULL;
    2290             :   // Make statement: first = 1.
    2291       25291 :   if (next) {
    2292             :     first = NewTemporary(temp_name);
    2293        3806 :     VariableProxy* first_proxy = factory()->NewVariableProxy(first);
    2294        3806 :     Expression* const1 = factory()->NewSmiLiteral(1, kNoSourcePosition);
    2295             :     Assignment* assignment = factory()->NewAssignment(
    2296        3806 :         Token::ASSIGN, first_proxy, const1, kNoSourcePosition);
    2297             :     Statement* assignment_statement =
    2298        3806 :         factory()->NewExpressionStatement(assignment, kNoSourcePosition);
    2299             :     outer_block->statements()->Add(assignment_statement, zone());
    2300             :   }
    2301             : 
    2302             :   // make statement: undefined;
    2303             :   outer_block->statements()->Add(
    2304             :       factory()->NewExpressionStatement(
    2305       25291 :           factory()->NewUndefinedLiteral(kNoSourcePosition), kNoSourcePosition),
    2306             :       zone());
    2307             : 
    2308             :   // Make statement: outer: for (;;)
    2309             :   // Note that we don't actually create the label, or set this loop up as an
    2310             :   // explicit break target, instead handing it directly to those nodes that
    2311             :   // need to know about it. This should be safe because we don't run any code
    2312             :   // in this function that looks up break targets.
    2313             :   ForStatement* outer_loop =
    2314       25291 :       factory()->NewForStatement(NULL, kNoSourcePosition);
    2315             :   outer_block->statements()->Add(outer_loop, zone());
    2316             :   outer_block->set_scope(scope());
    2317             : 
    2318       25291 :   Block* inner_block = factory()->NewBlock(NULL, 3, false, kNoSourcePosition);
    2319             :   {
    2320       25291 :     BlockState block_state(&scope_, inner_scope);
    2321             : 
    2322             :     Block* ignore_completion_block = factory()->NewBlock(
    2323       25291 :         nullptr, for_info.bound_names.length() + 3, true, kNoSourcePosition);
    2324       25291 :     ZoneList<Variable*> inner_vars(for_info.bound_names.length(), zone());
    2325             :     // For each let variable x:
    2326             :     //    make statement: let/const x = temp_x.
    2327      119012 :     for (int i = 0; i < for_info.bound_names.length(); i++) {
    2328      102645 :       Declaration* decl = DeclareVariable(
    2329             :           for_info.bound_names[i], for_info.parsing_result.descriptor.mode,
    2330      102645 :           kNoSourcePosition, CHECK_OK);
    2331       34215 :       inner_vars.Add(decl->proxy()->var(), zone());
    2332       34215 :       VariableProxy* temp_proxy = factory()->NewVariableProxy(temps.at(i));
    2333             :       Assignment* assignment = factory()->NewAssignment(
    2334       34215 :           Token::INIT, decl->proxy(), temp_proxy, kNoSourcePosition);
    2335             :       Statement* assignment_statement =
    2336       34215 :           factory()->NewExpressionStatement(assignment, kNoSourcePosition);
    2337             :       DCHECK(init->position() != kNoSourcePosition);
    2338       68430 :       decl->proxy()->var()->set_initializer_position(init->position());
    2339             :       ignore_completion_block->statements()->Add(assignment_statement, zone());
    2340             :     }
    2341             : 
    2342             :     // Make statement: if (first == 1) { first = 0; } else { next; }
    2343       25291 :     if (next) {
    2344             :       DCHECK(first);
    2345             :       Expression* compare = NULL;
    2346             :       // Make compare expression: first == 1.
    2347             :       {
    2348        3806 :         Expression* const1 = factory()->NewSmiLiteral(1, kNoSourcePosition);
    2349        3806 :         VariableProxy* first_proxy = factory()->NewVariableProxy(first);
    2350             :         compare = factory()->NewCompareOperation(Token::EQ, first_proxy, const1,
    2351        3806 :                                                  kNoSourcePosition);
    2352             :       }
    2353             :       Statement* clear_first = NULL;
    2354             :       // Make statement: first = 0.
    2355             :       {
    2356        3806 :         VariableProxy* first_proxy = factory()->NewVariableProxy(first);
    2357        3806 :         Expression* const0 = factory()->NewSmiLiteral(0, kNoSourcePosition);
    2358             :         Assignment* assignment = factory()->NewAssignment(
    2359        3806 :             Token::ASSIGN, first_proxy, const0, kNoSourcePosition);
    2360             :         clear_first =
    2361        3806 :             factory()->NewExpressionStatement(assignment, kNoSourcePosition);
    2362             :       }
    2363             :       Statement* clear_first_or_next = factory()->NewIfStatement(
    2364        3806 :           compare, clear_first, next, kNoSourcePosition);
    2365             :       ignore_completion_block->statements()->Add(clear_first_or_next, zone());
    2366             :     }
    2367             : 
    2368             :     Variable* flag = NewTemporary(temp_name);
    2369             :     // Make statement: flag = 1.
    2370             :     {
    2371       25291 :       VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
    2372       25291 :       Expression* const1 = factory()->NewSmiLiteral(1, kNoSourcePosition);
    2373             :       Assignment* assignment = factory()->NewAssignment(
    2374       25291 :           Token::ASSIGN, flag_proxy, const1, kNoSourcePosition);
    2375             :       Statement* assignment_statement =
    2376       25291 :           factory()->NewExpressionStatement(assignment, kNoSourcePosition);
    2377             :       ignore_completion_block->statements()->Add(assignment_statement, zone());
    2378             :     }
    2379             : 
    2380             :     // Make statement: if (!cond) break.
    2381       25291 :     if (cond) {
    2382             :       Statement* stop =
    2383       16363 :           factory()->NewBreakStatement(outer_loop, kNoSourcePosition);
    2384       16363 :       Statement* noop = factory()->NewEmptyStatement(kNoSourcePosition);
    2385             :       ignore_completion_block->statements()->Add(
    2386       16363 :           factory()->NewIfStatement(cond, noop, stop, cond->position()),
    2387             :           zone());
    2388             :     }
    2389             : 
    2390             :     inner_block->statements()->Add(ignore_completion_block, zone());
    2391             :     // Make cond expression for main loop: flag == 1.
    2392             :     Expression* flag_cond = NULL;
    2393             :     {
    2394       25291 :       Expression* const1 = factory()->NewSmiLiteral(1, kNoSourcePosition);
    2395       25291 :       VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
    2396             :       flag_cond = factory()->NewCompareOperation(Token::EQ, flag_proxy, const1,
    2397       25291 :                                                  kNoSourcePosition);
    2398             :     }
    2399             : 
    2400             :     // Create chain of expressions "flag = 0, temp_x = x, ..."
    2401             :     Statement* compound_next_statement = NULL;
    2402             :     {
    2403             :       Expression* compound_next = NULL;
    2404             :       // Make expression: flag = 0.
    2405             :       {
    2406       25291 :         VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
    2407       25291 :         Expression* const0 = factory()->NewSmiLiteral(0, kNoSourcePosition);
    2408             :         compound_next = factory()->NewAssignment(Token::ASSIGN, flag_proxy,
    2409       25291 :                                                  const0, kNoSourcePosition);
    2410             :       }
    2411             : 
    2412             :       // Make the comma-separated list of temp_x = x assignments.
    2413             :       int inner_var_proxy_pos = scanner()->location().beg_pos;
    2414      119012 :       for (int i = 0; i < for_info.bound_names.length(); i++) {
    2415       34215 :         VariableProxy* temp_proxy = factory()->NewVariableProxy(temps.at(i));
    2416             :         VariableProxy* proxy =
    2417       34215 :             factory()->NewVariableProxy(inner_vars.at(i), inner_var_proxy_pos);
    2418             :         Assignment* assignment = factory()->NewAssignment(
    2419       34215 :             Token::ASSIGN, temp_proxy, proxy, kNoSourcePosition);
    2420             :         compound_next = factory()->NewBinaryOperation(
    2421       34215 :             Token::COMMA, compound_next, assignment, kNoSourcePosition);
    2422             :       }
    2423             : 
    2424             :       compound_next_statement =
    2425       25291 :           factory()->NewExpressionStatement(compound_next, kNoSourcePosition);
    2426             :     }
    2427             : 
    2428             :     // Make statement: labels: for (; flag == 1; flag = 0, temp_x = x)
    2429             :     // Note that we re-use the original loop node, which retains its labels
    2430             :     // and ensures that any break or continue statements in body point to
    2431             :     // the right place.
    2432             :     loop->Initialize(NULL, flag_cond, compound_next_statement, body);
    2433             :     inner_block->statements()->Add(loop, zone());
    2434             : 
    2435             :     // Make statement: {{if (flag == 1) break;}}
    2436             :     {
    2437             :       Expression* compare = NULL;
    2438             :       // Make compare expresion: flag == 1.
    2439             :       {
    2440       25291 :         Expression* const1 = factory()->NewSmiLiteral(1, kNoSourcePosition);
    2441       25291 :         VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
    2442             :         compare = factory()->NewCompareOperation(Token::EQ, flag_proxy, const1,
    2443       25291 :                                                  kNoSourcePosition);
    2444             :       }
    2445             :       Statement* stop =
    2446       25291 :           factory()->NewBreakStatement(outer_loop, kNoSourcePosition);
    2447       25291 :       Statement* empty = factory()->NewEmptyStatement(kNoSourcePosition);
    2448             :       Statement* if_flag_break =
    2449       25291 :           factory()->NewIfStatement(compare, stop, empty, kNoSourcePosition);
    2450             :       inner_block->statements()->Add(IgnoreCompletion(if_flag_break), zone());
    2451             :     }
    2452             : 
    2453             :     inner_block->set_scope(inner_scope);
    2454             :   }
    2455             : 
    2456             :   outer_loop->Initialize(NULL, NULL, NULL, inner_block);
    2457       25291 :   return outer_block;
    2458             : }
    2459             : 
    2460      322209 : void Parser::AddArrowFunctionFormalParameters(
    2461             :     ParserFormalParameters* parameters, Expression* expr, int end_pos,
    2462             :     bool* ok) {
    2463             :   // ArrowFunctionFormals ::
    2464             :   //    Binary(Token::COMMA, NonTailArrowFunctionFormals, Tail)
    2465             :   //    Tail
    2466             :   // NonTailArrowFunctionFormals ::
    2467             :   //    Binary(Token::COMMA, NonTailArrowFunctionFormals, VariableProxy)
    2468             :   //    VariableProxy
    2469             :   // Tail ::
    2470             :   //    VariableProxy
    2471             :   //    Spread(VariableProxy)
    2472             :   //
    2473             :   // As we need to visit the parameters in left-to-right order, we recurse on
    2474             :   // the left-hand side of comma expressions.
    2475             :   //
    2476      322209 :   if (expr->IsBinaryOperation()) {
    2477       92240 :     BinaryOperation* binop = expr->AsBinaryOperation();
    2478             :     // The classifier has already run, so we know that the expression is a valid
    2479             :     // arrow function formals production.
    2480             :     DCHECK_EQ(binop->op(), Token::COMMA);
    2481             :     Expression* left = binop->left();
    2482             :     Expression* right = binop->right();
    2483       46120 :     int comma_pos = binop->position();
    2484             :     AddArrowFunctionFormalParameters(parameters, left, comma_pos,
    2485      368329 :                                      CHECK_OK_VOID);
    2486             :     // LHS of comma expression should be unparenthesized.
    2487             :     expr = right;
    2488             :   }
    2489             : 
    2490             :   // Only the right-most expression may be a rest parameter.
    2491             :   DCHECK(!parameters->has_rest);
    2492             : 
    2493             :   bool is_rest = expr->IsSpread();
    2494      321921 :   if (is_rest) {
    2495        4340 :     expr = expr->AsSpread()->expression();
    2496        2170 :     parameters->has_rest = true;
    2497             :   }
    2498      321921 :   if (parameters->is_simple) {
    2499      593746 :     parameters->is_simple = !is_rest && expr->IsVariableProxy();
    2500             :   }
    2501             : 
    2502             :   Expression* initializer = nullptr;
    2503      321921 :   if (expr->IsAssignment()) {
    2504       12940 :     Assignment* assignment = expr->AsAssignment();
    2505             :     DCHECK(!assignment->is_compound());
    2506             :     initializer = assignment->value();
    2507             :     expr = assignment->target();
    2508             :   }
    2509             : 
    2510             :   AddFormalParameter(parameters, expr, initializer,
    2511             :                      end_pos, is_rest);
    2512             : }
    2513             : 
    2514      602281 : void Parser::DeclareArrowFunctionFormalParameters(
    2515             :     ParserFormalParameters* parameters, Expression* expr,
    2516             :     const Scanner::Location& params_loc, Scanner::Location* duplicate_loc,
    2517             :     bool* ok) {
    2518      931257 :   if (expr->IsEmptyParentheses()) return;
    2519             : 
    2520             :   AddArrowFunctionFormalParameters(parameters, expr, params_loc.end_pos,
    2521      276089 :                                    CHECK_OK_VOID);
    2522             : 
    2523      273305 :   if (parameters->arity > Code::kMaxArguments) {
    2524             :     ReportMessageAt(params_loc, MessageTemplate::kMalformedArrowFunParamList);
    2525           0 :     *ok = false;
    2526           0 :     return;
    2527             :   }
    2528             : 
    2529      561487 :   ExpressionClassifier classifier(this);
    2530      273305 :   if (!parameters->is_simple) {
    2531             :     this->classifier()->RecordNonSimpleParameter();
    2532             :   }
    2533      273305 :   DeclareFormalParameters(parameters->scope, parameters->params);
    2534      273305 :   if (!this->classifier()
    2535             :            ->is_valid_formal_parameter_list_without_duplicates()) {
    2536             :     *duplicate_loc =
    2537          73 :         this->classifier()->duplicate_formal_parameter_error().location;
    2538             :   }
    2539             :   DCHECK_EQ(parameters->is_simple, parameters->scope->has_simple_parameters());
    2540             : }
    2541             : 
    2542      110847 : void Parser::PrepareGeneratorVariables() {
    2543             :   // For generators, allocating variables in contexts is currently a win because
    2544             :   // it minimizes the work needed to suspend and resume an activation.  The
    2545             :   // code produced for generators relies on this forced context allocation (it
    2546             :   // does not restore the frame's parameters upon resume).
    2547      221694 :   function_state_->scope()->ForceContextAllocation();
    2548             : 
    2549             :   // Calling a generator returns a generator object.  That object is stored
    2550             :   // in a temporary variable, a definition that is used by "yield"
    2551             :   // expressions.
    2552             :   function_state_->scope()->DeclareGeneratorObjectVar(
    2553      332541 :       ast_value_factory()->dot_generator_object_string());
    2554      110847 : }
    2555             : 
    2556     7562010 : FunctionLiteral* Parser::ParseFunctionLiteral(
    2557             :     const AstRawString* function_name, Scanner::Location function_name_location,
    2558             :     FunctionNameValidity function_name_validity, FunctionKind kind,
    2559             :     int function_token_pos, FunctionLiteral::FunctionType function_type,
    2560     7562024 :     LanguageMode language_mode, bool* ok) {
    2561             :   // Function ::
    2562             :   //   '(' FormalParameterList? ')' '{' FunctionBody '}'
    2563             :   //
    2564             :   // Getter ::
    2565             :   //   '(' ')' '{' FunctionBody '}'
    2566             :   //
    2567             :   // Setter ::
    2568             :   //   '(' PropertySetParameterList ')' '{' FunctionBody '}'
    2569             : 
    2570    28058464 :   int pos = function_token_pos == kNoSourcePosition ? peek_position()
    2571     7562010 :                                                     : function_token_pos;
    2572             : 
    2573             :   // Anonymous functions were passed either the empty symbol or a null
    2574             :   // handle as the function name.  Remember if we were passed a non-empty
    2575             :   // handle to decide whether to invoke function name inference.
    2576     7562010 :   bool should_infer_name = function_name == NULL;
    2577             : 
    2578             :   // We want a non-null handle as the function name.
    2579     7562010 :   if (should_infer_name) {
    2580     3253824 :     function_name = ast_value_factory()->empty_string();
    2581             :   }
    2582             : 
    2583             :   FunctionLiteral::EagerCompileHint eager_compile_hint =
    2584     7562010 :       function_state_->next_function_is_likely_called()
    2585             :           ? FunctionLiteral::kShouldEagerCompile
    2586     7562010 :           : default_eager_compile_hint();
    2587             : 
    2588             :   // Determine if the function can be parsed lazily. Lazy parsing is
    2589             :   // different from lazy compilation; we need to parse more eagerly than we
    2590             :   // compile.
    2591             : 
    2592             :   // We can only parse lazily if we also compile lazily. The heuristics for lazy
    2593             :   // compilation are:
    2594             :   // - It must not have been prohibited by the caller to Parse (some callers
    2595             :   //   need a full AST).
    2596             :   // - The outer scope must allow lazy compilation of inner functions.
    2597             :   // - The function mustn't be a function expression with an open parenthesis
    2598             :   //   before; we consider that a hint that the function will be called
    2599             :   //   immediately, and it would be a waste of time to make it lazily
    2600             :   //   compiled.
    2601             :   // These are all things we can know at this point, without looking at the
    2602             :   // function itself.
    2603             : 
    2604             :   // We separate between lazy parsing top level functions and lazy parsing inner
    2605             :   // functions, because the latter needs to do more work. In particular, we need
    2606             :   // to track unresolved variables to distinguish between these cases:
    2607             :   // (function foo() {
    2608             :   //   bar = function() { return 1; }
    2609             :   //  })();
    2610             :   // and
    2611             :   // (function foo() {
    2612             :   //   var a = 1;
    2613             :   //   bar = function() { return a; }
    2614             :   //  })();
    2615             : 
    2616             :   // Now foo will be parsed eagerly and compiled eagerly (optimization: assume
    2617             :   // parenthesis before the function means that it will be called
    2618             :   // immediately). bar can be parsed lazily, but we need to parse it in a mode
    2619             :   // that tracks unresolved variables.
    2620             :   DCHECK_IMPLIES(parse_lazily(), FLAG_lazy);
    2621             :   DCHECK_IMPLIES(parse_lazily(), allow_lazy_);
    2622             :   DCHECK_IMPLIES(parse_lazily(), extension_ == nullptr);
    2623             : 
    2624             :   const bool is_lazy =
    2625     7562010 :       eager_compile_hint == FunctionLiteral::kShouldLazyCompile;
    2626             :   const bool is_top_level =
    2627             :       impl()->AllowsLazyParsingWithoutUnresolvedVariables();
    2628     7562010 :   const bool is_lazy_top_level_function = is_lazy && is_top_level;
    2629     7562010 :   const bool is_lazy_inner_function = is_lazy && !is_top_level;
    2630             :   const bool is_declaration = function_type == FunctionLiteral::kDeclaration;
    2631             : 
    2632             :   RuntimeCallTimerScope runtime_timer(
    2633             :       runtime_call_stats_,
    2634             :       parsing_on_main_thread_
    2635             :           ? &RuntimeCallStats::ParseFunctionLiteral
    2636     7562010 :           : &RuntimeCallStats::ParseBackgroundFunctionLiteral);
    2637             : 
    2638             :   // Determine whether we can still lazy parse the inner function.
    2639             :   // The preconditions are:
    2640             :   // - Lazy compilation has to be enabled.
    2641             :   // - Neither V8 natives nor native function declarations can be allowed,
    2642             :   //   since parsing one would retroactively force the function to be
    2643             :   //   eagerly compiled.
    2644             :   // - The invoker of this parser can't depend on the AST being eagerly
    2645             :   //   built (either because the function is about to be compiled, or
    2646             :   //   because the AST is going to be inspected for some reason).
    2647             :   // - Because of the above, we can't be attempting to parse a
    2648             :   //   FunctionExpression; even without enclosing parentheses it might be
    2649             :   //   immediately invoked.
    2650             :   // - The function literal shouldn't be hinted to eagerly compile.
    2651             : 
    2652             :   // Inner functions will be parsed using a temporary Zone. After parsing, we
    2653             :   // will migrate unresolved variable into a Scope in the main Zone.
    2654             : 
    2655             :   const bool should_preparse_inner =
    2656     7562024 :       parse_lazily() && FLAG_lazy_inner_functions && is_lazy_inner_function &&
    2657     1416039 :       (is_declaration || FLAG_aggressive_lazy_inner_functions);
    2658             : 
    2659             :   // This may be modified later to reflect preparsing decision taken
    2660             :   bool should_preparse =
    2661     7562024 :       (parse_lazily() && is_lazy_top_level_function) || should_preparse_inner;
    2662             : 
    2663             :   ZoneList<Statement*>* body = nullptr;
    2664     7562024 :   int expected_property_count = -1;
    2665             :   bool should_be_used_once_hint = false;
    2666     7562024 :   int num_parameters = -1;
    2667     7562024 :   int function_length = -1;
    2668     7562024 :   bool has_duplicate_parameters = false;
    2669             :   int function_literal_id = GetNextFunctionLiteralId();
    2670             : 
    2671             :   Zone* outer_zone = zone();
    2672             :   DeclarationScope* scope;
    2673             : 
    2674             :   {
    2675             :     // Temporary zones can nest. When we migrate free variables (see below), we
    2676             :     // need to recreate them in the previous Zone.
    2677             :     AstNodeFactory previous_zone_ast_node_factory(ast_value_factory());
    2678             :     previous_zone_ast_node_factory.set_zone(zone());
    2679             : 
    2680             :     // Open a new zone scope, which sets our AstNodeFactory to allocate in the
    2681             :     // new temporary zone if the preconditions are satisfied, and ensures that
    2682             :     // the previous zone is always restored after parsing the body. To be able
    2683             :     // to do scope analysis correctly after full parsing, we migrate needed
    2684             :     // information when the function is parsed.
    2685     7562024 :     Zone temp_zone(zone()->allocator(), ZONE_NAME);
    2686     7562025 :     DiscardableZoneScope zone_scope(this, &temp_zone, should_preparse);
    2687             : 
    2688             :     // This Scope lives in the main zone. We'll migrate data into that zone
    2689             :     // later.
    2690     7562028 :     scope = NewFunctionScope(kind, outer_zone);
    2691     7562025 :     SetLanguageMode(scope, language_mode);
    2692             : #ifdef DEBUG
    2693             :     scope->SetScopeName(function_name);
    2694             :     if (should_preparse) scope->set_needs_migration();
    2695             : #endif
    2696             : 
    2697     7562026 :     Expect(Token::LPAREN, CHECK_OK);
    2698     4066904 :     scope->set_start_position(scanner()->location().beg_pos);
    2699             : 
    2700             :     // Eager or lazy parse? If is_lazy_top_level_function, we'll parse
    2701             :     // lazily. We'll call SkipFunction, which may decide to
    2702             :     // abort lazy parsing if it suspects that wasn't a good idea. If so (in
    2703             :     // which case the parser is expected to have backtracked), or if we didn't
    2704             :     // try to lazy parse in the first place, we'll have to parse eagerly.
    2705     7558620 :     if (should_preparse) {
    2706             :       DCHECK(parse_lazily());
    2707             :       DCHECK(is_lazy_top_level_function || is_lazy_inner_function);
    2708             :       Scanner::BookmarkScope bookmark(scanner());
    2709     1402991 :       bookmark.Set();
    2710             :       LazyParsingResult result =
    2711             :           SkipFunction(kind, scope, &num_parameters, is_lazy_inner_function,
    2712     1402991 :                        is_lazy_top_level_function, CHECK_OK);
    2713             : 
    2714     1355801 :       if (result == kLazyParsingAborted) {
    2715             :         DCHECK(is_lazy_top_level_function);
    2716          44 :         bookmark.Apply();
    2717             :         // This is probably an initialization function. Inform the compiler it
    2718             :         // should also eager-compile this function, and that we expect it to be
    2719             :         // used once.
    2720             :         eager_compile_hint = FunctionLiteral::kShouldEagerCompile;
    2721             :         should_be_used_once_hint = true;
    2722          44 :         scope->ResetAfterPreparsing(ast_value_factory(), true);
    2723          44 :         zone_scope.Reset();
    2724             :         // Trigger eager (re-)parsing, just below this block.
    2725             :         should_preparse = false;
    2726             :       }
    2727             :     }
    2728             : 
    2729     7511430 :     if (should_preparse) {
    2730             :       scope->AnalyzePartially(&previous_zone_ast_node_factory,
    2731     1355757 :                               preparsed_scope_data_);
    2732             :     } else {
    2733             :       body = ParseFunction(function_name, pos, kind, function_type, scope,
    2734             :                            &num_parameters, &function_length,
    2735             :                            &has_duplicate_parameters, &expected_property_count,
    2736     6155673 :                            CHECK_OK);
    2737             :     }
    2738             : 
    2739             :     DCHECK_EQ(should_preparse, temp_zoned_);
    2740     7418971 :     if (V8_UNLIKELY(FLAG_trace_preparse)) {
    2741             :       PrintF("  [%s]: %i-%i %.*s\n",
    2742             :              should_preparse ? (is_top_level ? "Preparse no-resolution"
    2743             :                                              : "Preparse resolution")
    2744             :                              : "Full parse",
    2745             :              scope->start_position(), scope->end_position(),
    2746           0 :              function_name->byte_length(), function_name->raw_data());
    2747             :     }
    2748     7418971 :     if (V8_UNLIKELY(FLAG_runtime_stats)) {
    2749           0 :       if (should_preparse) {
    2750             :         RuntimeCallStats::CounterId counter_id =
    2751             :             parsing_on_main_thread_
    2752             :                 ? &RuntimeCallStats::PreParseWithVariableResolution
    2753           0 :                 : &RuntimeCallStats::PreParseBackgroundWithVariableResolution;
    2754           0 :         if (is_top_level) {
    2755             :           counter_id =
    2756             :               parsing_on_main_thread_
    2757             :                   ? &RuntimeCallStats::PreParseNoVariableResolution
    2758           0 :                   : &RuntimeCallStats::PreParseBackgroundNoVariableResolution;
    2759             :         }
    2760             :         RuntimeCallStats::CorrectCurrentCounterId(runtime_call_stats_,
    2761           0 :                                                   counter_id);
    2762             :       }
    2763             :     }
    2764             : 
    2765             :     // Validate function name. We can do this only after parsing the function,
    2766             :     // since the function can declare itself strict.
    2767             :     language_mode = scope->language_mode();
    2768             :     CheckFunctionName(language_mode, function_name, function_name_validity,
    2769     7418971 :                       function_name_location, CHECK_OK);
    2770             : 
    2771     7417411 :     if (is_strict(language_mode)) {
    2772             :       CheckStrictOctalLiteral(scope->start_position(), scope->end_position(),
    2773     4066904 :                               CHECK_OK);
    2774             :     }
    2775    14822034 :     CheckConflictingVarDeclarations(scope, CHECK_OK);
    2776             :   }  // DiscardableZoneScope goes out of scope.
    2777             : 
    2778             :   FunctionLiteral::ParameterFlag duplicate_parameters =
    2779             :       has_duplicate_parameters ? FunctionLiteral::kHasDuplicateParameters
    2780     7404689 :                                : FunctionLiteral::kNoDuplicateParameters;
    2781             : 
    2782             :   // Note that the FunctionLiteral needs to be created in the main Zone again.
    2783             :   FunctionLiteral* function_literal = factory()->NewFunctionLiteral(
    2784             :       function_name, scope, body, expected_property_count, num_parameters,
    2785             :       function_length, duplicate_parameters, function_type, eager_compile_hint,
    2786     7404689 :       pos, true, function_literal_id);
    2787             :   function_literal->set_function_token_position(function_token_pos);
    2788     7404686 :   if (should_be_used_once_hint)
    2789             :     function_literal->set_should_be_used_once_hint();
    2790             : 
    2791     7404686 :   if (should_infer_name) {
    2792             :     DCHECK_NOT_NULL(fni_);
    2793     3197959 :     fni_->AddFunction(function_literal);
    2794             :   }
    2795     7404686 :   return function_literal;
    2796             : }
    2797             : 
    2798     1434202 : Parser::LazyParsingResult Parser::SkipFunction(FunctionKind kind,
    2799             :                                                DeclarationScope* function_scope,
    2800             :                                                int* num_parameters,
    2801             :                                                bool is_inner_function,
    2802     2288599 :                                                bool may_abort, bool* ok) {
    2803             :   DCHECK_NE(kNoSourcePosition, function_scope->start_position());
    2804             :   DCHECK_EQ(kNoSourcePosition, parameters_end_pos_);
    2805     1434202 :   if (produce_cached_parse_data()) CHECK(log_);
    2806             : 
    2807             :   DCHECK_IMPLIES(IsArrowFunction(kind),
    2808             :                  scanner()->current_token() == Token::ARROW);
    2809             : 
    2810             :   // Inner functions are not part of the cached data.
    2811     1434328 :   if (!is_inner_function && consume_cached_parse_data() &&
    2812         132 :       !cached_parse_data_->rejected()) {
    2813             :     // If we have cached data, we use it to skip parsing the function. The data
    2814             :     // contains the information we need to construct the lazy function.
    2815             :     FunctionEntry entry =
    2816     1384742 :         cached_parse_data_->GetFunctionEntry(function_scope->start_position());
    2817             :     // Check that cached data is valid. If not, mark it as invalid (the embedder
    2818             :     // handles it). Note that end position greater than end of stream is safe,
    2819             :     // and hard to check.
    2820         246 :     if (entry.is_valid() &&
    2821             :         entry.end_pos() > function_scope->start_position()) {
    2822         254 :       total_preparse_skipped_ += entry.end_pos() - position();
    2823             :       function_scope->set_end_position(entry.end_pos());
    2824         240 :       scanner()->SeekForward(entry.end_pos() - 1);
    2825         240 :       Expect(Token::RBRACE, CHECK_OK_VALUE(kLazyParsingComplete));
    2826         120 :       *num_parameters = entry.num_parameters();
    2827         120 :       SetLanguageMode(function_scope, entry.language_mode());
    2828         120 :       if (entry.uses_super_property())
    2829             :         function_scope->RecordSuperPropertyUsage();
    2830             :       SkipFunctionLiterals(entry.num_inner_functions());
    2831         120 :       return kLazyParsingComplete;
    2832             :     }
    2833           6 :     cached_parse_data_->Reject();
    2834             :   }
    2835             : 
    2836     1434082 :   if (FLAG_use_parse_tasks && !is_inner_function &&
    2837           0 :       reusable_preparser()->preparse_data()) {
    2838             :     // All top-level functions are already preparsed and parser tasks for eager
    2839             :     // functions are already created. Use data gathered during the preparse step
    2840             :     // to skip the function.
    2841             :     PreParseData::FunctionData data =
    2842             :         reusable_preparser()->preparse_data()->GetFunctionData(
    2843           0 :             function_scope->start_position());
    2844           0 :     if (data.is_valid()) {
    2845           0 :       if (FLAG_trace_parse_tasks) {
    2846             :         PrintF("Skipping top level func @ %d : %d using preparse data\n",
    2847           0 :                function_scope->start_position(), data.end);
    2848             :       }
    2849             :       function_scope->set_end_position(data.end);
    2850           0 :       scanner()->SeekForward(data.end - 1);
    2851           0 :       Expect(Token::RBRACE, CHECK_OK_VALUE(kLazyParsingComplete));
    2852           0 :       *num_parameters = data.num_parameters;
    2853           0 :       SetLanguageMode(function_scope, data.language_mode);
    2854           0 :       if (data.uses_super_property) {
    2855             :         function_scope->RecordSuperPropertyUsage();
    2856             :       }
    2857           0 :       SkipFunctionLiterals(data.num_inner_functions);
    2858           0 :       return kLazyParsingComplete;
    2859             :     }
    2860             :   }
    2861             : 
    2862             :   // FIXME(marja): There are 3 ways to skip functions now. Unify them.
    2863     1434082 :   if (preparsed_scope_data_->Consuming()) {
    2864             :     DCHECK(FLAG_experimental_preparser_scope_analysis);
    2865          14 :     const PreParseData::FunctionData& data =
    2866             :         preparsed_scope_data_->FindSkippableFunction(
    2867          14 :             function_scope->start_position());
    2868          14 :     if (data.is_valid()) {
    2869             :       function_scope->set_is_skipped_function(true);
    2870             :       function_scope->outer_scope()->SetMustUsePreParsedScopeData();
    2871             : 
    2872             :       function_scope->set_end_position(data.end);
    2873          28 :       scanner()->SeekForward(data.end - 1);
    2874          14 :       Expect(Token::RBRACE, CHECK_OK_VALUE(kLazyParsingComplete));
    2875          14 :       *num_parameters = data.num_parameters;
    2876          14 :       SetLanguageMode(function_scope, data.language_mode);
    2877          14 :       if (data.uses_super_property) {
    2878             :         function_scope->RecordSuperPropertyUsage();
    2879             :       }
    2880          14 :       SkipFunctionLiterals(data.num_inner_functions);
    2881          14 :       return kLazyParsingComplete;
    2882             :     }
    2883             :   }
    2884             : 
    2885             :   // With no cached data, we partially parse the function, without building an
    2886             :   // AST. This gathers the data needed to build a lazy function.
    2887     2868136 :   TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.PreParse");
    2888             : 
    2889             :   // Aborting inner function preparsing would leave scopes in an inconsistent
    2890             :   // state; we don't parse inner functions in the abortable mode anyway.
    2891             :   DCHECK(!is_inner_function || !may_abort);
    2892             : 
    2893             :   PreParser::PreParseResult result = reusable_preparser()->PreParseFunction(
    2894             :       kind, function_scope, parsing_module_, is_inner_function, may_abort,
    2895     1434068 :       use_counts_);
    2896             : 
    2897             :   // Return immediately if pre-parser decided to abort parsing.
    2898     1434068 :   if (result == PreParser::kPreParseAbort) return kLazyParsingAborted;
    2899     1434016 :   if (result == PreParser::kPreParseStackOverflow) {
    2900             :     // Propagate stack overflow.
    2901             :     set_stack_overflow();
    2902          52 :     *ok = false;
    2903          52 :     return kLazyParsingComplete;
    2904             :   }
    2905     1433964 :   if (pending_error_handler_.has_pending_error()) {
    2906       49700 :     *ok = false;
    2907       49700 :     return kLazyParsingComplete;
    2908             :   }
    2909     4152996 :   PreParserLogger* logger = reusable_preparser()->logger();
    2910             :   function_scope->set_end_position(logger->end());
    2911     1384264 :   Expect(Token::RBRACE, CHECK_OK_VALUE(kLazyParsingComplete));
    2912             :   total_preparse_skipped_ +=
    2913     1384264 :       function_scope->end_position() - function_scope->start_position();
    2914     1384264 :   *num_parameters = logger->num_parameters();
    2915             :   SkipFunctionLiterals(logger->num_inner_functions());
    2916     2238661 :   if (!is_inner_function && produce_cached_parse_data()) {
    2917             :     DCHECK(log_);
    2918             :     log_->LogFunction(function_scope->start_position(),
    2919             :                       function_scope->end_position(), *num_parameters,
    2920             :                       language_mode(), function_scope->uses_super_property(),
    2921         612 :                       logger->num_inner_functions());
    2922             :   }
    2923     1434068 :   return kLazyParsingComplete;
    2924             : }
    2925             : 
    2926             : 
    2927      169272 : Statement* Parser::BuildAssertIsCoercible(Variable* var) {
    2928             :   // if (var === null || var === undefined)
    2929             :   //     throw /* type error kNonCoercible) */;
    2930             : 
    2931             :   Expression* condition = factory()->NewBinaryOperation(
    2932             :       Token::OR,
    2933             :       factory()->NewCompareOperation(
    2934      169272 :           Token::EQ_STRICT, factory()->NewVariableProxy(var),
    2935      338544 :           factory()->NewUndefinedLiteral(kNoSourcePosition), kNoSourcePosition),
    2936             :       factory()->NewCompareOperation(
    2937      169272 :           Token::EQ_STRICT, factory()->NewVariableProxy(var),
    2938      507816 :           factory()->NewNullLiteral(kNoSourcePosition), kNoSourcePosition),
    2939      169272 :       kNoSourcePosition);
    2940             :   Expression* throw_type_error =
    2941             :       NewThrowTypeError(MessageTemplate::kNonCoercible,
    2942      169272 :                         ast_value_factory()->empty_string(), kNoSourcePosition);
    2943             :   IfStatement* if_statement = factory()->NewIfStatement(
    2944             :       condition,
    2945      169272 :       factory()->NewExpressionStatement(throw_type_error, kNoSourcePosition),
    2946      338544 :       factory()->NewEmptyStatement(kNoSourcePosition), kNoSourcePosition);
    2947      169272 :   return if_statement;
    2948             : }
    2949             : 
    2950             : 
    2951             : class InitializerRewriter final
    2952             :     : public AstTraversalVisitor<InitializerRewriter> {
    2953             :  public:
    2954             :   InitializerRewriter(uintptr_t stack_limit, Expression* root, Parser* parser,
    2955             :                       Scope* scope)
    2956             :       : AstTraversalVisitor(stack_limit, root),
    2957             :         parser_(parser),
    2958       30182 :         scope_(scope) {}
    2959             : 
    2960             :  private:
    2961             :   // This is required so that the overriden Visit* methods can be
    2962             :   // called by the base class (template).
    2963             :   friend class AstTraversalVisitor<InitializerRewriter>;
    2964             : 
    2965             :   // Just rewrite destructuring assignments wrapped in RewritableExpressions.
    2966         158 :   void VisitRewritableExpression(RewritableExpression* to_rewrite) {
    2967         316 :     if (to_rewrite->is_rewritten()) return;
    2968             :     Parser::PatternRewriter::RewriteDestructuringAssignment(parser_, to_rewrite,
    2969         114 :                                                             scope_);
    2970             :     AstTraversalVisitor::VisitRewritableExpression(to_rewrite);
    2971             :   }
    2972             : 
    2973             :   // Code in function literals does not need to be eagerly rewritten, it will be
    2974             :   // rewritten when scheduled.
    2975             :   void VisitFunctionLiteral(FunctionLiteral* expr) {}
    2976             : 
    2977             :   Parser* parser_;
    2978             :   Scope* scope_;
    2979             : };
    2980             : 
    2981             : 
    2982       30182 : void Parser::RewriteParameterInitializer(Expression* expr, Scope* scope) {
    2983       30182 :   InitializerRewriter rewriter(stack_limit_, expr, this, scope);
    2984             :   rewriter.Run();
    2985       30182 : }
    2986             : 
    2987             : 
    2988       49002 : Block* Parser::BuildParameterInitializationBlock(
    2989             :     const ParserFormalParameters& parameters, bool* ok) {
    2990             :   DCHECK(!parameters.is_simple);
    2991             :   DCHECK(scope()->is_function_scope());
    2992             :   DCHECK_EQ(scope(), parameters.scope);
    2993      321037 :   Block* init_block = factory()->NewBlock(NULL, 1, true, kNoSourcePosition);
    2994             :   int index = 0;
    2995      190226 :   for (auto parameter : parameters.params) {
    2996             :     DeclarationDescriptor descriptor;
    2997       93522 :     descriptor.declaration_kind = DeclarationDescriptor::PARAMETER;
    2998       93522 :     descriptor.scope = scope();
    2999       93522 :     descriptor.mode = LET;
    3000       93522 :     descriptor.declaration_pos = parameter->pattern->position();
    3001             :     // The position that will be used by the AssignmentExpression
    3002             :     // which copies from the temp parameter to the pattern.
    3003             :     //
    3004             :     // TODO(adamk): Should this be kNoSourcePosition, since
    3005             :     // it's just copying from a temp var to the real param var?
    3006       93522 :     descriptor.initialization_pos = parameter->pattern->position();
    3007             :     Expression* initial_value =
    3008      187044 :         factory()->NewVariableProxy(parameters.scope->parameter(index));
    3009       93522 :     if (parameter->initializer != nullptr) {
    3010             :       // IS_UNDEFINED($param) ? initializer : $param
    3011             : 
    3012             :       // Ensure initializer is rewritten
    3013       30182 :       RewriteParameterInitializer(parameter->initializer, scope());
    3014             : 
    3015             :       auto condition = factory()->NewCompareOperation(
    3016             :           Token::EQ_STRICT,
    3017       60364 :           factory()->NewVariableProxy(parameters.scope->parameter(index)),
    3018       60364 :           factory()->NewUndefinedLiteral(kNoSourcePosition), kNoSourcePosition);
    3019             :       initial_value = factory()->NewConditional(
    3020       30182 :           condition, parameter->initializer, initial_value, kNoSourcePosition);
    3021       30182 :       descriptor.initialization_pos = parameter->initializer->position();
    3022             :     }
    3023             : 
    3024             :     Scope* param_scope = scope();
    3025             :     Block* param_block = init_block;
    3026      145637 :     if (!parameter->is_simple() && scope()->calls_sloppy_eval()) {
    3027        1347 :       param_scope = NewVarblockScope();
    3028        1347 :       param_scope->set_start_position(descriptor.initialization_pos);
    3029        1347 :       param_scope->set_end_position(parameter->initializer_end_position);
    3030             :       param_scope->RecordEvalCall();
    3031        1347 :       param_block = factory()->NewBlock(NULL, 8, true, kNoSourcePosition);
    3032             :       param_block->set_scope(param_scope);
    3033             :       // Pass the appropriate scope in so that PatternRewriter can appropriately
    3034             :       // rewrite inner initializers of the pattern to param_scope
    3035        1347 :       descriptor.scope = param_scope;
    3036             :       // Rewrite the outer initializer to point to param_scope
    3037             :       ReparentParameterExpressionScope(stack_limit(), initial_value,
    3038        1347 :                                        param_scope);
    3039             :     }
    3040             : 
    3041       93522 :     BlockState block_state(&scope_, param_scope);
    3042             :     DeclarationParsingResult::Declaration decl(
    3043       93522 :         parameter->pattern, parameter->initializer_end_position, initial_value);
    3044             :     PatternRewriter::DeclareAndInitializeVariables(
    3045       93522 :         this, param_block, &descriptor, &decl, nullptr, CHECK_OK);
    3046             : 
    3047       92222 :     if (param_block != init_block) {
    3048        1347 :       param_scope = param_scope->FinalizeBlockScope();
    3049        1347 :       if (param_scope != nullptr) {
    3050        1347 :         CheckConflictingVarDeclarations(param_scope, CHECK_OK);
    3051             :       }
    3052             :       init_block->statements()->Add(param_block, zone());
    3053             :     }
    3054       92222 :     ++index;
    3055             :   }
    3056             :   return init_block;
    3057             : }
    3058             : 
    3059             : Scope* Parser::NewHiddenCatchScopeWithParent(Scope* parent) {
    3060      464250 :   Scope* catch_scope = NewScopeWithParent(parent, CATCH_SCOPE);
    3061      464250 :   catch_scope->DeclareLocal(ast_value_factory()->dot_catch_string(), VAR);
    3062      464250 :   catch_scope->set_is_hidden();
    3063             :   return catch_scope;
    3064             : }
    3065             : 
    3066       34035 : Block* Parser::BuildRejectPromiseOnException(Block* inner_block) {
    3067             :   // .promise = %AsyncFunctionPromiseCreate();
    3068             :   // try {
    3069             :   //   <inner_block>
    3070             :   // } catch (.catch) {
    3071             :   //   %RejectPromise(.promise, .catch);
    3072             :   //   return .promise;
    3073             :   // } finally {
    3074             :   //   %AsyncFunctionPromiseRelease(.promise);
    3075             :   // }
    3076      204210 :   Block* result = factory()->NewBlock(nullptr, 2, true, kNoSourcePosition);
    3077             : 
    3078             :   // .promise = %AsyncFunctionPromiseCreate();
    3079             :   Statement* set_promise;
    3080             :   {
    3081             :     Expression* create_promise = factory()->NewCallRuntime(
    3082             :         Context::ASYNC_FUNCTION_PROMISE_CREATE_INDEX,
    3083       34035 :         new (zone()) ZoneList<Expression*>(0, zone()), kNoSourcePosition);
    3084             :     Assignment* assign_promise = factory()->NewAssignment(
    3085       34035 :         Token::ASSIGN, factory()->NewVariableProxy(PromiseVariable()),
    3086       34035 :         create_promise, kNoSourcePosition);
    3087             :     set_promise =
    3088       34035 :         factory()->NewExpressionStatement(assign_promise, kNoSourcePosition);
    3089             :   }
    3090             :   result->statements()->Add(set_promise, zone());
    3091             : 
    3092             :   // catch (.catch) { return %RejectPromise(.promise, .catch), .promise }
    3093             :   Scope* catch_scope = NewHiddenCatchScopeWithParent(scope());
    3094             : 
    3095             :   Expression* promise_reject = BuildRejectPromise(
    3096       34035 :       factory()->NewVariableProxy(catch_scope->catch_variable()),
    3097       34035 :       kNoSourcePosition);
    3098             :   Block* catch_block = IgnoreCompletion(
    3099       34035 :       factory()->NewReturnStatement(promise_reject, kNoSourcePosition));
    3100             : 
    3101             :   TryStatement* try_catch_statement =
    3102             :       factory()->NewTryCatchStatementForAsyncAwait(
    3103       34035 :           inner_block, catch_scope, catch_block, kNoSourcePosition);
    3104             : 
    3105             :   // There is no TryCatchFinally node, so wrap it in an outer try/finally
    3106             :   Block* outer_try_block = IgnoreCompletion(try_catch_statement);
    3107             : 
    3108             :   // finally { %AsyncFunctionPromiseRelease(.promise) }
    3109             :   Block* finally_block;
    3110             :   {
    3111       34035 :     ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(1, zone());
    3112       34035 :     args->Add(factory()->NewVariableProxy(PromiseVariable()), zone());
    3113             :     Expression* call_promise_release = factory()->NewCallRuntime(
    3114       34035 :         Context::ASYNC_FUNCTION_PROMISE_RELEASE_INDEX, args, kNoSourcePosition);
    3115             :     Statement* promise_release = factory()->NewExpressionStatement(
    3116       34035 :         call_promise_release, kNoSourcePosition);
    3117             :     finally_block = IgnoreCompletion(promise_release);
    3118             :   }
    3119             : 
    3120             :   Statement* try_finally_statement = factory()->NewTryFinallyStatement(
    3121       34035 :       outer_try_block, finally_block, kNoSourcePosition);
    3122             : 
    3123             :   result->statements()->Add(try_finally_statement, zone());
    3124       34035 :   return result;
    3125             : }
    3126             : 
    3127      106167 : Assignment* Parser::BuildCreateJSGeneratorObject(int pos, FunctionKind kind) {
    3128             :   // .generator = %CreateJSGeneratorObject(...);
    3129             :   DCHECK_NOT_NULL(function_state_->generator_object_variable());
    3130      318501 :   ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(2, zone());
    3131      106167 :   args->Add(factory()->NewThisFunction(pos), zone());
    3132             :   args->Add(IsArrowFunction(kind) ? GetLiteralUndefined(pos)
    3133             :                                   : ThisExpression(kNoSourcePosition),
    3134      106167 :             zone());
    3135             :   Expression* allocation =
    3136      106167 :       factory()->NewCallRuntime(Runtime::kCreateJSGeneratorObject, args, pos);
    3137             :   VariableProxy* proxy =
    3138      212334 :       factory()->NewVariableProxy(function_state_->generator_object_variable());
    3139             :   return factory()->NewAssignment(Token::INIT, proxy, allocation,
    3140      106167 :                                   kNoSourcePosition);
    3141             : }
    3142             : 
    3143       32224 : Expression* Parser::BuildResolvePromise(Expression* value, int pos) {
    3144             :   // %ResolvePromise(.promise, value), .promise
    3145       96672 :   ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(2, zone());
    3146       32224 :   args->Add(factory()->NewVariableProxy(PromiseVariable()), zone());
    3147             :   args->Add(value, zone());
    3148             :   Expression* call_runtime =
    3149       32224 :       factory()->NewCallRuntime(Context::PROMISE_RESOLVE_INDEX, args, pos);
    3150             :   return factory()->NewBinaryOperation(
    3151             :       Token::COMMA, call_runtime,
    3152       64448 :       factory()->NewVariableProxy(PromiseVariable()), pos);
    3153             : }
    3154             : 
    3155       34035 : Expression* Parser::BuildRejectPromise(Expression* value, int pos) {
    3156             :   // %promise_internal_reject(.promise, value, false), .promise
    3157             :   // Disables the additional debug event for the rejection since a debug event
    3158             :   // already happened for the exception that got us here.
    3159      136140 :   ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(3, zone());
    3160       34035 :   args->Add(factory()->NewVariableProxy(PromiseVariable()), zone());
    3161             :   args->Add(value, zone());
    3162       34035 :   args->Add(factory()->NewBooleanLiteral(false, pos), zone());
    3163             :   Expression* call_runtime = factory()->NewCallRuntime(
    3164       34035 :       Context::PROMISE_INTERNAL_REJECT_INDEX, args, pos);
    3165             :   return factory()->NewBinaryOperation(
    3166             :       Token::COMMA, call_runtime,
    3167       68070 :       factory()->NewVariableProxy(PromiseVariable()), pos);
    3168             : }
    3169             : 
    3170      334930 : Variable* Parser::PromiseVariable() {
    3171             :   // Based on the various compilation paths, there are many different code
    3172             :   // paths which may be the first to access the Promise temporary. Whichever
    3173             :   // comes first should create it and stash it in the FunctionState.
    3174      367274 :   Variable* promise = function_state_->promise_variable();
    3175      334930 :   if (function_state_->promise_variable() == nullptr) {
    3176             :     promise = function_state_->scope()->DeclarePromiseVar(
    3177       97032 :         ast_value_factory()->empty_string());
    3178             :   }
    3179      334930 :   return promise;
    3180             : }
    3181             : 
    3182       32860 : Variable* Parser::AsyncGeneratorAwaitVariable() {
    3183       44246 :   Variable* result = function_state_->scope()->async_generator_await_var();
    3184       32860 :   if (result == nullptr) {
    3185             :     result = function_state_->scope()->DeclareAsyncGeneratorAwaitVar(
    3186       34158 :         ast_value_factory()->empty_string());
    3187             :   }
    3188       32860 :   return result;
    3189             : }
    3190             : 
    3191       65583 : Expression* Parser::BuildInitialYield(int pos, FunctionKind kind) {
    3192       65583 :   Assignment* assignment = BuildCreateJSGeneratorObject(pos, kind);
    3193             :   VariableProxy* generator =
    3194      196749 :       factory()->NewVariableProxy(function_state_->generator_object_variable());
    3195             :   // The position of the yield is important for reporting the exception
    3196             :   // caused by calling the .throw method on a generator suspended at the
    3197             :   // initial yield (i.e. right after generator instantiation).
    3198             :   return BuildSuspend(generator, assignment, scope()->start_position(),
    3199       65583 :                       Suspend::kOnExceptionThrow, SuspendFlags::kYield);
    3200             : }
    3201             : 
    3202     6155666 : ZoneList<Statement*>* Parser::ParseFunction(
    3203             :     const AstRawString* function_name, int pos, FunctionKind kind,
    3204             :     FunctionLiteral::FunctionType function_type,
    3205             :     DeclarationScope* function_scope, int* num_parameters, int* function_length,
    3206             :     bool* has_duplicate_parameters, int* expected_property_count, bool* ok) {
    3207     6155666 :   ParsingModeScope mode(this, allow_lazy_ ? PARSE_LAZILY : PARSE_EAGERLY);
    3208             : 
    3209     6155666 :   FunctionState function_state(&function_state_, &scope_, function_scope);
    3210             : 
    3211             :   DuplicateFinder duplicate_finder;
    3212    24492469 :   ExpressionClassifier formals_classifier(this, &duplicate_finder);
    3213             : 
    3214     6155677 :   if (IsResumableFunction(kind)) PrepareGeneratorVariables();
    3215             : 
    3216     6155674 :   int expected_parameters_end_pos = parameters_end_pos_;
    3217     6155674 :   if (expected_parameters_end_pos != kNoSourcePosition) {
    3218             :     // This is the first function encountered in a CreateDynamicFunction eval.
    3219         914 :     parameters_end_pos_ = kNoSourcePosition;
    3220             :     // The function name should have been ignored, giving us the empty string
    3221             :     // here.
    3222             :     DCHECK_EQ(function_name, ast_value_factory()->empty_string());
    3223             :   }
    3224             : 
    3225             :   ParserFormalParameters formals(function_scope);
    3226     6155674 :   ParseFormalParameterList(&formals, CHECK_OK);
    3227     6138320 :   if (expected_parameters_end_pos != kNoSourcePosition) {
    3228             :     // Check for '(' or ')' shenanigans in the parameter string for dynamic
    3229             :     // functions.
    3230             :     int position = peek_position();
    3231         713 :     if (position < expected_parameters_end_pos) {
    3232             :       ReportMessageAt(Scanner::Location(position, position + 1),
    3233          15 :                       MessageTemplate::kArgStringTerminatesParametersEarly);
    3234          15 :       *ok = false;
    3235          15 :       return nullptr;
    3236         698 :     } else if (position > expected_parameters_end_pos) {
    3237             :       ReportMessageAt(Scanner::Location(expected_parameters_end_pos - 2,
    3238             :                                         expected_parameters_end_pos),
    3239           0 :                       MessageTemplate::kUnexpectedEndOfArgString);
    3240           0 :       *ok = false;
    3241           0 :       return nullptr;
    3242             :     }
    3243             :   }
    3244     6138305 :   Expect(Token::RPAREN, CHECK_OK);
    3245             :   int formals_end_position = scanner()->location().end_pos;
    3246    12274424 :   *num_parameters = formals.num_parameters();
    3247     6137212 :   *function_length = formals.function_length;
    3248             : 
    3249             :   CheckArityRestrictions(formals.arity, kind, formals.has_rest,
    3250             :                          function_scope->start_position(), formals_end_position,
    3251     6137212 :                          CHECK_OK);
    3252     6136335 :   Expect(Token::LBRACE, CHECK_OK);
    3253             : 
    3254     6135653 :   ZoneList<Statement*>* body = new (zone()) ZoneList<Statement*>(8, zone());
    3255     6135649 :   ParseFunctionBody(body, function_name, pos, formals, kind, function_type, ok);
    3256             : 
    3257             :   // Validate parameter names. We can do this only after parsing the function,
    3258             :   // since the function can declare itself strict.
    3259             :   const bool allow_duplicate_parameters =
    3260     8424101 :       is_sloppy(function_scope->language_mode()) && formals.is_simple &&
    3261             :       !IsConciseMethod(kind);
    3262             :   ValidateFormalParameters(function_scope->language_mode(),
    3263    12271280 :                            allow_duplicate_parameters, CHECK_OK);
    3264             : 
    3265             :   RewriteDestructuringAssignments();
    3266             : 
    3267             :   *has_duplicate_parameters =
    3268     6063214 :       !classifier()->is_valid_formal_parameter_list_without_duplicates();
    3269             : 
    3270     6063214 :   *expected_property_count = function_state.expected_property_count();
    3271     6063214 :   return body;
    3272             : }
    3273             : 
    3274             : void Parser::DeclareClassVariable(const AstRawString* name,
    3275             :                                   ClassInfo* class_info, int class_token_pos,
    3276             :                                   bool* ok) {
    3277             : #ifdef DEBUG
    3278             :   scope()->SetScopeName(name);
    3279             : #endif
    3280             : 
    3281      105813 :   if (name != nullptr) {
    3282       83888 :     class_info->proxy = factory()->NewVariableProxy(name, NORMAL_VARIABLE);
    3283             :     Declaration* declaration = factory()->NewVariableDeclaration(
    3284       83888 :         class_info->proxy, scope(), class_token_pos);
    3285             :     Declare(declaration, DeclarationDescriptor::NORMAL, CONST,
    3286       83888 :             Variable::DefaultInitializationFlag(CONST), ok);
    3287             :   }
    3288             : }
    3289             : 
    3290             : // This method declares a property of the given class.  It updates the
    3291             : // following fields of class_info, as appropriate:
    3292             : //   - constructor
    3293             : //   - properties
    3294             : void Parser::DeclareClassProperty(const AstRawString* class_name,
    3295             :                                   ClassLiteralProperty* property,
    3296             :                                   ClassLiteralProperty::Kind kind,
    3297             :                                   bool is_static, bool is_constructor,
    3298             :                                   ClassInfo* class_info, bool* ok) {
    3299      350663 :   if (is_constructor) {
    3300             :     DCHECK(!class_info->constructor);
    3301       28082 :     class_info->constructor = GetPropertyValue(property)->AsFunctionLiteral();
    3302             :     DCHECK_NOT_NULL(class_info->constructor);
    3303             :     class_info->constructor->set_raw_name(
    3304       12908 :         class_name != nullptr ? ast_value_factory()->NewConsString(class_name)
    3305       26949 :                               : ast_value_factory()->empty_cons_string());
    3306             :     return;
    3307             :   }
    3308             : 
    3309             :   if (property->kind() == ClassLiteralProperty::FIELD) {
    3310             :     DCHECK(allow_harmony_class_fields());
    3311             :     // TODO(littledan): Implement class fields
    3312             :   }
    3313      336622 :   class_info->properties->Add(property, zone());
    3314             : }
    3315             : 
    3316             : // This method rewrites a class literal into a do-expression.
    3317             : // It uses the following fields of class_info:
    3318             : //   - constructor (if missing, it updates it with a default constructor)
    3319             : //   - proxy
    3320             : //   - extends
    3321             : //   - properties
    3322             : //   - has_name_static_property
    3323             : //   - has_static_computed_names
    3324             : Expression* Parser::RewriteClassLiteral(const AstRawString* name,
    3325             :                                         ClassInfo* class_info, int pos,
    3326       92611 :                                         bool* ok) {
    3327       92611 :   int end_pos = scanner()->location().end_pos;
    3328       92611 :   Block* do_block = factory()->NewBlock(nullptr, 1, false, pos);
    3329       92611 :   Variable* result_var = NewTemporary(ast_value_factory()->empty_string());
    3330       92611 :   DoExpression* do_expr = factory()->NewDoExpression(do_block, result_var, pos);
    3331             : 
    3332       92611 :   bool has_extends = class_info->extends != nullptr;
    3333       92611 :   bool has_default_constructor = class_info->constructor == nullptr;
    3334       92611 :   if (has_default_constructor) {
    3335             :     class_info->constructor =
    3336       78884 :         DefaultConstructor(name, has_extends, pos, end_pos);
    3337             :   }
    3338             : 
    3339       92611 :   scope()->set_end_position(end_pos);
    3340             : 
    3341       92611 :   if (name != nullptr) {
    3342             :     DCHECK_NOT_NULL(class_info->proxy);
    3343       75707 :     class_info->proxy->var()->set_initializer_position(end_pos);
    3344             :   }
    3345             : 
    3346             :   ClassLiteral* class_literal = factory()->NewClassLiteral(
    3347             :       class_info->proxy, class_info->extends, class_info->constructor,
    3348             :       class_info->properties, pos, end_pos,
    3349             :       class_info->has_name_static_property,
    3350       92611 :       class_info->has_static_computed_names);
    3351             : 
    3352             :   do_block->statements()->Add(
    3353             :       factory()->NewExpressionStatement(
    3354             :           factory()->NewAssignment(Token::ASSIGN,
    3355       92611 :                                    factory()->NewVariableProxy(result_var),
    3356       92611 :                                    class_literal, kNoSourcePosition),
    3357       92611 :           pos),
    3358      185222 :       zone());
    3359       92611 :   do_block->set_scope(scope()->FinalizeBlockScope());
    3360       92611 :   do_expr->set_represented_function(class_info->constructor);
    3361       92611 :   AddFunctionForNameInference(class_info->constructor);
    3362             : 
    3363             :   return do_expr;
    3364             : }
    3365             : 
    3366           0 : Literal* Parser::GetLiteralUndefined(int position) {
    3367      602584 :   return factory()->NewUndefinedLiteral(position);
    3368             : }
    3369             : 
    3370             : 
    3371     9987207 : void Parser::CheckConflictingVarDeclarations(Scope* scope, bool* ok) {
    3372    10025203 :   Declaration* decl = scope->CheckConflictingVarDeclarations();
    3373     9987199 :   if (decl != NULL) {
    3374             :     // In ES6, conflicting variable bindings are early errors.
    3375             :     const AstRawString* name = decl->proxy()->raw_name();
    3376       37996 :     int position = decl->proxy()->position();
    3377             :     Scanner::Location location =
    3378             :         position == kNoSourcePosition
    3379             :             ? Scanner::Location::invalid()
    3380       37996 :             : Scanner::Location(position, position + 1);
    3381             :     ReportMessageAt(location, MessageTemplate::kVarRedeclaration, name);
    3382       37996 :     *ok = false;
    3383             :   }
    3384     9987199 : }
    3385             : 
    3386             : 
    3387       15474 : void Parser::InsertShadowingVarBindingInitializers(Block* inner_block) {
    3388             :   // For each var-binding that shadows a parameter, insert an assignment
    3389             :   // initializing the variable with the parameter.
    3390       15474 :   Scope* inner_scope = inner_block->scope();
    3391             :   DCHECK(inner_scope->is_declaration_scope());
    3392             :   Scope* function_scope = inner_scope->outer_scope();
    3393             :   DCHECK(function_scope->is_function_scope());
    3394       15474 :   BlockState block_state(&scope_, inner_scope);
    3395      124577 :   for (Declaration* decl : *inner_scope->declarations()) {
    3396       94302 :     if (decl->proxy()->var()->mode() != VAR || !decl->IsVariableDeclaration()) {
    3397       42108 :       continue;
    3398             :     }
    3399             :     const AstRawString* name = decl->proxy()->raw_name();
    3400        7327 :     Variable* parameter = function_scope->LookupLocal(name);
    3401        7327 :     if (parameter == nullptr) continue;
    3402             :     VariableProxy* to = NewUnresolved(name);
    3403        2086 :     VariableProxy* from = factory()->NewVariableProxy(parameter);
    3404             :     Expression* assignment =
    3405        1043 :         factory()->NewAssignment(Token::ASSIGN, to, from, kNoSourcePosition);
    3406             :     Statement* statement =
    3407        2086 :         factory()->NewExpressionStatement(assignment, kNoSourcePosition);
    3408             :     inner_block->statements()->InsertAt(0, statement, zone());
    3409             :   }
    3410       15474 : }
    3411             : 
    3412     3999217 : void Parser::InsertSloppyBlockFunctionVarBindings(DeclarationScope* scope) {
    3413             :   // For the outermost eval scope, we cannot hoist during parsing: let
    3414             :   // declarations in the surrounding scope may prevent hoisting, but the
    3415             :   // information is unaccessible during parsing. In this case, we hoist later in
    3416             :   // DeclarationScope::Analyze.
    3417     3999217 :   if (scope->is_eval_scope() && scope->outer_scope() == original_scope_) {
    3418     3999217 :     return;
    3419             :   }
    3420     2925817 :   scope->HoistSloppyBlockFunctions(factory());
    3421             : }
    3422             : 
    3423             : // ----------------------------------------------------------------------------
    3424             : // Parser support
    3425             : 
    3426       25158 : bool Parser::TargetStackContainsLabel(const AstRawString* label) {
    3427       50083 :   for (ParserTarget* t = target_stack_; t != NULL; t = t->previous()) {
    3428       49850 :     if (ContainsLabel(t->statement()->labels(), label)) return true;
    3429             :   }
    3430             :   return false;
    3431             : }
    3432             : 
    3433             : 
    3434      283602 : BreakableStatement* Parser::LookupBreakTarget(const AstRawString* label,
    3435             :                                               bool* ok) {
    3436      283602 :   bool anonymous = label == NULL;
    3437      515802 :   for (ParserTarget* t = target_stack_; t != NULL; t = t->previous()) {
    3438      515433 :     BreakableStatement* stat = t->statement();
    3439     1477297 :     if ((anonymous && stat->is_target_for_anonymous()) ||
    3440       69002 :         (!anonymous && ContainsLabel(stat->labels(), label))) {
    3441             :       return stat;
    3442             :     }
    3443             :   }
    3444             :   return NULL;
    3445             : }
    3446             : 
    3447             : 
    3448       94230 : IterationStatement* Parser::LookupContinueTarget(const AstRawString* label,
    3449             :                                                  bool* ok) {
    3450             :   bool anonymous = label == NULL;
    3451      294587 :   for (ParserTarget* t = target_stack_; t != NULL; t = t->previous()) {
    3452      294281 :     IterationStatement* stat = t->statement()->AsIterationStatement();
    3453      294281 :     if (stat == NULL) continue;
    3454             : 
    3455             :     DCHECK(stat->is_target_for_anonymous());
    3456      100110 :     if (anonymous || ContainsLabel(stat->labels(), label)) {
    3457             :       return stat;
    3458             :     }
    3459             :   }
    3460             :   return NULL;
    3461             : }
    3462             : 
    3463             : 
    3464     2263499 : void Parser::HandleSourceURLComments(Isolate* isolate, Handle<Script> script) {
    3465     2263499 :   Handle<String> source_url = scanner_.SourceUrl(isolate);
    3466     2263503 :   if (!source_url.is_null()) {
    3467        2306 :     script->set_source_url(*source_url);
    3468             :   }
    3469     2263503 :   Handle<String> source_mapping_url = scanner_.SourceMappingUrl(isolate);
    3470     2263500 :   if (!source_mapping_url.is_null()) {
    3471         133 :     script->set_source_mapping_url(*source_mapping_url);
    3472             :   }
    3473     2263500 : }
    3474             : 
    3475      386293 : void Parser::ReportErrors(Isolate* isolate, Handle<Script> script) {
    3476      761977 :   if (stack_overflow()) {
    3477       10609 :     isolate->StackOverflow();
    3478             :   } else {
    3479             :     DCHECK(pending_error_handler_.has_pending_error());
    3480             :     // Internalize ast values for throwing the pending error.
    3481      375684 :     ast_value_factory()->Internalize(isolate);
    3482      375684 :     pending_error_handler_.ThrowPendingError(isolate, script);
    3483             :   }
    3484      386293 : }
    3485             : 
    3486     7135449 : void Parser::UpdateStatistics(Isolate* isolate, Handle<Script> script) {
    3487             :   // Move statistics to Isolate.
    3488   142708904 :   for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount;
    3489             :        ++feature) {
    3490   139141176 :     if (use_counts_[feature] > 0) {
    3491     3603991 :       isolate->CountUsage(v8::Isolate::UseCounterFeature(feature));
    3492             :     }
    3493             :   }
    3494     3567728 :   if (scanner_.FoundHtmlComment()) {
    3495          15 :     isolate->CountUsage(v8::Isolate::kHtmlComment);
    3496          30 :     if (script->line_offset() == 0 && script->column_offset() == 0) {
    3497          15 :       isolate->CountUsage(v8::Isolate::kHtmlCommentInExternalScript);
    3498             :     }
    3499             :   }
    3500             :   isolate->counters()->total_preparse_skipped()->Increment(
    3501     7135456 :       total_preparse_skipped_);
    3502     3567881 :   if (!parsing_on_main_thread_ &&
    3503         153 :       FLAG_runtime_stats ==
    3504             :           v8::tracing::TracingCategoryObserver::ENABLED_BY_NATIVE) {
    3505             :     // Copy over the counters from the background thread to the main counters on
    3506             :     // the isolate.
    3507           0 :     isolate->counters()->runtime_call_stats()->Add(runtime_call_stats_);
    3508             :   }
    3509     3567728 : }
    3510             : 
    3511         778 : void Parser::ParseOnBackground(ParseInfo* info) {
    3512         160 :   parsing_on_main_thread_ = false;
    3513             : 
    3514             :   DCHECK(info->literal() == NULL);
    3515             :   FunctionLiteral* result = NULL;
    3516             : 
    3517         160 :   ParserLogger logger;
    3518         160 :   if (produce_cached_parse_data()) {
    3519           6 :     if (allow_lazy_) {
    3520           6 :       log_ = &logger;
    3521             :     } else {
    3522           0 :       compile_options_ = ScriptCompiler::kNoCompileOptions;
    3523             :     }
    3524             :   }
    3525         160 :   if (FLAG_runtime_stats) {
    3526             :     // Create separate runtime stats for background parsing.
    3527         132 :     runtime_call_stats_ = new (zone()) RuntimeCallStats();
    3528             :   }
    3529             : 
    3530             :   std::unique_ptr<Utf16CharacterStream> stream;
    3531             :   Utf16CharacterStream* stream_ptr;
    3532         160 :   if (info->character_stream()) {
    3533             :     DCHECK(info->source_stream() == nullptr);
    3534             :     stream_ptr = info->character_stream();
    3535             :   } else {
    3536             :     DCHECK(info->character_stream() == nullptr);
    3537             :     stream.reset(ScannerStream::For(info->source_stream(),
    3538             :                                     info->source_stream_encoding(),
    3539         264 :                                     runtime_call_stats_));
    3540             :     stream_ptr = stream.get();
    3541             :   }
    3542         160 :   scanner_.Initialize(stream_ptr);
    3543             :   DCHECK(info->maybe_outer_scope_info().is_null());
    3544             : 
    3545             :   DCHECK(original_scope_);
    3546             : 
    3547             :   // When streaming, we don't know the length of the source until we have parsed
    3548             :   // it. The raw data can be UTF-8, so we wouldn't know the source length until
    3549             :   // we have decoded it anyway even if we knew the raw data length (which we
    3550             :   // don't). We work around this by storing all the scopes which need their end
    3551             :   // position set at the end of the script (the top scope and possible eval
    3552             :   // scopes) and set their end position after we know the script length.
    3553         160 :   if (info->is_toplevel()) {
    3554         132 :     fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone());
    3555         132 :     result = DoParseProgram(info);
    3556             :   } else {
    3557          28 :     result = DoParseFunction(info);
    3558             :   }
    3559             : 
    3560             :   info->set_literal(result);
    3561             : 
    3562             :   // We cannot internalize on a background thread; a foreground task will take
    3563             :   // care of calling Parser::Internalize just before compilation.
    3564             : 
    3565         160 :   if (produce_cached_parse_data()) {
    3566          12 :     if (result != NULL) *info->cached_data() = logger.GetScriptData();
    3567           6 :     log_ = NULL;
    3568             :   }
    3569         160 :   if (FLAG_runtime_stats &
    3570             :       v8::tracing::TracingCategoryObserver::ENABLED_BY_TRACING) {
    3571           0 :     auto value = v8::tracing::TracedValue::Create();
    3572           0 :     runtime_call_stats_->Dump(value.get());
    3573           0 :     TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("v8.runtime_stats"),
    3574             :                          "V8.RuntimeStats", TRACE_EVENT_SCOPE_THREAD,
    3575             :                          "runtime-call-stats", std::move(value));
    3576             :   }
    3577         160 : }
    3578             : 
    3579       40750 : Parser::TemplateLiteralState Parser::OpenTemplateLiteral(int pos) {
    3580       81500 :   return new (zone()) TemplateLiteral(zone(), pos);
    3581             : }
    3582             : 
    3583       70792 : void Parser::AddTemplateSpan(TemplateLiteralState* state, bool should_cook,
    3584             :                              bool tail) {
    3585             :   DCHECK(should_cook || allow_harmony_template_escapes());
    3586      208092 :   int pos = scanner()->location().beg_pos;
    3587             :   int end = scanner()->location().end_pos - (tail ? 1 : 2);
    3588       70792 :   const AstRawString* trv = scanner()->CurrentRawSymbol(ast_value_factory());
    3589       70792 :   Literal* raw = factory()->NewStringLiteral(trv, pos);
    3590       70792 :   if (should_cook) {
    3591       66508 :     const AstRawString* tv = scanner()->CurrentSymbol(ast_value_factory());
    3592       66508 :     Literal* cooked = factory()->NewStringLiteral(tv, pos);
    3593       66508 :     (*state)->AddTemplateSpan(cooked, raw, end, zone());
    3594             :   } else {
    3595        4284 :     (*state)->AddTemplateSpan(GetLiteralUndefined(pos), raw, end, zone());
    3596             :   }
    3597       70792 : }
    3598             : 
    3599             : 
    3600           0 : void Parser::AddTemplateExpression(TemplateLiteralState* state,
    3601             :                                    Expression* expression) {
    3602       40118 :   (*state)->AddExpression(expression, zone());
    3603           0 : }
    3604             : 
    3605             : 
    3606       28893 : Expression* Parser::CloseTemplateLiteral(TemplateLiteralState* state, int start,
    3607             :                                          Expression* tag) {
    3608       28893 :   TemplateLiteral* lit = *state;
    3609             :   int pos = lit->position();
    3610       28893 :   const ZoneList<Expression*>* cooked_strings = lit->cooked();
    3611       28893 :   const ZoneList<Expression*>* raw_strings = lit->raw();
    3612             :   const ZoneList<Expression*>* expressions = lit->expressions();
    3613             :   DCHECK_EQ(cooked_strings->length(), raw_strings->length());
    3614             :   DCHECK_EQ(cooked_strings->length(), expressions->length() + 1);
    3615             : 
    3616       28893 :   if (!tag) {
    3617             :     // Build tree of BinaryOps to simplify code-generation
    3618       20574 :     Expression* expr = cooked_strings->at(0);
    3619             :     int i = 0;
    3620       69870 :     while (i < expressions->length()) {
    3621      115059 :       Expression* sub = expressions->at(i++);
    3622       28722 :       Expression* cooked_str = cooked_strings->at(i);
    3623             : 
    3624             :       // Let middle be ToString(sub).
    3625             :       ZoneList<Expression*>* args =
    3626      115677 :           new (zone()) ZoneList<Expression*>(1, zone());
    3627             :       args->Add(sub, zone());
    3628             :       Expression* middle = factory()->NewCallRuntime(Runtime::kInlineToString,
    3629       28722 :                                                      args, sub->position());
    3630             : 
    3631             :       expr = factory()->NewBinaryOperation(
    3632             :           Token::ADD, factory()->NewBinaryOperation(
    3633       28722 :                           Token::ADD, expr, middle, expr->position()),
    3634       28722 :           cooked_str, sub->position());
    3635             :     }
    3636             :     return expr;
    3637             :   } else {
    3638        8319 :     uint32_t hash = ComputeTemplateLiteralHash(lit);
    3639             : 
    3640             :     // $getTemplateCallSite
    3641        8319 :     ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(4, zone());
    3642             :     args->Add(factory()->NewArrayLiteral(
    3643        8319 :                   const_cast<ZoneList<Expression*>*>(cooked_strings), pos),
    3644             :               zone());
    3645             :     args->Add(factory()->NewArrayLiteral(
    3646        8319 :                   const_cast<ZoneList<Expression*>*>(raw_strings), pos),
    3647             :               zone());
    3648             : 
    3649             :     // Truncate hash to Smi-range.
    3650        8319 :     Smi* hash_obj = Smi::cast(Internals::IntToSmi(static_cast<int>(hash)));
    3651        8319 :     args->Add(factory()->NewNumberLiteral(hash_obj->value(), pos), zone());
    3652             : 
    3653             :     Expression* call_site = factory()->NewCallRuntime(
    3654        8319 :         Context::GET_TEMPLATE_CALL_SITE_INDEX, args, start);
    3655             : 
    3656             :     // Call TagFn
    3657             :     ZoneList<Expression*>* call_args =
    3658       16638 :         new (zone()) ZoneList<Expression*>(expressions->length() + 1, zone());
    3659             :     call_args->Add(call_site, zone());
    3660             :     call_args->AddAll(*expressions, zone());
    3661        8319 :     return factory()->NewCall(tag, call_args, pos);
    3662             :   }
    3663             : }
    3664             : 
    3665             : 
    3666        8319 : uint32_t Parser::ComputeTemplateLiteralHash(const TemplateLiteral* lit) {
    3667             :   const ZoneList<Expression*>* raw_strings = lit->raw();
    3668        8319 :   int total = raw_strings->length();
    3669             :   DCHECK(total);
    3670             : 
    3671             :   uint32_t running_hash = 0;
    3672             : 
    3673       23268 :   for (int index = 0; index < total; ++index) {
    3674       14949 :     if (index) {
    3675             :       running_hash = StringHasher::ComputeRunningHashOneByte(
    3676             :           running_hash, "${}", 3);
    3677             :     }
    3678             : 
    3679       14949 :     const AstRawString* raw_string =
    3680       29898 :         raw_strings->at(index)->AsLiteral()->raw_value()->AsString();
    3681       14949 :     if (raw_string->is_one_byte()) {
    3682             :       const char* data = reinterpret_cast<const char*>(raw_string->raw_data());
    3683             :       running_hash = StringHasher::ComputeRunningHashOneByte(
    3684             :           running_hash, data, raw_string->length());
    3685             :     } else {
    3686             :       const uc16* data = reinterpret_cast<const uc16*>(raw_string->raw_data());
    3687             :       running_hash = StringHasher::ComputeRunningHash(running_hash, data,
    3688             :                                                       raw_string->length());
    3689             :     }
    3690             :   }
    3691             : 
    3692        8319 :   return running_hash;
    3693             : }
    3694             : 
    3695             : namespace {
    3696             : 
    3697        7180 : bool OnlyLastArgIsSpread(ZoneList<Expression*>* args) {
    3698       16296 :   for (int i = 0; i < args->length() - 1; i++) {
    3699       11488 :     if (args->at(i)->IsSpread()) {
    3700             :       return false;
    3701             :     }
    3702             :   }
    3703       12956 :   return args->at(args->length() - 1)->IsSpread();
    3704             : }
    3705             : 
    3706             : }  // namespace
    3707             : 
    3708         702 : ZoneList<Expression*>* Parser::PrepareSpreadArguments(
    3709             :     ZoneList<Expression*>* list) {
    3710       10787 :   ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(1, zone());
    3711         702 :   if (list->length() == 1) {
    3712             :     // Spread-call with single spread argument produces an InternalArray
    3713             :     // containing the values from the array.
    3714             :     //
    3715             :     // Function is called or constructed with the produced array of arguments
    3716             :     //
    3717             :     // EG: Apply(Func, Spread(spread0))
    3718             :     ZoneList<Expression*>* spread_list =
    3719           0 :         new (zone()) ZoneList<Expression*>(0, zone());
    3720           0 :     spread_list->Add(list->at(0)->AsSpread()->expression(), zone());
    3721             :     args->Add(factory()->NewCallRuntime(Runtime::kSpreadIterablePrepare,
    3722           0 :                                         spread_list, kNoSourcePosition),
    3723             :               zone());
    3724           0 :     return args;
    3725             :   } else {
    3726             :     // Spread-call with multiple arguments produces array literals for each
    3727             :     // sequences of unspread arguments, and converts each spread iterable to
    3728             :     // an Internal array. Finally, all of these produced arrays are flattened
    3729             :     // into a single InternalArray, containing the arguments for the call.
    3730             :     //
    3731             :     // EG: Apply(Func, Flatten([unspread0, unspread1], Spread(spread0),
    3732             :     //                         Spread(spread1), [unspread2, unspread3]))
    3733             :     int i = 0;
    3734             :     int n = list->length();
    3735        1932 :     while (i < n) {
    3736        3250 :       if (!list->at(i)->IsSpread()) {
    3737             :         ZoneList<Expression*>* unspread =
    3738        1145 :             new (zone()) ZoneList<Expression*>(1, zone());
    3739             : 
    3740             :         // Push array of unspread parameters
    3741        9787 :         while (i < n && !list->at(i)->IsSpread()) {
    3742        3998 :           unspread->Add(list->at(i++), zone());
    3743             :         }
    3744        1145 :         args->Add(factory()->NewArrayLiteral(unspread, kNoSourcePosition),
    3745             :                   zone());
    3746             : 
    3747        1145 :         if (i == n) break;
    3748             :       }
    3749             : 
    3750             :       // Push eagerly spread argument
    3751             :       ZoneList<Expression*>* spread_list =
    3752        1230 :           new (zone()) ZoneList<Expression*>(1, zone());
    3753        3690 :       spread_list->Add(list->at(i++)->AsSpread()->expression(), zone());
    3754             :       args->Add(factory()->NewCallRuntime(Context::SPREAD_ITERABLE_INDEX,
    3755        1230 :                                           spread_list, kNoSourcePosition),
    3756             :                 zone());
    3757             :     }
    3758             : 
    3759         702 :     list = new (zone()) ZoneList<Expression*>(1, zone());
    3760             :     list->Add(factory()->NewCallRuntime(Context::SPREAD_ARGUMENTS_INDEX, args,
    3761         702 :                                         kNoSourcePosition),
    3762             :               zone());
    3763         702 :     return list;
    3764             :   }
    3765             :   UNREACHABLE();
    3766             : }
    3767             : 
    3768        6918 : Expression* Parser::SpreadCall(Expression* function,
    3769             :                                ZoneList<Expression*>* args, int pos,
    3770             :                                Call::PossiblyEval is_possibly_eval) {
    3771             :   // Handle these cases in BytecodeGenerator.
    3772             :   // [Call,New]WithSpread bytecodes aren't used with tailcalls - see
    3773             :   // https://crbug.com/v8/5867
    3774        8497 :   if (!allow_tailcalls() && OnlyLastArgIsSpread(args)) {
    3775       12446 :     return factory()->NewCall(function, args, pos);
    3776             :   }
    3777             : 
    3778        1390 :   if (function->IsSuperCallReference()) {
    3779             :     // Super calls
    3780             :     // $super_constructor = %_GetSuperConstructor(<this-function>)
    3781             :     // %reflect_construct($super_constructor, args, new.target)
    3782             : 
    3783          42 :     args = PrepareSpreadArguments(args);
    3784          42 :     ZoneList<Expression*>* tmp = new (zone()) ZoneList<Expression*>(1, zone());
    3785          84 :     tmp->Add(function->AsSuperCallReference()->this_function_var(), zone());
    3786             :     Expression* super_constructor = factory()->NewCallRuntime(
    3787          42 :         Runtime::kInlineGetSuperConstructor, tmp, pos);
    3788             :     args->InsertAt(0, super_constructor, zone());
    3789          84 :     args->Add(function->AsSuperCallReference()->new_target_var(), zone());
    3790             :     return factory()->NewCallRuntime(Context::REFLECT_CONSTRUCT_INDEX, args,
    3791          42 :                                      pos);
    3792             :   } else {
    3793         653 :     args = PrepareSpreadArguments(args);
    3794        1306 :     if (function->IsProperty()) {
    3795             :       // Method calls
    3796         210 :       if (function->AsProperty()->IsSuperAccess()) {
    3797           0 :         Expression* home = ThisExpression(kNoSourcePosition);
    3798             :         args->InsertAt(0, function, zone());
    3799             :         args->InsertAt(1, home, zone());
    3800             :       } else {
    3801         105 :         Variable* temp = NewTemporary(ast_value_factory()->empty_string());
    3802         105 :         VariableProxy* obj = factory()->NewVariableProxy(temp);
    3803             :         Assignment* assign_obj = factory()->NewAssignment(
    3804             :             Token::ASSIGN, obj, function->AsProperty()->obj(),
    3805         210 :             kNoSourcePosition);
    3806             :         function = factory()->NewProperty(
    3807         315 :             assign_obj, function->AsProperty()->key(), kNoSourcePosition);
    3808             :         args->InsertAt(0, function, zone());
    3809         105 :         obj = factory()->NewVariableProxy(temp);
    3810         210 :         args->InsertAt(1, obj, zone());
    3811             :       }
    3812             :     } else {
    3813             :       // Non-method calls
    3814             :       args->InsertAt(0, function, zone());
    3815         548 :       args->InsertAt(1, factory()->NewUndefinedLiteral(kNoSourcePosition),
    3816        1096 :                      zone());
    3817             :     }
    3818        1306 :     return factory()->NewCallRuntime(Context::REFLECT_APPLY_INDEX, args, pos);
    3819             :   }
    3820             : }
    3821             : 
    3822         262 : Expression* Parser::SpreadCallNew(Expression* function,
    3823             :                                   ZoneList<Expression*>* args, int pos) {
    3824         262 :   if (OnlyLastArgIsSpread(args)) {
    3825             :     // Handle in BytecodeGenerator.
    3826         262 :     return factory()->NewCallNew(function, args, pos);
    3827             :   }
    3828           7 :   args = PrepareSpreadArguments(args);
    3829             :   args->InsertAt(0, function, zone());
    3830             : 
    3831          14 :   return factory()->NewCallRuntime(Context::REFLECT_CONSTRUCT_INDEX, args, pos);
    3832             : }
    3833             : 
    3834             : 
    3835    41625207 : void Parser::SetLanguageMode(Scope* scope, LanguageMode mode) {
    3836             :   v8::Isolate::UseCounterFeature feature;
    3837    41625207 :   if (is_sloppy(mode))
    3838             :     feature = v8::Isolate::kSloppyMode;
    3839    17292290 :   else if (is_strict(mode))
    3840             :     feature = v8::Isolate::kStrictMode;
    3841             :   else
    3842           0 :     UNREACHABLE();
    3843    41625207 :   ++use_counts_[feature];
    3844             :   scope->SetLanguageMode(mode);
    3845    41625207 : }
    3846             : 
    3847       11102 : void Parser::SetAsmModule() {
    3848             :   // Store the usage count; The actual use counter on the isolate is
    3849             :   // incremented after parsing is done.
    3850       11102 :   ++use_counts_[v8::Isolate::kUseAsm];
    3851             :   DCHECK(scope()->is_declaration_scope());
    3852       11102 :   scope()->AsDeclarationScope()->set_asm_module();
    3853       11102 : }
    3854             : 
    3855             : void Parser::MarkCollectedTailCallExpressions() {
    3856             :   const ZoneList<Expression*>& tail_call_expressions =
    3857     6680620 :       function_state_->tail_call_expressions().expressions();
    3858     6696329 :   for (int i = 0; i < tail_call_expressions.length(); ++i) {
    3859     6696329 :     MarkTailPosition(tail_call_expressions[i]);
    3860             :   }
    3861             : }
    3862             : 
    3863         672 : Expression* Parser::ExpressionListToExpression(ZoneList<Expression*>* args) {
    3864        1560 :   Expression* expr = args->at(0);
    3865        1776 :   for (int i = 1; i < args->length(); ++i) {
    3866             :     expr = factory()->NewBinaryOperation(Token::COMMA, expr, args->at(i),
    3867         432 :                                          expr->position());
    3868             :   }
    3869         672 :   return expr;
    3870             : }
    3871             : 
    3872             : // This method intoduces the line initializing the generator object
    3873             : // when desugaring the body of async_function.
    3874             : void Parser::PrepareAsyncFunctionBody(ZoneList<Statement*>* body,
    3875             :                                       FunctionKind kind, int pos) {
    3876             :   // When parsing an async arrow function, we get here without having called
    3877             :   // PrepareGeneratorVariables yet, so do it now.
    3878       40584 :   if (function_state_->generator_object_variable() == nullptr) {
    3879        3363 :     PrepareGeneratorVariables();
    3880             :   }
    3881             :   body->Add(factory()->NewExpressionStatement(
    3882       40584 :                 BuildCreateJSGeneratorObject(pos, kind), kNoSourcePosition),
    3883       81168 :             zone());
    3884             : }
    3885             : 
    3886             : // This method completes the desugaring of the body of async_function.
    3887             : void Parser::RewriteAsyncFunctionBody(ZoneList<Statement*>* body, Block* block,
    3888             :                                       Expression* return_value, bool* ok) {
    3889             :   // function async_function() {
    3890             :   //   .generator_object = %CreateJSGeneratorObject();
    3891             :   //   BuildRejectPromiseOnException({
    3892             :   //     ... block ...
    3893             :   //     return %ResolvePromise(.promise, expr), .promise;
    3894             :   //   })
    3895             :   // }
    3896             : 
    3897       64448 :   return_value = BuildResolvePromise(return_value, return_value->position());
    3898             :   block->statements()->Add(
    3899       32224 :       factory()->NewReturnStatement(return_value, return_value->position()),
    3900       64448 :       zone());
    3901       32224 :   block = BuildRejectPromiseOnException(block);
    3902       32224 :   body->Add(block, zone());
    3903             : }
    3904             : 
    3905             : Expression* Parser::RewriteAwaitExpression(Expression* value, int await_pos) {
    3906             :   // In an Async Function:
    3907             :   //   yield do {
    3908             :   //     tmp = <operand>;
    3909             :   //     %AsyncFunctionAwait(.generator_object, tmp, .promise);
    3910             :   //     .promise
    3911             :   //   }
    3912             :   //
    3913             :   // In an Async Generator:
    3914             :   //   yield do {
    3915             :   //     tmp = <operand>;
    3916             :   //     %AsyncGeneratorAwait(.generator_object, tmp)
    3917             :   //     .await_result_var
    3918             :   //   }
    3919             :   //
    3920             :   // The value of the expression is returned to the caller of the async
    3921             :   // function for the first yield statement; for this, .promise is the
    3922             :   // appropriate return value, being a Promise that will be fulfilled or
    3923             :   // rejected with the appropriate value by the desugaring. Subsequent yield
    3924             :   // occurrences will return to the AsyncFunctionNext call within the
    3925             :   // implemementation of the intermediate throwaway Promise's then handler.
    3926             :   // This handler has nothing useful to do with the value, as the Promise is
    3927             :   // ignored. If we yielded the value of the throwawayPromise that
    3928             :   // AsyncFunctionAwait creates as an intermediate, it would create a memory
    3929             :   // leak; we must return .promise instead;
    3930             :   // The operand needs to be evaluated on a separate statement in order to get
    3931             :   // a break location, and the .promise needs to be read earlier so that it
    3932             :   // doesn't insert a false location.
    3933             :   // TODO(littledan): investigate why this ordering is needed in more detail.
    3934             :   //
    3935             :   // In the case of Async Generators, `.await_result_var` is not actually used
    3936             :   // for anything, but exists because of the current requirement that
    3937             :   // Do Expressions have a result variable.
    3938             :   Variable* generator_object_variable =
    3939      100031 :       function_state_->generator_object_variable();
    3940             :   DCHECK_NOT_NULL(generator_object_variable);
    3941             : 
    3942             :   const int nopos = kNoSourcePosition;
    3943             : 
    3944      100031 :   Block* do_block = factory()->NewBlock(nullptr, 2, false, nopos);
    3945             : 
    3946             :   // Wrap value evaluation to provide a break location.
    3947      100031 :   Variable* temp_var = NewTemporary(ast_value_factory()->empty_string());
    3948             :   Expression* value_assignment = factory()->NewAssignment(
    3949      100031 :       Token::ASSIGN, factory()->NewVariableProxy(temp_var), value, nopos);
    3950             :   do_block->statements()->Add(
    3951      100031 :       factory()->NewExpressionStatement(value_assignment, value->position()),
    3952      200062 :       zone());
    3953             : 
    3954             :   Expression* generator_object =
    3955      100031 :       factory()->NewVariableProxy(generator_object_variable);
    3956             : 
    3957      100031 :   if (is_async_generator()) {
    3958             :     // AsyncGeneratorAwaitCaught will be rewritten to
    3959             :     // AsyncGeneratorAwaitUncaught by AstNumberingVisitor if there is no local
    3960             :     // enclosing try/catch block (not counting the one implicitly added in
    3961             :     // ParseAndRewriteGeneratorFunctionBody)
    3962       32860 :     ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(2, zone());
    3963       32860 :     args->Add(generator_object, zone());
    3964       32860 :     args->Add(factory()->NewVariableProxy(temp_var), zone());
    3965             : 
    3966             :     Expression* await = factory()->NewCallRuntime(
    3967       32860 :         Context::ASYNC_GENERATOR_AWAIT_CAUGHT, args, nopos);
    3968             :     do_block->statements()->Add(
    3969       32860 :         factory()->NewExpressionStatement(await, await_pos), zone());
    3970             : 
    3971             :     // Wrap await to provide a break location between value evaluation and
    3972             :     // yield.
    3973             :     Expression* do_expr = factory()->NewDoExpression(
    3974       32860 :         do_block, AsyncGeneratorAwaitVariable(), nopos);
    3975             :     return BuildSuspend(generator_object, do_expr, nopos,
    3976       32860 :                         Suspend::kOnExceptionRethrow, SuspendFlags::kAwait);
    3977             :   }
    3978             : 
    3979             :   // The parser emits calls to AsyncFunctionAwaitCaught or but the
    3980             :   // AstNumberingVisitor will rewrite this to AsyncFunctionAwaitUncaught or if
    3981             :   // there is no local enclosing try/catch block.
    3982       67171 :   ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(3, zone());
    3983       67171 :   args->Add(generator_object, zone());
    3984       67171 :   args->Add(factory()->NewVariableProxy(temp_var), zone());
    3985       67171 :   args->Add(factory()->NewVariableProxy(PromiseVariable()), zone());
    3986             : 
    3987             :   Expression* await = factory()->NewCallRuntime(
    3988       67171 :       Context::ASYNC_FUNCTION_AWAIT_CAUGHT_INDEX, args, nopos);
    3989             :   do_block->statements()->Add(
    3990       67171 :       factory()->NewExpressionStatement(await, await_pos), zone());
    3991             : 
    3992             :   // Wrap await to provide a break location between value evaluation and yield.
    3993             :   Expression* do_expr =
    3994       67171 :       factory()->NewDoExpression(do_block, PromiseVariable(), nopos);
    3995             : 
    3996             :   return factory()->NewSuspend(generator_object, do_expr, nopos,
    3997             :                                Suspend::kOnExceptionRethrow,
    3998       67171 :                                SuspendFlags::kAwait);
    3999             : }
    4000             : 
    4001             : class NonPatternRewriter : public AstExpressionRewriter {
    4002             :  public:
    4003        3276 :   NonPatternRewriter(uintptr_t stack_limit, Parser* parser)
    4004        3276 :       : AstExpressionRewriter(stack_limit), parser_(parser) {}
    4005        6552 :   ~NonPatternRewriter() override {}
    4006             : 
    4007             :  private:
    4008       15397 :   bool RewriteExpression(Expression* expr) override {
    4009       15397 :     if (expr->IsRewritableExpression()) return true;
    4010             :     // Rewrite only what could have been a pattern but is not.
    4011       12073 :     if (expr->IsArrayLiteral()) {
    4012             :       // Spread rewriting in array literals.
    4013        6648 :       ArrayLiteral* lit = expr->AsArrayLiteral();
    4014        6648 :       VisitExpressions(lit->values());
    4015        6648 :       replacement_ = parser_->RewriteSpreads(lit);
    4016        3324 :       return false;
    4017             :     }
    4018        8749 :     if (expr->IsObjectLiteral()) {
    4019             :       return true;
    4020             :     }
    4021        8749 :     if (expr->IsBinaryOperation() &&
    4022           0 :         expr->AsBinaryOperation()->op() == Token::COMMA) {
    4023             :       return true;
    4024             :     }
    4025             :     // Everything else does not need rewriting.
    4026        8749 :     return false;
    4027             :   }
    4028             : 
    4029           0 :   void VisitLiteralProperty(LiteralProperty* property) override {
    4030           0 :     if (property == nullptr) return;
    4031             :     // Do not rewrite (computed) key expressions
    4032           0 :     AST_REWRITE_PROPERTY(Expression, property, value);
    4033             :   }
    4034             : 
    4035             :   Parser* parser_;
    4036             : };
    4037             : 
    4038             : void Parser::RewriteNonPattern(bool* ok) {
    4039   305732726 :   ValidateExpression(CHECK_OK_VOID);
    4040   152863472 :   auto non_patterns_to_rewrite = function_state_->non_patterns_to_rewrite();
    4041   152863472 :   int begin = classifier()->GetNonPatternBegin();
    4042   152863472 :   int end = non_patterns_to_rewrite->length();
    4043   152863472 :   if (begin < end) {
    4044        3276 :     NonPatternRewriter rewriter(stack_limit_, this);
    4045        3324 :     for (int i = begin; i < end; i++) {
    4046             :       DCHECK(non_patterns_to_rewrite->at(i)->IsRewritableExpression());
    4047        3324 :       rewriter.Rewrite(non_patterns_to_rewrite->at(i));
    4048             :     }
    4049        3276 :     non_patterns_to_rewrite->Rewind(begin);
    4050             :   }
    4051             : }
    4052             : 
    4053             : 
    4054             : void Parser::RewriteDestructuringAssignments() {
    4055             :   const auto& assignments =
    4056     8643200 :       function_state_->destructuring_assignments_to_rewrite();
    4057     8730595 :   for (int i = assignments.length() - 1; i >= 0; --i) {
    4058             :     // Rewrite list in reverse, so that nested assignment patterns are rewritten
    4059             :     // correctly.
    4060       87397 :     const DestructuringAssignment& pair = assignments.at(i);
    4061       87397 :     RewritableExpression* to_rewrite =
    4062       87397 :         pair.assignment->AsRewritableExpression();
    4063             :     DCHECK_NOT_NULL(to_rewrite);
    4064       87397 :     if (!to_rewrite->is_rewritten()) {
    4065             :       // Since this function is called at the end of parsing the program,
    4066             :       // pair.scope may already have been removed by FinalizeBlockScope in the
    4067             :       // meantime.
    4068       73529 :       Scope* scope = pair.scope->GetUnremovedScope();
    4069       73529 :       PatternRewriter::RewriteDestructuringAssignment(this, to_rewrite, scope);
    4070             :     }
    4071             :   }
    4072             : }
    4073             : 
    4074             : Expression* Parser::RewriteExponentiation(Expression* left, Expression* right,
    4075             :                                           int pos) {
    4076        2262 :   ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(2, zone());
    4077        2262 :   args->Add(left, zone());
    4078        2262 :   args->Add(right, zone());
    4079        2262 :   return factory()->NewCallRuntime(Context::MATH_POW_INDEX, args, pos);
    4080             : }
    4081             : 
    4082             : Expression* Parser::RewriteAssignExponentiation(Expression* left,
    4083             :                                                 Expression* right, int pos) {
    4084         179 :   ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(2, zone());
    4085         206 :   if (left->IsVariableProxy()) {
    4086             :     VariableProxy* lhs = left->AsVariableProxy();
    4087             : 
    4088             :     Expression* result;
    4089             :     DCHECK_NOT_NULL(lhs->raw_name());
    4090         152 :     result = ExpressionFromIdentifier(lhs->raw_name(), lhs->position());
    4091         152 :     args->Add(left, zone());
    4092         152 :     args->Add(right, zone());
    4093             :     Expression* call =
    4094         152 :         factory()->NewCallRuntime(Context::MATH_POW_INDEX, args, pos);
    4095         152 :     return factory()->NewAssignment(Token::ASSIGN, result, call, pos);
    4096          27 :   } else if (left->IsProperty()) {
    4097          54 :     Property* prop = left->AsProperty();
    4098          27 :     auto temp_obj = NewTemporary(ast_value_factory()->empty_string());
    4099          27 :     auto temp_key = NewTemporary(ast_value_factory()->empty_string());
    4100             :     Expression* assign_obj = factory()->NewAssignment(
    4101          27 :         Token::ASSIGN, factory()->NewVariableProxy(temp_obj), prop->obj(),
    4102          54 :         kNoSourcePosition);
    4103             :     Expression* assign_key = factory()->NewAssignment(
    4104          27 :         Token::ASSIGN, factory()->NewVariableProxy(temp_key), prop->key(),
    4105          54 :         kNoSourcePosition);
    4106          27 :     args->Add(factory()->NewProperty(factory()->NewVariableProxy(temp_obj),
    4107          27 :                                      factory()->NewVariableProxy(temp_key),
    4108          54 :                                      left->position()),
    4109          54 :               zone());
    4110          27 :     args->Add(right, zone());
    4111             :     Expression* call =
    4112          27 :         factory()->NewCallRuntime(Context::MATH_POW_INDEX, args, pos);
    4113             :     Expression* target = factory()->NewProperty(
    4114          27 :         factory()->NewVariableProxy(temp_obj),
    4115          54 :         factory()->NewVariableProxy(temp_key), kNoSourcePosition);
    4116             :     Expression* assign =
    4117          27 :         factory()->NewAssignment(Token::ASSIGN, target, call, pos);
    4118             :     return factory()->NewBinaryOperation(
    4119             :         Token::COMMA, assign_obj,
    4120          27 :         factory()->NewBinaryOperation(Token::COMMA, assign_key, assign, pos),
    4121          27 :         pos);
    4122             :   }
    4123           0 :   UNREACHABLE();
    4124             :   return nullptr;
    4125             : }
    4126             : 
    4127             : Expression* Parser::RewriteSpreads(ArrayLiteral* lit) {
    4128             :   // Array literals containing spreads are rewritten using do expressions, e.g.
    4129             :   //    [1, 2, 3, ...x, 4, ...y, 5]
    4130             :   // is roughly rewritten as:
    4131             :   //    do {
    4132             :   //      $R = [1, 2, 3];
    4133             :   //      for ($i of x) %AppendElement($R, $i);
    4134             :   //      %AppendElement($R, 4);
    4135             :   //      for ($j of y) %AppendElement($R, $j);
    4136             :   //      %AppendElement($R, 5);
    4137             :   //      $R
    4138             :   //    }
    4139             :   // where $R, $i and $j are fresh temporary variables.
    4140        3324 :   ZoneList<Expression*>::iterator s = lit->FirstSpread();
    4141        3324 :   if (s == lit->EndValue()) return nullptr;  // no spread, no rewriting...
    4142        3324 :   Variable* result = NewTemporary(ast_value_factory()->dot_result_string());
    4143             :   // NOTE: The value assigned to R is the whole original array literal,
    4144             :   // spreads included. This will be fixed before the rewritten AST is returned.
    4145             :   // $R = lit
    4146             :   Expression* init_result = factory()->NewAssignment(
    4147        3324 :       Token::INIT, factory()->NewVariableProxy(result), lit, kNoSourcePosition);
    4148        3324 :   Block* do_block = factory()->NewBlock(nullptr, 16, false, kNoSourcePosition);
    4149             :   do_block->statements()->Add(
    4150        3324 :       factory()->NewExpressionStatement(init_result, kNoSourcePosition),
    4151        6648 :       zone());
    4152             :   // Traverse the array literal starting from the first spread.
    4153        9705 :   while (s != lit->EndValue()) {
    4154        6381 :     Expression* value = *s++;
    4155       11778 :     Spread* spread = value->AsSpread();
    4156        6381 :     if (spread == nullptr) {
    4157             :       // If the element is not a spread, we're adding a single:
    4158             :       // %AppendElement($R, value)
    4159             :       // or, in case of a hole,
    4160             :       // ++($R.length)
    4161        2144 :       if (!value->IsLiteral() ||
    4162         352 :           !value->AsLiteral()->raw_value()->IsTheHole()) {
    4163             :         ZoneList<Expression*>* append_element_args = NewExpressionList(2);
    4164         881 :         append_element_args->Add(factory()->NewVariableProxy(result), zone());
    4165         881 :         append_element_args->Add(value, zone());
    4166             :         do_block->statements()->Add(
    4167             :             factory()->NewExpressionStatement(
    4168             :                 factory()->NewCallRuntime(Runtime::kAppendElement,
    4169             :                                           append_element_args,
    4170         881 :                                           kNoSourcePosition),
    4171         881 :                 kNoSourcePosition),
    4172        1762 :             zone());
    4173             :       } else {
    4174             :         Property* length_property = factory()->NewProperty(
    4175         103 :             factory()->NewVariableProxy(result),
    4176             :             factory()->NewStringLiteral(ast_value_factory()->length_string(),
    4177         103 :                                         kNoSourcePosition),
    4178         103 :             kNoSourcePosition);
    4179             :         CountOperation* count_op = factory()->NewCountOperation(
    4180         103 :             Token::INC, true /* prefix */, length_property, kNoSourcePosition);
    4181             :         do_block->statements()->Add(
    4182         103 :             factory()->NewExpressionStatement(count_op, kNoSourcePosition),
    4183         206 :             zone());
    4184             :       }
    4185             :     } else {
    4186             :       // If it's a spread, we're adding a for/of loop iterating through it.
    4187        5397 :       Variable* each = NewTemporary(ast_value_factory()->dot_for_string());
    4188        5397 :       Expression* subject = spread->expression();
    4189             :       // %AppendElement($R, each)
    4190             :       Statement* append_body;
    4191             :       {
    4192             :         ZoneList<Expression*>* append_element_args = NewExpressionList(2);
    4193        5397 :         append_element_args->Add(factory()->NewVariableProxy(result), zone());
    4194        5397 :         append_element_args->Add(factory()->NewVariableProxy(each), zone());
    4195             :         append_body = factory()->NewExpressionStatement(
    4196             :             factory()->NewCallRuntime(Runtime::kAppendElement,
    4197        5397 :                                       append_element_args, kNoSourcePosition),
    4198        5397 :             kNoSourcePosition);
    4199             :       }
    4200             :       // for (each of spread) %AppendElement($R, each)
    4201             :       ForOfStatement* loop =
    4202        5397 :           factory()->NewForOfStatement(nullptr, kNoSourcePosition);
    4203             :       const bool finalize = false;
    4204        5397 :       InitializeForOfStatement(loop, factory()->NewVariableProxy(each), subject,
    4205        5397 :                                append_body, finalize, IteratorType::kNormal);
    4206        5397 :       do_block->statements()->Add(loop, zone());
    4207             :     }
    4208             :   }
    4209             :   // Now, rewind the original array literal to truncate everything from the
    4210             :   // first spread (included) until the end. This fixes $R's initialization.
    4211        3324 :   lit->RewindSpreads();
    4212        3324 :   return factory()->NewDoExpression(do_block, result, lit->position());
    4213             : }
    4214             : 
    4215             : void Parser::QueueDestructuringAssignmentForRewriting(Expression* expr) {
    4216             :   DCHECK(expr->IsRewritableExpression());
    4217             :   function_state_->AddDestructuringAssignment(
    4218       92429 :       DestructuringAssignment(expr, scope()));
    4219             : }
    4220             : 
    4221             : void Parser::QueueNonPatternForRewriting(Expression* expr, bool* ok) {
    4222             :   DCHECK(expr->IsRewritableExpression());
    4223       19210 :   function_state_->AddNonPatternForRewriting(expr, ok);
    4224             : }
    4225             : 
    4226       30615 : void Parser::AddAccessorPrefixToFunctionName(bool is_get,
    4227             :                                              FunctionLiteral* function,
    4228             :                                              const AstRawString* name) {
    4229             :   DCHECK_NOT_NULL(name);
    4230       61230 :   const AstRawString* prefix = is_get ? ast_value_factory()->get_space_string()
    4231       42228 :                                       : ast_value_factory()->set_space_string();
    4232       30615 :   function->set_raw_name(ast_value_factory()->NewConsString(prefix, name));
    4233       30615 : }
    4234             : 
    4235     4681466 : void Parser::SetFunctionNameFromPropertyName(ObjectLiteralProperty* property,
    4236             :                                              const AstRawString* name) {
    4237             :   DCHECK(property->kind() != ObjectLiteralProperty::GETTER);
    4238             :   DCHECK(property->kind() != ObjectLiteralProperty::SETTER);
    4239             : 
    4240             :   // Computed name setting must happen at runtime.
    4241             :   DCHECK(!property->is_computed_name());
    4242             : 
    4243             :   // Ignore "__proto__" as a name when it's being used to set the [[Prototype]]
    4244             :   // of an object literal.
    4245     4681466 :   if (property->kind() == ObjectLiteralProperty::PROTOTYPE) return;
    4246             : 
    4247     4588801 :   Expression* value = property->value();
    4248             : 
    4249             :   DCHECK(!value->IsAnonymousFunctionDefinition() ||
    4250             :          property->kind() == ObjectLiteralProperty::COMPUTED);
    4251     4588801 :   SetFunctionName(value, name);
    4252             : }
    4253             : 
    4254    21314770 : void Parser::SetFunctionNameFromIdentifierRef(Expression* value,
    4255             :                                               Expression* identifier) {
    4256    42629543 :   if (!identifier->IsVariableProxy()) return;
    4257    29084062 :   SetFunctionName(value, identifier->AsVariableProxy()->raw_name());
    4258             : }
    4259             : 
    4260    19131029 : void Parser::SetFunctionName(Expression* value, const AstRawString* name) {
    4261             :   DCHECK_NOT_NULL(name);
    4262    38262058 :   if (!value->IsAnonymousFunctionDefinition()) return;
    4263      820725 :   auto function = value->AsFunctionLiteral();
    4264      820725 :   if (function != nullptr) {
    4265      820725 :     function->set_raw_name(ast_value_factory()->NewConsString(name));
    4266             :   } else {
    4267             :     DCHECK(value->IsDoExpression());
    4268             :     value->AsDoExpression()->represented_function()->set_raw_name(
    4269        5180 :         ast_value_factory()->NewConsString(name));
    4270             :   }
    4271             : }
    4272             : 
    4273             : 
    4274             : // Desugaring of yield*
    4275             : // ====================
    4276             : //
    4277             : // With the help of do-expressions and function.sent, we desugar yield* into a
    4278             : // loop containing a "raw" yield (a yield that doesn't wrap an iterator result
    4279             : // object around its argument).  Concretely, "yield* iterable" turns into
    4280             : // roughly the following code:
    4281             : //
    4282             : //   do {
    4283             : //     const kNext = 0;
    4284             : //     const kReturn = 1;
    4285             : //     const kThrow = 2;
    4286             : //
    4287             : //     let input = undefined;
    4288             : //     let mode = kNext;
    4289             : //     let output = undefined;
    4290             : //
    4291             : //     let iterator = GetIterator(iterable);
    4292             : //
    4293             : //     while (true) {
    4294             : //       // From the generator to the iterator:
    4295             : //       // Forward input according to resume mode and obtain output.
    4296             : //       switch (mode) {
    4297             : //         case kNext:
    4298             : //           output = iterator.next(input);
    4299             : //           if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output);
    4300             : //           break;
    4301             : //         case kReturn:
    4302             : //           IteratorClose(iterator, input, output);  // See below.
    4303             : //           break;
    4304             : //         case kThrow:
    4305             : //           let iteratorThrow = iterator.throw;
    4306             : //           if (IS_NULL_OR_UNDEFINED(iteratorThrow)) {
    4307             : //             IteratorClose(iterator);  // See below.
    4308             : //             throw MakeTypeError(kThrowMethodMissing);
    4309             : //           }
    4310             : //           output = %_Call(iteratorThrow, iterator, input);
    4311             : //           if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output);
    4312             : //           break;
    4313             : //       }
    4314             : //       if (output.done) break;
    4315             : //
    4316             : //       // From the generator to its user:
    4317             : //       // Forward output, receive new input, and determine resume mode.
    4318             : //       mode = kReturn;
    4319             : //       try {
    4320             : //         try {
    4321             : //           RawYield(output);  // See explanation above.
    4322             : //           mode = kNext;
    4323             : //         } catch (error) {
    4324             : //           mode = kThrow;
    4325             : //         }
    4326             : //       } finally {
    4327             : //         input = function.sent;
    4328             : //         continue;
    4329             : //       }
    4330             : //     }
    4331             : //
    4332             : //     if (mode === kReturn) {
    4333             : //       return {value: output.value, done: true};
    4334             : //     }
    4335             : //     output.value
    4336             : //   }
    4337             : //
    4338             : // IteratorClose(iterator) expands to the following:
    4339             : //
    4340             : //   let iteratorReturn = iterator.return;
    4341             : //   if (!IS_NULL_OR_UNDEFINED(iteratorReturn)) {
    4342             : //     let output = %_Call(iteratorReturn, iterator);
    4343             : //     if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output);
    4344             : //   }
    4345             : //
    4346             : // IteratorClose(iterator, input, output) expands to the following:
    4347             : //
    4348             : //   let iteratorReturn = iterator.return;
    4349             : //   if (IS_NULL_OR_UNDEFINED(iteratorReturn)) return input;
    4350             : //   output = %_Call(iteratorReturn, iterator, input);
    4351             : //   if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output);
    4352             : 
    4353        2599 : Expression* Parser::RewriteYieldStar(Expression* generator,
    4354             :                                      Expression* iterable, int pos) {
    4355             :   const int nopos = kNoSourcePosition;
    4356             :   IteratorType type =
    4357      176449 :       is_async_generator() ? IteratorType::kAsync : IteratorType::kNormal;
    4358             : 
    4359             :   // Forward definition for break/continue statements.
    4360        2599 :   WhileStatement* loop = factory()->NewWhileStatement(nullptr, nopos);
    4361             : 
    4362             :   // let input = undefined;
    4363        2599 :   Variable* var_input = NewTemporary(ast_value_factory()->empty_string());
    4364             :   Statement* initialize_input;
    4365             :   {
    4366        2599 :     Expression* input_proxy = factory()->NewVariableProxy(var_input);
    4367             :     Expression* assignment =
    4368             :         factory()->NewAssignment(Token::ASSIGN, input_proxy,
    4369        2599 :                                  factory()->NewUndefinedLiteral(nopos), nopos);
    4370        2599 :     initialize_input = factory()->NewExpressionStatement(assignment, nopos);
    4371             :   }
    4372             : 
    4373             :   // let mode = kNext;
    4374        2599 :   Variable* var_mode = NewTemporary(ast_value_factory()->empty_string());
    4375             :   Statement* initialize_mode;
    4376             :   {
    4377        2599 :     Expression* mode_proxy = factory()->NewVariableProxy(var_mode);
    4378             :     Expression* knext =
    4379        2599 :         factory()->NewSmiLiteral(JSGeneratorObject::kNext, nopos);
    4380             :     Expression* assignment =
    4381        2599 :         factory()->NewAssignment(Token::ASSIGN, mode_proxy, knext, nopos);
    4382        2599 :     initialize_mode = factory()->NewExpressionStatement(assignment, nopos);
    4383             :   }
    4384             : 
    4385             :   // let output = undefined;
    4386        2599 :   Variable* var_output = NewTemporary(ast_value_factory()->empty_string());
    4387             :   Statement* initialize_output;
    4388             :   {
    4389        2599 :     Expression* output_proxy = factory()->NewVariableProxy(var_output);
    4390             :     Expression* assignment =
    4391             :         factory()->NewAssignment(Token::ASSIGN, output_proxy,
    4392        2599 :                                  factory()->NewUndefinedLiteral(nopos), nopos);
    4393        2599 :     initialize_output = factory()->NewExpressionStatement(assignment, nopos);
    4394             :   }
    4395             : 
    4396             :   // let iterator = GetIterator(iterable);
    4397        2599 :   Variable* var_iterator = NewTemporary(ast_value_factory()->empty_string());
    4398             :   Statement* get_iterator;
    4399             :   {
    4400        2599 :     Expression* iterator = factory()->NewGetIterator(iterable, type, nopos);
    4401        2599 :     Expression* iterator_proxy = factory()->NewVariableProxy(var_iterator);
    4402             :     Expression* assignment = factory()->NewAssignment(
    4403        2599 :         Token::ASSIGN, iterator_proxy, iterator, nopos);
    4404        2599 :     get_iterator = factory()->NewExpressionStatement(assignment, nopos);
    4405             :   }
    4406             : 
    4407             :   // output = iterator.next(input);
    4408             :   Statement* call_next;
    4409             :   {
    4410        2599 :     Expression* iterator_proxy = factory()->NewVariableProxy(var_iterator);
    4411             :     Expression* literal =
    4412        5198 :         factory()->NewStringLiteral(ast_value_factory()->next_string(), nopos);
    4413             :     Expression* next_property =
    4414        2599 :         factory()->NewProperty(iterator_proxy, literal, nopos);
    4415        2599 :     Expression* input_proxy = factory()->NewVariableProxy(var_input);
    4416        2599 :     auto args = new (zone()) ZoneList<Expression*>(1, zone());
    4417             :     args->Add(input_proxy, zone());
    4418        2599 :     Expression* call = factory()->NewCall(next_property, args, nopos);
    4419        2599 :     if (type == IteratorType::kAsync) {
    4420             :       call = RewriteAwaitExpression(call, nopos);
    4421             :     }
    4422        2599 :     Expression* output_proxy = factory()->NewVariableProxy(var_output);
    4423             :     Expression* assignment =
    4424        2599 :         factory()->NewAssignment(Token::ASSIGN, output_proxy, call, nopos);
    4425        2599 :     call_next = factory()->NewExpressionStatement(assignment, nopos);
    4426             :   }
    4427             : 
    4428             :   // if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output);
    4429             :   Statement* validate_next_output;
    4430             :   {
    4431             :     Expression* is_receiver_call;
    4432             :     {
    4433        2599 :       auto args = new (zone()) ZoneList<Expression*>(1, zone());
    4434        2599 :       args->Add(factory()->NewVariableProxy(var_output), zone());
    4435             :       is_receiver_call =
    4436        2599 :           factory()->NewCallRuntime(Runtime::kInlineIsJSReceiver, args, nopos);
    4437             :     }
    4438             : 
    4439             :     Statement* throw_call;
    4440             :     {
    4441        2599 :       auto args = new (zone()) ZoneList<Expression*>(1, zone());
    4442        2599 :       args->Add(factory()->NewVariableProxy(var_output), zone());
    4443             :       Expression* call = factory()->NewCallRuntime(
    4444        2599 :           Runtime::kThrowIteratorResultNotAnObject, args, nopos);
    4445        2599 :       throw_call = factory()->NewExpressionStatement(call, nopos);
    4446             :     }
    4447             : 
    4448             :     validate_next_output = factory()->NewIfStatement(
    4449        2599 :         is_receiver_call, factory()->NewEmptyStatement(nopos), throw_call,
    4450        2599 :         nopos);
    4451             :   }
    4452             : 
    4453             :   // let iteratorThrow = iterator.throw;
    4454        2599 :   Variable* var_throw = NewTemporary(ast_value_factory()->empty_string());
    4455             :   Statement* get_throw;
    4456             :   {
    4457        2599 :     Expression* iterator_proxy = factory()->NewVariableProxy(var_iterator);
    4458             :     Expression* literal =
    4459        5198 :         factory()->NewStringLiteral(ast_value_factory()->throw_string(), nopos);
    4460             :     Expression* property =
    4461        2599 :         factory()->NewProperty(iterator_proxy, literal, nopos);
    4462        2599 :     Expression* throw_proxy = factory()->NewVariableProxy(var_throw);
    4463             :     Expression* assignment =
    4464        2599 :         factory()->NewAssignment(Token::ASSIGN, throw_proxy, property, nopos);
    4465        2599 :     get_throw = factory()->NewExpressionStatement(assignment, nopos);
    4466             :   }
    4467             : 
    4468             :   // if (IS_NULL_OR_UNDEFINED(iteratorThrow) {
    4469             :   //   IteratorClose(iterator);
    4470             :   //   throw MakeTypeError(kThrowMethodMissing);
    4471             :   // }
    4472             :   Statement* check_throw;
    4473             :   {
    4474             :     Expression* condition = factory()->NewCompareOperation(
    4475        2599 :         Token::EQ, factory()->NewVariableProxy(var_throw),
    4476        5198 :         factory()->NewNullLiteral(nopos), nopos);
    4477             :     Expression* call =
    4478             :         NewThrowTypeError(MessageTemplate::kThrowMethodMissing,
    4479        2599 :                           ast_value_factory()->empty_string(), nopos);
    4480        2599 :     Statement* throw_call = factory()->NewExpressionStatement(call, nopos);
    4481             : 
    4482        2599 :     Block* then = factory()->NewBlock(nullptr, 4 + 1, false, nopos);
    4483             :     BuildIteratorCloseForCompletion(
    4484             :         scope(), then->statements(), var_iterator,
    4485        5198 :         factory()->NewSmiLiteral(Parser::kNormalCompletion, nopos), type);
    4486             :     then->statements()->Add(throw_call, zone());
    4487             :     check_throw = factory()->NewIfStatement(
    4488        5198 :         condition, then, factory()->NewEmptyStatement(nopos), nopos);
    4489             :   }
    4490             : 
    4491             :   // output = %_Call(iteratorThrow, iterator, input);
    4492             :   Statement* call_throw;
    4493             :   {
    4494        2599 :     auto args = new (zone()) ZoneList<Expression*>(3, zone());
    4495        2599 :     args->Add(factory()->NewVariableProxy(var_throw), zone());
    4496        2599 :     args->Add(factory()->NewVariableProxy(var_iterator), zone());
    4497        2599 :     args->Add(factory()->NewVariableProxy(var_input), zone());
    4498             :     Expression* call =
    4499        2599 :         factory()->NewCallRuntime(Runtime::kInlineCall, args, nopos);
    4500        2599 :     if (type == IteratorType::kAsync) {
    4501             :       call = RewriteAwaitExpression(call, nopos);
    4502             :     }
    4503             :     Expression* assignment = factory()->NewAssignment(
    4504        5198 :         Token::ASSIGN, factory()->NewVariableProxy(var_output), call, nopos);
    4505        2599 :     call_throw = factory()->NewExpressionStatement(assignment, nopos);
    4506             :   }
    4507             : 
    4508             :   // if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output);
    4509             :   Statement* validate_throw_output;
    4510             :   {
    4511             :     Expression* is_receiver_call;
    4512             :     {
    4513        2599 :       auto args = new (zone()) ZoneList<Expression*>(1, zone());
    4514        2599 :       args->Add(factory()->NewVariableProxy(var_output), zone());
    4515             :       is_receiver_call =
    4516        2599 :           factory()->NewCallRuntime(Runtime::kInlineIsJSReceiver, args, nopos);
    4517             :     }
    4518             : 
    4519             :     Statement* throw_call;
    4520             :     {
    4521        2599 :       auto args = new (zone()) ZoneList<Expression*>(1, zone());
    4522        2599 :       args->Add(factory()->NewVariableProxy(var_output), zone());
    4523             :       Expression* call = factory()->NewCallRuntime(
    4524        2599 :           Runtime::kThrowIteratorResultNotAnObject, args, nopos);
    4525        2599 :       throw_call = factory()->NewExpressionStatement(call, nopos);
    4526             :     }
    4527             : 
    4528             :     validate_throw_output = factory()->NewIfStatement(
    4529        2599 :         is_receiver_call, factory()->NewEmptyStatement(nopos), throw_call,
    4530        2599 :         nopos);
    4531             :   }
    4532             : 
    4533             :   // if (output.done) break;
    4534             :   Statement* if_done;
    4535             :   {
    4536        2599 :     Expression* output_proxy = factory()->NewVariableProxy(var_output);
    4537             :     Expression* literal =
    4538        5198 :         factory()->NewStringLiteral(ast_value_factory()->done_string(), nopos);
    4539        2599 :     Expression* property = factory()->NewProperty(output_proxy, literal, nopos);
    4540        2599 :     BreakStatement* break_loop = factory()->NewBreakStatement(loop, nopos);
    4541             :     if_done = factory()->NewIfStatement(
    4542        5198 :         property, break_loop, factory()->NewEmptyStatement(nopos), nopos);
    4543             :   }
    4544             : 
    4545             : 
    4546             :   // mode = kReturn;
    4547             :   Statement* set_mode_return;
    4548             :   {
    4549        2599 :     Expression* mode_proxy = factory()->NewVariableProxy(var_mode);
    4550             :     Expression* kreturn =
    4551        2599 :         factory()->NewSmiLiteral(JSGeneratorObject::kReturn, nopos);
    4552             :     Expression* assignment =
    4553        2599 :         factory()->NewAssignment(Token::ASSIGN, mode_proxy, kreturn, nopos);
    4554        2599 :     set_mode_return = factory()->NewExpressionStatement(assignment, nopos);
    4555             :   }
    4556             : 
    4557             :   // Yield(output);
    4558             :   Statement* yield_output;
    4559             :   {
    4560        2599 :     Expression* output_proxy = factory()->NewVariableProxy(var_output);
    4561             :     Suspend* yield =
    4562             :         BuildSuspend(generator, output_proxy, nopos, Suspend::kOnExceptionThrow,
    4563        2599 :                      SuspendFlags::kYieldStar);
    4564        2599 :     yield_output = factory()->NewExpressionStatement(yield, nopos);
    4565             :   }
    4566             : 
    4567             :   // mode = kNext;
    4568             :   Statement* set_mode_next;
    4569             :   {
    4570        2599 :     Expression* mode_proxy = factory()->NewVariableProxy(var_mode);
    4571             :     Expression* knext =
    4572        2599 :         factory()->NewSmiLiteral(JSGeneratorObject::kNext, nopos);
    4573             :     Expression* assignment =
    4574        2599 :         factory()->NewAssignment(Token::ASSIGN, mode_proxy, knext, nopos);
    4575        2599 :     set_mode_next = factory()->NewExpressionStatement(assignment, nopos);
    4576             :   }
    4577             : 
    4578             :   // mode = kThrow;
    4579             :   Statement* set_mode_throw;
    4580             :   {
    4581        2599 :     Expression* mode_proxy = factory()->NewVariableProxy(var_mode);
    4582             :     Expression* kthrow =
    4583        2599 :         factory()->NewSmiLiteral(JSGeneratorObject::kThrow, nopos);
    4584             :     Expression* assignment =
    4585        2599 :         factory()->NewAssignment(Token::ASSIGN, mode_proxy, kthrow, nopos);
    4586        2599 :     set_mode_throw = factory()->NewExpressionStatement(assignment, nopos);
    4587             :   }
    4588             : 
    4589             :   // input = function.sent;
    4590             :   Statement* get_input;
    4591             :   {
    4592        2599 :     Expression* function_sent = FunctionSentExpression(nopos);
    4593        2599 :     Expression* input_proxy = factory()->NewVariableProxy(var_input);
    4594             :     Expression* assignment = factory()->NewAssignment(
    4595        2599 :         Token::ASSIGN, input_proxy, function_sent, nopos);
    4596        2599 :     get_input = factory()->NewExpressionStatement(assignment, nopos);
    4597             :   }
    4598             : 
    4599             :   // if (mode === kReturn) {
    4600             :   //   return {value: output.value, done: true};
    4601             :   // }
    4602             :   Statement* maybe_return_value;
    4603             :   {
    4604        2599 :     Expression* mode_proxy = factory()->NewVariableProxy(var_mode);
    4605             :     Expression* kreturn =
    4606        2599 :         factory()->NewSmiLiteral(JSGeneratorObject::kReturn, nopos);
    4607             :     Expression* condition = factory()->NewCompareOperation(
    4608        2599 :         Token::EQ_STRICT, mode_proxy, kreturn, nopos);
    4609             : 
    4610        2599 :     Expression* output_proxy = factory()->NewVariableProxy(var_output);
    4611             :     Expression* literal =
    4612        5198 :         factory()->NewStringLiteral(ast_value_factory()->value_string(), nopos);
    4613        2599 :     Expression* property = factory()->NewProperty(output_proxy, literal, nopos);
    4614        2599 :     Statement* return_value = BuildReturnStatement(property, nopos);
    4615             : 
    4616             :     maybe_return_value = factory()->NewIfStatement(
    4617        5198 :         condition, return_value, factory()->NewEmptyStatement(nopos), nopos);
    4618             :   }
    4619             : 
    4620             :   // output.value
    4621             :   Statement* get_value;
    4622             :   {
    4623        2599 :     Expression* output_proxy = factory()->NewVariableProxy(var_output);
    4624             :     Expression* literal =
    4625        5198 :         factory()->NewStringLiteral(ast_value_factory()->value_string(), nopos);
    4626        2599 :     Expression* property = factory()->NewProperty(output_proxy, literal, nopos);
    4627        2599 :     get_value = factory()->NewExpressionStatement(property, nopos);
    4628             :   }
    4629             : 
    4630             :   // Now put things together.
    4631             : 
    4632             :   // try { ... } catch(e) { ... }
    4633             :   Statement* try_catch;
    4634             :   {
    4635        2599 :     Block* try_block = factory()->NewBlock(nullptr, 2, false, nopos);
    4636             :     try_block->statements()->Add(yield_output, zone());
    4637             :     try_block->statements()->Add(set_mode_next, zone());
    4638             : 
    4639        2599 :     Block* catch_block = factory()->NewBlock(nullptr, 1, false, nopos);
    4640             :     catch_block->statements()->Add(set_mode_throw, zone());
    4641             : 
    4642             :     Scope* catch_scope = NewHiddenCatchScopeWithParent(scope());
    4643             : 
    4644             :     try_catch = factory()->NewTryCatchStatementForDesugaring(
    4645        2599 :         try_block, catch_scope, catch_block, nopos);
    4646             :   }
    4647             : 
    4648             :   // try { ... } finally { ... }
    4649             :   Statement* try_finally;
    4650             :   {
    4651        2599 :     Block* try_block = factory()->NewBlock(nullptr, 1, false, nopos);
    4652             :     try_block->statements()->Add(try_catch, zone());
    4653             : 
    4654        2599 :     Block* finally = factory()->NewBlock(nullptr, 2, false, nopos);
    4655             :     finally->statements()->Add(get_input, zone());
    4656        2599 :     finally->statements()->Add(factory()->NewContinueStatement(loop, nopos),
    4657             :                                zone());
    4658             : 
    4659        2599 :     try_finally = factory()->NewTryFinallyStatement(try_block, finally, nopos);
    4660             :   }
    4661             : 
    4662             :   // switch (mode) { ... }
    4663        2599 :   SwitchStatement* switch_mode = factory()->NewSwitchStatement(nullptr, nopos);
    4664             :   {
    4665        2599 :     auto case_next = new (zone()) ZoneList<Statement*>(3, zone());
    4666             :     case_next->Add(call_next, zone());
    4667             :     case_next->Add(validate_next_output, zone());
    4668        2599 :     case_next->Add(factory()->NewBreakStatement(switch_mode, nopos), zone());
    4669             : 
    4670        2599 :     auto case_return = new (zone()) ZoneList<Statement*>(5, zone());
    4671        2599 :     BuildIteratorClose(case_return, var_iterator, var_input, var_output, type);
    4672        2599 :     case_return->Add(factory()->NewBreakStatement(switch_mode, nopos), zone());
    4673             : 
    4674        2599 :     auto case_throw = new (zone()) ZoneList<Statement*>(5, zone());
    4675             :     case_throw->Add(get_throw, zone());
    4676             :     case_throw->Add(check_throw, zone());
    4677             :     case_throw->Add(call_throw, zone());
    4678             :     case_throw->Add(validate_throw_output, zone());
    4679        2599 :     case_throw->Add(factory()->NewBreakStatement(switch_mode, nopos), zone());
    4680             : 
    4681        2599 :     auto cases = new (zone()) ZoneList<CaseClause*>(3, zone());
    4682             :     Expression* knext =
    4683        2599 :         factory()->NewSmiLiteral(JSGeneratorObject::kNext, nopos);
    4684             :     Expression* kreturn =
    4685        2599 :         factory()->NewSmiLiteral(JSGeneratorObject::kReturn, nopos);
    4686             :     Expression* kthrow =
    4687        2599 :         factory()->NewSmiLiteral(JSGeneratorObject::kThrow, nopos);
    4688        2599 :     cases->Add(factory()->NewCaseClause(knext, case_next, nopos), zone());
    4689        2599 :     cases->Add(factory()->NewCaseClause(kreturn, case_return, nopos), zone());
    4690        2599 :     cases->Add(factory()->NewCaseClause(kthrow, case_throw, nopos), zone());
    4691             : 
    4692        2599 :     switch_mode->Initialize(factory()->NewVariableProxy(var_mode), cases);
    4693             :   }
    4694             : 
    4695             :   // while (true) { ... }
    4696             :   // Already defined earlier: WhileStatement* loop = ...
    4697             :   {
    4698        2599 :     Block* loop_body = factory()->NewBlock(nullptr, 5, false, nopos);
    4699             :     loop_body->statements()->Add(switch_mode, zone());
    4700             :     loop_body->statements()->Add(if_done, zone());
    4701             :     loop_body->statements()->Add(set_mode_return, zone());
    4702             : 
    4703        2599 :     if (is_async_generator()) {
    4704             :       // AsyncGeneratorYield does not yield the original iterator result,
    4705             :       // unlike sync generators. Do `output = output.value`
    4706        1158 :       VariableProxy* output_proxy = factory()->NewVariableProxy(var_output);
    4707             :       Expression* literal = factory()->NewStringLiteral(
    4708        2316 :           ast_value_factory()->value_string(), nopos);
    4709             :       Assignment* assign = factory()->NewAssignment(
    4710             :           Token::ASSIGN, output_proxy,
    4711        1158 :           factory()->NewProperty(factory()->NewVariableProxy(var_output),
    4712        1158 :                                  literal, nopos),
    4713        1158 :           nopos);
    4714             :       loop_body->statements()->Add(
    4715        1158 :           factory()->NewExpressionStatement(assign, nopos), zone());
    4716             :     }
    4717             : 
    4718             :     loop_body->statements()->Add(try_finally, zone());
    4719             : 
    4720        2599 :     loop->Initialize(factory()->NewBooleanLiteral(true, nopos), loop_body);
    4721             :   }
    4722             : 
    4723             :   // do { ... }
    4724             :   DoExpression* yield_star;
    4725             :   {
    4726             :     // The rewriter needs to process the get_value statement only, hence we
    4727             :     // put the preceding statements into an init block.
    4728             : 
    4729        2599 :     Block* do_block_ = factory()->NewBlock(nullptr, 6, true, nopos);
    4730             :     do_block_->statements()->Add(initialize_input, zone());
    4731             :     do_block_->statements()->Add(initialize_mode, zone());
    4732             :     do_block_->statements()->Add(initialize_output, zone());
    4733             :     do_block_->statements()->Add(get_iterator, zone());
    4734             :     do_block_->statements()->Add(loop, zone());
    4735             :     do_block_->statements()->Add(maybe_return_value, zone());
    4736             : 
    4737        2599 :     Block* do_block = factory()->NewBlock(nullptr, 2, false, nopos);
    4738             :     do_block->statements()->Add(do_block_, zone());
    4739             :     do_block->statements()->Add(get_value, zone());
    4740             : 
    4741             :     Variable* dot_result =
    4742        2599 :         NewTemporary(ast_value_factory()->dot_result_string());
    4743        2599 :     yield_star = factory()->NewDoExpression(do_block, dot_result, nopos);
    4744        2599 :     Rewriter::Rewrite(this, GetClosureScope(), yield_star, ast_value_factory());
    4745             :   }
    4746             : 
    4747        2599 :   return yield_star;
    4748             : }
    4749             : 
    4750      207967 : Statement* Parser::CheckCallable(Variable* var, Expression* error, int pos) {
    4751             :   const int nopos = kNoSourcePosition;
    4752             :   Statement* validate_var;
    4753             :   {
    4754             :     Expression* type_of = factory()->NewUnaryOperation(
    4755      623901 :         Token::TYPEOF, factory()->NewVariableProxy(var), nopos);
    4756             :     Expression* function_literal = factory()->NewStringLiteral(
    4757      415934 :         ast_value_factory()->function_string(), nopos);
    4758             :     Expression* condition = factory()->NewCompareOperation(
    4759      207967 :         Token::EQ_STRICT, type_of, function_literal, nopos);
    4760             : 
    4761      207967 :     Statement* throw_call = factory()->NewExpressionStatement(error, pos);
    4762             : 
    4763             :     validate_var = factory()->NewIfStatement(
    4764      415934 :         condition, factory()->NewEmptyStatement(nopos), throw_call, nopos);
    4765             :   }
    4766      207967 :   return validate_var;
    4767             : }
    4768             : 
    4769        2599 : void Parser::BuildIteratorClose(ZoneList<Statement*>* statements,
    4770             :                                 Variable* iterator, Variable* input,
    4771             :                                 Variable* var_output, IteratorType type) {
    4772             :   //
    4773             :   // This function adds four statements to [statements], corresponding to the
    4774             :   // following code:
    4775             :   //
    4776             :   //   let iteratorReturn = iterator.return;
    4777             :   //   if (IS_NULL_OR_UNDEFINED(iteratorReturn) {
    4778             :   //     return {value: input, done: true};
    4779             :   //   }
    4780             :   //   output = %_Call(iteratorReturn, iterator, input);
    4781             :   //   if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output);
    4782             :   //
    4783             : 
    4784             :   const int nopos = kNoSourcePosition;
    4785             : 
    4786             :   // let iteratorReturn = iterator.return;
    4787             :   Variable* var_return = var_output;  // Reusing the output variable.
    4788             :   Statement* get_return;
    4789             :   {
    4790       36386 :     Expression* iterator_proxy = factory()->NewVariableProxy(iterator);
    4791             :     Expression* literal = factory()->NewStringLiteral(
    4792        5198 :         ast_value_factory()->return_string(), nopos);
    4793             :     Expression* property =
    4794        2599 :         factory()->NewProperty(iterator_proxy, literal, nopos);
    4795        2599 :     Expression* return_proxy = factory()->NewVariableProxy(var_return);
    4796             :     Expression* assignment =
    4797        2599 :         factory()->NewAssignment(Token::ASSIGN, return_proxy, property, nopos);
    4798        2599 :     get_return = factory()->NewExpressionStatement(assignment, nopos);
    4799             :   }
    4800             : 
    4801             :   // if (IS_NULL_OR_UNDEFINED(iteratorReturn) {
    4802             :   //   return {value: input, done: true};
    4803             :   // }
    4804             :   Statement* check_return;
    4805             :   {
    4806             :     Expression* condition = factory()->NewCompareOperation(
    4807        2599 :         Token::EQ, factory()->NewVariableProxy(var_return),
    4808        5198 :         factory()->NewNullLiteral(nopos), nopos);
    4809             : 
    4810        2599 :     Expression* value = factory()->NewVariableProxy(input);
    4811             : 
    4812        2599 :     Statement* return_input = BuildReturnStatement(value, nopos);
    4813             : 
    4814             :     check_return = factory()->NewIfStatement(
    4815        5198 :         condition, return_input, factory()->NewEmptyStatement(nopos), nopos);
    4816             :   }
    4817             : 
    4818             :   // output = %_Call(iteratorReturn, iterator, input);
    4819             :   Statement* call_return;
    4820             :   {
    4821        2599 :     auto args = new (zone()) ZoneList<Expression*>(3, zone());
    4822        2599 :     args->Add(factory()->NewVariableProxy(var_return), zone());
    4823        2599 :     args->Add(factory()->NewVariableProxy(iterator), zone());
    4824        2599 :     args->Add(factory()->NewVariableProxy(input), zone());
    4825             : 
    4826             :     Expression* call =
    4827        2599 :         factory()->NewCallRuntime(Runtime::kInlineCall, args, nopos);
    4828        2599 :     if (type == IteratorType::kAsync) {
    4829             :       call = RewriteAwaitExpression(call, nopos);
    4830             :     }
    4831        2599 :     Expression* output_proxy = factory()->NewVariableProxy(var_output);
    4832             :     Expression* assignment =
    4833        2599 :         factory()->NewAssignment(Token::ASSIGN, output_proxy, call, nopos);
    4834        2599 :     call_return = factory()->NewExpressionStatement(assignment, nopos);
    4835             :   }
    4836             : 
    4837             :   // if (!IS_RECEIVER(output)) %ThrowIteratorResultNotAnObject(output);
    4838             :   Statement* validate_output;
    4839             :   {
    4840             :     Expression* is_receiver_call;
    4841             :     {
    4842        2599 :       auto args = new (zone()) ZoneList<Expression*>(1, zone());
    4843        2599 :       args->Add(factory()->NewVariableProxy(var_output), zone());
    4844             :       is_receiver_call =
    4845        2599 :           factory()->NewCallRuntime(Runtime::kInlineIsJSReceiver, args, nopos);
    4846             :     }
    4847             : 
    4848             :     Statement* throw_call;
    4849             :     {
    4850        2599 :       auto args = new (zone()) ZoneList<Expression*>(1, zone());
    4851        2599 :       args->Add(factory()->NewVariableProxy(var_output), zone());
    4852             :       Expression* call = factory()->NewCallRuntime(
    4853        2599 :           Runtime::kThrowIteratorResultNotAnObject, args, nopos);
    4854        2599 :       throw_call = factory()->NewExpressionStatement(call, nopos);
    4855             :     }
    4856             : 
    4857             :     validate_output = factory()->NewIfStatement(
    4858        2599 :         is_receiver_call, factory()->NewEmptyStatement(nopos), throw_call,
    4859        2599 :         nopos);
    4860             :   }
    4861             : 
    4862             :   statements->Add(get_return, zone());
    4863             :   statements->Add(check_return, zone());
    4864             :   statements->Add(call_return, zone());
    4865             :   statements->Add(validate_output, zone());
    4866        2599 : }
    4867             : 
    4868      205368 : void Parser::FinalizeIteratorUse(Scope* use_scope, Variable* completion,
    4869             :                                  Expression* condition, Variable* iter,
    4870             :                                  Block* iterator_use, Block* target,
    4871             :                                  IteratorType type) {
    4872             :   //
    4873             :   // This function adds two statements to [target], corresponding to the
    4874             :   // following code:
    4875             :   //
    4876             :   //   completion = kNormalCompletion;
    4877             :   //   try {
    4878             :   //     try {
    4879             :   //       iterator_use
    4880             :   //     } catch(e) {
    4881             :   //       if (completion === kAbruptCompletion) completion = kThrowCompletion;
    4882             :   //       %ReThrow(e);
    4883             :   //     }
    4884             :   //   } finally {
    4885             :   //     if (condition) {
    4886             :   //       #BuildIteratorCloseForCompletion(iter, completion)
    4887             :   //     }
    4888             :   //   }
    4889             :   //
    4890             : 
    4891             :   const int nopos = kNoSourcePosition;
    4892             : 
    4893             :   // completion = kNormalCompletion;
    4894             :   Statement* initialize_completion;
    4895             :   {
    4896     1642944 :     Expression* proxy = factory()->NewVariableProxy(completion);
    4897             :     Expression* assignment = factory()->NewAssignment(
    4898             :         Token::ASSIGN, proxy,
    4899      205368 :         factory()->NewSmiLiteral(Parser::kNormalCompletion, nopos), nopos);
    4900             :     initialize_completion =
    4901      205368 :         factory()->NewExpressionStatement(assignment, nopos);
    4902             :   }
    4903             : 
    4904             :   // if (completion === kAbruptCompletion) completion = kThrowCompletion;
    4905             :   Statement* set_completion_throw;
    4906             :   {
    4907             :     Expression* condition = factory()->NewCompareOperation(
    4908      205368 :         Token::EQ_STRICT, factory()->NewVariableProxy(completion),
    4909      410736 :         factory()->NewSmiLiteral(Parser::kAbruptCompletion, nopos), nopos);
    4910             : 
    4911      205368 :     Expression* proxy = factory()->NewVariableProxy(completion);
    4912             :     Expression* assignment = factory()->NewAssignment(
    4913             :         Token::ASSIGN, proxy,
    4914      205368 :         factory()->NewSmiLiteral(Parser::kThrowCompletion, nopos), nopos);
    4915      205368 :     Statement* statement = factory()->NewExpressionStatement(assignment, nopos);
    4916             :     set_completion_throw = factory()->NewIfStatement(
    4917      410736 :         condition, statement, factory()->NewEmptyStatement(nopos), nopos);
    4918             :   }
    4919             : 
    4920             :   // if (condition) {
    4921             :   //   #BuildIteratorCloseForCompletion(iter, completion)
    4922             :   // }
    4923             :   Block* maybe_close;
    4924             :   {
    4925      205368 :     Block* block = factory()->NewBlock(nullptr, 2, true, nopos);
    4926      205368 :     Expression* proxy = factory()->NewVariableProxy(completion);
    4927             :     BuildIteratorCloseForCompletion(use_scope, block->statements(), iter, proxy,
    4928      205368 :                                     type);
    4929             :     DCHECK(block->statements()->length() == 2);
    4930             : 
    4931             :     maybe_close = IgnoreCompletion(factory()->NewIfStatement(
    4932      410736 :         condition, block, factory()->NewEmptyStatement(nopos), nopos));
    4933             :   }
    4934             : 
    4935             :   // try { #try_block }
    4936             :   // catch(e) {
    4937             :   //   #set_completion_throw;
    4938             :   //   %ReThrow(e);
    4939             :   // }
    4940             :   Statement* try_catch;
    4941             :   {
    4942             :     Scope* catch_scope = NewHiddenCatchScopeWithParent(use_scope);
    4943             : 
    4944             :     Statement* rethrow;
    4945             :     // We use %ReThrow rather than the ordinary throw because we want to
    4946             :     // preserve the original exception message.  This is also why we create a
    4947             :     // TryCatchStatementForReThrow below (which does not clear the pending
    4948             :     // message), rather than a TryCatchStatement.
    4949             :     {
    4950      205368 :       auto args = new (zone()) ZoneList<Expression*>(1, zone());
    4951      205368 :       args->Add(factory()->NewVariableProxy(catch_scope->catch_variable()),
    4952             :                 zone());
    4953             :       rethrow = factory()->NewExpressionStatement(
    4954      205368 :           factory()->NewCallRuntime(Runtime::kReThrow, args, nopos), nopos);
    4955             :     }
    4956             : 
    4957      205368 :     Block* catch_block = factory()->NewBlock(nullptr, 2, false, nopos);
    4958             :     catch_block->statements()->Add(set_completion_throw, zone());
    4959             :     catch_block->statements()->Add(rethrow, zone());
    4960             : 
    4961             :     try_catch = factory()->NewTryCatchStatementForReThrow(
    4962      205368 :         iterator_use, catch_scope, catch_block, nopos);
    4963             :   }
    4964             : 
    4965             :   // try { #try_catch } finally { #maybe_close }
    4966             :   Statement* try_finally;
    4967             :   {
    4968      205368 :     Block* try_block = factory()->NewBlock(nullptr, 1, false, nopos);
    4969             :     try_block->statements()->Add(try_catch, zone());
    4970             : 
    4971             :     try_finally =
    4972      205368 :         factory()->NewTryFinallyStatement(try_block, maybe_close, nopos);
    4973             :   }
    4974             : 
    4975             :   target->statements()->Add(initialize_completion, zone());
    4976             :   target->statements()->Add(try_finally, zone());
    4977      205368 : }
    4978             : 
    4979      207967 : void Parser::BuildIteratorCloseForCompletion(Scope* scope,
    4980             :                                              ZoneList<Statement*>* statements,
    4981             :                                              Variable* iterator,
    4982             :                                              Expression* completion,
    4983             :                                              IteratorType type) {
    4984             :   //
    4985             :   // This function adds two statements to [statements], corresponding to the
    4986             :   // following code:
    4987             :   //
    4988             :   //   let iteratorReturn = iterator.return;
    4989             :   //   if (!IS_NULL_OR_UNDEFINED(iteratorReturn)) {
    4990             :   //     if (completion === kThrowCompletion) {
    4991             :   //       if (!IS_CALLABLE(iteratorReturn)) {
    4992             :   //         throw MakeTypeError(kReturnMethodNotCallable);
    4993             :   //       }
    4994             :   //       [if (IteratorType == kAsync)]
    4995             :   //           try { Await(%_Call(iteratorReturn, iterator) } catch (_) { }
    4996             :   //       [else]
    4997             :   //           try { %_Call(iteratorReturn, iterator) } catch (_) { }
    4998             :   //       [endif]
    4999             :   //     } else {
    5000             :   //       [if (IteratorType == kAsync)]
    5001             :   //           let output = Await(%_Call(iteratorReturn, iterator));
    5002             :   //       [else]
    5003             :   //           let output = %_Call(iteratorReturn, iterator);
    5004             :   //       [endif]
    5005             :   //       if (!IS_RECEIVER(output)) {
    5006             :   //         %ThrowIterResultNotAnObject(output);
    5007             :   //       }
    5008             :   //     }
    5009             :   //   }
    5010             :   //
    5011             : 
    5012             :   const int nopos = kNoSourcePosition;
    5013             :   // let iteratorReturn = iterator.return;
    5014     4367307 :   Variable* var_return = NewTemporary(ast_value_factory()->empty_string());
    5015             :   Statement* get_return;
    5016             :   {
    5017      207967 :     Expression* iterator_proxy = factory()->NewVariableProxy(iterator);
    5018             :     Expression* literal = factory()->NewStringLiteral(
    5019      415934 :         ast_value_factory()->return_string(), nopos);
    5020             :     Expression* property =
    5021      207967 :         factory()->NewProperty(iterator_proxy, literal, nopos);
    5022      207967 :     Expression* return_proxy = factory()->NewVariableProxy(var_return);
    5023             :     Expression* assignment =
    5024      207967 :         factory()->NewAssignment(Token::ASSIGN, return_proxy, property, nopos);
    5025      207967 :     get_return = factory()->NewExpressionStatement(assignment, nopos);
    5026             :   }
    5027             : 
    5028             :   // if (!IS_CALLABLE(iteratorReturn)) {
    5029             :   //   throw MakeTypeError(kReturnMethodNotCallable);
    5030             :   // }
    5031             :   Statement* check_return_callable;
    5032             :   {
    5033             :     Expression* throw_expr =
    5034             :         NewThrowTypeError(MessageTemplate::kReturnMethodNotCallable,
    5035      207967 :                           ast_value_factory()->empty_string(), nopos);
    5036      207967 :     check_return_callable = CheckCallable(var_return, throw_expr, nopos);
    5037             :   }
    5038             : 
    5039             :   // try { %_Call(iteratorReturn, iterator) } catch (_) { }
    5040             :   Statement* try_call_return;
    5041             :   {
    5042      207967 :     auto args = new (zone()) ZoneList<Expression*>(2, zone());
    5043      207967 :     args->Add(factory()->NewVariableProxy(var_return), zone());
    5044      207967 :     args->Add(factory()->NewVariableProxy(iterator), zone());
    5045             : 
    5046             :     Expression* call =
    5047      207967 :         factory()->NewCallRuntime(Runtime::kInlineCall, args, nopos);
    5048             : 
    5049      207967 :     if (type == IteratorType::kAsync) {
    5050             :       call = RewriteAwaitExpression(call, nopos);
    5051             :     }
    5052             : 
    5053      207967 :     Block* try_block = factory()->NewBlock(nullptr, 1, false, nopos);
    5054      207967 :     try_block->statements()->Add(factory()->NewExpressionStatement(call, nopos),
    5055             :                                  zone());
    5056             : 
    5057      207967 :     Block* catch_block = factory()->NewBlock(nullptr, 0, false, nopos);
    5058             :     Scope* catch_scope = NewHiddenCatchScopeWithParent(scope);
    5059             :     try_call_return = factory()->NewTryCatchStatement(try_block, catch_scope,
    5060      207967 :                                                       catch_block, nopos);
    5061             :   }
    5062             : 
    5063             :   // let output = %_Call(iteratorReturn, iterator);
    5064             :   // if (!IS_RECEIVER(output)) {
    5065             :   //   %ThrowIteratorResultNotAnObject(output);
    5066             :   // }
    5067             :   Block* validate_return;
    5068             :   {
    5069      207967 :     Variable* var_output = NewTemporary(ast_value_factory()->empty_string());
    5070             :     Statement* call_return;
    5071             :     {
    5072      207967 :       auto args = new (zone()) ZoneList<Expression*>(2, zone());
    5073      207967 :       args->Add(factory()->NewVariableProxy(var_return), zone());
    5074      207967 :       args->Add(factory()->NewVariableProxy(iterator), zone());
    5075             :       Expression* call =
    5076      207967 :           factory()->NewCallRuntime(Runtime::kInlineCall, args, nopos);
    5077      207967 :       if (type == IteratorType::kAsync) {
    5078             :         call = RewriteAwaitExpression(call, nopos);
    5079             :       }
    5080             : 
    5081      207967 :       Expression* output_proxy = factory()->NewVariableProxy(var_output);
    5082             :       Expression* assignment =
    5083      207967 :           factory()->NewAssignment(Token::ASSIGN, output_proxy, call, nopos);
    5084      207967 :       call_return = factory()->NewExpressionStatement(assignment, nopos);
    5085             :     }
    5086             : 
    5087             :     Expression* is_receiver_call;
    5088             :     {
    5089      207967 :       auto args = new (zone()) ZoneList<Expression*>(1, zone());
    5090      207967 :       args->Add(factory()->NewVariableProxy(var_output), zone());
    5091             :       is_receiver_call =
    5092      207967 :           factory()->NewCallRuntime(Runtime::kInlineIsJSReceiver, args, nopos);
    5093             :     }
    5094             : 
    5095             :     Statement* throw_call;
    5096             :     {
    5097      207967 :       auto args = new (zone()) ZoneList<Expression*>(1, zone());
    5098      207967 :       args->Add(factory()->NewVariableProxy(var_output), zone());
    5099             :       Expression* call = factory()->NewCallRuntime(
    5100      207967 :           Runtime::kThrowIteratorResultNotAnObject, args, nopos);
    5101      207967 :       throw_call = factory()->NewExpressionStatement(call, nopos);
    5102             :     }
    5103             : 
    5104             :     Statement* check_return = factory()->NewIfStatement(
    5105      207967 :         is_receiver_call, factory()->NewEmptyStatement(nopos), throw_call,
    5106      207967 :         nopos);
    5107             : 
    5108      207967 :     validate_return = factory()->NewBlock(nullptr, 2, false, nopos);
    5109             :     validate_return->statements()->Add(call_return, zone());
    5110             :     validate_return->statements()->Add(check_return, zone());
    5111             :   }
    5112             : 
    5113             :   // if (completion === kThrowCompletion) {
    5114             :   //   #check_return_callable;
    5115             :   //   #try_call_return;
    5116             :   // } else {
    5117             :   //   #validate_return;
    5118             :   // }
    5119             :   Statement* call_return_carefully;
    5120             :   {
    5121             :     Expression* condition = factory()->NewCompareOperation(
    5122             :         Token::EQ_STRICT, completion,
    5123      207967 :         factory()->NewSmiLiteral(Parser::kThrowCompletion, nopos), nopos);
    5124             : 
    5125      207967 :     Block* then_block = factory()->NewBlock(nullptr, 2, false, nopos);
    5126             :     then_block->statements()->Add(check_return_callable, zone());
    5127             :     then_block->statements()->Add(try_call_return, zone());
    5128             : 
    5129             :     call_return_carefully = factory()->NewIfStatement(condition, then_block,
    5130      207967 :                                                       validate_return, nopos);
    5131             :   }
    5132             : 
    5133             :   // if (!IS_NULL_OR_UNDEFINED(iteratorReturn)) { ... }
    5134             :   Statement* maybe_call_return;
    5135             :   {
    5136             :     Expression* condition = factory()->NewCompareOperation(
    5137      207967 :         Token::EQ, factory()->NewVariableProxy(var_return),
    5138      415934 :         factory()->NewNullLiteral(nopos), nopos);
    5139             : 
    5140             :     maybe_call_return = factory()->NewIfStatement(
    5141      207967 :         condition, factory()->NewEmptyStatement(nopos), call_return_carefully,
    5142      207967 :         nopos);
    5143             :   }
    5144             : 
    5145             :   statements->Add(get_return, zone());
    5146             :   statements->Add(maybe_call_return, zone());
    5147      207967 : }
    5148             : 
    5149      257004 : Statement* Parser::FinalizeForOfStatement(ForOfStatement* loop,
    5150             :                                           Variable* var_completion,
    5151             :                                           IteratorType type, int pos) {
    5152             :   //
    5153             :   // This function replaces the loop with the following wrapping:
    5154             :   //
    5155             :   //   completion = kNormalCompletion;
    5156             :   //   try {
    5157             :   //     try {
    5158             :   //       #loop;
    5159             :   //     } catch(e) {
    5160             :   //       if (completion === kAbruptCompletion) completion = kThrowCompletion;
    5161             :   //       %ReThrow(e);
    5162             :   //     }
    5163             :   //   } finally {
    5164             :   //     if (!(completion === kNormalCompletion)) {
    5165             :   //       #BuildIteratorCloseForCompletion(#iterator, completion)
    5166             :   //     }
    5167             :   //   }
    5168             :   //
    5169             :   // Note that the loop's body and its assign_each already contain appropriate
    5170             :   // assignments to completion (see InitializeForOfStatement).
    5171             :   //
    5172             : 
    5173             :   const int nopos = kNoSourcePosition;
    5174             : 
    5175             :   // !(completion === kNormalCompletion)
    5176             :   Expression* closing_condition;
    5177             :   {
    5178             :     Expression* cmp = factory()->NewCompareOperation(
    5179      128502 :         Token::EQ_STRICT, factory()->NewVariableProxy(var_completion),
    5180      514008 :         factory()->NewSmiLiteral(Parser::kNormalCompletion, nopos), nopos);
    5181      128502 :     closing_condition = factory()->NewUnaryOperation(Token::NOT, cmp, nopos);
    5182             :   }
    5183             : 
    5184      128502 :   Block* final_loop = factory()->NewBlock(nullptr, 2, false, nopos);
    5185             :   {
    5186      128502 :     Block* try_block = factory()->NewBlock(nullptr, 1, false, nopos);
    5187             :     try_block->statements()->Add(loop, zone());
    5188             : 
    5189             :     // The scope in which the parser creates this loop.
    5190      128502 :     Scope* loop_scope = scope()->outer_scope();
    5191             :     DCHECK_EQ(loop_scope->scope_type(), BLOCK_SCOPE);
    5192             :     DCHECK_EQ(scope()->scope_type(), BLOCK_SCOPE);
    5193             : 
    5194             :     FinalizeIteratorUse(loop_scope, var_completion, closing_condition,
    5195      128502 :                         loop->iterator(), try_block, final_loop, type);
    5196             :   }
    5197             : 
    5198      128502 :   return final_loop;
    5199             : }
    5200             : 
    5201             : #undef CHECK_OK
    5202             : #undef CHECK_OK_VOID
    5203             : #undef CHECK_FAILED
    5204             : 
    5205             : }  // namespace internal
    5206             : }  // namespace v8

Generated by: LCOV version 1.10