LCOV - code coverage report
Current view: top level - src/parsing - parser.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 1549 1641 94.4 %
Date: 2017-10-20 Functions: 105 114 92.1 %

          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 <algorithm>
       8             : #include <memory>
       9             : 
      10             : #include "src/api.h"
      11             : #include "src/ast/ast-expression-rewriter.h"
      12             : #include "src/ast/ast-function-literal-id-reindexer.h"
      13             : #include "src/ast/ast-traversal-visitor.h"
      14             : #include "src/ast/ast.h"
      15             : #include "src/bailout-reason.h"
      16             : #include "src/base/platform/platform.h"
      17             : #include "src/char-predicates-inl.h"
      18             : #include "src/compiler-dispatcher/compiler-dispatcher.h"
      19             : #include "src/messages.h"
      20             : #include "src/objects-inl.h"
      21             : #include "src/parsing/duplicate-finder.h"
      22             : #include "src/parsing/expression-scope-reparenter.h"
      23             : #include "src/parsing/parse-info.h"
      24             : #include "src/parsing/rewriter.h"
      25             : #include "src/runtime/runtime.h"
      26             : #include "src/string-stream.h"
      27             : #include "src/tracing/trace-event.h"
      28             : 
      29             : namespace v8 {
      30             : namespace internal {
      31             : 
      32        1020 : ScriptData::ScriptData(const byte* data, int length)
      33        1020 :     : owns_data_(false), rejected_(false), data_(data), length_(length) {
      34        2040 :   if (!IsAligned(reinterpret_cast<intptr_t>(data), kPointerAlignment)) {
      35           4 :     byte* copy = NewArray<byte>(length);
      36             :     DCHECK(IsAligned(reinterpret_cast<intptr_t>(copy), kPointerAlignment));
      37           4 :     CopyBytes(copy, data, length);
      38           4 :     data_ = copy;
      39             :     AcquireDataOwnership();
      40             :   }
      41        1020 : }
      42             : 
      43         230 : FunctionEntry ParseData::GetFunctionEntry(int start) {
      44             :   // The current pre-data entry must be a FunctionEntry with the given
      45             :   // start position.
      46         345 :   if ((function_index_ + FunctionEntry::kSize <= Length()) &&
      47         115 :       (static_cast<int>(Data()[function_index_]) == start)) {
      48             :     int index = function_index_;
      49         105 :     function_index_ += FunctionEntry::kSize;
      50         105 :     Vector<unsigned> subvector(&(Data()[index]), FunctionEntry::kSize);
      51         105 :     return FunctionEntry(subvector);
      52             :   }
      53          10 :   return FunctionEntry();
      54             : }
      55             : 
      56             : 
      57          30 : int ParseData::FunctionCount() {
      58             :   int functions_size = FunctionsSize();
      59          30 :   if (functions_size < 0) return 0;
      60          30 :   if (functions_size % FunctionEntry::kSize != 0) return 0;
      61          30 :   return functions_size / FunctionEntry::kSize;
      62             : }
      63             : 
      64             : 
      65          95 : bool ParseData::IsSane() {
      66         190 :   if (!IsAligned(script_data_->length(), sizeof(unsigned))) return false;
      67             :   // Check that the header data is valid and doesn't specify
      68             :   // point to positions outside the store.
      69             :   int data_length = Length();
      70          95 :   if (data_length < PreparseDataConstants::kHeaderSize) return false;
      71          95 :   if (Magic() != PreparseDataConstants::kMagicNumber) return false;
      72          90 :   if (Version() != PreparseDataConstants::kCurrentVersion) return false;
      73             :   // Check that the space allocated for function entries is sane.
      74             :   int functions_size = FunctionsSize();
      75          90 :   if (functions_size < 0) return false;
      76          90 :   if (functions_size % FunctionEntry::kSize != 0) return false;
      77             :   // Check that the total size has room for header and function entries.
      78             :   int minimum_size =
      79          90 :       PreparseDataConstants::kHeaderSize + functions_size;
      80          90 :   if (data_length < minimum_size) return false;
      81          90 :   return true;
      82             : }
      83             : 
      84             : 
      85          60 : void ParseData::Initialize() {
      86             :   // Prepares state for use.
      87             :   int data_length = Length();
      88          60 :   if (data_length >= PreparseDataConstants::kHeaderSize) {
      89          60 :     function_index_ = PreparseDataConstants::kHeaderSize;
      90             :   }
      91           5 : }
      92             : 
      93             : 
      94           0 : unsigned ParseData::Magic() {
      95          95 :   return Data()[PreparseDataConstants::kMagicOffset];
      96             : }
      97             : 
      98             : 
      99           0 : unsigned ParseData::Version() {
     100          90 :   return Data()[PreparseDataConstants::kVersionOffset];
     101             : }
     102             : 
     103             : 
     104          30 : int ParseData::FunctionsSize() {
     105         120 :   return static_cast<int>(Data()[PreparseDataConstants::kFunctionsSizeOffset]);
     106             : }
     107             : 
     108             : // Helper for putting parts of the parse results into a temporary zone when
     109             : // parsing inner function bodies.
     110             : class DiscardableZoneScope {
     111             :  public:
     112     5234306 :   DiscardableZoneScope(Parser* parser, Zone* temp_zone, bool 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     5234306 :         prev_temp_zoned_(parser->temp_zoned_) {
     119     5234307 :     if (use_temp_zone) {
     120             :       DCHECK(!parser_->temp_zoned_);
     121     2247093 :       parser_->allow_lazy_ = false;
     122     2247093 :       parser_->temp_zoned_ = true;
     123     2247093 :       parser_->fni_ = &fni_;
     124     2247093 :       parser_->zone_ = temp_zone;
     125     2247093 :       parser_->factory()->set_zone(temp_zone);
     126     2247093 :       if (parser_->reusable_preparser_ != nullptr) {
     127     1863341 :         parser_->reusable_preparser_->zone_ = temp_zone;
     128     1863341 :         parser_->reusable_preparser_->factory()->set_zone(temp_zone);
     129             :       }
     130             :     }
     131     5234307 :   }
     132     5234355 :   void Reset() {
     133     5234355 :     parser_->fni_ = prev_fni_;
     134     5234355 :     parser_->zone_ = prev_zone_;
     135     5234355 :     parser_->factory()->set_zone(prev_zone_);
     136     5234355 :     parser_->allow_lazy_ = prev_allow_lazy_;
     137     5234355 :     parser_->temp_zoned_ = prev_temp_zoned_;
     138     5234355 :     if (parser_->reusable_preparser_ != nullptr) {
     139     2320796 :       parser_->reusable_preparser_->zone_ = prev_zone_;
     140     2320796 :       parser_->reusable_preparser_->factory()->set_zone(prev_zone_);
     141             :     }
     142     5234355 :   }
     143     5234302 :   ~DiscardableZoneScope() { Reset(); }
     144             : 
     145             :  private:
     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     1678406 : void Parser::SetCachedData(ParseInfo* info) {
     157             :   DCHECK_NULL(cached_parse_data_);
     158     1678346 :   if (consume_cached_parse_data()) {
     159          60 :     if (allow_lazy_) {
     160          60 :       cached_parse_data_ = ParseData::FromCachedData(*info->cached_data());
     161     1678406 :       if (cached_parse_data_ != nullptr) return;
     162             :     }
     163           5 :     compile_options_ = ScriptCompiler::kNoCompileOptions;
     164             :   }
     165             : }
     166             : 
     167       76903 : 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             : 
     173             :   FunctionKind kind = call_super ? FunctionKind::kDefaultDerivedConstructor
     174       76903 :                                  : FunctionKind::kDefaultBaseConstructor;
     175      287553 :   DeclarationScope* function_scope = NewFunctionScope(kind);
     176       76903 :   SetLanguageMode(function_scope, LanguageMode::kStrict);
     177             :   // Set start and end position to the same value
     178             :   function_scope->set_start_position(pos);
     179             :   function_scope->set_end_position(pos);
     180             :   ZoneList<Statement*>* body = nullptr;
     181             : 
     182             :   {
     183       76903 :     FunctionState function_state(&function_state_, &scope_, function_scope);
     184             : 
     185       76903 :     body = new (zone()) ZoneList<Statement*>(call_super ? 2 : 1, zone());
     186       76903 :     if (call_super) {
     187             :       // Create a SuperCallReference and handle in BytecodeGenerator.
     188       14211 :       auto constructor_args_name = ast_value_factory()->empty_string();
     189             :       bool is_duplicate;
     190             :       bool is_rest = true;
     191             :       bool is_optional = false;
     192             :       Variable* constructor_args = function_scope->DeclareParameter(
     193             :           constructor_args_name, TEMPORARY, is_optional, is_rest, &is_duplicate,
     194       14211 :           ast_value_factory(), pos);
     195             : 
     196             :       ZoneList<Expression*>* args =
     197       14211 :           new (zone()) ZoneList<Expression*>(1, zone());
     198             :       Spread* spread_args = factory()->NewSpread(
     199       28422 :           factory()->NewVariableProxy(constructor_args), pos, pos);
     200             : 
     201       14211 :       args->Add(spread_args, zone());
     202       14211 :       Expression* super_call_ref = NewSuperCallReference(pos);
     203       14211 :       Expression* call = factory()->NewCall(super_call_ref, args, pos);
     204       28422 :       body->Add(factory()->NewReturnStatement(call, pos), zone());
     205             :     }
     206             : 
     207       76903 :     expected_property_count = function_state.expected_property_count();
     208             :   }
     209             : 
     210             :   FunctionLiteral* function_literal = factory()->NewFunctionLiteral(
     211             :       name, function_scope, body, expected_property_count, parameter_count,
     212             :       parameter_count, FunctionLiteral::kNoDuplicateParameters,
     213             :       FunctionLiteral::kAnonymousExpression, default_eager_compile_hint(), pos,
     214       76903 :       true, GetNextFunctionLiteralId());
     215             : 
     216       76903 :   return function_literal;
     217             : }
     218             : 
     219             : // ----------------------------------------------------------------------------
     220             : // The CHECK_OK macro is a convenient macro to enforce error
     221             : // handling for functions that may fail (by returning !*ok).
     222             : //
     223             : // CAUTION: This macro appends extra statements after a call,
     224             : // thus it must never be used where only a single statement
     225             : // is correct (e.g. an if statement branch w/o braces)!
     226             : 
     227             : #define CHECK_OK_VALUE(x) ok); \
     228             :   if (!*ok) return x;          \
     229             :   ((void)0
     230             : #define DUMMY )  // to make indentation work
     231             : #undef DUMMY
     232             : 
     233             : #define CHECK_OK CHECK_OK_VALUE(nullptr)
     234             : #define CHECK_OK_VOID CHECK_OK_VALUE(this->Void())
     235             : 
     236             : #define CHECK_FAILED /**/); \
     237             :   if (failed_) return nullptr;  \
     238             :   ((void)0
     239             : #define DUMMY )  // to make indentation work
     240             : #undef DUMMY
     241             : 
     242             : // ----------------------------------------------------------------------------
     243             : // Implementation of Parser
     244             : 
     245     4742264 : bool Parser::ShortcutNumericLiteralBinaryExpression(Expression** x,
     246             :                                                     Expression* y,
     247             :                                                     Token::Value op, int pos) {
     248    12890211 :   if ((*x)->AsLiteral() && (*x)->AsLiteral()->raw_value()->IsNumber() &&
     249     6646820 :       y->AsLiteral() && y->AsLiteral()->raw_value()->IsNumber()) {
     250     1183626 :     double x_val = (*x)->AsLiteral()->raw_value()->AsNumber();
     251     1183626 :     double y_val = y->AsLiteral()->raw_value()->AsNumber();
     252      591813 :     switch (op) {
     253             :       case Token::ADD:
     254       16314 :         *x = factory()->NewNumberLiteral(x_val + y_val, pos);
     255       16314 :         return true;
     256             :       case Token::SUB:
     257        1288 :         *x = factory()->NewNumberLiteral(x_val - y_val, pos);
     258        1288 :         return true;
     259             :       case Token::MUL:
     260      249908 :         *x = factory()->NewNumberLiteral(x_val * y_val, pos);
     261      249908 :         return true;
     262             :       case Token::DIV:
     263        3383 :         *x = factory()->NewNumberLiteral(x_val / y_val, pos);
     264        3383 :         return true;
     265             :       case Token::BIT_OR: {
     266       18687 :         int value = DoubleToInt32(x_val) | DoubleToInt32(y_val);
     267       18687 :         *x = factory()->NewNumberLiteral(value, pos);
     268       18687 :         return true;
     269             :       }
     270             :       case Token::BIT_AND: {
     271         435 :         int value = DoubleToInt32(x_val) & DoubleToInt32(y_val);
     272         435 :         *x = factory()->NewNumberLiteral(value, pos);
     273         435 :         return true;
     274             :       }
     275             :       case Token::BIT_XOR: {
     276         234 :         int value = DoubleToInt32(x_val) ^ DoubleToInt32(y_val);
     277         234 :         *x = factory()->NewNumberLiteral(value, pos);
     278         234 :         return true;
     279             :       }
     280             :       case Token::SHL: {
     281      289945 :         int value = DoubleToInt32(x_val) << (DoubleToInt32(y_val) & 0x1f);
     282      289945 :         *x = factory()->NewNumberLiteral(value, pos);
     283      289945 :         return true;
     284             :       }
     285             :       case Token::SHR: {
     286         384 :         uint32_t shift = DoubleToInt32(y_val) & 0x1f;
     287         384 :         uint32_t value = DoubleToUint32(x_val) >> shift;
     288         384 :         *x = factory()->NewNumberLiteral(value, pos);
     289         384 :         return true;
     290             :       }
     291             :       case Token::SAR: {
     292         421 :         uint32_t shift = DoubleToInt32(y_val) & 0x1f;
     293         421 :         int value = ArithmeticShiftRight(DoubleToInt32(x_val), shift);
     294         421 :         *x = factory()->NewNumberLiteral(value, pos);
     295         421 :         return true;
     296             :       }
     297             :       case Token::EXP: {
     298         304 :         double value = Pow(x_val, y_val);
     299         304 :         int int_value = static_cast<int>(value);
     300             :         *x = factory()->NewNumberLiteral(
     301         304 :             int_value == value && value != -0.0 ? int_value : value, pos);
     302         304 :         return true;
     303             :       }
     304             :       default:
     305             :         break;
     306             :     }
     307             :   }
     308             :   return false;
     309             : }
     310             : 
     311     1378768 : Expression* Parser::BuildUnaryExpression(Expression* expression,
     312             :                                          Token::Value op, int pos) {
     313             :   DCHECK_NOT_NULL(expression);
     314     1378770 :   if (expression->IsLiteral()) {
     315     1434306 :     const AstValue* literal = expression->AsLiteral()->raw_value();
     316      717153 :     if (op == Token::NOT) {
     317             :       // Convert the literal to a boolean condition and negate it.
     318         274 :       bool condition = literal->BooleanValue();
     319         274 :       return factory()->NewBooleanLiteral(!condition, pos);
     320      716879 :     } else if (literal->IsNumber()) {
     321             :       // Compute some expressions involving only number literals.
     322      716132 :       double value = literal->AsNumber();
     323      716132 :       switch (op) {
     324             :         case Token::ADD:
     325             :           return expression;
     326             :         case Token::SUB:
     327      437945 :           return factory()->NewNumberLiteral(-value, pos);
     328             :         case Token::BIT_NOT:
     329        1240 :           return factory()->NewNumberLiteral(~DoubleToInt32(value), pos);
     330             :         default:
     331             :           break;
     332             :       }
     333             :     }
     334             :   }
     335     1875679 :   return factory()->NewUnaryOperation(op, expression, pos);
     336             : }
     337             : 
     338      269010 : Expression* Parser::NewThrowError(Runtime::FunctionId id,
     339             :                                   MessageTemplate::Template message,
     340             :                                   const AstRawString* arg, int pos) {
     341      807030 :   ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(2, zone());
     342      269010 :   args->Add(factory()->NewSmiLiteral(message, pos), zone());
     343      269010 :   args->Add(factory()->NewStringLiteral(arg, pos), zone());
     344      269010 :   CallRuntime* call_constructor = factory()->NewCallRuntime(id, args, pos);
     345      538020 :   return factory()->NewThrow(call_constructor, pos);
     346             : }
     347             : 
     348        2814 : Expression* Parser::NewSuperPropertyReference(int pos) {
     349             :   // this_function[home_object_symbol]
     350             :   VariableProxy* this_function_proxy =
     351        2814 :       NewUnresolved(ast_value_factory()->this_function_string(), pos);
     352             :   Expression* home_object_symbol_literal = factory()->NewSymbolLiteral(
     353        2814 :       AstSymbol::kHomeObjectSymbol, kNoSourcePosition);
     354             :   Expression* home_object = factory()->NewProperty(
     355        2814 :       this_function_proxy, home_object_symbol_literal, pos);
     356             :   return factory()->NewSuperPropertyReference(
     357        8442 :       ThisExpression(pos)->AsVariableProxy(), home_object, pos);
     358             : }
     359             : 
     360       16531 : Expression* Parser::NewSuperCallReference(int pos) {
     361             :   VariableProxy* new_target_proxy =
     362       33062 :       NewUnresolved(ast_value_factory()->new_target_string(), pos);
     363             :   VariableProxy* this_function_proxy =
     364       16531 :       NewUnresolved(ast_value_factory()->this_function_string(), pos);
     365             :   return factory()->NewSuperCallReference(
     366             :       ThisExpression(pos)->AsVariableProxy(), new_target_proxy,
     367       49593 :       this_function_proxy, pos);
     368             : }
     369             : 
     370       13404 : Expression* Parser::NewTargetExpression(int pos) {
     371       13404 :   auto proxy = NewUnresolved(ast_value_factory()->new_target_string(), pos);
     372             :   proxy->set_is_new_target();
     373       13404 :   return proxy;
     374             : }
     375             : 
     376          35 : Expression* Parser::FunctionSentExpression(int pos) {
     377             :   // We desugar function.sent into %_GeneratorGetInputOrDebugPos(generator).
     378         105 :   ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(1, zone());
     379             :   VariableProxy* generator = factory()->NewVariableProxy(
     380          70 :       function_state_->scope()->generator_object_var());
     381          35 :   args->Add(generator, zone());
     382             :   return factory()->NewCallRuntime(Runtime::kInlineGeneratorGetInputOrDebugPos,
     383          35 :                                    args, pos);
     384             : }
     385             : 
     386        3125 : Expression* Parser::ImportMetaExpression(int pos) {
     387             :   return factory()->NewCallRuntime(
     388             :       Runtime::kGetImportMetaObject,
     389        6250 :       new (zone()) ZoneList<Expression*>(0, zone()), pos);
     390             : }
     391             : 
     392    20986392 : Literal* Parser::ExpressionFromLiteral(Token::Value token, int pos) {
     393    20986392 :   switch (token) {
     394             :     case Token::NULL_LITERAL:
     395    20296011 :       return factory()->NewNullLiteral(pos);
     396             :     case Token::TRUE_LITERAL:
     397      316932 :       return factory()->NewBooleanLiteral(true, pos);
     398             :     case Token::FALSE_LITERAL:
     399      373450 :       return factory()->NewBooleanLiteral(false, pos);
     400             :     case Token::SMI: {
     401    19055887 :       uint32_t value = scanner()->smi_value();
     402    19055887 :       return factory()->NewSmiLiteral(value, pos);
     403             :     }
     404             :     case Token::NUMBER: {
     405     1052157 :       double value = scanner()->DoubleValue();
     406     1052157 :       return factory()->NewNumberLiteral(value, pos);
     407             :     }
     408             :     case Token::BIGINT:
     409             :       return factory()->NewBigIntLiteral(
     410          25 :           scanner()->CurrentLiteralAsCString(zone()), pos);
     411             :     default:
     412             :       DCHECK(false);
     413             :   }
     414             :   return nullptr;
     415             : }
     416             : 
     417             : Expression* Parser::NewV8Intrinsic(const AstRawString* name,
     418      803090 :                                    ZoneList<Expression*>* args, int pos,
     419             :                                    bool* ok) {
     420     1099279 :   if (extension_ != nullptr) {
     421             :     // The extension structures are only accessible while parsing the
     422             :     // very first time, not when reparsing because of lazy compilation.
     423           5 :     GetClosureScope()->ForceEagerCompilation();
     424             :   }
     425             : 
     426             :   DCHECK(name->is_one_byte());
     427             :   const Runtime::Function* function =
     428     1099279 :       Runtime::FunctionForName(name->raw_data(), name->length());
     429             : 
     430     1099278 :   if (function != nullptr) {
     431             :     // Check for possible name clash.
     432             :     DCHECK_EQ(Context::kNotFound,
     433             :               Context::IntrinsicIndexForName(name->raw_data(), name->length()));
     434             :     // Check for built-in IS_VAR macro.
     435      958532 :     if (function->function_id == Runtime::kIS_VAR) {
     436             :       DCHECK_EQ(Runtime::RUNTIME, function->intrinsic_type);
     437             :       // %IS_VAR(x) evaluates to x if x is a variable,
     438             :       // leads to a parse error otherwise.  Could be implemented as an
     439             :       // inline function %_IS_VAR(x) to eliminate this special case.
     440        1410 :       if (args->length() == 1 && args->at(0)->AsVariableProxy() != nullptr) {
     441         705 :         return args->at(0);
     442             :       } else {
     443           0 :         ReportMessage(MessageTemplate::kNotIsvar);
     444           0 :         *ok = false;
     445             :         return nullptr;
     446             :       }
     447             :     }
     448             : 
     449             :     // Check that the expected number of arguments are being passed.
     450     1760212 :     if (function->nargs != -1 && function->nargs != args->length()) {
     451          10 :       ReportMessage(MessageTemplate::kRuntimeWrongNumArgs);
     452          10 :       *ok = false;
     453             :       return nullptr;
     454             :     }
     455             : 
     456      957817 :     return factory()->NewCallRuntime(function, args, pos);
     457             :   }
     458             : 
     459             :   int context_index =
     460      140746 :       Context::IntrinsicIndexForName(name->raw_data(), name->length());
     461             : 
     462             :   // Check that the function is defined.
     463      140746 :   if (context_index == Context::kNotFound) {
     464          50 :     ReportMessage(MessageTemplate::kNotDefined, name);
     465          50 :     *ok = false;
     466             :     return nullptr;
     467             :   }
     468             : 
     469      140696 :   return factory()->NewCallRuntime(context_index, args, pos);
     470             : }
     471             : 
     472    16069549 : Parser::Parser(ParseInfo* info)
     473             :     : ParserBase<Parser>(info->zone(), &scanner_, info->stack_limit(),
     474             :                          info->extension(), info->GetOrCreateAstValueFactory(),
     475             :                          info->runtime_call_stats(), true),
     476             :       scanner_(info->unicode_cache(), use_counts_),
     477             :       reusable_preparser_(nullptr),
     478             :       mode_(PARSE_EAGERLY),  // Lazy mode must be set explicitly.
     479             :       source_range_map_(info->source_range_map()),
     480             :       target_stack_(nullptr),
     481             :       compile_options_(info->compile_options()),
     482             :       cached_parse_data_(nullptr),
     483             :       total_preparse_skipped_(0),
     484             :       temp_zoned_(false),
     485             :       log_(nullptr),
     486     2348007 :       consumed_preparsed_scope_data_(info->consumed_preparsed_scope_data()),
     487    21132071 :       parameters_end_pos_(info->parameters_end_pos()) {
     488             :   // Even though we were passed ParseInfo, we should not store it in
     489             :   // Parser - this makes sure that Isolate is not accidentally accessed via
     490             :   // ParseInfo during background parsing.
     491             :   DCHECK_NOT_NULL(info->character_stream());
     492             :   // Determine if functions can be lazily compiled. This is necessary to
     493             :   // allow some of our builtin JS files to be lazily compiled. These
     494             :   // builtins cannot be handled lazily by the parser, since we have to know
     495             :   // if a function uses the special natives syntax, which is something the
     496             :   // parser records.
     497             :   // If the debugger requests compilation for break points, we cannot be
     498             :   // aggressive about lazy compilation, because it might trigger compilation
     499             :   // of functions without an outer context when setting a breakpoint through
     500             :   // Debug::FindSharedFunctionInfoInScript
     501             :   // We also compile eagerly for kProduceExhaustiveCodeCache.
     502     4695666 :   bool can_compile_lazily = FLAG_lazy && !info->is_eager();
     503             : 
     504             :   set_default_eager_compile_hint(can_compile_lazily
     505             :                                      ? FunctionLiteral::kShouldLazyCompile
     506     2348007 :                                      : FunctionLiteral::kShouldEagerCompile);
     507     6410425 :   allow_lazy_ = FLAG_lazy && info->allow_lazy_parsing() && !info->is_native() &&
     508     4326376 :                 info->extension() == nullptr && can_compile_lazily;
     509     3992136 :   set_allow_natives(FLAG_allow_natives_syntax || info->is_native());
     510     2348007 :   set_allow_harmony_do_expressions(FLAG_harmony_do_expressions);
     511     2348007 :   set_allow_harmony_function_sent(FLAG_harmony_function_sent);
     512     2348007 :   set_allow_harmony_restrictive_generators(FLAG_harmony_restrictive_generators);
     513     2348007 :   set_allow_harmony_class_fields(FLAG_harmony_class_fields);
     514     2348007 :   set_allow_harmony_object_rest_spread(FLAG_harmony_object_rest_spread);
     515     2348007 :   set_allow_harmony_dynamic_import(FLAG_harmony_dynamic_import);
     516     2348007 :   set_allow_harmony_import_meta(FLAG_harmony_import_meta);
     517     2348007 :   set_allow_harmony_async_iteration(FLAG_harmony_async_iteration);
     518     2348007 :   set_allow_harmony_template_escapes(FLAG_harmony_template_escapes);
     519     2348007 :   set_allow_harmony_bigint(FLAG_harmony_bigint);
     520   100964259 :   for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount;
     521             :        ++feature) {
     522    98616252 :     use_counts_[feature] = 0;
     523             :   }
     524     2348007 : }
     525             : 
     526     2348008 : void Parser::DeserializeScopeChain(
     527             :     ParseInfo* info, MaybeHandle<ScopeInfo> maybe_outer_scope_info) {
     528             :   // TODO(wingo): Add an outer SCRIPT_SCOPE corresponding to the native
     529             :   // context, which will have the "this" binding for script scopes.
     530     4368744 :   DeclarationScope* script_scope = NewScriptScope();
     531             :   info->set_script_scope(script_scope);
     532             :   Scope* scope = script_scope;
     533             :   Handle<ScopeInfo> outer_scope_info;
     534     2348008 :   if (maybe_outer_scope_info.ToHandle(&outer_scope_info)) {
     535             :     DCHECK(ThreadId::Current().Equals(
     536             :         outer_scope_info->GetIsolate()->thread_id()));
     537             :     scope = Scope::DeserializeScopeChain(
     538             :         zone(), *outer_scope_info, script_scope, ast_value_factory(),
     539     1010368 :         Scope::DeserializationMode::kScopesOnly);
     540             :     DCHECK(!info->is_module() || scope->is_module_scope());
     541             :   }
     542     2348008 :   original_scope_ = scope;
     543     2348008 : }
     544             : 
     545             : namespace {
     546             : 
     547     4043820 : void MaybeResetCharacterStream(ParseInfo* info, FunctionLiteral* literal) {
     548             :   // Don't reset the character stream if there is an asm.js module since it will
     549             :   // be used again by the asm-parser.
     550     4696014 :   if (!FLAG_stress_validate_asm &&
     551     1695813 :       (literal == nullptr || !literal->scope()->ContainsAsmModule())) {
     552     1955213 :     info->ResetCharacterStream();
     553             :   }
     554     2348008 : }
     555             : 
     556             : }  // namespace
     557             : 
     558     5035152 : FunctionLiteral* Parser::ParseProgram(Isolate* isolate, ParseInfo* info) {
     559             :   // TODO(bmeurer): We temporarily need to pass allow_nesting = true here,
     560             :   // see comment for HistogramTimerScope class.
     561             : 
     562             :   // It's OK to use the Isolate & counters here, since this function is only
     563             :   // called in the main thread.
     564             :   DCHECK(parsing_on_main_thread_);
     565             :   RuntimeCallTimerScope runtime_timer(
     566             :       runtime_call_stats_, info->is_eval() ? &RuntimeCallStats::ParseEval
     567     1678345 :                                            : &RuntimeCallStats::ParseProgram);
     568     5035037 :   TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.ParseProgram");
     569             :   base::ElapsedTimer timer;
     570     1678346 :   if (FLAG_trace_parse) {
     571             :     timer.Start();
     572             :   }
     573     3356692 :   fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone());
     574             : 
     575             :   // Initialize parser state.
     576     1678345 :   ParserLogger logger;
     577             : 
     578     1678346 :   if (produce_cached_parse_data()) {
     579         115 :     if (allow_lazy_) {
     580         115 :       log_ = &logger;
     581             :     } else {
     582           0 :       compile_options_ = ScriptCompiler::kNoCompileOptions;
     583             :     }
     584     1678231 :   } else if (consume_cached_parse_data()) {
     585          55 :     cached_parse_data_->Initialize();
     586             :   }
     587             : 
     588     1678346 :   DeserializeScopeChain(info, info->maybe_outer_scope_info());
     589             : 
     590     3356690 :   scanner_.Initialize(info->character_stream(), info->is_module());
     591     1678345 :   FunctionLiteral* result = DoParseProgram(info);
     592     1678346 :   MaybeResetCharacterStream(info, result);
     593             : 
     594     1678346 :   HandleSourceURLComments(isolate, info->script());
     595             : 
     596     1678346 :   if (FLAG_trace_parse && result != nullptr) {
     597           0 :     double ms = timer.Elapsed().InMillisecondsF();
     598           0 :     if (info->is_eval()) {
     599           0 :       PrintF("[parsing eval");
     600           0 :     } else if (info->script()->name()->IsString()) {
     601             :       String* name = String::cast(info->script()->name());
     602           0 :       std::unique_ptr<char[]> name_chars = name->ToCString();
     603           0 :       PrintF("[parsing script: %s", name_chars.get());
     604             :     } else {
     605           0 :       PrintF("[parsing script");
     606             :     }
     607           0 :     PrintF(" - took %0.3f ms]\n", ms);
     608             :   }
     609     1678346 :   if (produce_cached_parse_data() && result != nullptr) {
     610         115 :     *info->cached_data() = logger.GetScriptData();
     611             :   }
     612     1678346 :   log_ = nullptr;
     613     1678346 :   return result;
     614             : }
     615             : 
     616             : 
     617     1704901 : FunctionLiteral* Parser::DoParseProgram(ParseInfo* info) {
     618             :   // Note that this function can be called from the main thread or from a
     619             :   // background thread. We should not access anything Isolate / heap dependent
     620             :   // via ParseInfo, and also not pass it forward.
     621             :   DCHECK_NULL(scope_);
     622             :   DCHECK_NULL(target_stack_);
     623             : 
     624     1678455 :   ParsingModeScope mode(this, allow_lazy_ ? PARSE_LAZILY : PARSE_EAGERLY);
     625     8648201 :   ResetFunctionLiteralId();
     626             :   DCHECK(info->function_literal_id() == FunctionLiteral::kIdTypeTopLevel ||
     627             :          info->function_literal_id() == FunctionLiteral::kIdTypeInvalid);
     628             : 
     629             :   FunctionLiteral* result = nullptr;
     630             :   {
     631     1678455 :     Scope* outer = original_scope_;
     632             :     DCHECK_NOT_NULL(outer);
     633     1678455 :     parsing_module_ = info->is_module();
     634     1678455 :     if (info->is_eval()) {
     635      978149 :       outer = NewEvalScope(outer);
     636      700306 :     } else if (parsing_module_) {
     637             :       DCHECK_EQ(outer, info->script_scope());
     638       26446 :       outer = NewModuleScope(info->script_scope());
     639             :     }
     640             : 
     641     1678455 :     DeclarationScope* scope = outer->AsDeclarationScope();
     642             : 
     643             :     scope->set_start_position(0);
     644             : 
     645     1678454 :     FunctionState function_state(&function_state_, &scope_, scope);
     646             : 
     647     2036471 :     ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16, zone());
     648     1678455 :     bool ok = true;
     649             :     int beg_pos = scanner()->location().beg_pos;
     650     1678455 :     if (parsing_module_) {
     651             :       // Declare the special module parameter.
     652       26446 :       auto name = ast_value_factory()->empty_string();
     653       26446 :       bool is_duplicate = false;
     654             :       bool is_rest = false;
     655             :       bool is_optional = false;
     656             :       auto var =
     657             :           scope->DeclareParameter(name, VAR, is_optional, is_rest,
     658       26446 :                                   &is_duplicate, ast_value_factory(), beg_pos);
     659             :       DCHECK(!is_duplicate);
     660             :       var->AllocateTo(VariableLocation::PARAMETER, 0);
     661             : 
     662       26446 :       PrepareGeneratorVariables();
     663             :       scope->ForceContextAllocation();
     664             :       Expression* initial_yield =
     665       26446 :           BuildInitialYield(kNoSourcePosition, kGeneratorFunction);
     666             :       body->Add(
     667       26446 :           factory()->NewExpressionStatement(initial_yield, kNoSourcePosition),
     668       26446 :           zone());
     669             : 
     670       26446 :       ParseModuleItemList(body, &ok);
     671       38490 :       ok = ok &&
     672             :            module()->Validate(this->scope()->AsModuleScope(),
     673       62578 :                               &pending_error_handler_, zone());
     674             :     } else {
     675             :       // Don't count the mode in the use counters--give the program a chance
     676             :       // to enable script-wide strict mode below.
     677             :       this->scope()->SetLanguageMode(info->language_mode());
     678     1652009 :       ParseStatementList(body, Token::EOS, &ok);
     679             :     }
     680             : 
     681             :     // The parser will peek but not consume EOS.  Our scope logically goes all
     682             :     // the way to the EOS, though.
     683             :     scope->set_end_position(scanner()->peek_location().beg_pos);
     684             : 
     685     3057646 :     if (ok && is_strict(language_mode())) {
     686      205392 :       CheckStrictOctalLiteral(beg_pos, scanner()->location().end_pos, &ok);
     687             :     }
     688     3057124 :     if (ok && is_sloppy(language_mode())) {
     689             :       // TODO(littledan): Function bindings on the global object that modify
     690             :       // pre-existing bindings should be made writable, enumerable and
     691             :       // nonconfigurable if possible, whereas this code will leave attributes
     692             :       // unchanged if the property already exists.
     693     1173799 :       InsertSloppyBlockFunctionVarBindings(scope);
     694             :     }
     695     1678456 :     if (ok) {
     696     1378668 :       CheckConflictingVarDeclarations(scope, &ok);
     697             :     }
     698             : 
     699     3040933 :     if (ok && info->parse_restriction() == ONLY_SINGLE_FUNCTION_LITERAL) {
     700      716024 :       if (body->length() != 1 ||
     701     1074031 :           !body->at(0)->IsExpressionStatement() ||
     702             :           !body->at(0)->AsExpressionStatement()->
     703      716014 :               expression()->IsFunctionLiteral()) {
     704          20 :         ReportMessage(MessageTemplate::kSingleFunctionLiteral);
     705          20 :         ok = false;
     706             :       }
     707             :     }
     708             : 
     709     1678456 :     if (ok) {
     710             :       RewriteDestructuringAssignments();
     711     1362457 :       int parameter_count = parsing_module_ ? 1 : 0;
     712             :       result = factory()->NewScriptOrEvalFunctionLiteral(
     713             :           scope, body, function_state.expected_property_count(),
     714     1362457 :           parameter_count);
     715             :     }
     716             :   }
     717             : 
     718             :   info->set_max_function_literal_id(GetLastFunctionLiteralId());
     719             : 
     720             :   // Make sure the target stack is empty.
     721             :   DCHECK_NULL(target_stack_);
     722             : 
     723     1678456 :   return result;
     724             : }
     725             : 
     726     1339047 : FunctionLiteral* Parser::ParseFunction(Isolate* isolate, ParseInfo* info,
     727             :                                        Handle<SharedFunctionInfo> shared_info) {
     728             :   // It's OK to use the Isolate & counters here, since this function is only
     729             :   // called in the main thread.
     730             :   DCHECK(parsing_on_main_thread_);
     731             :   RuntimeCallTimerScope runtime_timer(runtime_call_stats_,
     732      669523 :                                       &RuntimeCallStats::ParseFunction);
     733     2008570 :   TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.ParseFunction");
     734             :   base::ElapsedTimer timer;
     735      669523 :   if (FLAG_trace_parse) {
     736             :     timer.Start();
     737             :   }
     738      669523 :   DeserializeScopeChain(info, info->maybe_outer_scope_info());
     739             :   DCHECK_EQ(factory()->zone(), info->zone());
     740             : 
     741             :   // Initialize parser state.
     742             :   Handle<String> name(shared_info->name());
     743      669524 :   info->set_function_name(ast_value_factory()->GetString(name));
     744     1339048 :   scanner_.Initialize(info->character_stream(), info->is_module());
     745             : 
     746      669524 :   FunctionLiteral* result = DoParseFunction(info, info->function_name());
     747      669524 :   MaybeResetCharacterStream(info, result);
     748      669524 :   if (result != nullptr) {
     749      668141 :     Handle<String> inferred_name(shared_info->inferred_name());
     750             :     result->set_inferred_name(inferred_name);
     751             :   }
     752             : 
     753      669524 :   if (FLAG_trace_parse && result != nullptr) {
     754           0 :     double ms = timer.Elapsed().InMillisecondsF();
     755             :     // We need to make sure that the debug-name is available.
     756           0 :     ast_value_factory()->Internalize(isolate);
     757           0 :     std::unique_ptr<char[]> name_chars = result->debug_name()->ToCString();
     758           0 :     PrintF("[parsing function: %s - took %0.3f ms]\n", name_chars.get(), ms);
     759             :   }
     760      669524 :   return result;
     761             : }
     762             : 
     763      669551 : static FunctionLiteral::FunctionType ComputeFunctionType(ParseInfo* info) {
     764      669551 :   if (info->is_declaration()) {
     765             :     return FunctionLiteral::kDeclaration;
     766      365964 :   } else if (info->is_named_expression()) {
     767             :     return FunctionLiteral::kNamedExpression;
     768      897974 :   } else if (IsConciseMethod(info->function_kind()) ||
     769      253726 :              IsAccessorFunction(info->function_kind())) {
     770             :     return FunctionLiteral::kAccessorOrMethod;
     771             :   }
     772      248227 :   return FunctionLiteral::kAnonymousExpression;
     773             : }
     774             : 
     775     1750703 : FunctionLiteral* Parser::DoParseFunction(ParseInfo* info,
     776             :                                          const AstRawString* raw_name) {
     777             :   DCHECK_NOT_NULL(raw_name);
     778             :   DCHECK_NULL(scope_);
     779             :   DCHECK_NULL(target_stack_);
     780             : 
     781             :   DCHECK(ast_value_factory());
     782     1609163 :   fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone());
     783      669550 :   fni_->PushEnclosingName(raw_name);
     784             : 
     785             :   ResetFunctionLiteralId();
     786             :   DCHECK_LT(0, info->function_literal_id());
     787      669551 :   SkipFunctionLiterals(info->function_literal_id() - 1);
     788             : 
     789             :   ParsingModeScope parsing_mode(this, PARSE_EAGERLY);
     790             : 
     791             :   // Place holder for the result.
     792             :   FunctionLiteral* result = nullptr;
     793             : 
     794             :   {
     795             :     // Parse the function literal.
     796      669551 :     Scope* outer = original_scope_;
     797      669551 :     DeclarationScope* outer_function = outer->GetClosureScope();
     798             :     DCHECK(outer);
     799      669551 :     FunctionState function_state(&function_state_, &scope_, outer_function);
     800             :     BlockState block_state(&scope_, outer);
     801             :     DCHECK(is_sloppy(outer->language_mode()) ||
     802             :            is_strict(info->language_mode()));
     803      669551 :     FunctionLiteral::FunctionType function_type = ComputeFunctionType(info);
     804      669551 :     FunctionKind kind = info->function_kind();
     805      669550 :     bool ok = true;
     806             : 
     807      669550 :     if (IsArrowFunction(kind)) {
     808      135204 :       if (IsAsyncFunction(kind)) {
     809             :         DCHECK(!scanner()->HasAnyLineTerminatorAfterNext());
     810         925 :         if (!Check(Token::ASYNC)) {
     811           0 :           CHECK(stack_overflow());
     812         135 :           return nullptr;
     813             :         }
     814        1820 :         if (!(peek_any_identifier() || peek() == Token::LPAREN)) {
     815         135 :           CHECK(stack_overflow());
     816             :           return nullptr;
     817             :         }
     818             :       }
     819             : 
     820             :       // TODO(adamk): We should construct this scope from the ScopeInfo.
     821      135069 :       DeclarationScope* scope = NewFunctionScope(kind);
     822             : 
     823             :       // This bit only needs to be explicitly set because we're
     824             :       // not passing the ScopeInfo to the Scope constructor.
     825      135069 :       SetLanguageMode(scope, info->language_mode());
     826             : 
     827             :       scope->set_start_position(info->start_position());
     828      135069 :       ExpressionClassifier formals_classifier(this);
     829             :       ParserFormalParameters formals(scope);
     830             :       int rewritable_length =
     831      135069 :           function_state.destructuring_assignments_to_rewrite().length();
     832             :       {
     833             :         // Parsing patterns as variable reference expression creates
     834             :         // NewUnresolved references in current scope. Enter arrow function
     835             :         // scope for formal parameter parsing.
     836             :         BlockState block_state(&scope_, scope);
     837      135069 :         if (Check(Token::LPAREN)) {
     838             :           // '(' StrictFormalParameters ')'
     839      123256 :           ParseFormalParameterList(&formals, &ok);
     840      123256 :           if (ok) ok = Check(Token::RPAREN);
     841             :         } else {
     842             :           // BindingIdentifier
     843       11813 :           ParseFormalParameter(&formals, &ok);
     844       11813 :           if (ok) {
     845             :             DeclareFormalParameters(formals.scope, formals.params,
     846       11813 :                                     formals.is_simple);
     847             :           }
     848             :         }
     849             :       }
     850             : 
     851      135069 :       if (ok) {
     852      135069 :         if (GetLastFunctionLiteralId() != info->function_literal_id() - 1) {
     853             :           // If there were FunctionLiterals in the parameters, we need to
     854             :           // renumber them to shift down so the next function literal id for
     855             :           // the arrow function is the one requested.
     856             :           AstFunctionLiteralIdReindexer reindexer(
     857             :               stack_limit_,
     858         303 :               (info->function_literal_id() - 1) - GetLastFunctionLiteralId());
     859        1046 :           for (auto p : formals.params) {
     860         440 :             if (p->pattern != nullptr) reindexer.Reindex(p->pattern);
     861         440 :             if (p->initializer != nullptr) reindexer.Reindex(p->initializer);
     862             :           }
     863             :           ResetFunctionLiteralId();
     864         606 :           SkipFunctionLiterals(info->function_literal_id() - 1);
     865             :         }
     866             : 
     867             :         // Pass `accept_IN=true` to ParseArrowFunctionLiteral --- This should
     868             :         // not be observable, or else the preparser would have failed.
     869             :         Expression* expression =
     870      135069 :             ParseArrowFunctionLiteral(true, formals, rewritable_length, &ok);
     871      135069 :         if (ok) {
     872             :           // Scanning must end at the same position that was recorded
     873             :           // previously. If not, parsing has been interrupted due to a stack
     874             :           // overflow, at which point the partially parsed arrow function
     875             :           // concise body happens to be a valid expression. This is a problem
     876             :           // only for arrow functions with single expression bodies, since there
     877             :           // is no end token such as "}" for normal functions.
     878      134859 :           if (scanner()->location().end_pos == info->end_position()) {
     879             :             // The pre-parser saw an arrow function here, so the full parser
     880             :             // must produce a FunctionLiteral.
     881             :             DCHECK(expression->IsFunctionLiteral());
     882      134859 :             result = expression->AsFunctionLiteral();
     883             :             // Rewrite destructuring assignments in the parameters. (The ones
     884             :             // inside the function body are rewritten by
     885             :             // ParseArrowFunctionLiteral.)
     886             :             RewriteDestructuringAssignments();
     887             :           } else {
     888           0 :             ok = false;
     889             :           }
     890             :         }
     891             :       }
     892      534346 :     } else if (IsDefaultConstructor(kind)) {
     893             :       DCHECK_EQ(scope(), outer);
     894             :       result = DefaultConstructor(raw_name, IsDerivedConstructor(kind),
     895        6302 :                                   info->start_position(), info->end_position());
     896             :     } else {
     897             :       result = ParseFunctionLiteral(
     898             :           raw_name, Scanner::Location::invalid(), kSkipFunctionNameCheck, kind,
     899      528044 :           kNoSourcePosition, function_type, info->language_mode(), &ok);
     900             :     }
     901             :     // Make sure the results agree.
     902             :     DCHECK(ok == (result != nullptr));
     903             :   }
     904             : 
     905             :   // Make sure the target stack is empty.
     906             :   DCHECK_NULL(target_stack_);
     907             :   DCHECK_IMPLIES(result,
     908             :                  info->function_literal_id() == result->function_literal_id());
     909      669416 :   return result;
     910             : }
     911             : 
     912      107529 : Statement* Parser::ParseModuleItem(bool* ok) {
     913             :   // ecma262/#prod-ModuleItem
     914             :   // ModuleItem :
     915             :   //    ImportDeclaration
     916             :   //    ExportDeclaration
     917             :   //    StatementListItem
     918             : 
     919        5372 :   Token::Value next = peek();
     920             : 
     921      107529 :   if (next == Token::EXPORT) {
     922       19003 :     return ParseExportDeclaration(ok);
     923             :   }
     924             : 
     925       88526 :   if (next == Token::IMPORT) {
     926             :     // We must be careful not to parse a dynamic import expression as an import
     927             :     // declaration. Same for import.meta expressions.
     928             :     Token::Value peek_ahead = PeekAhead();
     929        8203 :     if ((!allow_harmony_dynamic_import() || peek_ahead != Token::LPAREN) &&
     930         215 :         (!allow_harmony_import_meta() || peek_ahead != Token::PERIOD)) {
     931        2331 :       ParseImportDeclaration(CHECK_OK);
     932        2372 :       return factory()->NewEmptyStatement(kNoSourcePosition);
     933             :     }
     934             :   }
     935             : 
     936       86195 :   return ParseStatementListItem(ok);
     937             : }
     938             : 
     939             : 
     940       26446 : void Parser::ParseModuleItemList(ZoneList<Statement*>* body, bool* ok) {
     941             :   // ecma262/#prod-Module
     942             :   // Module :
     943             :   //    ModuleBody?
     944             :   //
     945             :   // ecma262/#prod-ModuleItemList
     946             :   // ModuleBody :
     947             :   //    ModuleItem*
     948             : 
     949             :   DCHECK(scope()->is_module_scope());
     950      146019 :   while (peek() != Token::EOS) {
     951      133975 :     Statement* stat = ParseModuleItem(CHECK_OK_VOID);
     952       93127 :     if (stat && !stat->IsEmpty()) {
     953       78517 :       body->Add(stat, zone());
     954             :     }
     955             :   }
     956             : }
     957             : 
     958             : 
     959        1418 : const AstRawString* Parser::ParseModuleSpecifier(bool* ok) {
     960             :   // ModuleSpecifier :
     961             :   //    StringLiteral
     962             : 
     963        1418 :   Expect(Token::STRING, CHECK_OK);
     964        1403 :   return GetSymbol();
     965             : }
     966             : 
     967             : 
     968         503 : void Parser::ParseExportClause(ZoneList<const AstRawString*>* export_names,
     969             :                                ZoneList<Scanner::Location>* export_locations,
     970             :                                ZoneList<const AstRawString*>* local_names,
     971             :                                Scanner::Location* reserved_loc, bool* ok) {
     972             :   // ExportClause :
     973             :   //   '{' '}'
     974             :   //   '{' ExportsList '}'
     975             :   //   '{' ExportsList ',' '}'
     976             :   //
     977             :   // ExportsList :
     978             :   //   ExportSpecifier
     979             :   //   ExportsList ',' ExportSpecifier
     980             :   //
     981             :   // ExportSpecifier :
     982             :   //   IdentifierName
     983             :   //   IdentifierName 'as' IdentifierName
     984             : 
     985        2865 :   Expect(Token::LBRACE, CHECK_OK_VOID);
     986             : 
     987             :   Token::Value name_tok;
     988         594 :   while ((name_tok = peek()) != Token::RBRACE) {
     989             :     // Keep track of the first reserved word encountered in case our
     990             :     // caller needs to report an error.
     991        1084 :     if (!reserved_loc->IsValid() &&
     992             :         !Token::IsIdentifier(name_tok, LanguageMode::kStrict, false,
     993         542 :                              parsing_module_)) {
     994          68 :       *reserved_loc = scanner()->location();
     995             :     }
     996         582 :     const AstRawString* local_name = ParseIdentifierName(CHECK_OK_VOID);
     997         522 :     const AstRawString* export_name = nullptr;
     998         522 :     Scanner::Location location = scanner()->location();
     999         522 :     if (CheckContextualKeyword(Token::AS)) {
    1000         246 :       export_name = ParseIdentifierName(CHECK_OK_VOID);
    1001             :       // Set the location to the whole "a as b" string, so that it makes sense
    1002             :       // both for errors due to "a" and for errors due to "b".
    1003         236 :       location.end_pos = scanner()->location().end_pos;
    1004             :     }
    1005         512 :     if (export_name == nullptr) {
    1006         276 :       export_name = local_name;
    1007             :     }
    1008         512 :     export_names->Add(export_name, zone());
    1009         512 :     local_names->Add(local_name, zone());
    1010         512 :     export_locations->Add(location, zone());
    1011         512 :     if (peek() == Token::RBRACE) break;
    1012         101 :     Expect(Token::COMMA, CHECK_OK_VOID);
    1013             :   }
    1014             : 
    1015         463 :   Expect(Token::RBRACE, CHECK_OK_VOID);
    1016             : }
    1017             : 
    1018             : 
    1019        1152 : ZoneList<const Parser::NamedImport*>* Parser::ParseNamedImports(
    1020             :     int pos, bool* ok) {
    1021             :   // NamedImports :
    1022             :   //   '{' '}'
    1023             :   //   '{' ImportsList '}'
    1024             :   //   '{' ImportsList ',' '}'
    1025             :   //
    1026             :   // ImportsList :
    1027             :   //   ImportSpecifier
    1028             :   //   ImportsList ',' ImportSpecifier
    1029             :   //
    1030             :   // ImportSpecifier :
    1031             :   //   BindingIdentifier
    1032             :   //   IdentifierName 'as' BindingIdentifier
    1033             : 
    1034        6912 :   Expect(Token::LBRACE, CHECK_OK);
    1035             : 
    1036        1152 :   auto result = new (zone()) ZoneList<const NamedImport*>(1, zone());
    1037        2413 :   while (peek() != Token::RBRACE) {
    1038        1234 :     const AstRawString* import_name = ParseIdentifierName(CHECK_OK);
    1039             :     const AstRawString* local_name = import_name;
    1040             :     Scanner::Location location = scanner()->location();
    1041             :     // In the presence of 'as', the left-side of the 'as' can
    1042             :     // be any IdentifierName. But without 'as', it must be a valid
    1043             :     // BindingIdentifier.
    1044        1179 :     if (CheckContextualKeyword(Token::AS)) {
    1045         619 :       local_name = ParseIdentifierName(CHECK_OK);
    1046             :     }
    1047        1179 :     if (!Token::IsIdentifier(scanner()->current_token(), LanguageMode::kStrict,
    1048        2358 :                              false, parsing_module_)) {
    1049          30 :       *ok = false;
    1050          30 :       ReportMessage(MessageTemplate::kUnexpectedReserved);
    1051          30 :       return nullptr;
    1052        1149 :     } else if (IsEvalOrArguments(local_name)) {
    1053          15 :       *ok = false;
    1054          15 :       ReportMessage(MessageTemplate::kStrictEvalArguments);
    1055          15 :       return nullptr;
    1056             :     }
    1057             : 
    1058             :     DeclareVariable(local_name, CONST, kNeedsInitialization, position(),
    1059        1134 :                     CHECK_OK);
    1060             : 
    1061             :     NamedImport* import =
    1062             :         new (zone()) NamedImport(import_name, local_name, location);
    1063        1134 :     result->Add(import, zone());
    1064             : 
    1065        1134 :     if (peek() == Token::RBRACE) break;
    1066         149 :     Expect(Token::COMMA, CHECK_OK);
    1067             :   }
    1068             : 
    1069        1012 :   Expect(Token::RBRACE, CHECK_OK);
    1070        1012 :   return result;
    1071             : }
    1072             : 
    1073             : 
    1074        2331 : void Parser::ParseImportDeclaration(bool* ok) {
    1075             :   // ImportDeclaration :
    1076             :   //   'import' ImportClause 'from' ModuleSpecifier ';'
    1077             :   //   'import' ModuleSpecifier ';'
    1078             :   //
    1079             :   // ImportClause :
    1080             :   //   ImportedDefaultBinding
    1081             :   //   NameSpaceImport
    1082             :   //   NamedImports
    1083             :   //   ImportedDefaultBinding ',' NameSpaceImport
    1084             :   //   ImportedDefaultBinding ',' NamedImports
    1085             :   //
    1086             :   // NameSpaceImport :
    1087             :   //   '*' 'as' ImportedBinding
    1088             : 
    1089        4950 :   int pos = peek_position();
    1090        3558 :   Expect(Token::IMPORT, CHECK_OK_VOID);
    1091             : 
    1092             :   Token::Value tok = peek();
    1093             : 
    1094             :   // 'import' ModuleSpecifier ';'
    1095        2331 :   if (tok == Token::STRING) {
    1096          82 :     Scanner::Location specifier_loc = scanner()->peek_location();
    1097          82 :     const AstRawString* module_specifier = ParseModuleSpecifier(CHECK_OK_VOID);
    1098          82 :     ExpectSemicolon(CHECK_OK_VOID);
    1099          82 :     module()->AddEmptyImport(module_specifier, specifier_loc);
    1100          82 :     return;
    1101             :   }
    1102             : 
    1103             :   // Parse ImportedDefaultBinding if present.
    1104             :   const AstRawString* import_default_binding = nullptr;
    1105             :   Scanner::Location import_default_binding_loc;
    1106        2249 :   if (tok != Token::MUL && tok != Token::LBRACE) {
    1107             :     import_default_binding =
    1108         977 :         ParseIdentifier(kDontAllowRestrictedIdentifiers, CHECK_OK_VOID);
    1109          77 :     import_default_binding_loc = scanner()->location();
    1110             :     DeclareVariable(import_default_binding, CONST, kNeedsInitialization, pos,
    1111          77 :                     CHECK_OK_VOID);
    1112             :   }
    1113             : 
    1114             :   // Parse NameSpaceImport or NamedImports if present.
    1115             :   const AstRawString* module_namespace_binding = nullptr;
    1116             :   Scanner::Location module_namespace_binding_loc;
    1117        2911 :   const ZoneList<const NamedImport*>* named_imports = nullptr;
    1118        1349 :   if (import_default_binding == nullptr || Check(Token::COMMA)) {
    1119        1297 :     switch (peek()) {
    1120             :       case Token::MUL: {
    1121         135 :         Consume(Token::MUL);
    1122         135 :         ExpectContextualKeyword(Token::AS, CHECK_OK_VOID);
    1123             :         module_namespace_binding =
    1124         135 :             ParseIdentifier(kDontAllowRestrictedIdentifiers, CHECK_OK_VOID);
    1125         135 :         module_namespace_binding_loc = scanner()->location();
    1126             :         DeclareVariable(module_namespace_binding, CONST, kCreatedInitialized,
    1127         135 :                         pos, CHECK_OK_VOID);
    1128             :         break;
    1129             :       }
    1130             : 
    1131             :       case Token::LBRACE:
    1132        1152 :         named_imports = ParseNamedImports(pos, CHECK_OK_VOID);
    1133             :         break;
    1134             : 
    1135             :       default:
    1136          10 :         *ok = false;
    1137          10 :         ReportUnexpectedToken(scanner()->current_token());
    1138          10 :         return;
    1139             :     }
    1140             :   }
    1141             : 
    1142        1199 :   ExpectContextualKeyword(Token::FROM, CHECK_OK_VOID);
    1143        1109 :   Scanner::Location specifier_loc = scanner()->peek_location();
    1144        1109 :   const AstRawString* module_specifier = ParseModuleSpecifier(CHECK_OK_VOID);
    1145        1104 :   ExpectSemicolon(CHECK_OK_VOID);
    1146             : 
    1147             :   // Now that we have all the information, we can make the appropriate
    1148             :   // declarations.
    1149             : 
    1150             :   // TODO(neis): Would prefer to call DeclareVariable for each case below rather
    1151             :   // than above and in ParseNamedImports, but then a possible error message
    1152             :   // would point to the wrong location.  Maybe have a DeclareAt version of
    1153             :   // Declare that takes a location?
    1154             : 
    1155        1104 :   if (module_namespace_binding != nullptr) {
    1156             :     module()->AddStarImport(module_namespace_binding, module_specifier,
    1157             :                             module_namespace_binding_loc, specifier_loc,
    1158         120 :                             zone());
    1159             :   }
    1160             : 
    1161        1104 :   if (import_default_binding != nullptr) {
    1162             :     module()->AddImport(ast_value_factory()->default_string(),
    1163             :                         import_default_binding, module_specifier,
    1164         104 :                         import_default_binding_loc, specifier_loc, zone());
    1165             :   }
    1166             : 
    1167        1104 :   if (named_imports != nullptr) {
    1168         947 :     if (named_imports->length() == 0) {
    1169          17 :       module()->AddEmptyImport(module_specifier, specifier_loc);
    1170             :     } else {
    1171        2998 :       for (int i = 0; i < named_imports->length(); ++i) {
    1172        1034 :         const NamedImport* import = named_imports->at(i);
    1173             :         module()->AddImport(import->import_name, import->local_name,
    1174             :                             module_specifier, import->location, specifier_loc,
    1175        2068 :                             zone());
    1176             :       }
    1177             :     }
    1178             :   }
    1179             : }
    1180             : 
    1181             : 
    1182         386 : Statement* Parser::ParseExportDefault(bool* ok) {
    1183             :   //  Supports the following productions, starting after the 'default' token:
    1184             :   //    'export' 'default' HoistableDeclaration
    1185             :   //    'export' 'default' ClassDeclaration
    1186             :   //    'export' 'default' AssignmentExpression[In] ';'
    1187             : 
    1188        2068 :   Expect(Token::DEFAULT, CHECK_OK);
    1189         386 :   Scanner::Location default_loc = scanner()->location();
    1190             : 
    1191         386 :   ZoneList<const AstRawString*> local_names(1, zone());
    1192             :   Statement* result = nullptr;
    1193         386 :   switch (peek()) {
    1194             :     case Token::FUNCTION:
    1195          67 :       result = ParseHoistableDeclaration(&local_names, true, CHECK_OK);
    1196             :       break;
    1197             : 
    1198             :     case Token::CLASS:
    1199          44 :       Consume(Token::CLASS);
    1200          44 :       result = ParseClassDeclaration(&local_names, true, CHECK_OK);
    1201             :       break;
    1202             : 
    1203             :     case Token::ASYNC:
    1204         120 :       if (PeekAhead() == Token::FUNCTION &&
    1205             :           !scanner()->HasAnyLineTerminatorAfterNext()) {
    1206          60 :         Consume(Token::ASYNC);
    1207          60 :         result = ParseAsyncFunctionDeclaration(&local_names, true, CHECK_OK);
    1208             :         break;
    1209             :       }
    1210             :     /* falls through */
    1211             : 
    1212             :     default: {
    1213             :       int pos = position();
    1214         215 :       ExpressionClassifier classifier(this);
    1215         215 :       Expression* value = ParseAssignmentExpression(true, CHECK_OK);
    1216         175 :       RewriteNonPattern(CHECK_OK);
    1217         350 :       SetFunctionName(value, ast_value_factory()->default_string());
    1218             : 
    1219             :       const AstRawString* local_name =
    1220         350 :           ast_value_factory()->star_default_star_string();
    1221         175 :       local_names.Add(local_name, zone());
    1222             : 
    1223             :       // It's fine to declare this as CONST because the user has no way of
    1224             :       // writing to it.
    1225         700 :       Declaration* decl = DeclareVariable(local_name, CONST, pos, CHECK_OK);
    1226         175 :       decl->proxy()->var()->set_initializer_position(position());
    1227             : 
    1228             :       Assignment* assignment = factory()->NewAssignment(
    1229         175 :           Token::INIT, decl->proxy(), value, kNoSourcePosition);
    1230             :       result = IgnoreCompletion(
    1231         175 :           factory()->NewExpressionStatement(assignment, kNoSourcePosition));
    1232             : 
    1233         175 :       ExpectSemicolon(CHECK_OK);
    1234             :       break;
    1235             :     }
    1236             :   }
    1237             : 
    1238             :   DCHECK_EQ(local_names.length(), 1);
    1239             :   module()->AddExport(local_names.first(),
    1240             :                       ast_value_factory()->default_string(), default_loc,
    1241         963 :                       zone());
    1242             : 
    1243             :   DCHECK_NOT_NULL(result);
    1244         321 :   return result;
    1245             : }
    1246             : 
    1247       19003 : Statement* Parser::ParseExportDeclaration(bool* ok) {
    1248             :   // ExportDeclaration:
    1249             :   //    'export' '*' 'from' ModuleSpecifier ';'
    1250             :   //    'export' ExportClause ('from' ModuleSpecifier)? ';'
    1251             :   //    'export' VariableStatement
    1252             :   //    'export' Declaration
    1253             :   //    'export' 'default' ... (handled in ParseExportDefault)
    1254             : 
    1255       76232 :   Expect(Token::EXPORT, CHECK_OK);
    1256             :   int pos = position();
    1257             : 
    1258             :   Statement* result = nullptr;
    1259       19003 :   ZoneList<const AstRawString*> names(1, zone());
    1260       19003 :   Scanner::Location loc = scanner()->peek_location();
    1261       19003 :   switch (peek()) {
    1262             :     case Token::DEFAULT:
    1263         386 :       return ParseExportDefault(ok);
    1264             : 
    1265             :     case Token::MUL: {
    1266         114 :       Consume(Token::MUL);
    1267         114 :       loc = scanner()->location();
    1268         114 :       ExpectContextualKeyword(Token::FROM, CHECK_OK);
    1269         109 :       Scanner::Location specifier_loc = scanner()->peek_location();
    1270         109 :       const AstRawString* module_specifier = ParseModuleSpecifier(CHECK_OK);
    1271         104 :       ExpectSemicolon(CHECK_OK);
    1272         104 :       module()->AddStarExport(module_specifier, loc, specifier_loc, zone());
    1273         208 :       return factory()->NewEmptyStatement(pos);
    1274             :     }
    1275             : 
    1276             :     case Token::LBRACE: {
    1277             :       // There are two cases here:
    1278             :       //
    1279             :       // 'export' ExportClause ';'
    1280             :       // and
    1281             :       // 'export' ExportClause FromClause ';'
    1282             :       //
    1283             :       // In the first case, the exported identifiers in ExportClause must
    1284             :       // not be reserved words, while in the latter they may be. We
    1285             :       // pass in a location that gets filled with the first reserved word
    1286             :       // encountered, and then throw a SyntaxError if we are in the
    1287             :       // non-FromClause case.
    1288         503 :       Scanner::Location reserved_loc = Scanner::Location::invalid();
    1289         503 :       ZoneList<const AstRawString*> export_names(1, zone());
    1290         503 :       ZoneList<Scanner::Location> export_locations(1, zone());
    1291         503 :       ZoneList<const AstRawString*> original_names(1, zone());
    1292             :       ParseExportClause(&export_names, &export_locations, &original_names,
    1293         503 :                         &reserved_loc, CHECK_OK);
    1294             :       const AstRawString* module_specifier = nullptr;
    1295             :       Scanner::Location specifier_loc;
    1296         463 :       if (CheckContextualKeyword(Token::FROM)) {
    1297         118 :         specifier_loc = scanner()->peek_location();
    1298         118 :         module_specifier = ParseModuleSpecifier(CHECK_OK);
    1299         345 :       } else if (reserved_loc.IsValid()) {
    1300             :         // No FromClause, so reserved words are invalid in ExportClause.
    1301          10 :         *ok = false;
    1302             :         ReportMessageAt(reserved_loc, MessageTemplate::kUnexpectedReserved);
    1303             :         return nullptr;
    1304             :       }
    1305         448 :       ExpectSemicolon(CHECK_OK);
    1306         448 :       const int length = export_names.length();
    1307             :       DCHECK_EQ(length, original_names.length());
    1308             :       DCHECK_EQ(length, export_locations.length());
    1309         448 :       if (module_specifier == nullptr) {
    1310         370 :         for (int i = 0; i < length; ++i) {
    1311         740 :           module()->AddExport(original_names[i], export_names[i],
    1312        1480 :                               export_locations[i], zone());
    1313             :         }
    1314         113 :       } else if (length == 0) {
    1315          30 :         module()->AddEmptyImport(module_specifier, specifier_loc);
    1316             :       } else {
    1317         107 :         for (int i = 0; i < length; ++i) {
    1318         214 :           module()->AddExport(original_names[i], export_names[i],
    1319         107 :                               module_specifier, export_locations[i],
    1320         321 :                               specifier_loc, zone());
    1321             :         }
    1322             :       }
    1323         896 :       return factory()->NewEmptyStatement(pos);
    1324             :     }
    1325             : 
    1326             :     case Token::FUNCTION:
    1327         303 :       result = ParseHoistableDeclaration(&names, false, CHECK_OK);
    1328             :       break;
    1329             : 
    1330             :     case Token::CLASS:
    1331          33 :       Consume(Token::CLASS);
    1332          33 :       result = ParseClassDeclaration(&names, false, CHECK_OK);
    1333             :       break;
    1334             : 
    1335             :     case Token::VAR:
    1336             :     case Token::LET:
    1337             :     case Token::CONST:
    1338       17554 :       result = ParseVariableStatement(kStatementListItem, &names, CHECK_OK);
    1339             :       break;
    1340             : 
    1341             :     case Token::ASYNC:
    1342             :       // TODO(neis): Why don't we have the same check here as in
    1343             :       // ParseStatementListItem?
    1344         105 :       Consume(Token::ASYNC);
    1345         105 :       result = ParseAsyncFunctionDeclaration(&names, false, CHECK_OK);
    1346             :       break;
    1347             : 
    1348             :     default:
    1349           5 :       *ok = false;
    1350           5 :       ReportUnexpectedToken(scanner()->current_token());
    1351           5 :       return nullptr;
    1352             :   }
    1353       17895 :   loc.end_pos = scanner()->location().end_pos;
    1354             : 
    1355             :   ModuleDescriptor* descriptor = module();
    1356       35790 :   for (int i = 0; i < names.length(); ++i) {
    1357       35790 :     descriptor->AddExport(names[i], names[i], loc, zone());
    1358             :   }
    1359             : 
    1360             :   DCHECK_NOT_NULL(result);
    1361             :   return result;
    1362             : }
    1363             : 
    1364    44413263 : VariableProxy* Parser::NewUnresolved(const AstRawString* name, int begin_pos,
    1365             :                                      VariableKind kind) {
    1366    88875792 :   return scope()->NewUnresolved(factory(), name, begin_pos, kind);
    1367             : }
    1368             : 
    1369       24414 : VariableProxy* Parser::NewUnresolved(const AstRawString* name) {
    1370       48828 :   return scope()->NewUnresolved(factory(), name, scanner()->location().beg_pos);
    1371             : }
    1372             : 
    1373       79204 : Declaration* Parser::DeclareVariable(const AstRawString* name,
    1374             :                                      VariableMode mode, int pos, bool* ok) {
    1375             :   return DeclareVariable(name, mode, Variable::DefaultInitializationFlag(mode),
    1376      170296 :                          pos, ok);
    1377             : }
    1378             : 
    1379      171642 : Declaration* Parser::DeclareVariable(const AstRawString* name,
    1380             :                                      VariableMode mode, InitializationFlag init,
    1381             :                                      int pos, bool* ok) {
    1382             :   DCHECK_NOT_NULL(name);
    1383             :   VariableProxy* proxy = factory()->NewVariableProxy(
    1384      344962 :       name, NORMAL_VARIABLE, scanner()->location().beg_pos);
    1385             :   Declaration* declaration;
    1386      173320 :   if (mode == VAR && !scope()->is_declaration_scope()) {
    1387             :     DCHECK(scope()->is_block_scope() || scope()->is_with_scope());
    1388           0 :     declaration = factory()->NewNestedVariableDeclaration(proxy, scope(), pos);
    1389             :   } else {
    1390      171642 :     declaration = factory()->NewVariableDeclaration(proxy, pos);
    1391             :   }
    1392             :   Declare(declaration, DeclarationDescriptor::NORMAL, mode, init, ok, nullptr,
    1393      171642 :           scanner()->location().end_pos);
    1394      171642 :   if (!*ok) return nullptr;
    1395      168114 :   return declaration;
    1396             : }
    1397             : 
    1398    10802496 : Variable* Parser::Declare(Declaration* declaration,
    1399             :                           DeclarationDescriptor::Kind declaration_kind,
    1400             :                           VariableMode mode, InitializationFlag init, bool* ok,
    1401             :                           Scope* scope, int var_end_pos) {
    1402    10702300 :   if (scope == nullptr) {
    1403    21403188 :     scope = this->scope();
    1404             :   }
    1405    10702300 :   bool sloppy_mode_block_scope_function_redefinition = false;
    1406             :   Variable* variable = scope->DeclareVariable(
    1407             :       declaration, mode, init, allow_harmony_restrictive_generators(),
    1408    10702300 :       &sloppy_mode_block_scope_function_redefinition, ok);
    1409    10702299 :   if (!*ok) {
    1410             :     // If we only have the start position of a proxy, we can't highlight the
    1411             :     // whole variable name.  Pretend its length is 1 so that we highlight at
    1412             :     // least the first character.
    1413             :     Scanner::Location loc(declaration->proxy()->position(),
    1414             :                           var_end_pos != kNoSourcePosition
    1415             :                               ? var_end_pos
    1416      152058 :                               : declaration->proxy()->position() + 1);
    1417       51862 :     if (declaration_kind == DeclarationDescriptor::PARAMETER) {
    1418             :       ReportMessageAt(loc, MessageTemplate::kParamDupe);
    1419             :     } else {
    1420             :       ReportMessageAt(loc, MessageTemplate::kVarRedeclaration,
    1421             :                       declaration->proxy()->raw_name());
    1422             :     }
    1423             :     return nullptr;
    1424             :   }
    1425    10650437 :   if (sloppy_mode_block_scope_function_redefinition) {
    1426         200 :     ++use_counts_[v8::Isolate::kSloppyModeBlockScopedFunctionRedefinition];
    1427             :   }
    1428    10650437 :   return variable;
    1429             : }
    1430             : 
    1431      412146 : Block* Parser::BuildInitializationBlock(
    1432             :     DeclarationParsingResult* parsing_result,
    1433             :     ZoneList<const AstRawString*>* names, bool* ok) {
    1434      412146 :   Block* result = factory()->NewBlock(1, true);
    1435     1252006 :   for (auto declaration : parsing_result->declarations) {
    1436             :     DeclareAndInitializeVariables(result, &(parsing_result->descriptor),
    1437      427732 :                                   &declaration, names, CHECK_OK);
    1438             :   }
    1439      412128 :   return result;
    1440             : }
    1441             : 
    1442     1219128 : Statement* Parser::DeclareFunction(const AstRawString* variable_name,
    1443             :                                    FunctionLiteral* function, VariableMode mode,
    1444             :                                    int pos, bool is_sloppy_block_function,
    1445             :                                    ZoneList<const AstRawString*>* names,
    1446             :                                    bool* ok) {
    1447             :   VariableProxy* proxy =
    1448     1228119 :       factory()->NewVariableProxy(variable_name, NORMAL_VARIABLE);
    1449             : 
    1450             :   Declaration* declaration =
    1451     1219128 :       factory()->NewFunctionDeclaration(proxy, function, pos);
    1452             :   Declare(declaration, DeclarationDescriptor::NORMAL, mode, kCreatedInitialized,
    1453     1219128 :           CHECK_OK);
    1454     1217713 :   if (names) names->Add(variable_name, zone());
    1455     1217288 :   if (is_sloppy_block_function) {
    1456             :     SloppyBlockFunctionStatement* statement =
    1457        8566 :         factory()->NewSloppyBlockFunctionStatement();
    1458             :     GetDeclarationScope()->DeclareSloppyBlockFunction(variable_name, scope(),
    1459       17132 :                                                       statement);
    1460        8566 :     return statement;
    1461             :   }
    1462     2417444 :   return factory()->NewEmptyStatement(kNoSourcePosition);
    1463             : }
    1464             : 
    1465             : Statement* Parser::DeclareClass(const AstRawString* variable_name,
    1466             :                                 Expression* value,
    1467             :                                 ZoneList<const AstRawString*>* names,
    1468             :                                 int class_token_pos, int end_pos, bool* ok) {
    1469      147996 :   Declaration* decl =
    1470       77526 :       DeclareVariable(variable_name, LET, class_token_pos, CHECK_OK);
    1471       73998 :   decl->proxy()->var()->set_initializer_position(end_pos);
    1472       73998 :   if (names) names->Add(variable_name, zone());
    1473             : 
    1474       73998 :   Assignment* assignment = factory()->NewAssignment(Token::INIT, decl->proxy(),
    1475       73998 :                                                     value, class_token_pos);
    1476             :   return IgnoreCompletion(
    1477       73998 :       factory()->NewExpressionStatement(assignment, kNoSourcePosition));
    1478             : }
    1479             : 
    1480             : Statement* Parser::DeclareNative(const AstRawString* name, int pos, bool* ok) {
    1481             :   // Make sure that the function containing the native declaration
    1482             :   // isn't lazily compiled. The extension structures are only
    1483             :   // accessible while parsing the first time not when reparsing
    1484             :   // because of lazy compilation.
    1485        1678 :   GetClosureScope()->ForceEagerCompilation();
    1486             : 
    1487             :   // TODO(1240846): It's weird that native function declarations are
    1488             :   // introduced dynamically when we meet their declarations, whereas
    1489             :   // other functions are set up when entering the surrounding scope.
    1490        3356 :   Declaration* decl = DeclareVariable(name, VAR, pos, CHECK_OK);
    1491             :   NativeFunctionLiteral* lit =
    1492        1678 :       factory()->NewNativeFunctionLiteral(name, extension_, kNoSourcePosition);
    1493             :   return factory()->NewExpressionStatement(
    1494        1678 :       factory()->NewAssignment(Token::INIT, decl->proxy(), lit,
    1495        1678 :                                kNoSourcePosition),
    1496        1678 :       pos);
    1497             : }
    1498             : 
    1499       18095 : ZoneList<const AstRawString*>* Parser::DeclareLabel(
    1500             :     ZoneList<const AstRawString*>* labels, VariableProxy* var, bool* ok) {
    1501             :   DCHECK(IsIdentifier(var));
    1502       18095 :   const AstRawString* label = var->raw_name();
    1503             :   // TODO(1240780): We don't check for redeclaration of labels
    1504             :   // during preparsing since keeping track of the set of active
    1505             :   // labels requires nontrivial changes to the way scopes are
    1506             :   // structured.  However, these are probably changes we want to
    1507             :   // make later anyway so we should go back and fix this then.
    1508       18095 :   if (ContainsLabel(labels, label) || TargetStackContainsLabel(label)) {
    1509       53879 :     ReportMessage(MessageTemplate::kLabelRedeclaration, label);
    1510           0 :     *ok = false;
    1511           0 :     return nullptr;
    1512             :   }
    1513       18095 :   if (labels == nullptr) {
    1514       17689 :     labels = new (zone()) ZoneList<const AstRawString*>(1, zone());
    1515             :   }
    1516       18095 :   labels->Add(label, zone());
    1517             :   // Remove the "ghost" variable that turned out to be a label
    1518             :   // from the top scope. This way, we don't try to resolve it
    1519             :   // during the scope processing.
    1520       18095 :   scope()->RemoveUnresolved(var);
    1521       18095 :   return labels;
    1522             : }
    1523             : 
    1524       12551 : bool Parser::ContainsLabel(ZoneList<const AstRawString*>* labels,
    1525             :                            const AstRawString* label) {
    1526             :   DCHECK_NOT_NULL(label);
    1527       75547 :   if (labels != nullptr) {
    1528       13770 :     for (int i = labels->length(); i-- > 0;) {
    1529       12672 :       if (labels->at(i) == label) return true;
    1530             :     }
    1531             :   }
    1532             :   return false;
    1533             : }
    1534             : 
    1535             : Block* Parser::IgnoreCompletion(Statement* statement) {
    1536      461095 :   Block* block = factory()->NewBlock(1, true);
    1537      461095 :   block->statements()->Add(statement, zone());
    1538             :   return block;
    1539             : }
    1540             : 
    1541     2644910 : Expression* Parser::RewriteReturn(Expression* return_value, int pos) {
    1542     5289821 :   if (IsDerivedConstructor(function_state_->kind())) {
    1543             :     // For subclass constructors we need to return this in case of undefined;
    1544             :     // other primitive values trigger an exception in the ConstructStub.
    1545             :     //
    1546             :     //   return expr;
    1547             :     //
    1548             :     // Is rewritten as:
    1549             :     //
    1550             :     //   return (temp = expr) === undefined ? this : temp;
    1551             : 
    1552             :     // temp = expr
    1553         407 :     Variable* temp = NewTemporary(ast_value_factory()->empty_string());
    1554             :     Assignment* assign = factory()->NewAssignment(
    1555         814 :         Token::ASSIGN, factory()->NewVariableProxy(temp), return_value, pos);
    1556             : 
    1557             :     // temp === undefined
    1558             :     Expression* is_undefined = factory()->NewCompareOperation(
    1559             :         Token::EQ_STRICT, assign,
    1560         407 :         factory()->NewUndefinedLiteral(kNoSourcePosition), pos);
    1561             : 
    1562             :     // is_undefined ? this : temp
    1563             :     return_value =
    1564             :         factory()->NewConditional(is_undefined, ThisExpression(pos),
    1565         814 :                                   factory()->NewVariableProxy(temp), pos);
    1566             :   }
    1567     2644911 :   return return_value;
    1568             : }
    1569             : 
    1570         612 : Expression* Parser::RewriteDoExpression(Block* body, int pos, bool* ok) {
    1571        1224 :   Variable* result = NewTemporary(ast_value_factory()->dot_result_string());
    1572         612 :   DoExpression* expr = factory()->NewDoExpression(body, result, pos);
    1573         612 :   if (!Rewriter::Rewrite(this, GetClosureScope(), expr, ast_value_factory())) {
    1574           0 :     *ok = false;
    1575           0 :     return nullptr;
    1576             :   }
    1577             :   return expr;
    1578             : }
    1579             : 
    1580        1840 : Statement* Parser::RewriteSwitchStatement(SwitchStatement* switch_statement,
    1581             :                                           Scope* scope) {
    1582             :   // In order to get the CaseClauses to execute in their own lexical scope,
    1583             :   // but without requiring downstream code to have special scope handling
    1584             :   // code for switch statements, desugar into blocks as follows:
    1585             :   // {  // To group the statements--harmless to evaluate Expression in scope
    1586             :   //   .tag_variable = Expression;
    1587             :   //   {  // To give CaseClauses a scope
    1588             :   //     switch (.tag_variable) { CaseClause* }
    1589             :   //   }
    1590             :   // }
    1591             :   DCHECK_NOT_NULL(scope);
    1592             :   DCHECK(scope->is_block_scope());
    1593             :   DCHECK_GE(switch_statement->position(), scope->start_position());
    1594             :   DCHECK_LT(switch_statement->position(), scope->end_position());
    1595             : 
    1596        4600 :   Block* switch_block = factory()->NewBlock(2, false);
    1597             : 
    1598             :   Expression* tag = switch_statement->tag();
    1599             :   Variable* tag_variable =
    1600         920 :       NewTemporary(ast_value_factory()->dot_switch_tag_string());
    1601             :   Assignment* tag_assign = factory()->NewAssignment(
    1602         920 :       Token::ASSIGN, factory()->NewVariableProxy(tag_variable), tag,
    1603        1840 :       tag->position());
    1604             :   // Wrap with IgnoreCompletion so the tag isn't returned as the completion
    1605             :   // value, in case the switch statements don't have a value.
    1606             :   Statement* tag_statement = IgnoreCompletion(
    1607        1840 :       factory()->NewExpressionStatement(tag_assign, kNoSourcePosition));
    1608         920 :   switch_block->statements()->Add(tag_statement, zone());
    1609             : 
    1610         920 :   switch_statement->set_tag(factory()->NewVariableProxy(tag_variable));
    1611         920 :   Block* cases_block = factory()->NewBlock(1, false);
    1612         920 :   cases_block->statements()->Add(switch_statement, zone());
    1613             :   cases_block->set_scope(scope);
    1614         920 :   switch_block->statements()->Add(cases_block, zone());
    1615         920 :   return switch_block;
    1616             : }
    1617             : 
    1618       81707 : void Parser::RewriteCatchPattern(CatchInfo* catch_info, bool* ok) {
    1619       81707 :   if (catch_info->name == nullptr) {
    1620             :     DCHECK_NOT_NULL(catch_info->pattern);
    1621       92810 :     catch_info->name = ast_value_factory()->dot_catch_string();
    1622             :   }
    1623             :   Variable* catch_variable =
    1624       81707 :       catch_info->scope->DeclareLocal(catch_info->name, VAR);
    1625       81707 :   if (catch_info->pattern != nullptr) {
    1626             :     DeclarationDescriptor descriptor;
    1627        3701 :     descriptor.declaration_kind = DeclarationDescriptor::NORMAL;
    1628        3701 :     descriptor.scope = scope();
    1629        3701 :     descriptor.mode = LET;
    1630        3701 :     descriptor.declaration_pos = catch_info->pattern->position();
    1631        3701 :     descriptor.initialization_pos = catch_info->pattern->position();
    1632             : 
    1633             :     // Initializer position for variables declared by the pattern.
    1634             :     const int initializer_position = position();
    1635             : 
    1636             :     DeclarationParsingResult::Declaration decl(
    1637             :         catch_info->pattern, initializer_position,
    1638        7402 :         factory()->NewVariableProxy(catch_variable));
    1639             : 
    1640        3701 :     catch_info->init_block = factory()->NewBlock(8, true);
    1641             :     DeclareAndInitializeVariables(catch_info->init_block, &descriptor, &decl,
    1642        3701 :                                   &catch_info->bound_names, ok);
    1643             :   } else {
    1644       78006 :     catch_info->bound_names.Add(catch_info->name, zone());
    1645             :   }
    1646       81707 : }
    1647             : 
    1648       81424 : void Parser::ValidateCatchBlock(const CatchInfo& catch_info, bool* ok) {
    1649             :   // Check for `catch(e) { let e; }` and similar errors.
    1650       81424 :   Scope* inner_block_scope = catch_info.inner_block->scope();
    1651       81424 :   if (inner_block_scope != nullptr) {
    1652         342 :     Declaration* decl = inner_block_scope->CheckLexDeclarationsConflictingWith(
    1653        1191 :         catch_info.bound_names);
    1654        1191 :     if (decl != nullptr) {
    1655             :       const AstRawString* name = decl->proxy()->raw_name();
    1656         342 :       int position = decl->proxy()->position();
    1657             :       Scanner::Location location =
    1658             :           position == kNoSourcePosition
    1659             :               ? Scanner::Location::invalid()
    1660         342 :               : Scanner::Location(position, position + 1);
    1661             :       ReportMessageAt(location, MessageTemplate::kVarRedeclaration, name);
    1662         342 :       *ok = false;
    1663             :     }
    1664             :   }
    1665       81424 : }
    1666             : 
    1667       87296 : Statement* Parser::RewriteTryStatement(Block* try_block, Block* catch_block,
    1668             :                                        const SourceRange& catch_range,
    1669             :                                        Block* finally_block,
    1670             :                                        const SourceRange& finally_range,
    1671             :                                        const CatchInfo& catch_info, int pos) {
    1672             :   // Simplify the AST nodes by converting:
    1673             :   //   'try B0 catch B1 finally B2'
    1674             :   // to:
    1675             :   //   'try { try B0 catch B1 } finally B2'
    1676             : 
    1677       87296 :   if (catch_block != nullptr && finally_block != nullptr) {
    1678             :     // If we have both, create an inner try/catch.
    1679             :     DCHECK_NOT_NULL(catch_info.scope);
    1680             :     TryCatchStatement* statement;
    1681             :     statement = factory()->NewTryCatchStatement(try_block, catch_info.scope,
    1682        1408 :                                                 catch_block, kNoSourcePosition);
    1683             :     RecordTryCatchStatementSourceRange(statement, catch_range);
    1684             : 
    1685         704 :     try_block = factory()->NewBlock(1, false);
    1686         704 :     try_block->statements()->Add(statement, zone());
    1687             :     catch_block = nullptr;  // Clear to indicate it's been handled.
    1688             :   }
    1689             : 
    1690       87296 :   if (catch_block != nullptr) {
    1691             :     DCHECK_NULL(finally_block);
    1692             :     DCHECK_NOT_NULL(catch_info.scope);
    1693             :     TryCatchStatement* stmt = factory()->NewTryCatchStatement(
    1694       80378 :         try_block, catch_info.scope, catch_block, pos);
    1695             :     RecordTryCatchStatementSourceRange(stmt, catch_range);
    1696       80378 :     return stmt;
    1697             :   } else {
    1698             :     DCHECK_NOT_NULL(finally_block);
    1699             :     TryFinallyStatement* stmt =
    1700        6918 :         factory()->NewTryFinallyStatement(try_block, finally_block, pos);
    1701             :     RecordTryFinallyStatementSourceRange(stmt, finally_range);
    1702        6918 :     return stmt;
    1703             :   }
    1704             : }
    1705             : 
    1706       21086 : void Parser::ParseAndRewriteGeneratorFunctionBody(int pos, FunctionKind kind,
    1707             :                                                   ZoneList<Statement*>* body,
    1708             :                                                   bool* ok) {
    1709             :   // For ES6 Generators, we just prepend the initial yield.
    1710       21086 :   Expression* initial_yield = BuildInitialYield(pos, kind);
    1711       21086 :   body->Add(factory()->NewExpressionStatement(initial_yield, kNoSourcePosition),
    1712       42172 :             zone());
    1713       21086 :   ParseStatementList(body, Token::RBRACE, ok);
    1714       21086 : }
    1715             : 
    1716       18599 : void Parser::ParseAndRewriteAsyncGeneratorFunctionBody(
    1717             :     int pos, FunctionKind kind, ZoneList<Statement*>* body, bool* ok) {
    1718             :   // For ES2017 Async Generators, we produce:
    1719             :   //
    1720             :   // try {
    1721             :   //   InitialYield;
    1722             :   //   ...body...;
    1723             :   //   return undefined; // See comment below
    1724             :   // } catch (.catch) {
    1725             :   //   %AsyncGeneratorReject(generator, .catch);
    1726             :   // } finally {
    1727             :   //   %_GeneratorClose(generator);
    1728             :   // }
    1729             :   //
    1730             :   // - InitialYield yields the actual generator object.
    1731             :   // - Any return statement inside the body will have its argument wrapped
    1732             :   //   in an iterator result object with a "done" property set to `true`.
    1733             :   // - If the generator terminates for whatever reason, we must close it.
    1734             :   //   Hence the finally clause.
    1735             :   // - BytecodeGenerator performs special handling for ReturnStatements in
    1736             :   //   async generator functions, resolving the appropriate Promise with an
    1737             :   //   "done" iterator result object containing a Promise-unwrapped value.
    1738             :   DCHECK(IsAsyncGeneratorFunction(kind));
    1739             : 
    1740      146269 :   Block* try_block = factory()->NewBlock(3, false);
    1741       18599 :   Expression* initial_yield = BuildInitialYield(pos, kind);
    1742             :   try_block->statements()->Add(
    1743       18599 :       factory()->NewExpressionStatement(initial_yield, kNoSourcePosition),
    1744       18599 :       zone());
    1745       18599 :   ParseStatementList(try_block->statements(), Token::RBRACE, ok);
    1746       25079 :   if (!*ok) return;
    1747             : 
    1748             :   // Don't create iterator result for async generators, as the resume methods
    1749             :   // will create it.
    1750             :   Statement* final_return = BuildReturnStatement(
    1751       12119 :       factory()->NewUndefinedLiteral(kNoSourcePosition), kNoSourcePosition);
    1752       12119 :   try_block->statements()->Add(final_return, zone());
    1753             : 
    1754             :   // For AsyncGenerators, a top-level catch block will reject the Promise.
    1755             :   Scope* catch_scope = NewHiddenCatchScope();
    1756             : 
    1757             :   ZoneList<Expression*>* reject_args =
    1758       12119 :       new (zone()) ZoneList<Expression*>(2, zone());
    1759             :   reject_args->Add(factory()->NewVariableProxy(
    1760       36357 :                        function_state_->scope()->generator_object_var()),
    1761       12119 :                    zone());
    1762       12119 :   reject_args->Add(factory()->NewVariableProxy(catch_scope->catch_variable()),
    1763       12119 :                    zone());
    1764             : 
    1765             :   Expression* reject_call = factory()->NewCallRuntime(
    1766       12119 :       Runtime::kInlineAsyncGeneratorReject, reject_args, kNoSourcePosition);
    1767             :   Block* catch_block = IgnoreCompletion(
    1768       12119 :       factory()->NewReturnStatement(reject_call, kNoSourcePosition));
    1769             : 
    1770             :   TryStatement* try_catch = factory()->NewTryCatchStatementForAsyncAwait(
    1771       12119 :       try_block, catch_scope, catch_block, kNoSourcePosition);
    1772             : 
    1773       12119 :   try_block = factory()->NewBlock(1, false);
    1774       12119 :   try_block->statements()->Add(try_catch, zone());
    1775             : 
    1776       12119 :   Block* finally_block = factory()->NewBlock(1, false);
    1777             :   ZoneList<Expression*>* close_args =
    1778       12119 :       new (zone()) ZoneList<Expression*>(1, zone());
    1779             :   VariableProxy* call_proxy = factory()->NewVariableProxy(
    1780       24238 :       function_state_->scope()->generator_object_var());
    1781       12119 :   close_args->Add(call_proxy, zone());
    1782             :   Expression* close_call = factory()->NewCallRuntime(
    1783       12119 :       Runtime::kInlineGeneratorClose, close_args, kNoSourcePosition);
    1784             :   finally_block->statements()->Add(
    1785       24238 :       factory()->NewExpressionStatement(close_call, kNoSourcePosition), zone());
    1786             : 
    1787             :   body->Add(factory()->NewTryFinallyStatement(try_block, finally_block,
    1788       12119 :                                               kNoSourcePosition),
    1789       12119 :             zone());
    1790             : }
    1791             : 
    1792     3170734 : void Parser::CreateFunctionNameAssignment(
    1793             :     const AstRawString* function_name, int pos,
    1794             :     FunctionLiteral::FunctionType function_type,
    1795      132133 :     DeclarationScope* function_scope, ZoneList<Statement*>* result, int index) {
    1796     3170734 :   if (function_type == FunctionLiteral::kNamedExpression) {
    1797      132132 :     StatementT statement = factory()->NewEmptyStatement(kNoSourcePosition);
    1798      132133 :     if (function_scope->LookupLocal(function_name) == nullptr) {
    1799             :       // Now that we know the language mode, we can create the const assignment
    1800             :       // in the previously reserved spot.
    1801             :       DCHECK_EQ(function_scope, scope());
    1802      132045 :       Variable* fvar = function_scope->DeclareFunctionVar(function_name);
    1803      132045 :       VariableProxy* fproxy = factory()->NewVariableProxy(fvar);
    1804             :       statement = factory()->NewExpressionStatement(
    1805             :           factory()->NewAssignment(Token::INIT, fproxy,
    1806      132044 :                                    factory()->NewThisFunction(pos),
    1807      132044 :                                    kNoSourcePosition),
    1808      132044 :           kNoSourcePosition);
    1809             :     }
    1810             :     result->Set(index, statement);
    1811             :   }
    1812     3170735 : }
    1813             : 
    1814             : // [if (IteratorType == kNormal)]
    1815             : //     !%_IsJSReceiver(result = iterator.next()) &&
    1816             : //         %ThrowIteratorResultNotAnObject(result)
    1817             : // [else if (IteratorType == kAsync)]
    1818             : //     !%_IsJSReceiver(result = Await(iterator.next())) &&
    1819             : //         %ThrowIteratorResultNotAnObject(result)
    1820             : // [endif]
    1821      194967 : Expression* Parser::BuildIteratorNextResult(Expression* iterator,
    1822             :                                             Variable* result, IteratorType type,
    1823             :                                             int pos) {
    1824             :   Expression* next_literal = factory()->NewStringLiteral(
    1825     1364769 :       ast_value_factory()->next_string(), kNoSourcePosition);
    1826             :   Expression* next_property =
    1827      194967 :       factory()->NewProperty(iterator, next_literal, kNoSourcePosition);
    1828             :   ZoneList<Expression*>* next_arguments =
    1829      194967 :       new (zone()) ZoneList<Expression*>(0, zone());
    1830             :   Expression* next_call =
    1831      194967 :       factory()->NewCall(next_property, next_arguments, kNoSourcePosition);
    1832      194967 :   if (type == IteratorType::kAsync) {
    1833       20865 :     next_call = factory()->NewAwait(next_call, pos);
    1834             :   }
    1835      194967 :   Expression* result_proxy = factory()->NewVariableProxy(result);
    1836             :   Expression* left =
    1837      194967 :       factory()->NewAssignment(Token::ASSIGN, result_proxy, next_call, pos);
    1838             : 
    1839             :   // %_IsJSReceiver(...)
    1840             :   ZoneList<Expression*>* is_spec_object_args =
    1841      194967 :       new (zone()) ZoneList<Expression*>(1, zone());
    1842      194967 :   is_spec_object_args->Add(left, zone());
    1843             :   Expression* is_spec_object_call = factory()->NewCallRuntime(
    1844      194967 :       Runtime::kInlineIsJSReceiver, is_spec_object_args, pos);
    1845             : 
    1846             :   // %ThrowIteratorResultNotAnObject(result)
    1847      389934 :   Expression* result_proxy_again = factory()->NewVariableProxy(result);
    1848             :   ZoneList<Expression*>* throw_arguments =
    1849      194967 :       new (zone()) ZoneList<Expression*>(1, zone());
    1850      194967 :   throw_arguments->Add(result_proxy_again, zone());
    1851             :   Expression* throw_call = factory()->NewCallRuntime(
    1852      194967 :       Runtime::kThrowIteratorResultNotAnObject, throw_arguments, pos);
    1853             : 
    1854             :   return factory()->NewBinaryOperation(
    1855             :       Token::AND,
    1856      194967 :       factory()->NewUnaryOperation(Token::NOT, is_spec_object_call, pos),
    1857      389934 :       throw_call, pos);
    1858             : }
    1859             : 
    1860      127315 : Statement* Parser::InitializeForEachStatement(ForEachStatement* stmt,
    1861             :                                               Expression* each,
    1862             :                                               Expression* subject,
    1863             :                                               Statement* body) {
    1864      127315 :   ForOfStatement* for_of = stmt->AsForOfStatement();
    1865      127315 :   if (for_of != nullptr) {
    1866             :     const bool finalize = true;
    1867             :     return InitializeForOfStatement(for_of, each, subject, body, finalize,
    1868       79573 :                                     IteratorType::kNormal, each->position());
    1869             :   } else {
    1870       93004 :     if (each->IsArrayLiteral() || each->IsObjectLiteral()) {
    1871       16875 :       Variable* temp = NewTemporary(ast_value_factory()->empty_string());
    1872        5625 :       VariableProxy* temp_proxy = factory()->NewVariableProxy(temp);
    1873             :       Expression* assign_each =
    1874             :           RewriteDestructuringAssignment(factory()->NewAssignment(
    1875        5625 :               Token::ASSIGN, each, temp_proxy, kNoSourcePosition));
    1876        5625 :       auto block = factory()->NewBlock(2, false);
    1877             :       block->statements()->Add(
    1878        5625 :           factory()->NewExpressionStatement(assign_each, kNoSourcePosition),
    1879        5625 :           zone());
    1880        5625 :       block->statements()->Add(body, zone());
    1881        5625 :       body = block;
    1882        5625 :       each = factory()->NewVariableProxy(temp);
    1883             :     }
    1884             :     MarkExpressionAsAssigned(each);
    1885       47742 :     stmt->AsForInStatement()->Initialize(each, subject, body);
    1886             :   }
    1887       47742 :   return stmt;
    1888             : }
    1889             : 
    1890             : // Special case for legacy for
    1891             : //
    1892             : //    for (var x = initializer in enumerable) body
    1893             : //
    1894             : // An initialization block of the form
    1895             : //
    1896             : //    {
    1897             : //      x = initializer;
    1898             : //    }
    1899             : //
    1900             : // is returned in this case.  It has reserved space for two statements,
    1901             : // so that (later on during parsing), the equivalent of
    1902             : //
    1903             : //   for (x in enumerable) body
    1904             : //
    1905             : // is added as a second statement to it.
    1906       80308 : Block* Parser::RewriteForVarInLegacy(const ForInfo& for_info) {
    1907             :   const DeclarationParsingResult::Declaration& decl =
    1908       80308 :       for_info.parsing_result.declarations[0];
    1909      191863 :   if (!IsLexicalVariableMode(for_info.parsing_result.descriptor.mode) &&
    1910      110078 :       decl.pattern->IsVariableProxy() && decl.initializer != nullptr) {
    1911         212 :     ++use_counts_[v8::Isolate::kForInInitializer];
    1912         212 :     const AstRawString* name = decl.pattern->AsVariableProxy()->raw_name();
    1913         212 :     VariableProxy* single_var = NewUnresolved(name);
    1914         212 :     Block* init_block = factory()->NewBlock(2, true);
    1915             :     init_block->statements()->Add(
    1916             :         factory()->NewExpressionStatement(
    1917             :             factory()->NewAssignment(Token::ASSIGN, single_var,
    1918         212 :                                      decl.initializer, kNoSourcePosition),
    1919         212 :             kNoSourcePosition),
    1920         212 :         zone());
    1921         212 :     return init_block;
    1922             :   }
    1923             :   return nullptr;
    1924             : }
    1925             : 
    1926             : // Rewrite a for-in/of statement of the form
    1927             : //
    1928             : //   for (let/const/var x in/of e) b
    1929             : //
    1930             : // into
    1931             : //
    1932             : //   {
    1933             : //     var temp;
    1934             : //     for (temp in/of e) {
    1935             : //       let/const/var x = temp;
    1936             : //       b;
    1937             : //     }
    1938             : //     let x;  // for TDZ
    1939             : //   }
    1940       93749 : void Parser::DesugarBindingInForEachStatement(ForInfo* for_info,
    1941             :                                               Block** body_block,
    1942             :                                               Expression** each_variable,
    1943             :                                               bool* ok) {
    1944             :   DCHECK_EQ(1, for_info->parsing_result.declarations.size());
    1945             :   DeclarationParsingResult::Declaration& decl =
    1946       93749 :       for_info->parsing_result.declarations[0];
    1947      297553 :   Variable* temp = NewTemporary(ast_value_factory()->dot_for_string());
    1948       93749 :   auto each_initialization_block = factory()->NewBlock(1, true);
    1949             :   {
    1950       93749 :     auto descriptor = for_info->parsing_result.descriptor;
    1951       93749 :     descriptor.declaration_pos = kNoSourcePosition;
    1952       93749 :     descriptor.initialization_pos = kNoSourcePosition;
    1953       93749 :     descriptor.scope = scope();
    1954      187498 :     decl.initializer = factory()->NewVariableProxy(temp);
    1955             : 
    1956             :     bool is_for_var_of =
    1957      164068 :         for_info->mode == ForEachStatement::ITERATE &&
    1958       70319 :         for_info->parsing_result.descriptor.mode == VariableMode::VAR;
    1959             :     bool collect_names =
    1960       93749 :         IsLexicalVariableMode(for_info->parsing_result.descriptor.mode) ||
    1961             :         is_for_var_of;
    1962             : 
    1963             :     DeclareAndInitializeVariables(
    1964             :         each_initialization_block, &descriptor, &decl,
    1965       93866 :         collect_names ? &for_info->bound_names : nullptr, CHECK_OK_VOID);
    1966             : 
    1967             :     // Annex B.3.5 prohibits the form
    1968             :     // `try {} catch(e) { for (var e of {}); }`
    1969             :     // So if we are parsing a statement like `for (var ... of ...)`
    1970             :     // we need to walk up the scope chain and look for catch scopes
    1971             :     // which have a simple binding, then compare their binding against
    1972             :     // all of the names declared in the init of the for-of we're
    1973             :     // parsing.
    1974       93749 :     if (is_for_var_of) {
    1975       19945 :       Scope* catch_scope = scope();
    1976       67801 :       while (catch_scope != nullptr && !catch_scope->is_declaration_scope()) {
    1977       10031 :         if (catch_scope->is_catch_scope()) {
    1978         432 :           auto name = catch_scope->catch_variable()->raw_name();
    1979             :           // If it's a simple binding and the name is declared in the for loop.
    1980        1089 :           if (name != ast_value_factory()->dot_catch_string() &&
    1981         225 :               for_info->bound_names.Contains(name)) {
    1982             :             ReportMessageAt(for_info->parsing_result.bindings_loc,
    1983             :                             MessageTemplate::kVarRedeclaration, name);
    1984         117 :             *ok = false;
    1985             :             return;
    1986             :           }
    1987             :         }
    1988             :         catch_scope = catch_scope->outer_scope();
    1989             :       }
    1990             :     }
    1991             :   }
    1992             : 
    1993       93632 :   *body_block = factory()->NewBlock(3, false);
    1994       93632 :   (*body_block)->statements()->Add(each_initialization_block, zone());
    1995      187264 :   *each_variable = factory()->NewVariableProxy(temp, for_info->position);
    1996             : }
    1997             : 
    1998             : // Create a TDZ for any lexically-bound names in for in/of statements.
    1999       93632 : Block* Parser::CreateForEachStatementTDZ(Block* init_block,
    2000             :                                          const ForInfo& for_info, bool* ok) {
    2001       93632 :   if (IsLexicalVariableMode(for_info.parsing_result.descriptor.mode)) {
    2002             :     DCHECK_NULL(init_block);
    2003             : 
    2004      128071 :     init_block = factory()->NewBlock(1, false);
    2005             : 
    2006      256142 :     for (int i = 0; i < for_info.bound_names.length(); ++i) {
    2007             :       // TODO(adamk): This needs to be some sort of special
    2008             :       // INTERNAL variable that's invisible to the debugger
    2009             :       // but visible to everything else.
    2010      263071 :       Declaration* tdz_decl = DeclareVariable(for_info.bound_names[i], LET,
    2011      135000 :                                               kNoSourcePosition, CHECK_OK);
    2012       67500 :       tdz_decl->proxy()->var()->set_initializer_position(position());
    2013             :     }
    2014             :   }
    2015       93632 :   return init_block;
    2016             : }
    2017             : 
    2018      103232 : Statement* Parser::InitializeForOfStatement(
    2019             :     ForOfStatement* for_of, Expression* each, Expression* iterable,
    2020             :     Statement* body, bool finalize, IteratorType type, int next_result_pos) {
    2021             :   // Create the auxiliary expressions needed for iterating over the iterable,
    2022             :   // and initialize the given ForOfStatement with them.
    2023             :   // If finalize is true, also instrument the loop with code that performs the
    2024             :   // proper ES6 iterator finalization.  In that case, the result is not
    2025             :   // immediately a ForOfStatement.
    2026             :   const int nopos = kNoSourcePosition;
    2027      817474 :   auto avfactory = ast_value_factory();
    2028             : 
    2029             :   Variable* iterator = NewTemporary(avfactory->dot_iterator_string());
    2030             :   Variable* result = NewTemporary(avfactory->dot_result_string());
    2031             :   Variable* completion = NewTemporary(avfactory->empty_string());
    2032             : 
    2033             :   // iterator = GetIterator(iterable, type)
    2034             :   Expression* assign_iterator;
    2035             :   {
    2036             :     assign_iterator = factory()->NewAssignment(
    2037      103232 :         Token::ASSIGN, factory()->NewVariableProxy(iterator),
    2038      103232 :         factory()->NewGetIterator(iterable, type, iterable->position()),
    2039      206464 :         iterable->position());
    2040             :   }
    2041             : 
    2042             :   // [if (IteratorType == kNormal)]
    2043             :   //     !%_IsJSReceiver(result = iterator.next()) &&
    2044             :   //         %ThrowIteratorResultNotAnObject(result)
    2045             :   // [else if (IteratorType == kAsync)]
    2046             :   //     !%_IsJSReceiver(result = Await(iterator.next())) &&
    2047             :   //         %ThrowIteratorResultNotAnObject(result)
    2048             :   // [endif]
    2049             :   Expression* next_result;
    2050             :   {
    2051      103232 :     Expression* iterator_proxy = factory()->NewVariableProxy(iterator);
    2052             :     next_result =
    2053      103232 :         BuildIteratorNextResult(iterator_proxy, result, type, next_result_pos);
    2054             :   }
    2055             : 
    2056             :   // result.done
    2057             :   Expression* result_done;
    2058             :   {
    2059             :     Expression* done_literal = factory()->NewStringLiteral(
    2060      206464 :         ast_value_factory()->done_string(), kNoSourcePosition);
    2061      103232 :     Expression* result_proxy = factory()->NewVariableProxy(result);
    2062             :     result_done =
    2063      103232 :         factory()->NewProperty(result_proxy, done_literal, kNoSourcePosition);
    2064             :   }
    2065             : 
    2066             :   // result.value
    2067             :   Expression* result_value;
    2068             :   {
    2069             :     Expression* value_literal =
    2070      103232 :         factory()->NewStringLiteral(avfactory->value_string(), nopos);
    2071      103232 :     Expression* result_proxy = factory()->NewVariableProxy(result);
    2072      103232 :     result_value = factory()->NewProperty(result_proxy, value_literal, nopos);
    2073             :   }
    2074             : 
    2075             :   // {{tmp = #result_value, completion = kAbruptCompletion, tmp}}
    2076             :   // Expression* result_value (gets overwritten)
    2077      103232 :   if (finalize) {
    2078             :     Variable* tmp = NewTemporary(avfactory->empty_string());
    2079             :     Expression* save_result = factory()->NewAssignment(
    2080      200876 :         Token::ASSIGN, factory()->NewVariableProxy(tmp), result_value, nopos);
    2081             : 
    2082             :     Expression* set_completion_abrupt = factory()->NewAssignment(
    2083      100438 :         Token::ASSIGN, factory()->NewVariableProxy(completion),
    2084      200876 :         factory()->NewSmiLiteral(Parser::kAbruptCompletion, nopos), nopos);
    2085             : 
    2086             :     result_value = factory()->NewBinaryOperation(Token::COMMA, save_result,
    2087      100438 :                                                  set_completion_abrupt, nopos);
    2088             :     result_value = factory()->NewBinaryOperation(
    2089      200876 :         Token::COMMA, result_value, factory()->NewVariableProxy(tmp), nopos);
    2090             :   }
    2091             : 
    2092             :   // each = #result_value;
    2093             :   Expression* assign_each;
    2094             :   {
    2095             :     assign_each =
    2096      103232 :         factory()->NewAssignment(Token::ASSIGN, each, result_value, nopos);
    2097      202716 :     if (each->IsArrayLiteral() || each->IsObjectLiteral()) {
    2098       22498 :       assign_each = RewriteDestructuringAssignment(assign_each->AsAssignment());
    2099             :     }
    2100             :   }
    2101             : 
    2102             :   // {{completion = kNormalCompletion;}}
    2103             :   Statement* set_completion_normal;
    2104      103232 :   if (finalize) {
    2105      100438 :     Expression* proxy = factory()->NewVariableProxy(completion);
    2106             :     Expression* assignment = factory()->NewAssignment(
    2107             :         Token::ASSIGN, proxy,
    2108      100438 :         factory()->NewSmiLiteral(Parser::kNormalCompletion, nopos), nopos);
    2109             : 
    2110             :     set_completion_normal =
    2111      200876 :         IgnoreCompletion(factory()->NewExpressionStatement(assignment, nopos));
    2112             :   }
    2113             : 
    2114             :   // { #loop-body; #set_completion_normal }
    2115             :   // Statement* body (gets overwritten)
    2116      103232 :   if (finalize) {
    2117      100438 :     Block* block = factory()->NewBlock(2, false);
    2118      100438 :     block->statements()->Add(body, zone());
    2119      100438 :     block->statements()->Add(set_completion_normal, zone());
    2120      100438 :     body = block;
    2121             :   }
    2122             : 
    2123             :   for_of->Initialize(body, iterator, assign_iterator, next_result, result_done,
    2124      103232 :                      assign_each);
    2125             :   return finalize ? FinalizeForOfStatement(for_of, completion, type, nopos)
    2126      103232 :                   : for_of;
    2127             : }
    2128             : 
    2129       17391 : Statement* Parser::DesugarLexicalBindingsInForStatement(
    2130             :     ForStatement* loop, Statement* init, Expression* cond, Statement* next,
    2131             :     Statement* body, Scope* inner_scope, const ForInfo& for_info, bool* ok) {
    2132             :   // ES6 13.7.4.8 specifies that on each loop iteration the let variables are
    2133             :   // copied into a new environment.  Moreover, the "next" statement must be
    2134             :   // evaluated not in the environment of the just completed iteration but in
    2135             :   // that of the upcoming one.  We achieve this with the following desugaring.
    2136             :   // Extra care is needed to preserve the completion value of the original loop.
    2137             :   //
    2138             :   // We are given a for statement of the form
    2139             :   //
    2140             :   //  labels: for (let/const x = i; cond; next) body
    2141             :   //
    2142             :   // and rewrite it as follows.  Here we write {{ ... }} for init-blocks, ie.,
    2143             :   // blocks whose ignore_completion_value_ flag is set.
    2144             :   //
    2145             :   //  {
    2146             :   //    let/const x = i;
    2147             :   //    temp_x = x;
    2148             :   //    first = 1;
    2149             :   //    undefined;
    2150             :   //    outer: for (;;) {
    2151             :   //      let/const x = temp_x;
    2152             :   //      {{ if (first == 1) {
    2153             :   //           first = 0;
    2154             :   //         } else {
    2155             :   //           next;
    2156             :   //         }
    2157             :   //         flag = 1;
    2158             :   //         if (!cond) break;
    2159             :   //      }}
    2160             :   //      labels: for (; flag == 1; flag = 0, temp_x = x) {
    2161             :   //        body
    2162             :   //      }
    2163             :   //      {{ if (flag == 1)  // Body used break.
    2164             :   //           break;
    2165             :   //      }}
    2166             :   //    }
    2167             :   //  }
    2168             : 
    2169             :   DCHECK_GT(for_info.bound_names.length(), 0);
    2170      505515 :   ZoneList<Variable*> temps(for_info.bound_names.length(), zone());
    2171             : 
    2172             :   Block* outer_block =
    2173       17391 :       factory()->NewBlock(for_info.bound_names.length() + 4, false);
    2174             : 
    2175             :   // Add statement: let/const x = i.
    2176       17391 :   outer_block->statements()->Add(init, zone());
    2177             : 
    2178       17391 :   const AstRawString* temp_name = ast_value_factory()->dot_for_string();
    2179             : 
    2180             :   // For each lexical variable x:
    2181             :   //   make statement: temp_x = x.
    2182       81616 :   for (int i = 0; i < for_info.bound_names.length(); i++) {
    2183       23417 :     VariableProxy* proxy = NewUnresolved(for_info.bound_names[i]);
    2184       23417 :     Variable* temp = NewTemporary(temp_name);
    2185       23417 :     VariableProxy* temp_proxy = factory()->NewVariableProxy(temp);
    2186             :     Assignment* assignment = factory()->NewAssignment(Token::ASSIGN, temp_proxy,
    2187       23417 :                                                       proxy, kNoSourcePosition);
    2188             :     Statement* assignment_statement =
    2189       46834 :         factory()->NewExpressionStatement(assignment, kNoSourcePosition);
    2190       23417 :     outer_block->statements()->Add(assignment_statement, zone());
    2191       23417 :     temps.Add(temp, zone());
    2192             :   }
    2193             : 
    2194             :   Variable* first = nullptr;
    2195             :   // Make statement: first = 1.
    2196       17391 :   if (next) {
    2197             :     first = NewTemporary(temp_name);
    2198        2440 :     VariableProxy* first_proxy = factory()->NewVariableProxy(first);
    2199        2440 :     Expression* const1 = factory()->NewSmiLiteral(1, kNoSourcePosition);
    2200             :     Assignment* assignment = factory()->NewAssignment(
    2201        2440 :         Token::ASSIGN, first_proxy, const1, kNoSourcePosition);
    2202             :     Statement* assignment_statement =
    2203        4880 :         factory()->NewExpressionStatement(assignment, kNoSourcePosition);
    2204        2440 :     outer_block->statements()->Add(assignment_statement, zone());
    2205             :   }
    2206             : 
    2207             :   // make statement: undefined;
    2208             :   outer_block->statements()->Add(
    2209             :       factory()->NewExpressionStatement(
    2210       17391 :           factory()->NewUndefinedLiteral(kNoSourcePosition), kNoSourcePosition),
    2211       17391 :       zone());
    2212             : 
    2213             :   // Make statement: outer: for (;;)
    2214             :   // Note that we don't actually create the label, or set this loop up as an
    2215             :   // explicit break target, instead handing it directly to those nodes that
    2216             :   // need to know about it. This should be safe because we don't run any code
    2217             :   // in this function that looks up break targets.
    2218             :   ForStatement* outer_loop =
    2219       17391 :       factory()->NewForStatement(nullptr, kNoSourcePosition);
    2220       17391 :   outer_block->statements()->Add(outer_loop, zone());
    2221             :   outer_block->set_scope(scope());
    2222             : 
    2223       17391 :   Block* inner_block = factory()->NewBlock(3, false);
    2224             :   {
    2225       17391 :     BlockState block_state(&scope_, inner_scope);
    2226             : 
    2227             :     Block* ignore_completion_block =
    2228       17391 :         factory()->NewBlock(for_info.bound_names.length() + 3, true);
    2229       17391 :     ZoneList<Variable*> inner_vars(for_info.bound_names.length(), zone());
    2230             :     // For each let variable x:
    2231             :     //    make statement: let/const x = temp_x.
    2232       81616 :     for (int i = 0; i < for_info.bound_names.length(); i++) {
    2233       70251 :       Declaration* decl = DeclareVariable(
    2234             :           for_info.bound_names[i], for_info.parsing_result.descriptor.mode,
    2235       70251 :           kNoSourcePosition, CHECK_OK);
    2236       23417 :       inner_vars.Add(decl->proxy()->var(), zone());
    2237       23417 :       VariableProxy* temp_proxy = factory()->NewVariableProxy(temps.at(i));
    2238             :       Assignment* assignment = factory()->NewAssignment(
    2239       23417 :           Token::INIT, decl->proxy(), temp_proxy, kNoSourcePosition);
    2240             :       Statement* assignment_statement =
    2241       46834 :           factory()->NewExpressionStatement(assignment, kNoSourcePosition);
    2242       23417 :       int declaration_pos = for_info.parsing_result.descriptor.declaration_pos;
    2243             :       DCHECK_NE(declaration_pos, kNoSourcePosition);
    2244       23417 :       decl->proxy()->var()->set_initializer_position(declaration_pos);
    2245       23417 :       ignore_completion_block->statements()->Add(assignment_statement, zone());
    2246             :     }
    2247             : 
    2248             :     // Make statement: if (first == 1) { first = 0; } else { next; }
    2249       17391 :     if (next) {
    2250             :       DCHECK(first);
    2251             :       Expression* compare = nullptr;
    2252             :       // Make compare expression: first == 1.
    2253             :       {
    2254        2440 :         Expression* const1 = factory()->NewSmiLiteral(1, kNoSourcePosition);
    2255        2440 :         VariableProxy* first_proxy = factory()->NewVariableProxy(first);
    2256             :         compare = factory()->NewCompareOperation(Token::EQ, first_proxy, const1,
    2257        2440 :                                                  kNoSourcePosition);
    2258             :       }
    2259             :       Statement* clear_first = nullptr;
    2260             :       // Make statement: first = 0.
    2261             :       {
    2262        2440 :         VariableProxy* first_proxy = factory()->NewVariableProxy(first);
    2263        2440 :         Expression* const0 = factory()->NewSmiLiteral(0, kNoSourcePosition);
    2264             :         Assignment* assignment = factory()->NewAssignment(
    2265        2440 :             Token::ASSIGN, first_proxy, const0, kNoSourcePosition);
    2266             :         clear_first =
    2267        2440 :             factory()->NewExpressionStatement(assignment, kNoSourcePosition);
    2268             :       }
    2269             :       Statement* clear_first_or_next = factory()->NewIfStatement(
    2270        4880 :           compare, clear_first, next, kNoSourcePosition);
    2271        2440 :       ignore_completion_block->statements()->Add(clear_first_or_next, zone());
    2272             :     }
    2273             : 
    2274             :     Variable* flag = NewTemporary(temp_name);
    2275             :     // Make statement: flag = 1.
    2276             :     {
    2277       17391 :       VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
    2278       17391 :       Expression* const1 = factory()->NewSmiLiteral(1, kNoSourcePosition);
    2279             :       Assignment* assignment = factory()->NewAssignment(
    2280       17391 :           Token::ASSIGN, flag_proxy, const1, kNoSourcePosition);
    2281             :       Statement* assignment_statement =
    2282       34782 :           factory()->NewExpressionStatement(assignment, kNoSourcePosition);
    2283       17391 :       ignore_completion_block->statements()->Add(assignment_statement, zone());
    2284             :     }
    2285             : 
    2286             :     // Make statement: if (!cond) break.
    2287       17391 :     if (cond) {
    2288             :       Statement* stop =
    2289       11626 :           factory()->NewBreakStatement(outer_loop, kNoSourcePosition);
    2290       11626 :       Statement* noop = factory()->NewEmptyStatement(kNoSourcePosition);
    2291             :       ignore_completion_block->statements()->Add(
    2292       11626 :           factory()->NewIfStatement(cond, noop, stop, cond->position()),
    2293       11626 :           zone());
    2294             :     }
    2295             : 
    2296       17391 :     inner_block->statements()->Add(ignore_completion_block, zone());
    2297             :     // Make cond expression for main loop: flag == 1.
    2298             :     Expression* flag_cond = nullptr;
    2299             :     {
    2300       17391 :       Expression* const1 = factory()->NewSmiLiteral(1, kNoSourcePosition);
    2301       17391 :       VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
    2302             :       flag_cond = factory()->NewCompareOperation(Token::EQ, flag_proxy, const1,
    2303       17391 :                                                  kNoSourcePosition);
    2304             :     }
    2305             : 
    2306             :     // Create chain of expressions "flag = 0, temp_x = x, ..."
    2307             :     Statement* compound_next_statement = nullptr;
    2308             :     {
    2309             :       Expression* compound_next = nullptr;
    2310             :       // Make expression: flag = 0.
    2311             :       {
    2312       17391 :         VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
    2313       17391 :         Expression* const0 = factory()->NewSmiLiteral(0, kNoSourcePosition);
    2314             :         compound_next = factory()->NewAssignment(Token::ASSIGN, flag_proxy,
    2315       17391 :                                                  const0, kNoSourcePosition);
    2316             :       }
    2317             : 
    2318             :       // Make the comma-separated list of temp_x = x assignments.
    2319             :       int inner_var_proxy_pos = scanner()->location().beg_pos;
    2320       81616 :       for (int i = 0; i < for_info.bound_names.length(); i++) {
    2321       23417 :         VariableProxy* temp_proxy = factory()->NewVariableProxy(temps.at(i));
    2322             :         VariableProxy* proxy =
    2323       23417 :             factory()->NewVariableProxy(inner_vars.at(i), inner_var_proxy_pos);
    2324             :         Assignment* assignment = factory()->NewAssignment(
    2325       23417 :             Token::ASSIGN, temp_proxy, proxy, kNoSourcePosition);
    2326             :         compound_next = factory()->NewBinaryOperation(
    2327       23417 :             Token::COMMA, compound_next, assignment, kNoSourcePosition);
    2328             :       }
    2329             : 
    2330             :       compound_next_statement =
    2331       17391 :           factory()->NewExpressionStatement(compound_next, kNoSourcePosition);
    2332             :     }
    2333             : 
    2334             :     // Make statement: labels: for (; flag == 1; flag = 0, temp_x = x)
    2335             :     // Note that we re-use the original loop node, which retains its labels
    2336             :     // and ensures that any break or continue statements in body point to
    2337             :     // the right place.
    2338             :     loop->Initialize(nullptr, flag_cond, compound_next_statement, body);
    2339       17391 :     inner_block->statements()->Add(loop, zone());
    2340             : 
    2341             :     // Make statement: {{if (flag == 1) break;}}
    2342             :     {
    2343             :       Expression* compare = nullptr;
    2344             :       // Make compare expresion: flag == 1.
    2345             :       {
    2346       17391 :         Expression* const1 = factory()->NewSmiLiteral(1, kNoSourcePosition);
    2347       17391 :         VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
    2348             :         compare = factory()->NewCompareOperation(Token::EQ, flag_proxy, const1,
    2349       17391 :                                                  kNoSourcePosition);
    2350             :       }
    2351             :       Statement* stop =
    2352       17391 :           factory()->NewBreakStatement(outer_loop, kNoSourcePosition);
    2353       17391 :       Statement* empty = factory()->NewEmptyStatement(kNoSourcePosition);
    2354             :       Statement* if_flag_break =
    2355       17391 :           factory()->NewIfStatement(compare, stop, empty, kNoSourcePosition);
    2356       17391 :       inner_block->statements()->Add(IgnoreCompletion(if_flag_break), zone());
    2357             :     }
    2358             : 
    2359             :     inner_block->set_scope(inner_scope);
    2360             :   }
    2361             : 
    2362             :   outer_loop->Initialize(nullptr, nullptr, nullptr, inner_block);
    2363             : 
    2364       17391 :   return outer_block;
    2365             : }
    2366             : 
    2367      222641 : void Parser::AddArrowFunctionFormalParameters(
    2368             :     ParserFormalParameters* parameters, Expression* expr, int end_pos,
    2369             :     bool* ok) {
    2370             :   // ArrowFunctionFormals ::
    2371             :   //    Binary(Token::COMMA, NonTailArrowFunctionFormals, Tail)
    2372             :   //    Tail
    2373             :   // NonTailArrowFunctionFormals ::
    2374             :   //    Binary(Token::COMMA, NonTailArrowFunctionFormals, VariableProxy)
    2375             :   //    VariableProxy
    2376             :   // Tail ::
    2377             :   //    VariableProxy
    2378             :   //    Spread(VariableProxy)
    2379             :   //
    2380             :   // As we need to visit the parameters in left-to-right order, we recurse on
    2381             :   // the left-hand side of comma expressions.
    2382             :   //
    2383      222641 :   if (expr->IsBinaryOperation()) {
    2384       54386 :     BinaryOperation* binop = expr->AsBinaryOperation();
    2385             :     // The classifier has already run, so we know that the expression is a valid
    2386             :     // arrow function formals production.
    2387             :     DCHECK_EQ(binop->op(), Token::COMMA);
    2388             :     Expression* left = binop->left();
    2389             :     Expression* right = binop->right();
    2390       27193 :     int comma_pos = binop->position();
    2391             :     AddArrowFunctionFormalParameters(parameters, left, comma_pos,
    2392      249834 :                                      CHECK_OK_VOID);
    2393             :     // LHS of comma expression should be unparenthesized.
    2394             :     expr = right;
    2395             :   }
    2396             : 
    2397             :   // Only the right-most expression may be a rest parameter.
    2398             :   DCHECK(!parameters->has_rest);
    2399             : 
    2400             :   bool is_rest = expr->IsSpread();
    2401      222401 :   if (is_rest) {
    2402        4370 :     expr = expr->AsSpread()->expression();
    2403        2185 :     parameters->has_rest = true;
    2404             :   }
    2405             :   DCHECK_IMPLIES(parameters->is_simple, !is_rest);
    2406             :   DCHECK_IMPLIES(parameters->is_simple, expr->IsVariableProxy());
    2407             : 
    2408             :   Expression* initializer = nullptr;
    2409      222401 :   if (expr->IsAssignment()) {
    2410        5584 :     if (expr->IsRewritableExpression()) {
    2411             :       // This expression was parsed as a possible destructuring assignment.
    2412             :       // Mark it as already-rewritten to avoid an unnecessary visit later.
    2413        1812 :       expr->AsRewritableExpression()->set_rewritten();
    2414             :     }
    2415       11168 :     Assignment* assignment = expr->AsAssignment();
    2416             :     DCHECK(!assignment->IsCompoundAssignment());
    2417             :     initializer = assignment->value();
    2418             :     expr = assignment->target();
    2419             :   }
    2420             : 
    2421             :   AddFormalParameter(parameters, expr, initializer,
    2422             :                      end_pos, is_rest);
    2423             : }
    2424             : 
    2425      465758 : void Parser::DeclareArrowFunctionFormalParameters(
    2426             :     ParserFormalParameters* parameters, Expression* expr,
    2427             :     const Scanner::Location& params_loc, Scanner::Location* duplicate_loc,
    2428             :     bool* ok) {
    2429      738388 :   if (expr->IsEmptyParentheses()) return;
    2430             : 
    2431             :   AddArrowFunctionFormalParameters(parameters, expr, params_loc.end_pos,
    2432      195448 :                                    CHECK_OK_VOID);
    2433             : 
    2434      193128 :   if (parameters->arity > Code::kMaxArguments) {
    2435             :     ReportMessageAt(params_loc, MessageTemplate::kMalformedArrowFunParamList);
    2436           0 :     *ok = false;
    2437           0 :     return;
    2438             :   }
    2439             : 
    2440      193128 :   bool has_duplicate = false;
    2441             :   DeclareFormalParameters(parameters->scope, parameters->params,
    2442      193128 :                           parameters->is_simple, &has_duplicate);
    2443      193128 :   if (has_duplicate) {
    2444          48 :     *duplicate_loc = scanner()->location();
    2445             :   }
    2446             :   DCHECK_EQ(parameters->is_simple, parameters->scope->has_simple_parameters());
    2447             : }
    2448             : 
    2449      101636 : void Parser::PrepareGeneratorVariables() {
    2450             :   // The code produced for generators relies on forced context allocation of
    2451             :   // parameters (it does not restore the frame's parameters upon resume).
    2452      203272 :   function_state_->scope()->ForceContextAllocationForParameters();
    2453             : 
    2454             :   // Calling a generator returns a generator object.  That object is stored
    2455             :   // in a temporary variable, a definition that is used by "yield"
    2456             :   // expressions.
    2457             :   function_state_->scope()->DeclareGeneratorObjectVar(
    2458      304908 :       ast_value_factory()->dot_generator_object_string());
    2459      101636 : }
    2460             : 
    2461     5234302 : FunctionLiteral* Parser::ParseFunctionLiteral(
    2462             :     const AstRawString* function_name, Scanner::Location function_name_location,
    2463             :     FunctionNameValidity function_name_validity, FunctionKind kind,
    2464             :     int function_token_pos, FunctionLiteral::FunctionType function_type,
    2465     5234304 :     LanguageMode language_mode, bool* ok) {
    2466             :   // Function ::
    2467             :   //   '(' FormalParameterList? ')' '{' FunctionBody '}'
    2468             :   //
    2469             :   // Getter ::
    2470             :   //   '(' ')' '{' FunctionBody '}'
    2471             :   //
    2472             :   // Setter ::
    2473             :   //   '(' PropertySetParameterList ')' '{' FunctionBody '}'
    2474             : 
    2475    20586131 :   int pos = function_token_pos == kNoSourcePosition ? peek_position()
    2476     5234302 :                                                     : function_token_pos;
    2477             : 
    2478             :   // Anonymous functions were passed either the empty symbol or a null
    2479             :   // handle as the function name.  Remember if we were passed a non-empty
    2480             :   // handle to decide whether to invoke function name inference.
    2481     5234302 :   bool should_infer_name = function_name == nullptr;
    2482             : 
    2483             :   // We want a non-null handle as the function name by default. We will handle
    2484             :   // the "function does not have a shared name" case later.
    2485     5234302 :   if (should_infer_name) {
    2486     2224749 :     function_name = ast_value_factory()->empty_string();
    2487             :   }
    2488             : 
    2489             :   FunctionLiteral::EagerCompileHint eager_compile_hint =
    2490     5234302 :       function_state_->next_function_is_likely_called()
    2491             :           ? FunctionLiteral::kShouldEagerCompile
    2492     5234302 :           : default_eager_compile_hint();
    2493             : 
    2494             :   // Determine if the function can be parsed lazily. Lazy parsing is
    2495             :   // different from lazy compilation; we need to parse more eagerly than we
    2496             :   // compile.
    2497             : 
    2498             :   // We can only parse lazily if we also compile lazily. The heuristics for lazy
    2499             :   // compilation are:
    2500             :   // - It must not have been prohibited by the caller to Parse (some callers
    2501             :   //   need a full AST).
    2502             :   // - The outer scope must allow lazy compilation of inner functions.
    2503             :   // - The function mustn't be a function expression with an open parenthesis
    2504             :   //   before; we consider that a hint that the function will be called
    2505             :   //   immediately, and it would be a waste of time to make it lazily
    2506             :   //   compiled.
    2507             :   // These are all things we can know at this point, without looking at the
    2508             :   // function itself.
    2509             : 
    2510             :   // We separate between lazy parsing top level functions and lazy parsing inner
    2511             :   // functions, because the latter needs to do more work. In particular, we need
    2512             :   // to track unresolved variables to distinguish between these cases:
    2513             :   // (function foo() {
    2514             :   //   bar = function() { return 1; }
    2515             :   //  })();
    2516             :   // and
    2517             :   // (function foo() {
    2518             :   //   var a = 1;
    2519             :   //   bar = function() { return a; }
    2520             :   //  })();
    2521             : 
    2522             :   // Now foo will be parsed eagerly and compiled eagerly (optimization: assume
    2523             :   // parenthesis before the function means that it will be called
    2524             :   // immediately). bar can be parsed lazily, but we need to parse it in a mode
    2525             :   // that tracks unresolved variables.
    2526             :   DCHECK_IMPLIES(parse_lazily(), FLAG_lazy);
    2527             :   DCHECK_IMPLIES(parse_lazily(), allow_lazy_);
    2528             :   DCHECK_IMPLIES(parse_lazily(), extension_ == nullptr);
    2529             : 
    2530             :   const bool is_lazy =
    2531     5234302 :       eager_compile_hint == FunctionLiteral::kShouldLazyCompile;
    2532             :   const bool is_top_level =
    2533             :       impl()->AllowsLazyParsingWithoutUnresolvedVariables();
    2534     5234303 :   const bool is_lazy_top_level_function = is_lazy && is_top_level;
    2535     5234303 :   const bool is_lazy_inner_function = is_lazy && !is_top_level;
    2536             :   const bool is_expression =
    2537             :       function_type == FunctionLiteral::kAnonymousExpression ||
    2538             :       function_type == FunctionLiteral::kNamedExpression;
    2539             : 
    2540             :   RuntimeCallTimerScope runtime_timer(
    2541             :       runtime_call_stats_,
    2542             :       parsing_on_main_thread_
    2543             :           ? &RuntimeCallStats::ParseFunctionLiteral
    2544     5234303 :           : &RuntimeCallStats::ParseBackgroundFunctionLiteral);
    2545             : 
    2546             :   // Determine whether we can still lazy parse the inner function.
    2547             :   // The preconditions are:
    2548             :   // - Lazy compilation has to be enabled.
    2549             :   // - Neither V8 natives nor native function declarations can be allowed,
    2550             :   //   since parsing one would retroactively force the function to be
    2551             :   //   eagerly compiled.
    2552             :   // - The invoker of this parser can't depend on the AST being eagerly
    2553             :   //   built (either because the function is about to be compiled, or
    2554             :   //   because the AST is going to be inspected for some reason).
    2555             :   // - Because of the above, we can't be attempting to parse a
    2556             :   //   FunctionExpression; even without enclosing parentheses it might be
    2557             :   //   immediately invoked.
    2558             :   // - The function literal shouldn't be hinted to eagerly compile.
    2559             : 
    2560             :   // Inner functions will be parsed using a temporary Zone. After parsing, we
    2561             :   // will migrate unresolved variable into a Scope in the main Zone.
    2562             : 
    2563             :   const bool should_preparse_inner =
    2564     5234304 :       parse_lazily() && FLAG_lazy_inner_functions && is_lazy_inner_function &&
    2565      827568 :       (!is_expression || FLAG_aggressive_lazy_inner_functions);
    2566             : 
    2567             :   // This may be modified later to reflect preparsing decision taken
    2568             :   bool should_preparse =
    2569     5234304 :       (parse_lazily() && is_lazy_top_level_function) || should_preparse_inner;
    2570             : 
    2571             :   ZoneList<Statement*>* body = nullptr;
    2572     5234304 :   int expected_property_count = -1;
    2573     5234304 :   int num_parameters = -1;
    2574     5234304 :   int function_length = -1;
    2575     5234304 :   bool has_duplicate_parameters = false;
    2576             :   int function_literal_id = GetNextFunctionLiteralId();
    2577     5234304 :   ProducedPreParsedScopeData* produced_preparsed_scope_data = nullptr;
    2578             : 
    2579             :   Zone* outer_zone = zone();
    2580             :   DeclarationScope* scope;
    2581             : 
    2582             :   {
    2583             :     // Temporary zones can nest. When we migrate free variables (see below), we
    2584             :     // need to recreate them in the previous Zone.
    2585             :     AstNodeFactory previous_zone_ast_node_factory(ast_value_factory(), zone());
    2586             : 
    2587             :     // Open a new zone scope, which sets our AstNodeFactory to allocate in the
    2588             :     // new temporary zone if the preconditions are satisfied, and ensures that
    2589             :     // the previous zone is always restored after parsing the body. To be able
    2590             :     // to do scope analysis correctly after full parsing, we migrate needed
    2591             :     // information when the function is parsed.
    2592     5234304 :     Zone temp_zone(zone()->allocator(), ZONE_NAME);
    2593     5234306 :     DiscardableZoneScope zone_scope(this, &temp_zone, should_preparse);
    2594             : 
    2595             :     // This Scope lives in the main zone. We'll migrate data into that zone
    2596             :     // later.
    2597     5234307 :     scope = NewFunctionScope(kind, outer_zone);
    2598     5234307 :     SetLanguageMode(scope, language_mode);
    2599             : #ifdef DEBUG
    2600             :     scope->SetScopeName(function_name);
    2601             :     if (should_preparse) scope->set_needs_migration();
    2602             : #endif
    2603             : 
    2604     5234307 :     Expect(Token::LPAREN, CHECK_OK);
    2605     2671075 :     scope->set_start_position(scanner()->location().beg_pos);
    2606             : 
    2607             :     // Eager or lazy parse? If is_lazy_top_level_function, we'll parse
    2608             :     // lazily. We'll call SkipFunction, which may decide to
    2609             :     // abort lazy parsing if it suspects that wasn't a good idea. If so (in
    2610             :     // which case the parser is expected to have backtracked), or if we didn't
    2611             :     // try to lazy parse in the first place, we'll have to parse eagerly.
    2612     5231682 :     if (should_preparse) {
    2613             :       DCHECK(parse_lazily());
    2614             :       DCHECK(is_lazy_top_level_function || is_lazy_inner_function);
    2615             :       Scanner::BookmarkScope bookmark(scanner());
    2616     2245807 :       bookmark.Set();
    2617             :       LazyParsingResult result = SkipFunction(
    2618             :           function_name, kind, function_type, scope, &num_parameters,
    2619             :           &produced_preparsed_scope_data, is_lazy_inner_function,
    2620     2245807 :           is_lazy_top_level_function, CHECK_OK);
    2621             : 
    2622     2197162 :       if (result == kLazyParsingAborted) {
    2623             :         DCHECK(is_lazy_top_level_function);
    2624          49 :         bookmark.Apply();
    2625             :         // This is probably an initialization function. Inform the compiler it
    2626             :         // should also eager-compile this function.
    2627             :         eager_compile_hint = FunctionLiteral::kShouldEagerCompile;
    2628          49 :         scope->ResetAfterPreparsing(ast_value_factory(), true);
    2629          49 :         zone_scope.Reset();
    2630             :         // Trigger eager (re-)parsing, just below this block.
    2631             :         should_preparse = false;
    2632             :       }
    2633             :     }
    2634             : 
    2635     5183037 :     if (should_preparse) {
    2636     2197113 :       scope->AnalyzePartially(&previous_zone_ast_node_factory);
    2637             :     } else {
    2638             :       body = ParseFunction(function_name, pos, kind, function_type, scope,
    2639             :                            &num_parameters, &function_length,
    2640             :                            &has_duplicate_parameters, &expected_property_count,
    2641     2985924 :                            CHECK_OK);
    2642             :     }
    2643             : 
    2644             :     DCHECK_EQ(should_preparse, temp_zoned_);
    2645     5109814 :     if (V8_UNLIKELY(FLAG_trace_preparse)) {
    2646             :       PrintF("  [%s]: %i-%i %.*s\n",
    2647             :              should_preparse ? (is_top_level ? "Preparse no-resolution"
    2648             :                                              : "Preparse resolution")
    2649             :                              : "Full parse",
    2650             :              scope->start_position(), scope->end_position(),
    2651           0 :              function_name->byte_length(), function_name->raw_data());
    2652             :     }
    2653     5109814 :     if (V8_UNLIKELY(FLAG_runtime_stats)) {
    2654           0 :       if (should_preparse) {
    2655             :         RuntimeCallStats::CounterId counter_id =
    2656             :             parsing_on_main_thread_
    2657             :                 ? &RuntimeCallStats::PreParseWithVariableResolution
    2658           0 :                 : &RuntimeCallStats::PreParseBackgroundWithVariableResolution;
    2659           0 :         if (is_top_level) {
    2660             :           counter_id =
    2661             :               parsing_on_main_thread_
    2662             :                   ? &RuntimeCallStats::PreParseNoVariableResolution
    2663           0 :                   : &RuntimeCallStats::PreParseBackgroundNoVariableResolution;
    2664             :         }
    2665             :         RuntimeCallStats::CorrectCurrentCounterId(runtime_call_stats_,
    2666           0 :                                                   counter_id);
    2667             :       }
    2668             :     }
    2669             : 
    2670             :     // Validate function name. We can do this only after parsing the function,
    2671             :     // since the function can declare itself strict.
    2672             :     language_mode = scope->language_mode();
    2673             :     CheckFunctionName(language_mode, function_name, function_name_validity,
    2674     5109814 :                       function_name_location, CHECK_OK);
    2675             : 
    2676     5108599 :     if (is_strict(language_mode)) {
    2677             :       CheckStrictOctalLiteral(scope->start_position(), scope->end_position(),
    2678     2671075 :                               CHECK_OK);
    2679             :     }
    2680    10208982 :     CheckConflictingVarDeclarations(scope, CHECK_OK);
    2681             :   }  // DiscardableZoneScope goes out of scope.
    2682             : 
    2683             :   FunctionLiteral::ParameterFlag duplicate_parameters =
    2684             :       has_duplicate_parameters ? FunctionLiteral::kHasDuplicateParameters
    2685     5100419 :                                : FunctionLiteral::kNoDuplicateParameters;
    2686             : 
    2687             :   // Note that the FunctionLiteral needs to be created in the main Zone again.
    2688             :   FunctionLiteral* function_literal = factory()->NewFunctionLiteral(
    2689             :       function_name, scope, body, expected_property_count, num_parameters,
    2690             :       function_length, duplicate_parameters, function_type, eager_compile_hint,
    2691     5100419 :       pos, true, function_literal_id, produced_preparsed_scope_data);
    2692             :   function_literal->set_function_token_position(function_token_pos);
    2693             : 
    2694     5100420 :   if (should_infer_name) {
    2695             :     DCHECK_NOT_NULL(fni_);
    2696     2183192 :     fni_->AddFunction(function_literal);
    2697             :   }
    2698     5100421 :   return function_literal;
    2699             : }
    2700             : 
    2701     2269784 : Parser::LazyParsingResult Parser::SkipFunction(
    2702             :     const AstRawString* function_name, FunctionKind kind,
    2703             :     FunctionLiteral::FunctionType function_type,
    2704             :     DeclarationScope* function_scope, int* num_parameters,
    2705             :     ProducedPreParsedScopeData** produced_preparsed_scope_data,
    2706     2879794 :     bool is_inner_function, bool may_abort, bool* ok) {
    2707     2269784 :   FunctionState function_state(&function_state_, &scope_, function_scope);
    2708             : 
    2709             :   DCHECK_NE(kNoSourcePosition, function_scope->start_position());
    2710             :   DCHECK_EQ(kNoSourcePosition, parameters_end_pos_);
    2711     2269784 :   if (produce_cached_parse_data()) CHECK(log_);
    2712             : 
    2713             :   DCHECK_IMPLIES(IsArrowFunction(kind),
    2714             :                  scanner()->current_token() == Token::ARROW);
    2715             : 
    2716             :   // Inner functions are not part of the cached data.
    2717     2269889 :   if (!is_inner_function && consume_cached_parse_data() &&
    2718         110 :       !cached_parse_data_->rejected()) {
    2719             :     // If we have cached data, we use it to skip parsing the function. The data
    2720             :     // contains the information we need to construct the lazy function.
    2721             :     FunctionEntry entry =
    2722     2254511 :         cached_parse_data_->GetFunctionEntry(function_scope->start_position());
    2723             :     // Check that cached data is valid. If not, mark it as invalid (the embedder
    2724             :     // handles it). Note that end position greater than end of stream is safe,
    2725             :     // and hard to check.
    2726         205 :     if (entry.is_valid() &&
    2727             :         entry.end_pos() > function_scope->start_position()) {
    2728       35536 :       total_preparse_skipped_ += entry.end_pos() - position();
    2729             :       function_scope->set_end_position(entry.end_pos());
    2730         200 :       scanner()->SeekForward(entry.end_pos() - 1);
    2731         200 :       Expect(Token::RBRACE, CHECK_OK_VALUE(kLazyParsingComplete));
    2732         100 :       *num_parameters = entry.num_parameters();
    2733         100 :       SetLanguageMode(function_scope, entry.language_mode());
    2734         100 :       if (entry.uses_super_property())
    2735             :         function_scope->RecordSuperPropertyUsage();
    2736             :       SkipFunctionLiterals(entry.num_inner_functions());
    2737         100 :       return kLazyParsingComplete;
    2738             :     }
    2739           5 :     cached_parse_data_->Reject();
    2740             :   }
    2741             : 
    2742             :   // FIXME(marja): There are 3 ways to skip functions now. Unify them.
    2743             :   DCHECK_NOT_NULL(consumed_preparsed_scope_data_);
    2744     4539368 :   if (consumed_preparsed_scope_data_->HasData()) {
    2745             :     DCHECK(FLAG_preparser_scope_analysis);
    2746             :     int end_position;
    2747             :     LanguageMode language_mode;
    2748             :     int num_inner_functions;
    2749             :     bool uses_super_property;
    2750             :     *produced_preparsed_scope_data =
    2751             :         consumed_preparsed_scope_data_->GetDataForSkippableFunction(
    2752             :             main_zone(), function_scope->start_position(), &end_position,
    2753             :             num_parameters, &num_inner_functions, &uses_super_property,
    2754       35336 :             &language_mode);
    2755             : 
    2756             :     function_scope->outer_scope()->SetMustUsePreParsedScopeData();
    2757             :     function_scope->set_is_skipped_function(true);
    2758       35336 :     function_scope->set_end_position(end_position);
    2759       70672 :     scanner()->SeekForward(end_position - 1);
    2760       35336 :     Expect(Token::RBRACE, CHECK_OK_VALUE(kLazyParsingComplete));
    2761       35336 :     SetLanguageMode(function_scope, language_mode);
    2762       35336 :     if (uses_super_property) {
    2763             :       function_scope->RecordSuperPropertyUsage();
    2764             :     }
    2765       35336 :     SkipFunctionLiterals(num_inner_functions);
    2766       35336 :     return kLazyParsingComplete;
    2767             :   }
    2768             : 
    2769             :   // With no cached data, we partially parse the function, without building an
    2770             :   // AST. This gathers the data needed to build a lazy function.
    2771     6703044 :   TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.PreParse");
    2772             : 
    2773             :   // Aborting inner function preparsing would leave scopes in an inconsistent
    2774             :   // state; we don't parse inner functions in the abortable mode anyway.
    2775             :   DCHECK(!is_inner_function || !may_abort);
    2776             : 
    2777             :   PreParser::PreParseResult result = reusable_preparser()->PreParseFunction(
    2778             :       function_name, kind, function_type, function_scope, parsing_module_,
    2779     2234348 :       is_inner_function, may_abort, use_counts_, produced_preparsed_scope_data);
    2780             : 
    2781             :   // Return immediately if pre-parser decided to abort parsing.
    2782     2234348 :   if (result == PreParser::kPreParseAbort) return kLazyParsingAborted;
    2783     2234299 :   if (result == PreParser::kPreParseStackOverflow) {
    2784             :     // Propagate stack overflow.
    2785             :     set_stack_overflow();
    2786          25 :     *ok = false;
    2787          25 :     return kLazyParsingComplete;
    2788             :   }
    2789     2234274 :   if (pending_error_handler_.has_pending_error()) {
    2790       50810 :     *ok = false;
    2791       50810 :     return kLazyParsingComplete;
    2792             :   }
    2793     6550562 :   PreParserLogger* logger = reusable_preparser()->logger();
    2794             :   function_scope->set_end_position(logger->end());
    2795     2183464 :   Expect(Token::RBRACE, CHECK_OK_VALUE(kLazyParsingComplete));
    2796             :   total_preparse_skipped_ +=
    2797     2183464 :       function_scope->end_position() - function_scope->start_position();
    2798     2183464 :   *num_parameters = logger->num_parameters();
    2799             :   SkipFunctionLiterals(logger->num_inner_functions());
    2800     2793474 :   if (!is_inner_function && produce_cached_parse_data()) {
    2801             :     DCHECK(log_);
    2802             :     log_->LogFunction(function_scope->start_position(),
    2803             :                       function_scope->end_position(), *num_parameters,
    2804         170 :                       language_mode(), function_scope->NeedsHomeObject(),
    2805         510 :                       logger->num_inner_functions());
    2806             :   }
    2807             :   return kLazyParsingComplete;
    2808             : }
    2809             : 
    2810      102057 : Statement* Parser::BuildAssertIsCoercible(Variable* var,
    2811      102057 :                                           ObjectLiteral* pattern) {
    2812             :   // if (var === null || var === undefined)
    2813             :   //     throw /* type error kNonCoercible) */;
    2814      102057 :   auto source_position = pattern->position();
    2815      102057 :   const AstRawString* property = ast_value_factory()->empty_string();
    2816             :   MessageTemplate::Template msg = MessageTemplate::kNonCoercible;
    2817      220075 :   for (ObjectLiteralProperty* literal_property : *pattern->properties()) {
    2818      100830 :     Expression* key = literal_property->key();
    2819      100830 :     if (key->IsPropertyName()) {
    2820      169738 :       property = key->AsLiteral()->AsRawPropertyName();
    2821             :       msg = MessageTemplate::kNonCoercibleWithProperty;
    2822             :       source_position = key->position();
    2823       84869 :       break;
    2824             :     }
    2825             :   }
    2826             : 
    2827             :   Expression* condition = factory()->NewBinaryOperation(
    2828             :       Token::OR,
    2829             :       factory()->NewCompareOperation(
    2830      102057 :           Token::EQ_STRICT, factory()->NewVariableProxy(var),
    2831      204114 :           factory()->NewUndefinedLiteral(kNoSourcePosition), kNoSourcePosition),
    2832             :       factory()->NewCompareOperation(
    2833      102057 :           Token::EQ_STRICT, factory()->NewVariableProxy(var),
    2834      204114 :           factory()->NewNullLiteral(kNoSourcePosition), kNoSourcePosition),
    2835      102057 :       kNoSourcePosition);
    2836             :   Expression* throw_type_error =
    2837             :       NewThrowTypeError(msg, property, source_position);
    2838             :   IfStatement* if_statement = factory()->NewIfStatement(
    2839             :       condition,
    2840      102057 :       factory()->NewExpressionStatement(throw_type_error, kNoSourcePosition),
    2841      204114 :       factory()->NewEmptyStatement(kNoSourcePosition), kNoSourcePosition);
    2842      102057 :   return if_statement;
    2843             : }
    2844             : 
    2845             : class InitializerRewriter final
    2846             :     : public AstTraversalVisitor<InitializerRewriter> {
    2847             :  public:
    2848             :   InitializerRewriter(uintptr_t stack_limit, Expression* root, Parser* parser)
    2849       16056 :       : AstTraversalVisitor(stack_limit, root), parser_(parser) {}
    2850             : 
    2851             :  private:
    2852             :   // This is required so that the overriden Visit* methods can be
    2853             :   // called by the base class (template).
    2854             :   friend class AstTraversalVisitor<InitializerRewriter>;
    2855             : 
    2856             :   // Just rewrite destructuring assignments wrapped in RewritableExpressions.
    2857         186 :   void VisitRewritableExpression(RewritableExpression* to_rewrite) {
    2858         372 :     if (to_rewrite->is_rewritten()) return;
    2859         154 :     parser_->RewriteDestructuringAssignment(to_rewrite);
    2860             :     AstTraversalVisitor::VisitRewritableExpression(to_rewrite);
    2861             :   }
    2862             : 
    2863             :   // Code in function literals does not need to be eagerly rewritten, it will be
    2864             :   // rewritten when scheduled.
    2865             :   void VisitFunctionLiteral(FunctionLiteral* expr) {}
    2866             : 
    2867             :   Parser* parser_;
    2868             : };
    2869             : 
    2870       16056 : void Parser::RewriteParameterInitializer(Expression* expr) {
    2871       16056 :   InitializerRewriter rewriter(stack_limit_, expr, this);
    2872             :   rewriter.Run();
    2873       16056 : }
    2874             : 
    2875             : 
    2876       30029 : Block* Parser::BuildParameterInitializationBlock(
    2877             :     const ParserFormalParameters& parameters, bool* ok) {
    2878             :   DCHECK(!parameters.is_simple);
    2879             :   DCHECK(scope()->is_function_scope());
    2880             :   DCHECK_EQ(scope(), parameters.scope);
    2881      167022 :   Block* init_block = factory()->NewBlock(1, true);
    2882             :   int index = 0;
    2883      110282 :   for (auto parameter : parameters.params) {
    2884             :     DeclarationDescriptor descriptor;
    2885       51122 :     descriptor.declaration_kind = DeclarationDescriptor::PARAMETER;
    2886       51122 :     descriptor.scope = scope();
    2887       51122 :     descriptor.mode = LET;
    2888      102244 :     descriptor.declaration_pos = parameter->pattern->position();
    2889             :     // The position that will be used by the AssignmentExpression
    2890             :     // which copies from the temp parameter to the pattern.
    2891             :     //
    2892             :     // TODO(adamk): Should this be kNoSourcePosition, since
    2893             :     // it's just copying from a temp var to the real param var?
    2894      102244 :     descriptor.initialization_pos = parameter->pattern->position();
    2895             :     Expression* initial_value =
    2896      102244 :         factory()->NewVariableProxy(parameters.scope->parameter(index));
    2897       51122 :     if (parameter->initializer != nullptr) {
    2898             :       // IS_UNDEFINED($param) ? initializer : $param
    2899             : 
    2900             :       // Ensure initializer is rewritten
    2901       16056 :       RewriteParameterInitializer(parameter->initializer);
    2902             : 
    2903             :       auto condition = factory()->NewCompareOperation(
    2904             :           Token::EQ_STRICT,
    2905       32112 :           factory()->NewVariableProxy(parameters.scope->parameter(index)),
    2906       32112 :           factory()->NewUndefinedLiteral(kNoSourcePosition), kNoSourcePosition);
    2907             :       initial_value = factory()->NewConditional(
    2908       16056 :           condition, parameter->initializer, initial_value, kNoSourcePosition);
    2909       16056 :       descriptor.initialization_pos = parameter->initializer->position();
    2910             :     }
    2911             : 
    2912             :     Scope* param_scope = scope();
    2913             :     Block* param_block = init_block;
    2914       83251 :     if (!parameter->is_simple() &&
    2915       32129 :         scope()->AsDeclarationScope()->calls_sloppy_eval()) {
    2916        1310 :       param_scope = NewVarblockScope();
    2917        1310 :       param_scope->set_start_position(descriptor.initialization_pos);
    2918        1310 :       param_scope->set_end_position(parameter->initializer_end_position);
    2919             :       param_scope->RecordEvalCall();
    2920        1310 :       param_block = factory()->NewBlock(8, true);
    2921             :       param_block->set_scope(param_scope);
    2922             :       // Pass the appropriate scope in so that PatternRewriter can appropriately
    2923             :       // rewrite inner initializers of the pattern to param_scope
    2924        1310 :       descriptor.scope = param_scope;
    2925             :       // Rewrite the outer initializer to point to param_scope
    2926        1310 :       ReparentExpressionScope(stack_limit(), initial_value, param_scope);
    2927             :     }
    2928             : 
    2929       51122 :     BlockState block_state(&scope_, param_scope);
    2930             :     DeclarationParsingResult::Declaration decl(
    2931       51122 :         parameter->pattern, parameter->initializer_end_position, initial_value);
    2932             :     DeclareAndInitializeVariables(param_block, &descriptor, &decl, nullptr,
    2933       51122 :                                   CHECK_OK);
    2934             : 
    2935       50224 :     if (param_block != init_block) {
    2936        1310 :       param_scope = param_scope->FinalizeBlockScope();
    2937        1310 :       if (param_scope != nullptr) {
    2938        1310 :         CheckConflictingVarDeclarations(param_scope, CHECK_OK);
    2939             :       }
    2940        1310 :       init_block->statements()->Add(param_block, zone());
    2941             :     }
    2942       50224 :     ++index;
    2943             :   }
    2944             :   return init_block;
    2945             : }
    2946             : 
    2947             : Scope* Parser::NewHiddenCatchScope() {
    2948      373667 :   Scope* catch_scope = NewScopeWithParent(scope(), CATCH_SCOPE);
    2949      373667 :   catch_scope->DeclareLocal(ast_value_factory()->dot_catch_string(), VAR);
    2950      373667 :   catch_scope->set_is_hidden();
    2951             :   return catch_scope;
    2952             : }
    2953             : 
    2954       30112 : Block* Parser::BuildRejectPromiseOnException(Block* inner_block) {
    2955             :   // .promise = %AsyncFunctionPromiseCreate();
    2956             :   // try {
    2957             :   //   <inner_block>
    2958             :   // } catch (.catch) {
    2959             :   //   %RejectPromise(.promise, .catch);
    2960             :   //   return .promise;
    2961             :   // } finally {
    2962             :   //   %AsyncFunctionPromiseRelease(.promise);
    2963             :   // }
    2964      150560 :   Block* result = factory()->NewBlock(2, true);
    2965             : 
    2966             :   // .promise = %AsyncFunctionPromiseCreate();
    2967             :   Statement* set_promise;
    2968             :   {
    2969             :     Expression* create_promise = factory()->NewCallRuntime(
    2970             :         Context::ASYNC_FUNCTION_PROMISE_CREATE_INDEX,
    2971       30112 :         new (zone()) ZoneList<Expression*>(0, zone()), kNoSourcePosition);
    2972             :     Assignment* assign_promise = factory()->NewAssignment(
    2973       30112 :         Token::ASSIGN, factory()->NewVariableProxy(PromiseVariable()),
    2974       30112 :         create_promise, kNoSourcePosition);
    2975             :     set_promise =
    2976       60224 :         factory()->NewExpressionStatement(assign_promise, kNoSourcePosition);
    2977             :   }
    2978       30112 :   result->statements()->Add(set_promise, zone());
    2979             : 
    2980             :   // catch (.catch) { return %RejectPromise(.promise, .catch), .promise }
    2981             :   Scope* catch_scope = NewHiddenCatchScope();
    2982             : 
    2983             :   Expression* promise_reject = BuildRejectPromise(
    2984       30112 :       factory()->NewVariableProxy(catch_scope->catch_variable()),
    2985       30112 :       kNoSourcePosition);
    2986             :   Block* catch_block = IgnoreCompletion(
    2987       30112 :       factory()->NewReturnStatement(promise_reject, kNoSourcePosition));
    2988             : 
    2989             :   TryStatement* try_catch_statement =
    2990             :       factory()->NewTryCatchStatementForAsyncAwait(
    2991       30112 :           inner_block, catch_scope, catch_block, kNoSourcePosition);
    2992             : 
    2993             :   // There is no TryCatchFinally node, so wrap it in an outer try/finally
    2994             :   Block* outer_try_block = IgnoreCompletion(try_catch_statement);
    2995             : 
    2996             :   // finally { %AsyncFunctionPromiseRelease(.promise) }
    2997             :   Block* finally_block;
    2998             :   {
    2999       30112 :     ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(1, zone());
    3000       60224 :     args->Add(factory()->NewVariableProxy(PromiseVariable()), zone());
    3001             :     Expression* call_promise_release = factory()->NewCallRuntime(
    3002       30112 :         Context::ASYNC_FUNCTION_PROMISE_RELEASE_INDEX, args, kNoSourcePosition);
    3003             :     Statement* promise_release = factory()->NewExpressionStatement(
    3004       30112 :         call_promise_release, kNoSourcePosition);
    3005             :     finally_block = IgnoreCompletion(promise_release);
    3006             :   }
    3007             : 
    3008             :   Statement* try_finally_statement = factory()->NewTryFinallyStatement(
    3009       60224 :       outer_try_block, finally_block, kNoSourcePosition);
    3010             : 
    3011       30112 :   result->statements()->Add(try_finally_statement, zone());
    3012       30112 :   return result;
    3013             : }
    3014             : 
    3015       28512 : Expression* Parser::BuildResolvePromise(Expression* value, int pos) {
    3016             :   // %ResolvePromise(.promise, value), .promise
    3017       85536 :   ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(2, zone());
    3018       57024 :   args->Add(factory()->NewVariableProxy(PromiseVariable()), zone());
    3019       28512 :   args->Add(value, zone());
    3020             :   Expression* call_runtime =
    3021       28512 :       factory()->NewCallRuntime(Context::PROMISE_RESOLVE_INDEX, args, pos);
    3022             :   return factory()->NewBinaryOperation(
    3023             :       Token::COMMA, call_runtime,
    3024       85536 :       factory()->NewVariableProxy(PromiseVariable()), pos);
    3025             : }
    3026             : 
    3027       30112 : Expression* Parser::BuildRejectPromise(Expression* value, int pos) {
    3028             :   // %promise_internal_reject(.promise, value, false), .promise
    3029             :   // Disables the additional debug event for the rejection since a debug event
    3030             :   // already happened for the exception that got us here.
    3031      120448 :   ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(3, zone());
    3032       60224 :   args->Add(factory()->NewVariableProxy(PromiseVariable()), zone());
    3033       30112 :   args->Add(value, zone());
    3034       30112 :   args->Add(factory()->NewBooleanLiteral(false, pos), zone());
    3035             :   Expression* call_runtime = factory()->NewCallRuntime(
    3036       30112 :       Context::PROMISE_INTERNAL_REJECT_INDEX, args, pos);
    3037             :   return factory()->NewBinaryOperation(
    3038             :       Token::COMMA, call_runtime,
    3039       90336 :       factory()->NewVariableProxy(PromiseVariable()), pos);
    3040             : }
    3041             : 
    3042      177472 : Variable* Parser::PromiseVariable() {
    3043             :   // Based on the various compilation paths, there are many different code
    3044             :   // paths which may be the first to access the Promise temporary. Whichever
    3045             :   // comes first should create it and stash it in the FunctionState.
    3046      205984 :   Variable* promise = function_state_->scope()->promise_var();
    3047      177472 :   if (promise == nullptr) {
    3048             :     promise = function_state_->scope()->DeclarePromiseVar(
    3049       85536 :         ast_value_factory()->empty_string());
    3050             :   }
    3051      177472 :   return promise;
    3052             : }
    3053             : 
    3054       66131 : Expression* Parser::BuildInitialYield(int pos, FunctionKind kind) {
    3055             :   Expression* yield_result = factory()->NewVariableProxy(
    3056      198393 :       function_state_->scope()->generator_object_var());
    3057             :   // The position of the yield is important for reporting the exception
    3058             :   // caused by calling the .throw method on a generator suspended at the
    3059             :   // initial yield (i.e. right after generator instantiation).
    3060             :   return factory()->NewYield(yield_result, scope()->start_position(),
    3061       66131 :                              Suspend::kOnExceptionThrow);
    3062             : }
    3063             : 
    3064     2985924 : ZoneList<Statement*>* Parser::ParseFunction(
    3065             :     const AstRawString* function_name, int pos, FunctionKind kind,
    3066             :     FunctionLiteral::FunctionType function_type,
    3067             :     DeclarationScope* function_scope, int* num_parameters, int* function_length,
    3068             :     bool* has_duplicate_parameters, int* expected_property_count, bool* ok) {
    3069     2985924 :   ParsingModeScope mode(this, allow_lazy_ ? PARSE_LAZILY : PARSE_EAGERLY);
    3070             : 
    3071     2985924 :   FunctionState function_state(&function_state_, &scope_, function_scope);
    3072             : 
    3073             :   DuplicateFinder duplicate_finder;
    3074    11844675 :   ExpressionClassifier formals_classifier(this, &duplicate_finder);
    3075             : 
    3076     2985924 :   int expected_parameters_end_pos = parameters_end_pos_;
    3077     2985924 :   if (expected_parameters_end_pos != kNoSourcePosition) {
    3078             :     // This is the first function encountered in a CreateDynamicFunction eval.
    3079        2217 :     parameters_end_pos_ = kNoSourcePosition;
    3080             :     // The function name should have been ignored, giving us the empty string
    3081             :     // here.
    3082             :     DCHECK_EQ(function_name, ast_value_factory()->empty_string());
    3083             :   }
    3084             : 
    3085             :   ParserFormalParameters formals(function_scope);
    3086     2985924 :   ParseFormalParameterList(&formals, CHECK_OK);
    3087     2973183 :   if (expected_parameters_end_pos != kNoSourcePosition) {
    3088             :     // Check for '(' or ')' shenanigans in the parameter string for dynamic
    3089             :     // functions.
    3090             :     int position = peek_position();
    3091        2004 :     if (position < expected_parameters_end_pos) {
    3092             :       ReportMessageAt(Scanner::Location(position, position + 1),
    3093          10 :                       MessageTemplate::kArgStringTerminatesParametersEarly);
    3094          10 :       *ok = false;
    3095          10 :       return nullptr;
    3096        1994 :     } else if (position > expected_parameters_end_pos) {
    3097             :       ReportMessageAt(Scanner::Location(expected_parameters_end_pos - 2,
    3098             :                                         expected_parameters_end_pos),
    3099           0 :                       MessageTemplate::kUnexpectedEndOfArgString);
    3100           0 :       *ok = false;
    3101           0 :       return nullptr;
    3102             :     }
    3103             :   }
    3104     2973173 :   Expect(Token::RPAREN, CHECK_OK);
    3105             :   int formals_end_position = scanner()->location().end_pos;
    3106     5945004 :   *num_parameters = formals.num_parameters();
    3107     2972502 :   *function_length = formals.function_length;
    3108             : 
    3109             :   CheckArityRestrictions(formals.arity, kind, formals.has_rest,
    3110             :                          function_scope->start_position(), formals_end_position,
    3111     2972502 :                          CHECK_OK);
    3112     2972041 :   Expect(Token::LBRACE, CHECK_OK);
    3113             : 
    3114     2971544 :   ZoneList<Statement*>* body = new (zone()) ZoneList<Statement*>(8, zone());
    3115     2971543 :   ParseFunctionBody(body, function_name, pos, formals, kind, function_type, ok);
    3116             : 
    3117             :   // Validate parameter names. We can do this only after parsing the function,
    3118             :   // since the function can declare itself strict.
    3119             :   const bool allow_duplicate_parameters =
    3120     3882009 :       is_sloppy(function_scope->language_mode()) && formals.is_simple &&
    3121             :       !IsConciseMethod(kind);
    3122             :   ValidateFormalParameters(function_scope->language_mode(),
    3123     5943088 :                            allow_duplicate_parameters, CHECK_OK);
    3124             : 
    3125             :   RewriteDestructuringAssignments();
    3126             : 
    3127             :   *has_duplicate_parameters =
    3128     2912701 :       !classifier()->is_valid_formal_parameter_list_without_duplicates();
    3129             : 
    3130     2912701 :   *expected_property_count = function_state.expected_property_count();
    3131     2912701 :   return body;
    3132             : }
    3133             : 
    3134             : void Parser::DeclareClassVariable(const AstRawString* name,
    3135             :                                   ClassInfo* class_info, int class_token_pos,
    3136             :                                   bool* ok) {
    3137             : #ifdef DEBUG
    3138             :   scope()->SetScopeName(name);
    3139             : #endif
    3140             : 
    3141      125580 :   if (name != nullptr) {
    3142      102482 :     VariableProxy* proxy = factory()->NewVariableProxy(name, NORMAL_VARIABLE);
    3143             :     Declaration* declaration =
    3144      102482 :         factory()->NewVariableDeclaration(proxy, class_token_pos);
    3145             :     class_info->variable =
    3146             :         Declare(declaration, DeclarationDescriptor::NORMAL, CONST,
    3147      102482 :                 Variable::DefaultInitializationFlag(CONST), ok);
    3148             :   }
    3149             : }
    3150             : 
    3151             : // This method declares a property of the given class.  It updates the
    3152             : // following fields of class_info, as appropriate:
    3153             : //   - constructor
    3154             : //   - properties
    3155             : void Parser::DeclareClassProperty(const AstRawString* class_name,
    3156             :                                   ClassLiteralProperty* property,
    3157             :                                   ClassLiteralProperty::Kind kind,
    3158             :                                   bool is_static, bool is_constructor,
    3159             :                                   ClassInfo* class_info, bool* ok) {
    3160      472919 :   if (is_constructor) {
    3161             :     DCHECK(!class_info->constructor);
    3162       82786 :     class_info->constructor = property->value()->AsFunctionLiteral();
    3163             :     DCHECK_NOT_NULL(class_info->constructor);
    3164             :     class_info->constructor->set_raw_name(
    3165       38928 :         class_name != nullptr ? ast_value_factory()->NewConsString(class_name)
    3166       80321 :                               : nullptr);
    3167             :     return;
    3168             :   }
    3169             : 
    3170             :   if (property->kind() == ClassLiteralProperty::FIELD) {
    3171             :     DCHECK(allow_harmony_class_fields());
    3172             :     // TODO(littledan): Implement class fields
    3173             :   }
    3174      431526 :   class_info->properties->Add(property, zone());
    3175             : }
    3176             : 
    3177             : // This method generates a ClassLiteral AST node.
    3178             : // It uses the following fields of class_info:
    3179             : //   - constructor (if missing, it updates it with a default constructor)
    3180             : //   - proxy
    3181             : //   - extends
    3182             : //   - properties
    3183             : //   - has_name_static_property
    3184             : //   - has_static_computed_names
    3185             : Expression* Parser::RewriteClassLiteral(Scope* block_scope,
    3186             :                                         const AstRawString* name,
    3187             :                                         ClassInfo* class_info, int pos,
    3188      111783 :                                         int end_pos, bool* ok) {
    3189             :   DCHECK_NOT_NULL(block_scope);
    3190             :   DCHECK_EQ(block_scope->scope_type(), BLOCK_SCOPE);
    3191             :   DCHECK_EQ(block_scope->language_mode(), LanguageMode::kStrict);
    3192             : 
    3193      111783 :   bool has_extends = class_info->extends != nullptr;
    3194      111783 :   bool has_default_constructor = class_info->constructor == nullptr;
    3195      111783 :   if (has_default_constructor) {
    3196             :     class_info->constructor =
    3197       70601 :         DefaultConstructor(name, has_extends, pos, end_pos);
    3198             :   }
    3199             : 
    3200      111783 :   if (name != nullptr) {
    3201             :     DCHECK_NOT_NULL(class_info->variable);
    3202       92833 :     class_info->variable->set_initializer_position(end_pos);
    3203             :   }
    3204             : 
    3205             :   ClassLiteral* class_literal = factory()->NewClassLiteral(
    3206             :       block_scope, class_info->variable, class_info->extends,
    3207             :       class_info->constructor, class_info->properties, pos, end_pos,
    3208             :       class_info->has_name_static_property,
    3209      111783 :       class_info->has_static_computed_names, class_info->is_anonymous);
    3210             : 
    3211      111783 :   AddFunctionForNameInference(class_info->constructor);
    3212             : 
    3213             :   return class_literal;
    3214             : }
    3215             : 
    3216     7087646 : void Parser::CheckConflictingVarDeclarations(Scope* scope, bool* ok) {
    3217     7112072 :   Declaration* decl = scope->CheckConflictingVarDeclarations();
    3218     7087647 :   if (decl != nullptr) {
    3219             :     // In ES6, conflicting variable bindings are early errors.
    3220             :     const AstRawString* name = decl->proxy()->raw_name();
    3221       24426 :     int position = decl->proxy()->position();
    3222             :     Scanner::Location location =
    3223             :         position == kNoSourcePosition
    3224             :             ? Scanner::Location::invalid()
    3225       24426 :             : Scanner::Location(position, position + 1);
    3226             :     ReportMessageAt(location, MessageTemplate::kVarRedeclaration, name);
    3227       24426 :     *ok = false;
    3228             :   }
    3229     7087647 : }
    3230             : 
    3231             : 
    3232        8199 : void Parser::InsertShadowingVarBindingInitializers(Block* inner_block) {
    3233             :   // For each var-binding that shadows a parameter, insert an assignment
    3234             :   // initializing the variable with the parameter.
    3235        8199 :   Scope* inner_scope = inner_block->scope();
    3236             :   DCHECK(inner_scope->is_declaration_scope());
    3237             :   Scope* function_scope = inner_scope->outer_scope();
    3238             :   DCHECK(function_scope->is_function_scope());
    3239        8199 :   BlockState block_state(&scope_, inner_scope);
    3240       55202 :   for (Declaration* decl : *inner_scope->declarations()) {
    3241       41433 :     if (decl->proxy()->var()->mode() != VAR || !decl->IsVariableDeclaration()) {
    3242       16161 :       continue;
    3243             :     }
    3244             :     const AstRawString* name = decl->proxy()->raw_name();
    3245        4912 :     Variable* parameter = function_scope->LookupLocal(name);
    3246        4912 :     if (parameter == nullptr) continue;
    3247         785 :     VariableProxy* to = NewUnresolved(name);
    3248        1570 :     VariableProxy* from = factory()->NewVariableProxy(parameter);
    3249             :     Expression* assignment =
    3250         785 :         factory()->NewAssignment(Token::ASSIGN, to, from, kNoSourcePosition);
    3251             :     Statement* statement =
    3252        1570 :         factory()->NewExpressionStatement(assignment, kNoSourcePosition);
    3253         785 :     inner_block->statements()->InsertAt(0, statement, zone());
    3254             :   }
    3255        8199 : }
    3256             : 
    3257     2289990 : void Parser::InsertSloppyBlockFunctionVarBindings(DeclarationScope* scope) {
    3258             :   // For the outermost eval scope, we cannot hoist during parsing: let
    3259             :   // declarations in the surrounding scope may prevent hoisting, but the
    3260             :   // information is unaccessible during parsing. In this case, we hoist later in
    3261             :   // DeclarationScope::Analyze.
    3262     2289990 :   if (scope->is_eval_scope() && scope->outer_scope() == original_scope_) {
    3263     2289989 :     return;
    3264             :   }
    3265     1530163 :   scope->HoistSloppyBlockFunctions(factory());
    3266             : }
    3267             : 
    3268             : // ----------------------------------------------------------------------------
    3269             : // Parser support
    3270             : 
    3271       18095 : bool Parser::TargetStackContainsLabel(const AstRawString* label) {
    3272       33289 :   for (ParserTarget* t = target_stack_; t != nullptr; t = t->previous()) {
    3273       30388 :     if (ContainsLabel(t->statement()->labels(), label)) return true;
    3274             :   }
    3275             :   return false;
    3276             : }
    3277             : 
    3278             : 
    3279       67671 : BreakableStatement* Parser::LookupBreakTarget(const AstRawString* label,
    3280             :                                               bool* ok) {
    3281       67671 :   bool anonymous = label == nullptr;
    3282      121843 :   for (ParserTarget* t = target_stack_; t != nullptr; t = t->previous()) {
    3283       91867 :     BreakableStatement* stat = t->statement();
    3284      335009 :     if ((anonymous && stat->is_target_for_anonymous()) ||
    3285       59408 :         (!anonymous && ContainsLabel(stat->labels(), label))) {
    3286             :       return stat;
    3287             :     }
    3288             :   }
    3289             :   return nullptr;
    3290             : }
    3291             : 
    3292             : 
    3293       37165 : IterationStatement* Parser::LookupContinueTarget(const AstRawString* label,
    3294             :                                                  bool* ok) {
    3295             :   bool anonymous = label == nullptr;
    3296      129859 :   for (ParserTarget* t = target_stack_; t != nullptr; t = t->previous()) {
    3297      131944 :     IterationStatement* stat = t->statement()->AsIterationStatement();
    3298      129654 :     if (stat == nullptr) continue;
    3299             : 
    3300             :     DCHECK(stat->is_target_for_anonymous());
    3301       40365 :     if (anonymous || ContainsLabel(stat->labels(), label)) {
    3302             :       return stat;
    3303             :     }
    3304             :   }
    3305             :   return nullptr;
    3306             : }
    3307             : 
    3308             : 
    3309     1678478 : void Parser::HandleSourceURLComments(Isolate* isolate, Handle<Script> script) {
    3310     1678478 :   Handle<String> source_url = scanner_.SourceUrl(isolate);
    3311     1678478 :   if (!source_url.is_null()) {
    3312        2680 :     script->set_source_url(*source_url);
    3313             :   }
    3314     1678478 :   Handle<String> source_mapping_url = scanner_.SourceMappingUrl(isolate);
    3315     1678478 :   if (!source_mapping_url.is_null()) {
    3316         100 :     script->set_source_mapping_url(*source_mapping_url);
    3317             :   }
    3318     1678478 : }
    3319             : 
    3320      317383 : void Parser::ReportErrors(Isolate* isolate, Handle<Script> script) {
    3321      629792 :   if (stack_overflow()) {
    3322        4974 :     isolate->StackOverflow();
    3323             :   } else {
    3324             :     DCHECK(pending_error_handler_.has_pending_error());
    3325             :     // Internalize ast values for throwing the pending error.
    3326      312409 :     ast_value_factory()->Internalize(isolate);
    3327      312409 :     pending_error_handler_.ThrowPendingError(isolate, script);
    3328             :   }
    3329      317383 : }
    3330             : 
    3331     2348008 : void Parser::UpdateStatistics(Isolate* isolate, Handle<Script> script) {
    3332             :   // Move statistics to Isolate.
    3333   100964057 :   for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount;
    3334             :        ++feature) {
    3335    98616055 :     if (use_counts_[feature] > 0) {
    3336     2399993 :       isolate->CountUsage(v8::Isolate::UseCounterFeature(feature));
    3337             :     }
    3338             :   }
    3339     2348002 :   if (scanner_.FoundHtmlComment()) {
    3340          11 :     isolate->CountUsage(v8::Isolate::kHtmlComment);
    3341          22 :     if (script->line_offset() == 0 && script->column_offset() == 0) {
    3342          11 :       isolate->CountUsage(v8::Isolate::kHtmlCommentInExternalScript);
    3343             :     }
    3344             :   }
    3345             :   isolate->counters()->total_preparse_skipped()->Increment(
    3346     4696004 :       total_preparse_skipped_);
    3347     2348002 : }
    3348             : 
    3349         443 : void Parser::ParseOnBackground(ParseInfo* info) {
    3350         137 :   parsing_on_main_thread_ = false;
    3351             : 
    3352             :   DCHECK_NULL(info->literal());
    3353             :   FunctionLiteral* result = nullptr;
    3354             : 
    3355         137 :   ParserLogger logger;
    3356         137 :   if (produce_cached_parse_data()) {
    3357           5 :     if (allow_lazy_) {
    3358           5 :       log_ = &logger;
    3359             :     } else {
    3360           0 :       compile_options_ = ScriptCompiler::kNoCompileOptions;
    3361             :     }
    3362             :   }
    3363             : 
    3364         274 :   scanner_.Initialize(info->character_stream(), info->is_module());
    3365             :   DCHECK(info->maybe_outer_scope_info().is_null());
    3366             : 
    3367             :   DCHECK(original_scope_);
    3368             : 
    3369             :   // When streaming, we don't know the length of the source until we have parsed
    3370             :   // it. The raw data can be UTF-8, so we wouldn't know the source length until
    3371             :   // we have decoded it anyway even if we knew the raw data length (which we
    3372             :   // don't). We work around this by storing all the scopes which need their end
    3373             :   // position set at the end of the script (the top scope and possible eval
    3374             :   // scopes) and set their end position after we know the script length.
    3375         137 :   if (info->is_toplevel()) {
    3376         220 :     fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone());
    3377         110 :     result = DoParseProgram(info);
    3378             :   } else {
    3379          27 :     result = DoParseFunction(info, info->function_name());
    3380             :   }
    3381         137 :   MaybeResetCharacterStream(info, result);
    3382             : 
    3383             :   info->set_literal(result);
    3384             : 
    3385             :   // We cannot internalize on a background thread; a foreground task will take
    3386             :   // care of calling AstValueFactory::Internalize just before compilation.
    3387             : 
    3388         137 :   if (produce_cached_parse_data()) {
    3389          10 :     if (result != nullptr) *info->cached_data() = logger.GetScriptData();
    3390           5 :     log_ = nullptr;
    3391             :   }
    3392         137 :   if (FLAG_runtime_stats &
    3393             :       v8::tracing::TracingCategoryObserver::ENABLED_BY_TRACING) {
    3394           0 :     auto value = v8::tracing::TracedValue::Create();
    3395           0 :     runtime_call_stats_->Dump(value.get());
    3396           0 :     TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("v8.runtime_stats"),
    3397             :                          "V8.RuntimeStats", TRACE_EVENT_SCOPE_THREAD,
    3398             :                          "runtime-call-stats", std::move(value));
    3399             :   }
    3400         137 : }
    3401             : 
    3402       34433 : Parser::TemplateLiteralState Parser::OpenTemplateLiteral(int pos) {
    3403       68866 :   return new (zone()) TemplateLiteral(zone(), pos);
    3404             : }
    3405             : 
    3406       62557 : void Parser::AddTemplateSpan(TemplateLiteralState* state, bool should_cook,
    3407             :                              bool tail) {
    3408             :   DCHECK(should_cook || allow_harmony_template_escapes());
    3409      184211 :   int pos = scanner()->location().beg_pos;
    3410             :   int end = scanner()->location().end_pos - (tail ? 1 : 2);
    3411       62557 :   const AstRawString* trv = scanner()->CurrentRawSymbol(ast_value_factory());
    3412       62557 :   Literal* raw = factory()->NewStringLiteral(trv, pos);
    3413       62557 :   if (should_cook) {
    3414       59097 :     const AstRawString* tv = scanner()->CurrentSymbol(ast_value_factory());
    3415       59097 :     Literal* cooked = factory()->NewStringLiteral(tv, pos);
    3416       59097 :     (*state)->AddTemplateSpan(cooked, raw, end, zone());
    3417             :   } else {
    3418             :     (*state)->AddTemplateSpan(factory()->NewUndefinedLiteral(pos), raw, end,
    3419        3460 :                               zone());
    3420             :   }
    3421       62557 : }
    3422             : 
    3423             : 
    3424           0 : void Parser::AddTemplateExpression(TemplateLiteralState* state,
    3425             :                                    Expression* expression) {
    3426       36586 :   (*state)->AddExpression(expression, zone());
    3427           0 : }
    3428             : 
    3429             : 
    3430       24492 : Expression* Parser::CloseTemplateLiteral(TemplateLiteralState* state, int start,
    3431             :                                          Expression* tag) {
    3432       24492 :   TemplateLiteral* lit = *state;
    3433             :   int pos = lit->position();
    3434       24492 :   const ZoneList<Literal*>* cooked_strings = lit->cooked();
    3435       24492 :   const ZoneList<Literal*>* raw_strings = lit->raw();
    3436       51753 :   const ZoneList<Expression*>* expressions = lit->expressions();
    3437             :   DCHECK_EQ(cooked_strings->length(), raw_strings->length());
    3438             :   DCHECK_EQ(cooked_strings->length(), expressions->length() + 1);
    3439             : 
    3440       24492 :   if (!tag) {
    3441             :     // Build tree of BinaryOps to simplify code-generation
    3442       17674 :     Expression* expr = cooked_strings->at(0);
    3443             :     int i = 0;
    3444       62609 :     while (i < expressions->length()) {
    3445       54522 :       Expression* sub = expressions->at(i++);
    3446       27261 :       Expression* cooked_str = cooked_strings->at(i);
    3447             : 
    3448             :       // Let middle be ToString(sub).
    3449             :       ZoneList<Expression*>* args =
    3450       74976 :           new (zone()) ZoneList<Expression*>(1, zone());
    3451       27261 :       args->Add(sub, zone());
    3452             :       Expression* middle = factory()->NewCallRuntime(Runtime::kInlineToString,
    3453       54522 :                                                      args, sub->position());
    3454             : 
    3455             :       expr = factory()->NewBinaryOperation(
    3456             :           Token::ADD, factory()->NewBinaryOperation(
    3457       27261 :                           Token::ADD, expr, middle, expr->position()),
    3458       54522 :           cooked_str, sub->position());
    3459             :     }
    3460             :     return expr;
    3461             :   } else {
    3462             :     // GetTemplateObject
    3463        6818 :     const int32_t hash = ComputeTemplateLiteralHash(lit);
    3464             :     Expression* template_object = factory()->NewGetTemplateObject(
    3465             :         const_cast<ZoneList<Literal*>*>(cooked_strings),
    3466       13636 :         const_cast<ZoneList<Literal*>*>(raw_strings), hash, pos);
    3467             : 
    3468             :     // Call TagFn
    3469             :     ZoneList<Expression*>* call_args =
    3470       13636 :         new (zone()) ZoneList<Expression*>(expressions->length() + 1, zone());
    3471        6818 :     call_args->Add(template_object, zone());
    3472             :     call_args->AddAll(*expressions, zone());
    3473        6818 :     return factory()->NewTaggedTemplate(tag, call_args, pos);
    3474             :   }
    3475             : }
    3476             : 
    3477             : namespace {
    3478             : 
    3479             : // http://burtleburtle.net/bob/hash/integer.html
    3480        6818 : uint32_t HalfAvalance(uint32_t a) {
    3481        6818 :   a = (a + 0x479ab41d) + (a << 8);
    3482        6818 :   a = (a ^ 0xe4aa10ce) ^ (a >> 5);
    3483        6818 :   a = (a + 0x9942f0a6) - (a << 14);
    3484        6818 :   a = (a ^ 0x5aedd67d) ^ (a >> 3);
    3485        6818 :   a = (a + 0x17bea992) + (a << 7);
    3486        6818 :   return a;
    3487             : }
    3488             : 
    3489             : }  // namespace
    3490             : 
    3491        6818 : int32_t Parser::ComputeTemplateLiteralHash(const TemplateLiteral* lit) {
    3492        6818 :   const ZoneList<Literal*>* raw_strings = lit->raw();
    3493             :   int total = raw_strings->length();
    3494             :   DCHECK_GT(total, 0);
    3495             : 
    3496             :   uint32_t running_hash = 0;
    3497             : 
    3498       18992 :   for (int index = 0; index < total; ++index) {
    3499       12174 :     if (index) {
    3500             :       running_hash = StringHasher::ComputeRunningHashOneByte(
    3501             :           running_hash, "${}", 3);
    3502             :     }
    3503             : 
    3504       12174 :     const AstRawString* raw_string =
    3505       24348 :         raw_strings->at(index)->AsLiteral()->raw_value()->AsString();
    3506       12174 :     if (raw_string->is_one_byte()) {
    3507             :       const char* data = reinterpret_cast<const char*>(raw_string->raw_data());
    3508             :       running_hash = StringHasher::ComputeRunningHashOneByte(
    3509             :           running_hash, data, raw_string->length());
    3510             :     } else {
    3511             :       const uc16* data = reinterpret_cast<const uc16*>(raw_string->raw_data());
    3512             :       running_hash = StringHasher::ComputeRunningHash(running_hash, data,
    3513             :                                                       raw_string->length());
    3514             :     }
    3515             :   }
    3516             : 
    3517             :   // Pass {running_hash} throught a decent 'half avalance' hash function
    3518             :   // and take the most significant bits (in Smi range).
    3519        6818 :   return static_cast<int32_t>(HalfAvalance(running_hash)) >>
    3520        6818 :          (sizeof(int32_t) * CHAR_BIT - kSmiValueSize);
    3521             : }
    3522             : 
    3523             : namespace {
    3524             : 
    3525        9031 : bool OnlyLastArgIsSpread(ZoneList<Expression*>* args) {
    3526        9782 :   for (int i = 0; i < args->length() - 1; i++) {
    3527        2582 :     if (args->at(i)->IsSpread()) {
    3528             :       return false;
    3529             :     }
    3530             :   }
    3531        7200 :   return args->at(args->length() - 1)->IsSpread();
    3532             : }
    3533             : 
    3534             : }  // namespace
    3535             : 
    3536         540 : ZoneList<Expression*>* Parser::PrepareSpreadArguments(
    3537         540 :     ZoneList<Expression*>* list) {
    3538        8379 :   ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(1, zone());
    3539         540 :   if (list->length() == 1) {
    3540             :     // Spread-call with single spread argument produces an InternalArray
    3541             :     // containing the values from the array.
    3542             :     //
    3543             :     // Function is called or constructed with the produced array of arguments
    3544             :     //
    3545             :     // EG: Apply(Func, Spread(spread0))
    3546             :     ZoneList<Expression*>* spread_list =
    3547           0 :         new (zone()) ZoneList<Expression*>(0, zone());
    3548           0 :     spread_list->Add(list->at(0)->AsSpread()->expression(), zone());
    3549             :     args->Add(factory()->NewCallRuntime(Runtime::kSpreadIterablePrepare,
    3550           0 :                                         spread_list, kNoSourcePosition),
    3551           0 :               zone());
    3552           0 :     return args;
    3553             :   } else {
    3554             :     // Spread-call with multiple arguments produces array literals for each
    3555             :     // sequences of unspread arguments, and converts each spread iterable to
    3556             :     // an Internal array. Finally, all of these produced arrays are flattened
    3557             :     // into a single InternalArray, containing the arguments for the call.
    3558             :     //
    3559             :     // EG: Apply(Func, Flatten([unspread0, unspread1], Spread(spread0),
    3560             :     //                         Spread(spread1), [unspread2, unspread3]))
    3561             :     int i = 0;
    3562             :     int n = list->length();
    3563        1500 :     while (i < n) {
    3564        2510 :       if (!list->at(i)->IsSpread()) {
    3565             :         ZoneList<Expression*>* unspread =
    3566         883 :             new (zone()) ZoneList<Expression*>(1, zone());
    3567             : 
    3568             :         // Push array of unspread parameters
    3569        7661 :         while (i < n && !list->at(i)->IsSpread()) {
    3570        3146 :           unspread->Add(list->at(i++), zone());
    3571             :         }
    3572         883 :         args->Add(factory()->NewArrayLiteral(unspread, kNoSourcePosition),
    3573         883 :                   zone());
    3574             : 
    3575         883 :         if (i == n) break;
    3576             :       }
    3577             : 
    3578             :       // Push eagerly spread argument
    3579             :       ZoneList<Expression*>* spread_list =
    3580         960 :           new (zone()) ZoneList<Expression*>(1, zone());
    3581        2880 :       spread_list->Add(list->at(i++)->AsSpread()->expression(), zone());
    3582             :       args->Add(factory()->NewCallRuntime(Context::SPREAD_ITERABLE_INDEX,
    3583         960 :                                           spread_list, kNoSourcePosition),
    3584         960 :                 zone());
    3585             :     }
    3586             : 
    3587         540 :     list = new (zone()) ZoneList<Expression*>(1, zone());
    3588             :     list->Add(factory()->NewCallRuntime(Context::SPREAD_ARGUMENTS_INDEX, args,
    3589         540 :                                         kNoSourcePosition),
    3590         540 :               zone());
    3591         540 :     return list;
    3592             :   }
    3593             :   UNREACHABLE();
    3594             : }
    3595             : 
    3596        3976 : Expression* Parser::SpreadCall(Expression* function,
    3597             :                                ZoneList<Expression*>* args, int pos,
    3598             :                                Call::PossiblyEval is_possibly_eval) {
    3599             :   // Handle this case in BytecodeGenerator.
    3600        3976 :   if (OnlyLastArgIsSpread(args)) {
    3601        8064 :     return factory()->NewCall(function, args, pos);
    3602             :   }
    3603             : 
    3604        1068 :   if (function->IsSuperCallReference()) {
    3605             :     // Super calls
    3606             :     // $super_constructor = %_GetSuperConstructor(<this-function>)
    3607             :     // %reflect_construct($super_constructor, args, new.target)
    3608             : 
    3609          18 :     args = PrepareSpreadArguments(args);
    3610          18 :     ZoneList<Expression*>* tmp = new (zone()) ZoneList<Expression*>(1, zone());
    3611          36 :     tmp->Add(function->AsSuperCallReference()->this_function_var(), zone());
    3612             :     Expression* super_constructor = factory()->NewCallRuntime(
    3613          18 :         Runtime::kInlineGetSuperConstructor, tmp, pos);
    3614          18 :     args->InsertAt(0, super_constructor, zone());
    3615          36 :     args->Add(function->AsSuperCallReference()->new_target_var(), zone());
    3616             :     return factory()->NewCallRuntime(Context::REFLECT_CONSTRUCT_INDEX, args,
    3617          18 :                                      pos);
    3618             :   } else {
    3619         516 :     args = PrepareSpreadArguments(args);
    3620        1032 :     if (function->IsProperty()) {
    3621             :       // Method calls
    3622         152 :       if (function->AsProperty()->IsSuperAccess()) {
    3623           0 :         Expression* home = ThisExpression(kNoSourcePosition);
    3624           0 :         args->InsertAt(0, function, zone());
    3625           0 :         args->InsertAt(1, home, zone());
    3626             :       } else {
    3627          76 :         Variable* temp = NewTemporary(ast_value_factory()->empty_string());
    3628          76 :         VariableProxy* obj = factory()->NewVariableProxy(temp);
    3629             :         Assignment* assign_obj = factory()->NewAssignment(
    3630             :             Token::ASSIGN, obj, function->AsProperty()->obj(),
    3631         152 :             kNoSourcePosition);
    3632             :         function = factory()->NewProperty(
    3633         228 :             assign_obj, function->AsProperty()->key(), kNoSourcePosition);
    3634          76 :         args->InsertAt(0, function, zone());
    3635          76 :         obj = factory()->NewVariableProxy(temp);
    3636          76 :         args->InsertAt(1, obj, zone());
    3637             :       }
    3638             :     } else {
    3639             :       // Non-method calls
    3640         440 :       args->InsertAt(0, function, zone());
    3641         440 :       args->InsertAt(1, factory()->NewUndefinedLiteral(kNoSourcePosition),
    3642         440 :                      zone());
    3643             :     }
    3644        1032 :     return factory()->NewCallRuntime(Context::REFLECT_APPLY_INDEX, args, pos);
    3645             :   }
    3646             : }
    3647             : 
    3648         164 : Expression* Parser::SpreadCallNew(Expression* function,
    3649             :                                   ZoneList<Expression*>* args, int pos) {
    3650         164 :   if (OnlyLastArgIsSpread(args)) {
    3651             :     // Handle in BytecodeGenerator.
    3652         322 :     return factory()->NewCallNew(function, args, pos);
    3653             :   }
    3654           6 :   args = PrepareSpreadArguments(args);
    3655           6 :   args->InsertAt(0, function, zone());
    3656             : 
    3657          12 :   return factory()->NewCallRuntime(Context::REFLECT_CONSTRUCT_INDEX, args, pos);
    3658             : }
    3659             : 
    3660             : 
    3661    25773048 : void Parser::SetLanguageMode(Scope* scope, LanguageMode mode) {
    3662             :   v8::Isolate::UseCounterFeature feature;
    3663    25773048 :   if (is_sloppy(mode))
    3664             :     feature = v8::Isolate::kSloppyMode;
    3665    10064807 :   else if (is_strict(mode))
    3666             :     feature = v8::Isolate::kStrictMode;
    3667             :   else
    3668           0 :     UNREACHABLE();
    3669    25773048 :   ++use_counts_[feature];
    3670             :   scope->SetLanguageMode(mode);
    3671    25773048 : }
    3672             : 
    3673        5506 : void Parser::SetAsmModule() {
    3674             :   // Store the usage count; The actual use counter on the isolate is
    3675             :   // incremented after parsing is done.
    3676        5506 :   ++use_counts_[v8::Isolate::kUseAsm];
    3677             :   DCHECK(scope()->is_declaration_scope());
    3678        5506 :   scope()->AsDeclarationScope()->set_asm_module();
    3679        5506 : }
    3680             : 
    3681        3402 : Expression* Parser::ExpressionListToExpression(ZoneList<Expression*>* args) {
    3682        1360 :   Expression* expr = args->at(0);
    3683        4084 :   for (int i = 1; i < args->length(); ++i) {
    3684             :     expr = factory()->NewBinaryOperation(Token::COMMA, expr, args->at(i),
    3685        1364 :                                          expr->position());
    3686             :   }
    3687        1360 :   return expr;
    3688             : }
    3689             : 
    3690             : // This method completes the desugaring of the body of async_function.
    3691             : void Parser::RewriteAsyncFunctionBody(ZoneList<Statement*>* body, Block* block,
    3692             :                                       Expression* return_value, bool* ok) {
    3693             :   // function async_function() {
    3694             :   //   .generator_object = %CreateJSGeneratorObject();
    3695             :   //   BuildRejectPromiseOnException({
    3696             :   //     ... block ...
    3697             :   //     return %ResolvePromise(.promise, expr), .promise;
    3698             :   //   })
    3699             :   // }
    3700             : 
    3701       57024 :   return_value = BuildResolvePromise(return_value, return_value->position());
    3702             :   block->statements()->Add(
    3703       28512 :       factory()->NewReturnStatement(return_value, return_value->position()),
    3704       57024 :       zone());
    3705       28512 :   block = BuildRejectPromiseOnException(block);
    3706       28512 :   body->Add(block, zone());
    3707             : }
    3708             : 
    3709             : class NonPatternRewriter : public AstExpressionRewriter {
    3710             :  public:
    3711        2072 :   NonPatternRewriter(uintptr_t stack_limit, Parser* parser)
    3712        2072 :       : AstExpressionRewriter(stack_limit), parser_(parser) {}
    3713        4144 :   ~NonPatternRewriter() override {}
    3714             : 
    3715             :  private:
    3716        9050 :   bool RewriteExpression(Expression* expr) override {
    3717        9050 :     if (expr->IsRewritableExpression()) return true;
    3718             :     // Rewrite only what could have been a pattern but is not.
    3719        6938 :     if (expr->IsArrayLiteral()) {
    3720             :       // Spread rewriting in array literals.
    3721        4224 :       ArrayLiteral* lit = expr->AsArrayLiteral();
    3722        4224 :       VisitExpressions(lit->values());
    3723        4224 :       replacement_ = parser_->RewriteSpreads(lit);
    3724        2112 :       return false;
    3725             :     }
    3726        4826 :     if (expr->IsObjectLiteral()) {
    3727             :       return true;
    3728             :     }
    3729        4826 :     if (expr->IsBinaryOperation() &&
    3730           0 :         expr->AsBinaryOperation()->op() == Token::COMMA) {
    3731             :       return true;
    3732             :     }
    3733             :     // Everything else does not need rewriting.
    3734        4826 :     return false;
    3735             :   }
    3736             : 
    3737           0 :   void VisitLiteralProperty(LiteralProperty* property) override {
    3738           0 :     if (property == nullptr) return;
    3739             :     // Do not rewrite (computed) key expressions
    3740           0 :     AST_REWRITE_PROPERTY(Expression, property, value);
    3741             :   }
    3742             : 
    3743             :   Parser* parser_;
    3744             : };
    3745             : 
    3746             : void Parser::RewriteNonPattern(bool* ok) {
    3747   155882495 :   ValidateExpression(CHECK_OK_VOID);
    3748   155877676 :   auto non_patterns_to_rewrite = function_state_->non_patterns_to_rewrite();
    3749    77938839 :   int begin = classifier()->GetNonPatternBegin();
    3750             :   int end = non_patterns_to_rewrite->length();
    3751    77938839 :   if (begin < end) {
    3752        2072 :     NonPatternRewriter rewriter(stack_limit_, this);
    3753        2112 :     for (int i = begin; i < end; i++) {
    3754             :       DCHECK(non_patterns_to_rewrite->at(i)->IsRewritableExpression());
    3755        2112 :       rewriter.Rewrite(non_patterns_to_rewrite->at(i));
    3756             :     }
    3757        2072 :     non_patterns_to_rewrite->Rewind(begin);
    3758             :   }
    3759             : }
    3760             : 
    3761             : 
    3762             : void Parser::RewriteDestructuringAssignments() {
    3763     5000836 :   const auto& assignments =
    3764     5000840 :       function_state_->destructuring_assignments_to_rewrite();
    3765     5073892 :   for (int i = assignments.length() - 1; i >= 0; --i) {
    3766             :     // Rewrite list in reverse, so that nested assignment patterns are rewritten
    3767             :     // correctly.
    3768       73056 :     const DestructuringAssignment& pair = assignments.at(i);
    3769       73056 :     RewritableExpression* to_rewrite =
    3770       73056 :         pair.assignment->AsRewritableExpression();
    3771             :     DCHECK_NOT_NULL(to_rewrite);
    3772       73056 :     if (!to_rewrite->is_rewritten()) {
    3773             :       // Since this function is called at the end of parsing the program,
    3774             :       // pair.scope may already have been removed by FinalizeBlockScope in the
    3775             :       // meantime.
    3776       60758 :       Scope* scope = pair.scope->GetUnremovedScope();
    3777       60758 :       BlockState block_state(&scope_, scope);
    3778       60758 :       RewriteDestructuringAssignment(to_rewrite);
    3779             :     }
    3780             :   }
    3781             : }
    3782             : 
    3783             : Expression* Parser::RewriteExponentiation(Expression* left, Expression* right,
    3784             :                                           int pos) {
    3785        1791 :   ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(2, zone());
    3786        1791 :   args->Add(left, zone());
    3787        1791 :   args->Add(right, zone());
    3788        1791 :   return factory()->NewCallRuntime(Context::MATH_POW_INDEX, args, pos);
    3789             : }
    3790             : 
    3791             : Expression* Parser::RewriteAssignExponentiation(Expression* left,
    3792             :                                                 Expression* right, int pos) {
    3793         145 :   ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(2, zone());
    3794         310 :   if (left->IsVariableProxy()) {
    3795         125 :     VariableProxy* lhs = left->AsVariableProxy();
    3796             : 
    3797             :     Expression* result;
    3798             :     DCHECK_NOT_NULL(lhs->raw_name());
    3799         125 :     result = ExpressionFromIdentifier(lhs->raw_name(), lhs->position());
    3800         125 :     args->Add(left, zone());
    3801         125 :     args->Add(right, zone());
    3802             :     Expression* call =
    3803         125 :         factory()->NewCallRuntime(Context::MATH_POW_INDEX, args, pos);
    3804         125 :     return factory()->NewAssignment(Token::ASSIGN, result, call, pos);
    3805          40 :   } else if (left->IsProperty()) {
    3806          60 :     Property* prop = left->AsProperty();
    3807          20 :     auto temp_obj = NewTemporary(ast_value_factory()->empty_string());
    3808          20 :     auto temp_key = NewTemporary(ast_value_factory()->empty_string());
    3809             :     Expression* assign_obj = factory()->NewAssignment(
    3810          20 :         Token::ASSIGN, factory()->NewVariableProxy(temp_obj), prop->obj(),
    3811          40 :         kNoSourcePosition);
    3812             :     Expression* assign_key = factory()->NewAssignment(
    3813          20 :         Token::ASSIGN, factory()->NewVariableProxy(temp_key), prop->key(),
    3814          40 :         kNoSourcePosition);
    3815          20 :     args->Add(factory()->NewProperty(factory()->NewVariableProxy(temp_obj),
    3816          20 :                                      factory()->NewVariableProxy(temp_key),
    3817          60 :                                      left->position()),
    3818          40 :               zone());
    3819          20 :     args->Add(right, zone());
    3820             :     Expression* call =
    3821          20 :         factory()->NewCallRuntime(Context::MATH_POW_INDEX, args, pos);
    3822             :     Expression* target = factory()->NewProperty(
    3823          20 :         factory()->NewVariableProxy(temp_obj),
    3824          40 :         factory()->NewVariableProxy(temp_key), kNoSourcePosition);
    3825             :     Expression* assign =
    3826          20 :         factory()->NewAssignment(Token::ASSIGN, target, call, pos);
    3827             :     return factory()->NewBinaryOperation(
    3828             :         Token::COMMA, assign_obj,
    3829          20 :         factory()->NewBinaryOperation(Token::COMMA, assign_key, assign, pos),
    3830          20 :         pos);
    3831             :   }
    3832           0 :   UNREACHABLE();
    3833             : }
    3834             : 
    3835             : Expression* Parser::RewriteSpreads(ArrayLiteral* lit) {
    3836             :   // Array literals containing spreads are rewritten using do expressions, e.g.
    3837             :   //    [1, 2, 3, ...x, 4, ...y, 5]
    3838             :   // is roughly rewritten as:
    3839             :   //    do {
    3840             :   //      $R = [1, 2, 3];
    3841             :   //      for ($i of x) %AppendElement($R, $i);
    3842             :   //      %AppendElement($R, 4);
    3843             :   //      for ($j of y) %AppendElement($R, $j);
    3844             :   //      %AppendElement($R, 5);
    3845             :   //      $R
    3846             :   //    }
    3847             :   // where $R, $i and $j are fresh temporary variables.
    3848        2112 :   ZoneList<Expression*>::iterator s = lit->FirstSpread();
    3849        2112 :   if (s == lit->EndValue()) return nullptr;  // no spread, no rewriting...
    3850        2112 :   Variable* result = NewTemporary(ast_value_factory()->dot_result_string());
    3851             :   // NOTE: The value assigned to R is the whole original array literal,
    3852             :   // spreads included. This will be fixed before the rewritten AST is returned.
    3853             :   // $R = lit
    3854             :   Expression* init_result = factory()->NewAssignment(
    3855        2112 :       Token::INIT, factory()->NewVariableProxy(result), lit, kNoSourcePosition);
    3856        2112 :   Block* do_block = factory()->NewBlock(16, false);
    3857             :   do_block->statements()->Add(
    3858        2112 :       factory()->NewExpressionStatement(init_result, kNoSourcePosition),
    3859        4224 :       zone());
    3860             :   // Traverse the array literal starting from the first spread.
    3861        5770 :   while (s != lit->EndValue()) {
    3862        3658 :     Expression* value = *s++;
    3863        6452 :     Spread* spread = value->AsSpread();
    3864        3658 :     if (spread == nullptr) {
    3865             :       // If the element is not a spread, we're adding a single:
    3866             :       // %AppendElement($R, value)
    3867             :       // or, in case of a hole,
    3868             :       // ++($R.length)
    3869        1873 :       if (!value->IsLiteral() ||
    3870         290 :           !value->AsLiteral()->raw_value()->IsTheHole()) {
    3871             :         ZoneList<Expression*>* append_element_args = NewExpressionList(2);
    3872         778 :         append_element_args->Add(factory()->NewVariableProxy(result), zone());
    3873         778 :         append_element_args->Add(value, zone());
    3874             :         do_block->statements()->Add(
    3875             :             factory()->NewExpressionStatement(
    3876             :                 factory()->NewCallRuntime(Runtime::kAppendElement,
    3877             :                                           append_element_args,
    3878         778 :                                           kNoSourcePosition),
    3879         778 :                 kNoSourcePosition),
    3880        1556 :             zone());
    3881             :       } else {
    3882             :         Property* length_property = factory()->NewProperty(
    3883          86 :             factory()->NewVariableProxy(result),
    3884             :             factory()->NewStringLiteral(ast_value_factory()->length_string(),
    3885          86 :                                         kNoSourcePosition),
    3886          86 :             kNoSourcePosition);
    3887             :         CountOperation* count_op = factory()->NewCountOperation(
    3888          86 :             Token::INC, true /* prefix */, length_property, kNoSourcePosition);
    3889             :         do_block->statements()->Add(
    3890          86 :             factory()->NewExpressionStatement(count_op, kNoSourcePosition),
    3891         172 :             zone());
    3892             :       }
    3893             :     } else {
    3894             :       // If it's a spread, we're adding a for/of loop iterating through it.
    3895        2794 :       Variable* each = NewTemporary(ast_value_factory()->dot_for_string());
    3896        2794 :       Expression* subject = spread->expression();
    3897             :       // %AppendElement($R, each)
    3898             :       Statement* append_body;
    3899             :       {
    3900             :         ZoneList<Expression*>* append_element_args = NewExpressionList(2);
    3901        2794 :         append_element_args->Add(factory()->NewVariableProxy(result), zone());
    3902        2794 :         append_element_args->Add(factory()->NewVariableProxy(each), zone());
    3903             :         append_body = factory()->NewExpressionStatement(
    3904             :             factory()->NewCallRuntime(Runtime::kAppendElement,
    3905        2794 :                                       append_element_args, kNoSourcePosition),
    3906        2794 :             kNoSourcePosition);
    3907             :       }
    3908             :       // for (each of spread) %AppendElement($R, each)
    3909             :       ForOfStatement* loop =
    3910        2794 :           factory()->NewForOfStatement(nullptr, kNoSourcePosition);
    3911             :       const bool finalize = false;
    3912        2794 :       InitializeForOfStatement(loop, factory()->NewVariableProxy(each), subject,
    3913        2794 :                                append_body, finalize, IteratorType::kNormal);
    3914        2794 :       do_block->statements()->Add(loop, zone());
    3915             :     }
    3916             :   }
    3917             :   // Now, rewind the original array literal to truncate everything from the
    3918             :   // first spread (included) until the end. This fixes $R's initialization.
    3919        2112 :   lit->RewindSpreads();
    3920        2112 :   return factory()->NewDoExpression(do_block, result, lit->position());
    3921             : }
    3922             : 
    3923             : void Parser::QueueDestructuringAssignmentForRewriting(Expression* expr) {
    3924             :   DCHECK(expr->IsRewritableExpression());
    3925             :   function_state_->AddDestructuringAssignment(
    3926       77428 :       DestructuringAssignment(expr, scope()));
    3927             : }
    3928             : 
    3929             : void Parser::QueueNonPatternForRewriting(Expression* expr, bool* ok) {
    3930             :   DCHECK(expr->IsRewritableExpression());
    3931       15205 :   function_state_->AddNonPatternForRewriting(expr, ok);
    3932             : }
    3933             : 
    3934     8375730 : void Parser::SetFunctionNameFromPropertyName(LiteralProperty* property,
    3935             :                                              const AstRawString* name,
    3936             :                                              const AstRawString* prefix) {
    3937             :   // Ensure that the function we are going to create has shared name iff
    3938             :   // we are not going to set it later.
    3939     4187865 :   if (property->NeedsSetFunctionName()) {
    3940             :     name = nullptr;
    3941             :     prefix = nullptr;
    3942             :   } else {
    3943             :     // If the property value is an anonymous function or an anonymous class or
    3944             :     // a concise method or an accessor function which doesn't require the name
    3945             :     // to be set then the shared name must be provided.
    3946             :     DCHECK_IMPLIES(property->value()->IsAnonymousFunctionDefinition() ||
    3947             :                        property->value()->IsConciseMethodDefinition() ||
    3948             :                        property->value()->IsAccessorFunctionDefinition(),
    3949             :                    name != nullptr);
    3950             :   }
    3951             : 
    3952             :   Expression* value = property->value();
    3953     4187865 :   SetFunctionName(value, name, prefix);
    3954     4187863 : }
    3955             : 
    3956           0 : void Parser::SetFunctionNameFromPropertyName(ObjectLiteralProperty* property,
    3957             :                                              const AstRawString* name,
    3958             :                                              const AstRawString* prefix) {
    3959             :   // Ignore "__proto__" as a name when it's being used to set the [[Prototype]]
    3960             :   // of an object literal.
    3961             :   // See ES #sec-__proto__-property-names-in-object-initializers.
    3962     3748579 :   if (property->IsPrototype()) return;
    3963             : 
    3964             :   DCHECK(!property->value()->IsAnonymousFunctionDefinition() ||
    3965             :          property->kind() == ObjectLiteralProperty::COMPUTED);
    3966             : 
    3967             :   SetFunctionNameFromPropertyName(static_cast<LiteralProperty*>(property), name,
    3968     3714946 :                                   prefix);
    3969             : }
    3970             : 
    3971    12713486 : void Parser::SetFunctionNameFromIdentifierRef(Expression* value,
    3972             :                                               Expression* identifier) {
    3973    25426973 :   if (!identifier->IsVariableProxy()) return;
    3974    17406326 :   SetFunctionName(value, identifier->AsVariableProxy()->raw_name());
    3975             : }
    3976             : 
    3977    12891203 : void Parser::SetFunctionName(Expression* value, const AstRawString* name,
    3978             :                              const AstRawString* prefix) {
    3979    38226103 :   if (!value->IsAnonymousFunctionDefinition() &&
    3980    24901035 :       !value->IsConciseMethodDefinition() &&
    3981    12009832 :       !value->IsAccessorFunctionDefinition()) {
    3982    12891199 :     return;
    3983             :   }
    3984      909876 :   auto function = value->AsFunctionLiteral();
    3985      909876 :   if (value->IsClassLiteral()) {
    3986        2447 :     function = value->AsClassLiteral()->constructor();
    3987             :   }
    3988      909876 :   if (function != nullptr) {
    3989             :     AstConsString* cons_name = nullptr;
    3990      909876 :     if (name != nullptr) {
    3991      899416 :       if (prefix != nullptr) {
    3992       25038 :         cons_name = ast_value_factory()->NewConsString(prefix, name);
    3993             :       } else {
    3994      874378 :         cons_name = ast_value_factory()->NewConsString(name);
    3995             :       }
    3996             :     } else {
    3997             :       DCHECK_NULL(prefix);
    3998             :     }
    3999             :     function->set_raw_name(cons_name);
    4000             :   }
    4001             : }
    4002             : 
    4003      165718 : Statement* Parser::CheckCallable(Variable* var, Expression* error, int pos) {
    4004             :   const int nopos = kNoSourcePosition;
    4005             :   Statement* validate_var;
    4006             :   {
    4007             :     Expression* type_of = factory()->NewUnaryOperation(
    4008      497154 :         Token::TYPEOF, factory()->NewVariableProxy(var), nopos);
    4009             :     Expression* function_literal = factory()->NewStringLiteral(
    4010      331436 :         ast_value_factory()->function_string(), nopos);
    4011             :     Expression* condition = factory()->NewCompareOperation(
    4012      165718 :         Token::EQ_STRICT, type_of, function_literal, nopos);
    4013             : 
    4014      165718 :     Statement* throw_call = factory()->NewExpressionStatement(error, pos);
    4015             : 
    4016             :     validate_var = factory()->NewIfStatement(
    4017      331436 :         condition, factory()->NewEmptyStatement(nopos), throw_call, nopos);
    4018             :   }
    4019      165718 :   return validate_var;
    4020             : }
    4021             : 
    4022           0 : void Parser::BuildIteratorClose(ZoneList<Statement*>* statements,
    4023             :                                 Variable* iterator, Variable* input,
    4024             :                                 Variable* var_output, IteratorType type) {
    4025             :   //
    4026             :   // This function adds four statements to [statements], corresponding to the
    4027             :   // following code:
    4028             :   //
    4029             :   //   let iteratorReturn = iterator.return;
    4030             :   //   if (IS_NULL_OR_UNDEFINED(iteratorReturn) {
    4031             :   //     return {value: input, done: true};
    4032             :   //   }
    4033             :   //   output = %_Call(iteratorReturn, iterator, input);
    4034             :   //   if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output);
    4035             :   //
    4036             : 
    4037             :   const int nopos = kNoSourcePosition;
    4038             : 
    4039             :   // let iteratorReturn = iterator.return;
    4040             :   Variable* var_return = var_output;  // Reusing the output variable.
    4041             :   Statement* get_return;
    4042             :   {
    4043           0 :     Expression* iterator_proxy = factory()->NewVariableProxy(iterator);
    4044             :     Expression* literal = factory()->NewStringLiteral(
    4045           0 :         ast_value_factory()->return_string(), nopos);
    4046             :     Expression* property =
    4047           0 :         factory()->NewProperty(iterator_proxy, literal, nopos);
    4048           0 :     Expression* return_proxy = factory()->NewVariableProxy(var_return);
    4049             :     Expression* assignment =
    4050           0 :         factory()->NewAssignment(Token::ASSIGN, return_proxy, property, nopos);
    4051           0 :     get_return = factory()->NewExpressionStatement(assignment, nopos);
    4052             :   }
    4053             : 
    4054             :   // if (IS_NULL_OR_UNDEFINED(iteratorReturn) {
    4055             :   //   return {value: input, done: true};
    4056             :   // }
    4057             :   Statement* check_return;
    4058             :   {
    4059             :     Expression* condition = factory()->NewCompareOperation(
    4060           0 :         Token::EQ, factory()->NewVariableProxy(var_return),
    4061           0 :         factory()->NewNullLiteral(nopos), nopos);
    4062             : 
    4063           0 :     Expression* value = factory()->NewVariableProxy(input);
    4064             : 
    4065           0 :     Statement* return_input = BuildReturnStatement(value, nopos);
    4066             : 
    4067             :     check_return = factory()->NewIfStatement(
    4068           0 :         condition, return_input, factory()->NewEmptyStatement(nopos), nopos);
    4069             :   }
    4070             : 
    4071             :   // output = %_Call(iteratorReturn, iterator, input);
    4072             :   Statement* call_return;
    4073             :   {
    4074           0 :     auto args = new (zone()) ZoneList<Expression*>(3, zone());
    4075           0 :     args->Add(factory()->NewVariableProxy(var_return), zone());
    4076           0 :     args->Add(factory()->NewVariableProxy(iterator), zone());
    4077           0 :     args->Add(factory()->NewVariableProxy(input), zone());
    4078             : 
    4079             :     Expression* call =
    4080           0 :         factory()->NewCallRuntime(Runtime::kInlineCall, args, nopos);
    4081           0 :     if (type == IteratorType::kAsync) {
    4082           0 :       call = factory()->NewAwait(call, nopos);
    4083             :     }
    4084           0 :     Expression* output_proxy = factory()->NewVariableProxy(var_output);
    4085             :     Expression* assignment =
    4086           0 :         factory()->NewAssignment(Token::ASSIGN, output_proxy, call, nopos);
    4087           0 :     call_return = factory()->NewExpressionStatement(assignment, nopos);
    4088             :   }
    4089             : 
    4090             :   // if (!IS_RECEIVER(output)) %ThrowIteratorResultNotAnObject(output);
    4091             :   Statement* validate_output;
    4092             :   {
    4093             :     Expression* is_receiver_call;
    4094             :     {
    4095           0 :       auto args = new (zone()) ZoneList<Expression*>(1, zone());
    4096           0 :       args->Add(factory()->NewVariableProxy(var_output), zone());
    4097             :       is_receiver_call =
    4098           0 :           factory()->NewCallRuntime(Runtime::kInlineIsJSReceiver, args, nopos);
    4099             :     }
    4100             : 
    4101             :     Statement* throw_call;
    4102             :     {
    4103           0 :       auto args = new (zone()) ZoneList<Expression*>(1, zone());
    4104           0 :       args->Add(factory()->NewVariableProxy(var_output), zone());
    4105             :       Expression* call = factory()->NewCallRuntime(
    4106           0 :           Runtime::kThrowIteratorResultNotAnObject, args, nopos);
    4107           0 :       throw_call = factory()->NewExpressionStatement(call, nopos);
    4108             :     }
    4109             : 
    4110             :     validate_output = factory()->NewIfStatement(
    4111           0 :         is_receiver_call, factory()->NewEmptyStatement(nopos), throw_call,
    4112           0 :         nopos);
    4113             :   }
    4114             : 
    4115           0 :   statements->Add(get_return, zone());
    4116           0 :   statements->Add(check_return, zone());
    4117           0 :   statements->Add(call_return, zone());
    4118           0 :   statements->Add(validate_output, zone());
    4119           0 : }
    4120             : 
    4121      165718 : void Parser::FinalizeIteratorUse(Variable* completion, Expression* condition,
    4122             :                                  Variable* iter, Block* iterator_use,
    4123             :                                  Block* target, IteratorType type) {
    4124             :   //
    4125             :   // This function adds two statements to [target], corresponding to the
    4126             :   // following code:
    4127             :   //
    4128             :   //   completion = kNormalCompletion;
    4129             :   //   try {
    4130             :   //     try {
    4131             :   //       iterator_use
    4132             :   //     } catch(e) {
    4133             :   //       if (completion === kAbruptCompletion) completion = kThrowCompletion;
    4134             :   //       %ReThrow(e);
    4135             :   //     }
    4136             :   //   } finally {
    4137             :   //     if (condition) {
    4138             :   //       #BuildIteratorCloseForCompletion(iter, completion)
    4139             :   //     }
    4140             :   //   }
    4141             :   //
    4142             : 
    4143             :   const int nopos = kNoSourcePosition;
    4144             : 
    4145             :   // completion = kNormalCompletion;
    4146             :   Statement* initialize_completion;
    4147             :   {
    4148     1325744 :     Expression* proxy = factory()->NewVariableProxy(completion);
    4149             :     Expression* assignment = factory()->NewAssignment(
    4150             :         Token::ASSIGN, proxy,
    4151      165718 :         factory()->NewSmiLiteral(Parser::kNormalCompletion, nopos), nopos);
    4152             :     initialize_completion =
    4153      331436 :         factory()->NewExpressionStatement(assignment, nopos);
    4154             :   }
    4155             : 
    4156             :   // if (completion === kAbruptCompletion) completion = kThrowCompletion;
    4157             :   Statement* set_completion_throw;
    4158             :   {
    4159             :     Expression* condition = factory()->NewCompareOperation(
    4160      165718 :         Token::EQ_STRICT, factory()->NewVariableProxy(completion),
    4161      331436 :         factory()->NewSmiLiteral(Parser::kAbruptCompletion, nopos), nopos);
    4162             : 
    4163      165718 :     Expression* proxy = factory()->NewVariableProxy(completion);
    4164             :     Expression* assignment = factory()->NewAssignment(
    4165             :         Token::ASSIGN, proxy,
    4166      165718 :         factory()->NewSmiLiteral(Parser::kThrowCompletion, nopos), nopos);
    4167      165718 :     Statement* statement = factory()->NewExpressionStatement(assignment, nopos);
    4168             :     set_completion_throw = factory()->NewIfStatement(
    4169      497154 :         condition, statement, factory()->NewEmptyStatement(nopos), nopos);
    4170             :   }
    4171             : 
    4172             :   // if (condition) {
    4173             :   //   #BuildIteratorCloseForCompletion(iter, completion)
    4174             :   // }
    4175             :   Block* maybe_close;
    4176             :   {
    4177      165718 :     Block* block = factory()->NewBlock(2, true);
    4178      165718 :     Expression* proxy = factory()->NewVariableProxy(completion);
    4179      165718 :     BuildIteratorCloseForCompletion(block->statements(), iter, proxy, type);
    4180             :     DCHECK_EQ(block->statements()->length(), 2);
    4181             : 
    4182             :     maybe_close = IgnoreCompletion(factory()->NewIfStatement(
    4183      331436 :         condition, block, factory()->NewEmptyStatement(nopos), nopos));
    4184             :   }
    4185             : 
    4186             :   // try { #try_block }
    4187             :   // catch(e) {
    4188             :   //   #set_completion_throw;
    4189             :   //   %ReThrow(e);
    4190             :   // }
    4191             :   Statement* try_catch;
    4192             :   {
    4193             :     Scope* catch_scope = NewHiddenCatchScope();
    4194             : 
    4195             :     Statement* rethrow;
    4196             :     // We use %ReThrow rather than the ordinary throw because we want to
    4197             :     // preserve the original exception message.  This is also why we create a
    4198             :     // TryCatchStatementForReThrow below (which does not clear the pending
    4199             :     // message), rather than a TryCatchStatement.
    4200             :     {
    4201      165718 :       auto args = new (zone()) ZoneList<Expression*>(1, zone());
    4202      165718 :       args->Add(factory()->NewVariableProxy(catch_scope->catch_variable()),
    4203      165718 :                 zone());
    4204             :       rethrow = factory()->NewExpressionStatement(
    4205      331436 :           factory()->NewCallRuntime(Runtime::kReThrow, args, nopos), nopos);
    4206             :     }
    4207             : 
    4208      165718 :     Block* catch_block = factory()->NewBlock(2, false);
    4209      165718 :     catch_block->statements()->Add(set_completion_throw, zone());
    4210      165718 :     catch_block->statements()->Add(rethrow, zone());
    4211             : 
    4212             :     try_catch = factory()->NewTryCatchStatementForReThrow(
    4213      331436 :         iterator_use, catch_scope, catch_block, nopos);
    4214             :   }
    4215             : 
    4216             :   // try { #try_catch } finally { #maybe_close }
    4217             :   Statement* try_finally;
    4218             :   {
    4219      165718 :     Block* try_block = factory()->NewBlock(1, false);
    4220      165718 :     try_block->statements()->Add(try_catch, zone());
    4221             : 
    4222             :     try_finally =
    4223      331436 :         factory()->NewTryFinallyStatement(try_block, maybe_close, nopos);
    4224             :   }
    4225             : 
    4226      165718 :   target->statements()->Add(initialize_completion, zone());
    4227      165718 :   target->statements()->Add(try_finally, zone());
    4228      165718 : }
    4229             : 
    4230      165718 : void Parser::BuildIteratorCloseForCompletion(ZoneList<Statement*>* statements,
    4231             :                                              Variable* iterator,
    4232             :                                              Expression* completion,
    4233             :                                              IteratorType type) {
    4234             :   //
    4235             :   // This function adds two statements to [statements], corresponding to the
    4236             :   // following code:
    4237             :   //
    4238             :   //   let iteratorReturn = iterator.return;
    4239             :   //   if (!IS_NULL_OR_UNDEFINED(iteratorReturn)) {
    4240             :   //     if (completion === kThrowCompletion) {
    4241             :   //       if (!IS_CALLABLE(iteratorReturn)) {
    4242             :   //         throw MakeTypeError(kReturnMethodNotCallable);
    4243             :   //       }
    4244             :   //       [if (IteratorType == kAsync)]
    4245             :   //           try { Await(%_Call(iteratorReturn, iterator) } catch (_) { }
    4246             :   //       [else]
    4247             :   //           try { %_Call(iteratorReturn, iterator) } catch (_) { }
    4248             :   //       [endif]
    4249             :   //     } else {
    4250             :   //       [if (IteratorType == kAsync)]
    4251             :   //           let output = Await(%_Call(iteratorReturn, iterator));
    4252             :   //       [else]
    4253             :   //           let output = %_Call(iteratorReturn, iterator);
    4254             :   //       [endif]
    4255             :   //       if (!IS_RECEIVER(output)) {
    4256             :   //         %ThrowIterResultNotAnObject(output);
    4257             :   //       }
    4258             :   //     }
    4259             :   //   }
    4260             :   //
    4261             : 
    4262             :   const int nopos = kNoSourcePosition;
    4263             :   // let iteratorReturn = iterator.return;
    4264     3480078 :   Variable* var_return = NewTemporary(ast_value_factory()->empty_string());
    4265             :   Statement* get_return;
    4266             :   {
    4267      165718 :     Expression* iterator_proxy = factory()->NewVariableProxy(iterator);
    4268             :     Expression* literal = factory()->NewStringLiteral(
    4269      331436 :         ast_value_factory()->return_string(), nopos);
    4270             :     Expression* property =
    4271      165718 :         factory()->NewProperty(iterator_proxy, literal, nopos);
    4272      165718 :     Expression* return_proxy = factory()->NewVariableProxy(var_return);
    4273             :     Expression* assignment =
    4274      165718 :         factory()->NewAssignment(Token::ASSIGN, return_proxy, property, nopos);
    4275      331436 :     get_return = factory()->NewExpressionStatement(assignment, nopos);
    4276             :   }
    4277             : 
    4278             :   // if (!IS_CALLABLE(iteratorReturn)) {
    4279             :   //   throw MakeTypeError(kReturnMethodNotCallable);
    4280             :   // }
    4281             :   Statement* check_return_callable;
    4282             :   {
    4283             :     Expression* throw_expr =
    4284             :         NewThrowTypeError(MessageTemplate::kReturnMethodNotCallable,
    4285      165718 :                           ast_value_factory()->empty_string(), nopos);
    4286      165718 :     check_return_callable = CheckCallable(var_return, throw_expr, nopos);
    4287             :   }
    4288             : 
    4289             :   // try { %_Call(iteratorReturn, iterator) } catch (_) { }
    4290             :   Statement* try_call_return;
    4291             :   {
    4292      165718 :     auto args = new (zone()) ZoneList<Expression*>(2, zone());
    4293      331436 :     args->Add(factory()->NewVariableProxy(var_return), zone());
    4294      331436 :     args->Add(factory()->NewVariableProxy(iterator), zone());
    4295             : 
    4296             :     Expression* call =
    4297      165718 :         factory()->NewCallRuntime(Runtime::kInlineCall, args, nopos);
    4298             : 
    4299      165718 :     if (type == IteratorType::kAsync) {
    4300       20865 :       call = factory()->NewAwait(call, nopos);
    4301             :     }
    4302             : 
    4303      165718 :     Block* try_block = factory()->NewBlock(1, false);
    4304      165718 :     try_block->statements()->Add(factory()->NewExpressionStatement(call, nopos),
    4305      165718 :                                  zone());
    4306             : 
    4307      165718 :     Block* catch_block = factory()->NewBlock(0, false);
    4308             :     Scope* catch_scope = NewHiddenCatchScope();
    4309             :     try_call_return = factory()->NewTryCatchStatement(try_block, catch_scope,
    4310      331436 :                                                       catch_block, nopos);
    4311             :   }
    4312             : 
    4313             :   // let output = %_Call(iteratorReturn, iterator);
    4314             :   // if (!IS_RECEIVER(output)) {
    4315             :   //   %ThrowIteratorResultNotAnObject(output);
    4316             :   // }
    4317             :   Block* validate_return;
    4318             :   {
    4319      165718 :     Variable* var_output = NewTemporary(ast_value_factory()->empty_string());
    4320             :     Statement* call_return;
    4321             :     {
    4322      165718 :       auto args = new (zone()) ZoneList<Expression*>(2, zone());
    4323      331436 :       args->Add(factory()->NewVariableProxy(var_return), zone());
    4324      331436 :       args->Add(factory()->NewVariableProxy(iterator), zone());
    4325             :       Expression* call =
    4326      165718 :           factory()->NewCallRuntime(Runtime::kInlineCall, args, nopos);
    4327      165718 :       if (type == IteratorType::kAsync) {
    4328       20865 :         call = factory()->NewAwait(call, nopos);
    4329             :       }
    4330             : 
    4331      165718 :       Expression* output_proxy = factory()->NewVariableProxy(var_output);
    4332             :       Expression* assignment =
    4333      165718 :           factory()->NewAssignment(Token::ASSIGN, output_proxy, call, nopos);
    4334      331436 :       call_return = factory()->NewExpressionStatement(assignment, nopos);
    4335             :     }
    4336             : 
    4337             :     Expression* is_receiver_call;
    4338             :     {
    4339      165718 :       auto args = new (zone()) ZoneList<Expression*>(1, zone());
    4340      331436 :       args->Add(factory()->NewVariableProxy(var_output), zone());
    4341             :       is_receiver_call =
    4342      165718 :           factory()->NewCallRuntime(Runtime::kInlineIsJSReceiver, args, nopos);
    4343             :     }
    4344             : 
    4345             :     Statement* throw_call;
    4346             :     {
    4347      165718 :       auto args = new (zone()) ZoneList<Expression*>(1, zone());
    4348      331436 :       args->Add(factory()->NewVariableProxy(var_output), zone());
    4349             :       Expression* call = factory()->NewCallRuntime(
    4350      165718 :           Runtime::kThrowIteratorResultNotAnObject, args, nopos);
    4351      165718 :       throw_call = factory()->NewExpressionStatement(call, nopos);
    4352             :     }
    4353             : 
    4354             :     Statement* check_return = factory()->NewIfStatement(
    4355      165718 :         is_receiver_call, factory()->NewEmptyStatement(nopos), throw_call,
    4356      331436 :         nopos);
    4357             : 
    4358      165718 :     validate_return = factory()->NewBlock(2, false);
    4359      165718 :     validate_return->statements()->Add(call_return, zone());
    4360      165718 :     validate_return->statements()->Add(check_return, zone());
    4361             :   }
    4362             : 
    4363             :   // if (completion === kThrowCompletion) {
    4364             :   //   #check_return_callable;
    4365             :   //   #try_call_return;
    4366             :   // } else {
    4367             :   //   #validate_return;
    4368             :   // }
    4369             :   Statement* call_return_carefully;
    4370             :   {
    4371             :     Expression* condition = factory()->NewCompareOperation(
    4372             :         Token::EQ_STRICT, completion,
    4373      165718 :         factory()->NewSmiLiteral(Parser::kThrowCompletion, nopos), nopos);
    4374             : 
    4375      165718 :     Block* then_block = factory()->NewBlock(2, false);
    4376      165718 :     then_block->statements()->Add(check_return_callable, zone());
    4377      165718 :     then_block->statements()->Add(try_call_return, zone());
    4378             : 
    4379             :     call_return_carefully = factory()->NewIfStatement(condition, then_block,
    4380      165718 :                                                       validate_return, nopos);
    4381             :   }
    4382             : 
    4383             :   // if (!IS_NULL_OR_UNDEFINED(iteratorReturn)) { ... }
    4384             :   Statement* maybe_call_return;
    4385             :   {
    4386             :     Expression* condition = factory()->NewCompareOperation(
    4387      165718 :         Token::EQ, factory()->NewVariableProxy(var_return),
    4388      331436 :         factory()->NewNullLiteral(nopos), nopos);
    4389             : 
    4390             :     maybe_call_return = factory()->NewIfStatement(
    4391      165718 :         condition, factory()->NewEmptyStatement(nopos), call_return_carefully,
    4392      331436 :         nopos);
    4393             :   }
    4394             : 
    4395      165718 :   statements->Add(get_return, zone());
    4396      165718 :   statements->Add(maybe_call_return, zone());
    4397      165718 : }
    4398             : 
    4399      200876 : Statement* Parser::FinalizeForOfStatement(ForOfStatement* loop,
    4400             :                                           Variable* var_completion,
    4401             :                                           IteratorType type, int pos) {
    4402             :   //
    4403             :   // This function replaces the loop with the following wrapping:
    4404             :   //
    4405             :   //   completion = kNormalCompletion;
    4406             :   //   try {
    4407             :   //     try {
    4408             :   //       #loop;
    4409             :   //     } catch(e) {
    4410             :   //       if (completion === kAbruptCompletion) completion = kThrowCompletion;
    4411             :   //       %ReThrow(e);
    4412             :   //     }
    4413             :   //   } finally {
    4414             :   //     if (!(completion === kNormalCompletion)) {
    4415             :   //       #BuildIteratorCloseForCompletion(#iterator, completion)
    4416             :   //     }
    4417             :   //   }
    4418             :   //
    4419             :   // Note that the loop's body and its assign_each already contain appropriate
    4420             :   // assignments to completion (see InitializeForOfStatement).
    4421             :   //
    4422             : 
    4423             :   const int nopos = kNoSourcePosition;
    4424             : 
    4425             :   // !(completion === kNormalCompletion)
    4426             :   Expression* closing_condition;
    4427             :   {
    4428             :     Expression* cmp = factory()->NewCompareOperation(
    4429      100438 :         Token::EQ_STRICT, factory()->NewVariableProxy(var_completion),
    4430      301314 :         factory()->NewSmiLiteral(Parser::kNormalCompletion, nopos), nopos);
    4431      100438 :     closing_condition = factory()->NewUnaryOperation(Token::NOT, cmp, nopos);
    4432             :   }
    4433             : 
    4434      100438 :   Block* final_loop = factory()->NewBlock(2, false);
    4435             :   {
    4436      100438 :     Block* try_block = factory()->NewBlock(1, false);
    4437      100438 :     try_block->statements()->Add(loop, zone());
    4438             : 
    4439             :     FinalizeIteratorUse(var_completion, closing_condition, loop->iterator(),
    4440      100438 :                         try_block, final_loop, type);
    4441             :   }
    4442             : 
    4443      100438 :   return final_loop;
    4444             : }
    4445             : 
    4446             : #undef CHECK_OK
    4447             : #undef CHECK_OK_VOID
    4448             : #undef CHECK_FAILED
    4449             : 
    4450             : }  // namespace internal
    4451             : }  // namespace v8

Generated by: LCOV version 1.10