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